diff --git a/src/Main.java b/src/org/kuchelmeister/xkcd/poster/Main.java similarity index 91% rename from src/Main.java rename to src/org/kuchelmeister/xkcd/poster/Main.java index d127fd0..7dba152 100644 --- a/src/Main.java +++ b/src/org/kuchelmeister/xkcd/poster/Main.java @@ -1,3 +1,5 @@ +package org.kuchelmeister.xkcd.poster; + import java.io.File; import java.io.IOException; import java.util.Collection; @@ -6,10 +8,10 @@ import java.util.LinkedList; import javax.swing.JFileChooser; import javax.swing.filechooser.FileFilter; -import xkcd.construction.ImageArranger; -import xkcd.construction.ImageDataLoader; -import xkcd.construction.ImageSticher; -import xkcd.rectangle.imagepath.PathRectangle; +import org.kuchelmeister.xkcd.poster.construction.ImageArranger; +import org.kuchelmeister.xkcd.poster.construction.ImageDataLoader; +import org.kuchelmeister.xkcd.poster.construction.ImageSticher; +import org.kuchelmeister.xkcd.poster.rectangle.imagepath.PathRectangle; public class Main { diff --git a/src/xkcd/RectangleImage.java b/src/org/kuchelmeister/xkcd/poster/RectangleImage.java similarity index 96% rename from src/xkcd/RectangleImage.java rename to src/org/kuchelmeister/xkcd/poster/RectangleImage.java index 93cf1bf..e341e8f 100644 --- a/src/xkcd/RectangleImage.java +++ b/src/org/kuchelmeister/xkcd/poster/RectangleImage.java @@ -3,7 +3,7 @@ * To change this template file, choose Tools | Templates * and open the template in the editor. */ -package xkcd; +package org.kuchelmeister.xkcd.poster; import java.awt.Rectangle; import java.awt.image.BufferedImage; diff --git a/src/org/kuchelmeister/xkcd/poster/construction/ImageArranger.java b/src/org/kuchelmeister/xkcd/poster/construction/ImageArranger.java new file mode 100644 index 0000000..49f4900 --- /dev/null +++ b/src/org/kuchelmeister/xkcd/poster/construction/ImageArranger.java @@ -0,0 +1,170 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.kuchelmeister.xkcd.poster.construction; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.TreeSet; + +import org.kuchelmeister.xkcd.poster.construction.comparator.AreaComparator; +import org.kuchelmeister.xkcd.poster.construction.comparator.HeightFirstComparator; +import org.kuchelmeister.xkcd.poster.construction.comparator.WidthFirstComparator; +import org.kuchelmeister.xkcd.poster.rectangle.freespace.ClockwiseSplitFreeSpaceRectangle; +import org.kuchelmeister.xkcd.poster.rectangle.freespace.FreeSpaceRectangle; +import org.kuchelmeister.xkcd.poster.rectangle.imagepath.PathRectangle; + +/** + * @author Hannes + */ +public class ImageArranger { + + private final FreeSpaceRectangle currentBounds; + + private final Collection placed; + + private final double factor; + private final int startStepCount; + private final int stopper; + + public ImageArranger() { + factor = 0.5D; + startStepCount = 10000; + stopper = 500; + + currentBounds = null; + + placed = new ArrayList<>(); + + } + + /** + * Shifts the left top corener to the coordinates (0;0) + */ + private void shiftToLeftTop() { + if (currentBounds == null) { + return; + } + final int x = (int) -currentBounds.getX(); + final int y = (int) -currentBounds.getY(); + + for (final PathRectangle rect : placed) { + rect.setX((int) (rect.getX() + x)); + rect.setY((int) (rect.getY() + y)); + } + currentBounds.setX(0); + currentBounds.setY(0); + } + + public Collection arrangeRectangles(final Collection rectangles, + final double heightToWidthRatio) { + int stepCount = startStepCount; + + int height = stepCount; + int width = calcWidthFromHeight(stepCount, heightToWidthRatio); + + int direction = 1; + boolean readyToStop = false; + + while (!readyToStop || arrangeRectangles(rectangles, width, height) == null) { + // Loopcancelpermission: if accuracy is reached (stopper) and direction is from + // to small to to big (direction > 0) + if (stepCount < stopper && direction > 0) { + readyToStop = true; + } + if ((arrangeRectangles(rectangles, width, height) != null && direction > 0) + || (arrangeRectangles(rectangles, width, height) == null && direction < 0)) { + stepCount *= factor; + direction *= -1; + } + height += direction * stepCount; + width = calcWidthFromHeight(height, heightToWidthRatio); + System.out.println("W: " + width + " H:" + height + " StepCount: " + stepCount + " Direction: " + direction + + " ArrangeRectangles: " + ((arrangeRectangles(rectangles, width, height) == null) ? null + : arrangeRectangles(rectangles, width, height).size())); + } + + return arrangeRectangles(rectangles, width, height); + } + + private int calcWidthFromHeight(final int height, final double heightToWidthRatio) { + return (int) Math.round(height * heightToWidthRatio); + } + + public Collection arrangeRectangles(final Collection rectangles, final int width, + final int height) { + // System.out.println("Size: " + rectangles); + + placed.clear(); + final TreeSet widthSortedSet = new TreeSet<>(new WidthFirstComparator()); + final TreeSet heightSortedSet = new TreeSet<>(new HeightFirstComparator()); + + final TreeSet freeSpaceArea = new TreeSet<>(new AreaComparator()); + + widthSortedSet.addAll(rectangles); + heightSortedSet.addAll(rectangles); + + freeSpaceArea.add(new ClockwiseSplitFreeSpaceRectangle(0, 0, width, height)); + + while (widthSortedSet.size() > 0 && heightSortedSet.size() > 0) { + final PathRectangle _tmp = (widthSortedSet.last().getWidth() > heightSortedSet.last().getHeight()) + ? widthSortedSet.last() + : heightSortedSet.last(); + + widthSortedSet.remove(_tmp); + heightSortedSet.remove(_tmp); + + FreeSpaceRectangle _space = null; + + for (final FreeSpaceRectangle s : freeSpaceArea) { + if (s.couldContain(_tmp)) { + _space = s; + break; + } + } + // No space means not every image can be placed + if (_space == null) { + return null; + } + + placed.add(_tmp); + _tmp.setLocation((int) _space.getX(), (int) _space.getY()); + freeSpaceArea.addAll(_space.divideUp(_tmp)); + freeSpaceArea.remove(_space); + } + + shiftToLeftTop(); + + // + /* + * double spaceHeight = 0; double spaceWidth = 0; for (final FreeSpaceRectangle + * rect : freeSpaceArea) { if (rect.getWidth() + rect.getX() > spaceWidth) { + * spaceWidth = rect.getWidth() + rect.getX(); } if (rect.getHeight() + + * rect.getY() > spaceHeight) { spaceHeight = rect.getHeight() + rect.getY(); } + * } final double multiplier = 0.1; final BufferedImage bImage = new + * BufferedImage((int) (spaceWidth * multiplier), (int) (spaceHeight * + * multiplier), BufferedImage.TYPE_INT_ARGB); + * + * for (final FreeSpaceRectangle rect : freeSpaceArea) { final Graphics g = + * bImage.getGraphics(); + * + * + * g.setColor(Color.blue); g.fillRect((int) (rect.getX() * multiplier), (int) + * (rect.getY() * multiplier), (int) (rect.getWidth() * multiplier), (int) + * (rect.getHeight() * multiplier)); g.setColor(Color.red); g.drawRect((int) + * (rect.getX() * multiplier), (int) (rect.getY() * multiplier), (int) + * (rect.getWidth() * multiplier), (int) (rect.getHeight() * multiplier)); } try + * { ImageIO.write(bImage, "png", new + * File("C:\\Users\\Hannes\\Desktop\\savedNewFreeSpace.png")); } catch (final + * IOException e) { e.printStackTrace(); } + */ + // + return placed; + } + + private PathRectangle getNextPathRectangle(final PathRectangle widthRec, final PathRectangle heightRect) { + return (widthRec.getWidth() > heightRect.getHeight()) ? widthRec : heightRect; + } +} diff --git a/src/xkcd/construction/ImageDataLoader.java b/src/org/kuchelmeister/xkcd/poster/construction/ImageDataLoader.java similarity index 94% rename from src/xkcd/construction/ImageDataLoader.java rename to src/org/kuchelmeister/xkcd/poster/construction/ImageDataLoader.java index 94bd215..ecfb23e 100644 --- a/src/xkcd/construction/ImageDataLoader.java +++ b/src/org/kuchelmeister/xkcd/poster/construction/ImageDataLoader.java @@ -3,7 +3,7 @@ * To change this template file, choose Tools | Templates * and open the template in the editor. */ -package xkcd.construction; +package org.kuchelmeister.xkcd.poster.construction; import java.awt.image.BufferedImage; import java.io.File; @@ -13,7 +13,7 @@ import java.util.LinkedList; import javax.imageio.ImageIO; -import xkcd.rectangle.imagepath.PathRectangle; +import org.kuchelmeister.xkcd.poster.rectangle.imagepath.PathRectangle; /** * @author Hannes diff --git a/src/xkcd/construction/ImageSticher.java b/src/org/kuchelmeister/xkcd/poster/construction/ImageSticher.java similarity index 94% rename from src/xkcd/construction/ImageSticher.java rename to src/org/kuchelmeister/xkcd/poster/construction/ImageSticher.java index 2d93ce3..cdb704e 100644 --- a/src/xkcd/construction/ImageSticher.java +++ b/src/org/kuchelmeister/xkcd/poster/construction/ImageSticher.java @@ -3,7 +3,7 @@ * To change this template file, choose Tools | Templates * and open the template in the editor. */ -package xkcd.construction; +package org.kuchelmeister.xkcd.poster.construction; import java.awt.Color; import java.awt.image.BufferedImage; @@ -13,7 +13,7 @@ import java.util.Collection; import javax.imageio.ImageIO; -import xkcd.rectangle.imagepath.PathRectangle; +import org.kuchelmeister.xkcd.poster.rectangle.imagepath.PathRectangle; /** * @author Hannes diff --git a/src/xkcd/construction/comparator/AreaComparator.java b/src/org/kuchelmeister/xkcd/poster/construction/comparator/AreaComparator.java similarity index 83% rename from src/xkcd/construction/comparator/AreaComparator.java rename to src/org/kuchelmeister/xkcd/poster/construction/comparator/AreaComparator.java index 4c9b6c2..9ff515f 100644 --- a/src/xkcd/construction/comparator/AreaComparator.java +++ b/src/org/kuchelmeister/xkcd/poster/construction/comparator/AreaComparator.java @@ -3,9 +3,9 @@ * To change this template file, choose Tools | Templates * and open the template in the editor. */ -package xkcd.construction.comparator; +package org.kuchelmeister.xkcd.poster.construction.comparator; -import xkcd.rectangle.CustomRectangle; +import org.kuchelmeister.xkcd.poster.rectangle.CustomRectangle; import java.util.Comparator; diff --git a/src/xkcd/construction/comparator/HeightFirstComparator.java b/src/org/kuchelmeister/xkcd/poster/construction/comparator/HeightFirstComparator.java similarity index 86% rename from src/xkcd/construction/comparator/HeightFirstComparator.java rename to src/org/kuchelmeister/xkcd/poster/construction/comparator/HeightFirstComparator.java index 70c8179..b61f27a 100644 --- a/src/xkcd/construction/comparator/HeightFirstComparator.java +++ b/src/org/kuchelmeister/xkcd/poster/construction/comparator/HeightFirstComparator.java @@ -3,9 +3,9 @@ * To change this template file, choose Tools | Templates * and open the template in the editor. */ -package xkcd.construction.comparator; +package org.kuchelmeister.xkcd.poster.construction.comparator; -import xkcd.rectangle.CustomRectangle; +import org.kuchelmeister.xkcd.poster.rectangle.CustomRectangle; import java.util.Comparator; diff --git a/src/xkcd/construction/comparator/ImageMegapixelComparator.java b/src/org/kuchelmeister/xkcd/poster/construction/comparator/ImageMegapixelComparator.java similarity index 89% rename from src/xkcd/construction/comparator/ImageMegapixelComparator.java rename to src/org/kuchelmeister/xkcd/poster/construction/comparator/ImageMegapixelComparator.java index 18f2404..bee359c 100644 --- a/src/xkcd/construction/comparator/ImageMegapixelComparator.java +++ b/src/org/kuchelmeister/xkcd/poster/construction/comparator/ImageMegapixelComparator.java @@ -3,7 +3,7 @@ * To change this template file, choose Tools | Templates * and open the template in the editor. */ -package xkcd.construction.comparator; +package org.kuchelmeister.xkcd.poster.construction.comparator; import java.awt.image.BufferedImage; import java.util.Comparator; diff --git a/src/org/kuchelmeister/xkcd/poster/construction/comparator/WidthFirstComparator.java b/src/org/kuchelmeister/xkcd/poster/construction/comparator/WidthFirstComparator.java new file mode 100644 index 0000000..a7a84e8 --- /dev/null +++ b/src/org/kuchelmeister/xkcd/poster/construction/comparator/WidthFirstComparator.java @@ -0,0 +1,30 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.kuchelmeister.xkcd.poster.construction.comparator; + +import java.util.Comparator; + +import org.kuchelmeister.xkcd.poster.rectangle.CustomRectangle; + +/** + * @author Hannes + */ +public class WidthFirstComparator implements Comparator { + + @Override + public int compare(final CustomRectangle o1, final CustomRectangle o2) { + if (Double.compare(o1.getWidth(), o2.getWidth()) == 0) { + if (Double.compare(o1.getHeight(), o2.getHeight()) == 0) { + return Integer.compare(o1.hashCode(), o2.hashCode()); + } else { + return Double.compare(o1.getHeight(), o2.getHeight()); + } + } else { + return Double.compare(o1.getWidth(), o2.getWidth()); + } + } + +} diff --git a/src/xkcd/rectangle/CustomRectangle.java b/src/org/kuchelmeister/xkcd/poster/rectangle/CustomRectangle.java similarity index 96% rename from src/xkcd/rectangle/CustomRectangle.java rename to src/org/kuchelmeister/xkcd/poster/rectangle/CustomRectangle.java index 3787ffc..59bb55e 100644 --- a/src/xkcd/rectangle/CustomRectangle.java +++ b/src/org/kuchelmeister/xkcd/poster/rectangle/CustomRectangle.java @@ -3,7 +3,7 @@ * To change this template file, choose Tools | Templates * and open the template in the editor. */ -package xkcd.rectangle; +package org.kuchelmeister.xkcd.poster.rectangle; import java.awt.*; diff --git a/src/org/kuchelmeister/xkcd/poster/rectangle/freespace/ClockwiseSplitFreeSpaceRectangle.java b/src/org/kuchelmeister/xkcd/poster/rectangle/freespace/ClockwiseSplitFreeSpaceRectangle.java new file mode 100644 index 0000000..1ffc2d1 --- /dev/null +++ b/src/org/kuchelmeister/xkcd/poster/rectangle/freespace/ClockwiseSplitFreeSpaceRectangle.java @@ -0,0 +1,74 @@ +package org.kuchelmeister.xkcd.poster.rectangle.freespace; + +import java.util.ArrayList; +import java.util.Collection; + +import org.kuchelmeister.xkcd.poster.rectangle.CustomRectangle; + +/** + * @author Hannes + */ +public class ClockwiseSplitFreeSpaceRectangle extends FreeSpaceRectangle { + + public ClockwiseSplitFreeSpaceRectangle(final int x, final int y, final int width, final int height) { + super(x, y, width, height); + } + + @Override + public Collection divideUp(final CustomRectangle r) { + // System.out.println("Main: " + r.toString()); + // System.out.println("THIS: " + this.toString()); + final Collection rectangles = new ArrayList<>(); + if (!this.contains(r)) { + return rectangles; + } + final FreeSpaceFactory factory = new FreeSpaceFactory(); + + // Left + int x = 0; + int y = 0; + int tmpWidth = (int) (r.getX() - this.getX()); + int tmpHeight = (int) (r.getY() + r.getHeight() - this.getY()); + + if (tmpHeight > 0 && tmpWidth > 0) { + rectangles.add(factory.getFreeSpaceRect(x, y, tmpWidth, tmpHeight)); + // System.out.println("Left: " + factory.getFreeSpaceRect(x, y, tmpWidth, + // tmpHeight).toString()); + } + // Top + x = (int) r.getX(); + y = (int) this.getY(); + tmpWidth = (int) (this.getX() + this.getWidth() - r.getX()); + tmpHeight = (int) (r.getY() - this.getY()); + + if (tmpHeight > 0 && tmpWidth > 0) { + rectangles.add(factory.getFreeSpaceRect(x, y, tmpWidth, tmpHeight)); + // System.out.println("Top: " + factory.getFreeSpaceRect(x, y, tmpWidth, + // tmpHeight).toString()); + } + // Right + x = (int) (r.getX() + r.getWidth()); + y = (int) r.getY(); + tmpWidth = (int) (this.getX() + this.getWidth() - (r.getX() + r.getWidth())); + tmpHeight = (int) (this.getY() + this.getHeight() - r.getY()); + + if (tmpHeight > 0 && tmpWidth > 0) { + rectangles.add(factory.getFreeSpaceRect(x, y, tmpWidth, tmpHeight)); + // System.out.println("Right: " + factory.getFreeSpaceRect(x, y, tmpWidth, + // tmpHeight).toString()); + } + + // Bottom + x = (int) this.getX(); + y = (int) (r.getY() + r.getHeight()); + tmpWidth = (int) ((r.getX() + r.getWidth()) - this.getX()); + tmpHeight = (int) (this.getY() + this.getHeight() - (r.getY() + r.getHeight())); + + if (tmpHeight > 0 && tmpWidth > 0) { + rectangles.add(factory.getFreeSpaceRect(x, y, tmpWidth, tmpHeight)); + // System.out.println("Bottom: " + factory.getFreeSpaceRect(x, y, tmpWidth, + // tmpHeight).toString()); + } + return rectangles; + } +} diff --git a/src/org/kuchelmeister/xkcd/poster/rectangle/freespace/CounterclockwiseFreeSpaceRectangle.java b/src/org/kuchelmeister/xkcd/poster/rectangle/freespace/CounterclockwiseFreeSpaceRectangle.java new file mode 100644 index 0000000..5a24db4 --- /dev/null +++ b/src/org/kuchelmeister/xkcd/poster/rectangle/freespace/CounterclockwiseFreeSpaceRectangle.java @@ -0,0 +1,76 @@ +package org.kuchelmeister.xkcd.poster.rectangle.freespace; + +import java.util.ArrayList; +import java.util.Collection; + +import org.kuchelmeister.xkcd.poster.rectangle.CustomRectangle; +import org.kuchelmeister.xkcd.poster.rectangle.freespace.FreeSpaceFactory; +import org.kuchelmeister.xkcd.poster.rectangle.freespace.FreeSpaceRectangle; + +/** + * @author Hannes + */ +public class CounterclockwiseFreeSpaceRectangle extends FreeSpaceRectangle { + + public CounterclockwiseFreeSpaceRectangle(final int x, final int y, final int width, final int height) { + super(x, y, width, height); + } + + @Override + public Collection divideUp(final CustomRectangle r) { + // System.out.println("Main: " + r.toString()); + // System.out.println("THIS: " + this.toString()); + final Collection rectangles = new ArrayList<>(); + if (!this.contains(r)) { + return rectangles; + } + final FreeSpaceFactory factory = new FreeSpaceFactory(); + + // Left + int x = 0; + int y = 0; + int tmpWidth = (int) ((r.getX() + r.getWidth()) - this.getX()); + int tmpHeight = (int) (r.getY() - this.getY()); + + if (tmpHeight > 0 && tmpWidth > 0) { + rectangles.add(factory.getFreeSpaceRect(x, y, tmpWidth, tmpHeight)); + // System.out.println("Left: " + factory.getFreeSpaceRect(x, y, tmpWidth, + // tmpHeight).toString()); + } + // Top + x = (int) (r.getX() + r.getWidth()); + y = (int) this.getY(); + tmpWidth = (int) (this.getX() + this.getWidth() - (r.getX() + r.getWidth())); + tmpHeight = (int) (r.getY() + r.getHeight() - this.getY()); + + if (tmpHeight > 0 && tmpWidth > 0) { + rectangles.add(factory.getFreeSpaceRect(x, y, tmpWidth, tmpHeight)); + // System.out.println("Top: " + factory.getFreeSpaceRect(x, y, tmpWidth, + // tmpHeight).toString()); + } + // Right + x = (int) (r.getX()); + y = (int) (r.getY() + r.getHeight()); + tmpWidth = (int) (this.getX() + this.getWidth() - r.getX()); + tmpHeight = (int) (this.getY() + this.getHeight() - (r.getY() + r.getHeight())); + + if (tmpHeight > 0 && tmpWidth > 0) { + rectangles.add(factory.getFreeSpaceRect(x, y, tmpWidth, tmpHeight)); + // System.out.println("Right: " + factory.getFreeSpaceRect(x, y, tmpWidth, + // tmpHeight).toString()); + } + + // Bottom + x = (int) this.getX(); + y = (int) (r.getY()); + tmpWidth = (int) (r.getX() - this.getX()); + tmpHeight = (int) (this.getY() + this.getHeight() - r.getY()); + + if (tmpHeight > 0 && tmpWidth > 0) { + rectangles.add(factory.getFreeSpaceRect(x, y, tmpWidth, tmpHeight)); + // System.out.println("Bottom: " + factory.getFreeSpaceRect(x, y, tmpWidth, + // tmpHeight).toString()); + } + return rectangles; + } +} diff --git a/src/org/kuchelmeister/xkcd/poster/rectangle/freespace/FreeSpaceFactory.java b/src/org/kuchelmeister/xkcd/poster/rectangle/freespace/FreeSpaceFactory.java new file mode 100644 index 0000000..7d1a692 --- /dev/null +++ b/src/org/kuchelmeister/xkcd/poster/rectangle/freespace/FreeSpaceFactory.java @@ -0,0 +1,31 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.kuchelmeister.xkcd.poster.rectangle.freespace; + +import org.kuchelmeister.xkcd.poster.rectangle.freespace.ClockwiseSplitFreeSpaceRectangle; +import org.kuchelmeister.xkcd.poster.rectangle.freespace.FreeSpaceRectangle; + +/** + * @author Hannes + */ +public class FreeSpaceFactory { + private int counter; + + public FreeSpaceFactory() { + counter = 0; + } + + public FreeSpaceRectangle getFreeSpaceRect(final int x, final int y, final int width, final int height) { + counter++; + switch (counter % 2) { + case 1: + return new ClockwiseSplitFreeSpaceRectangle(x, y, width, height); + // case 0 + default: + return new CounterclockwiseFreeSpaceRectangle(x, y, width, height); + } + } +} diff --git a/src/org/kuchelmeister/xkcd/poster/rectangle/freespace/FreeSpaceRectangle.java b/src/org/kuchelmeister/xkcd/poster/rectangle/freespace/FreeSpaceRectangle.java new file mode 100644 index 0000000..56cd5c3 --- /dev/null +++ b/src/org/kuchelmeister/xkcd/poster/rectangle/freespace/FreeSpaceRectangle.java @@ -0,0 +1,34 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.kuchelmeister.xkcd.poster.rectangle.freespace; + +import java.util.Collection; + +import org.kuchelmeister.xkcd.poster.rectangle.CustomRectangle; + +/** + * + * @author Hannes + */ +public abstract class FreeSpaceRectangle extends CustomRectangle { + + public FreeSpaceRectangle(final int x, final int y, final int width, final int height) { + super(x, y, width, height); + } + + /** + * Method returns the smaller rectangles that will be generated if 'r' is placed + * inside the xkcd.rectangle If r is outsdie of this xkcd.rectangle the + * Collection will conly contain this. Otherwise it will only contain + * subrectangles. + * + * @param r + * the xkcd.rectangle which is placed and arround which shall be + * split + * @return xkcd.rectangle + */ + public abstract Collection divideUp(CustomRectangle r); +} diff --git a/src/org/kuchelmeister/xkcd/poster/rectangle/freespace/LeftRightSplitFreeSpaceRectangle.java b/src/org/kuchelmeister/xkcd/poster/rectangle/freespace/LeftRightSplitFreeSpaceRectangle.java new file mode 100644 index 0000000..a6b2e15 --- /dev/null +++ b/src/org/kuchelmeister/xkcd/poster/rectangle/freespace/LeftRightSplitFreeSpaceRectangle.java @@ -0,0 +1,18 @@ +package org.kuchelmeister.xkcd.poster.rectangle.freespace; + +import java.util.Collection; + +import org.kuchelmeister.xkcd.poster.rectangle.CustomRectangle; + +public class LeftRightSplitFreeSpaceRectangle extends FreeSpaceRectangle { + + public LeftRightSplitFreeSpaceRectangle(final int x, final int y, final int width, final int height) { + super(x, y, width, height); + } + + @Override + public Collection divideUp(final CustomRectangle r) { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, choose + // Tools | Templates. + } +} diff --git a/src/org/kuchelmeister/xkcd/poster/rectangle/freespace/OptimalSplitFreeSpaceRectangle.java b/src/org/kuchelmeister/xkcd/poster/rectangle/freespace/OptimalSplitFreeSpaceRectangle.java new file mode 100644 index 0000000..bca0d63 --- /dev/null +++ b/src/org/kuchelmeister/xkcd/poster/rectangle/freespace/OptimalSplitFreeSpaceRectangle.java @@ -0,0 +1,21 @@ +package org.kuchelmeister.xkcd.poster.rectangle.freespace; + +import java.util.Collection; + +import org.kuchelmeister.xkcd.poster.rectangle.CustomRectangle; + +/** + * @author Hannes + */ +public class OptimalSplitFreeSpaceRectangle extends FreeSpaceRectangle { + + public OptimalSplitFreeSpaceRectangle(final int x, final int y, final int width, final int height) { + super(x, y, width, height); + } + + @Override + public Collection divideUp(final CustomRectangle r) { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, choose + // Tools | Templates. + } +} diff --git a/src/org/kuchelmeister/xkcd/poster/rectangle/freespace/TopBottomSplitFreeSpaceRectangle.java b/src/org/kuchelmeister/xkcd/poster/rectangle/freespace/TopBottomSplitFreeSpaceRectangle.java new file mode 100644 index 0000000..2da7f42 --- /dev/null +++ b/src/org/kuchelmeister/xkcd/poster/rectangle/freespace/TopBottomSplitFreeSpaceRectangle.java @@ -0,0 +1,22 @@ +package org.kuchelmeister.xkcd.poster.rectangle.freespace; + +import java.util.Collection; + +import org.kuchelmeister.xkcd.poster.rectangle.CustomRectangle; + +/** + * @param + * @author Hannes + */ +public class TopBottomSplitFreeSpaceRectangle extends FreeSpaceRectangle { + + public TopBottomSplitFreeSpaceRectangle(final int x, final int y, final int width, final int height) { + super(x, y, width, height); + } + + @Override + public Collection divideUp(final CustomRectangle r) { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, choose + // Tools | Templates. + } +} diff --git a/src/org/kuchelmeister/xkcd/poster/rectangle/imagepath/PathRectangle.java b/src/org/kuchelmeister/xkcd/poster/rectangle/imagepath/PathRectangle.java new file mode 100644 index 0000000..bb029d3 --- /dev/null +++ b/src/org/kuchelmeister/xkcd/poster/rectangle/imagepath/PathRectangle.java @@ -0,0 +1,39 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.kuchelmeister.xkcd.poster.rectangle.imagepath; + +import java.io.File; +import java.io.FileNotFoundException; + +import org.kuchelmeister.xkcd.poster.rectangle.CustomRectangle; + +/** + * @author Hannes + */ +public class PathRectangle extends CustomRectangle { + private final File path; + + public PathRectangle(final File filePath, final int x, final int y, final int width, final int height) + throws FileNotFoundException { + super(x, y, width, height); + path = filePath; + if (!path.exists()) { + throw new FileNotFoundException("The filepath is not valid"); + } + } + + /** + * @return the path + */ + public File getPath() { + return path; + } + + @Override + public String toString() { + return super.toString() + " Path: " + path.toString(); + } +} diff --git a/src/xkcd/construction/ImageArranger.java b/src/xkcd/construction/ImageArranger.java deleted file mode 100644 index e396359..0000000 --- a/src/xkcd/construction/ImageArranger.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package xkcd.construction; - -import xkcd.construction.comparator.AreaComparator; -import xkcd.construction.comparator.HeightFirstComparator; -import xkcd.construction.comparator.WidthFirstComparator; -import xkcd.rectangle.freespace.ClockwiseSplitFreeSpaceRectangle; -import xkcd.rectangle.freespace.FreeSpaceRectangle; -import xkcd.rectangle.imagepath.PathRectangle; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.TreeSet; - -/** - * @author Hannes - */ -public class ImageArranger { - - - private final FreeSpaceRectangle currentBounds; - - private final Collection placed; - - private final double factor; - private final int startStepCount; - private final int stopper; - - public ImageArranger() { - factor = 0.5D; - startStepCount = 10000; - stopper = 500; - - currentBounds = null; - - placed = new ArrayList<>(); - - } - - /** - * Shifts the left top corener to the coordinates (0;0) - */ - private void shiftToLeftTop() { - if (currentBounds == null) - return; - final int x = (int) -currentBounds.getX(); - final int y = (int) -currentBounds.getY(); - - for (final PathRectangle rect : placed) { - rect.setX((int) (rect.getX() + x)); - rect.setY((int) (rect.getY() + y)); - } - currentBounds.setX(0); - currentBounds.setY(0); - } - - public Collection arrangeRectangles(final Collection rectangles, final double heightToWidthRatio) { - int stepCount = startStepCount; - - int height = stepCount; - int width = calcWidthFromHeight(stepCount, heightToWidthRatio); - - - int direction = 1; - boolean readyToStop = false; - - while (!readyToStop || arrangeRectangles(rectangles, width, height) == null) { - //Loopcancelpermission: if accuracy is reached (stopper) and direction is from to small to to big (direction > 0) - if (stepCount < stopper && direction > 0) { - readyToStop = true; - } - if ((arrangeRectangles(rectangles, width, height) != null && direction > 0) - || (arrangeRectangles(rectangles, width, height) == null && direction < 0)) { - stepCount *= factor; - direction *= -1; - } - height += direction * stepCount; - width = calcWidthFromHeight(height, heightToWidthRatio); - System.out.println("W: " + width + " H:" + height + " StepCount: " + stepCount + " Direction: " + direction + - " ArrangeRectangles: " + ((arrangeRectangles(rectangles, width, height) == null) ? null : arrangeRectangles(rectangles, width, height).size())); - } - - return arrangeRectangles(rectangles, width, height); - } - - private int calcWidthFromHeight(final int height, final double heightToWidthRatio) { - return (int) Math.round(height * heightToWidthRatio); - } - - public Collection arrangeRectangles(final Collection rectangles, final int width, final int height) { - //System.out.println("Size: " + rectangles); - - placed.clear(); - final TreeSet widthSortedSet = new TreeSet<>(new WidthFirstComparator()); - final TreeSet heightSortedSet = new TreeSet<>(new HeightFirstComparator()); - - final TreeSet freeSpaceArea = new TreeSet<>(new AreaComparator()); - - widthSortedSet.addAll(rectangles); - heightSortedSet.addAll(rectangles); - - freeSpaceArea.add(new ClockwiseSplitFreeSpaceRectangle(0, 0, width, height)); - - while (widthSortedSet.size() > 0 && heightSortedSet.size() > 0) { - final PathRectangle _tmp = (widthSortedSet.last().getWidth() > heightSortedSet.last().getHeight()) ? widthSortedSet.last() : heightSortedSet.last(); - - widthSortedSet.remove(_tmp); - heightSortedSet.remove(_tmp); - - FreeSpaceRectangle _space = null; - - for (final FreeSpaceRectangle s : freeSpaceArea) { - if (s.couldContain(_tmp)) { - _space = s; - break; - } - } - //No space means not every image can be placed - if (_space == null) { - return null; - } - - placed.add(_tmp); - _tmp.setLocation((int) _space.getX(), (int) _space.getY()); - freeSpaceArea.addAll(_space.divideUp(_tmp)); - freeSpaceArea.remove(_space); - } - - shiftToLeftTop(); - - // - /* - double spaceHeight = 0; - double spaceWidth = 0; - for (final FreeSpaceRectangle rect : freeSpaceArea) { - if (rect.getWidth() + rect.getX() > spaceWidth) { - spaceWidth = rect.getWidth() + rect.getX(); - } - if (rect.getHeight() + rect.getY() > spaceHeight) { - spaceHeight = rect.getHeight() + rect.getY(); - } - } - final double multiplier = 0.1; - final BufferedImage bImage = new BufferedImage((int) (spaceWidth * multiplier), (int) (spaceHeight * multiplier), BufferedImage.TYPE_INT_ARGB); - - for (final FreeSpaceRectangle rect : freeSpaceArea) { - final Graphics g = bImage.getGraphics(); - - - g.setColor(Color.blue); - g.fillRect((int) (rect.getX() * multiplier), (int) (rect.getY() * multiplier), (int) (rect.getWidth() * multiplier), (int) (rect.getHeight() * multiplier)); - g.setColor(Color.red); - g.drawRect((int) (rect.getX() * multiplier), (int) (rect.getY() * multiplier), (int) (rect.getWidth() * multiplier), (int) (rect.getHeight() * multiplier)); - } - try { - ImageIO.write(bImage, "png", new File("C:\\Users\\Hannes\\Desktop\\savedNewFreeSpace.png")); - } catch (final IOException e) { - e.printStackTrace(); - } - */ - // - return placed; - } - - private PathRectangle getNextPathRectangle(final PathRectangle widthRec, final PathRectangle heightRect) { - return (widthRec.getWidth() > heightRect.getHeight()) - ? widthRec : heightRect; - } -} diff --git a/src/xkcd/construction/comparator/WidthFirstComparator.java b/src/xkcd/construction/comparator/WidthFirstComparator.java deleted file mode 100644 index 618d98d..0000000 --- a/src/xkcd/construction/comparator/WidthFirstComparator.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package xkcd.construction.comparator; - -import xkcd.rectangle.CustomRectangle; - -import java.util.Comparator; - -/** - * @author Hannes - */ -public class WidthFirstComparator implements Comparator { - - @Override - public int compare(final CustomRectangle o1, final CustomRectangle o2) { - if (Double.compare(o1.getWidth(), o2.getWidth()) == 0) { - if (Double.compare(o1.getHeight(), o2.getHeight()) == 0) { - return Integer.compare(o1.hashCode(), o2.hashCode()); - } else { - return Double.compare(o1.getHeight(), o2.getHeight()); - } - } else { - return Double.compare(o1.getWidth(), o2.getWidth()); - } - } - -} diff --git a/src/xkcd/rectangle/freespace/ClockwiseSplitFreeSpaceRectangle.java b/src/xkcd/rectangle/freespace/ClockwiseSplitFreeSpaceRectangle.java deleted file mode 100644 index e2a6c3d..0000000 --- a/src/xkcd/rectangle/freespace/ClockwiseSplitFreeSpaceRectangle.java +++ /dev/null @@ -1,70 +0,0 @@ -package xkcd.rectangle.freespace; - -import xkcd.rectangle.CustomRectangle; - -import java.util.ArrayList; -import java.util.Collection; - -/** - * @author Hannes - */ -public class ClockwiseSplitFreeSpaceRectangle extends FreeSpaceRectangle { - - public ClockwiseSplitFreeSpaceRectangle(final int x, final int y, final int width, final int height) { - super(x, y, width, height); - } - - @Override - public Collection divideUp(final CustomRectangle r) { - //System.out.println("Main: " + r.toString()); - //System.out.println("THIS: " + this.toString()); - final Collection rectangles = new ArrayList<>(); - if (!this.contains(r)) { - return rectangles; - } - final FreeSpaceFactory factory = new FreeSpaceFactory(); - - //Left - int x = 0; - int y = 0; - int tmpWidth = (int) (r.getX() - this.getX()); - int tmpHeight = (int) (r.getY() + r.getHeight() - this.getY()); - - if (tmpHeight > 0 && tmpWidth > 0) { - rectangles.add(factory.getFreeSpaceRect(x, y, tmpWidth, tmpHeight)); - //System.out.println("Left: " + factory.getFreeSpaceRect(x, y, tmpWidth, tmpHeight).toString()); - } - //Top - x = (int) r.getX(); - y = (int) this.getY(); - tmpWidth = (int) (this.getX() + this.getWidth() - r.getX()); - tmpHeight = (int) (r.getY() - this.getY()); - - if (tmpHeight > 0 && tmpWidth > 0) { - rectangles.add(factory.getFreeSpaceRect(x, y, tmpWidth, tmpHeight)); - //System.out.println("Top: " + factory.getFreeSpaceRect(x, y, tmpWidth, tmpHeight).toString()); - } - //Right - x = (int) (r.getX() + r.getWidth()); - y = (int) r.getY(); - tmpWidth = (int) (this.getX() + this.getWidth() - (r.getX() + r.getWidth())); - tmpHeight = (int) (this.getY() + this.getHeight() - r.getY()); - - if (tmpHeight > 0 && tmpWidth > 0) { - rectangles.add(factory.getFreeSpaceRect(x, y, tmpWidth, tmpHeight)); - //System.out.println("Right: " + factory.getFreeSpaceRect(x, y, tmpWidth, tmpHeight).toString()); - } - - //Bottom - x = (int) this.getX(); - y = (int) (r.getY() + r.getHeight()); - tmpWidth = (int) ((r.getX() + r.getWidth()) - this.getX()); - tmpHeight = (int) (this.getY() + this.getHeight() - (r.getY() + r.getHeight())); - - if (tmpHeight > 0 && tmpWidth > 0) { - rectangles.add(factory.getFreeSpaceRect(x, y, tmpWidth, tmpHeight)); - //System.out.println("Bottom: " + factory.getFreeSpaceRect(x, y, tmpWidth, tmpHeight).toString()); - } - return rectangles; - } -} diff --git a/src/xkcd/rectangle/freespace/CounterclockwiseFreeSpaceRectangle.java b/src/xkcd/rectangle/freespace/CounterclockwiseFreeSpaceRectangle.java deleted file mode 100644 index 2033c94..0000000 --- a/src/xkcd/rectangle/freespace/CounterclockwiseFreeSpaceRectangle.java +++ /dev/null @@ -1,70 +0,0 @@ -package xkcd.rectangle.freespace; - -import xkcd.rectangle.CustomRectangle; - -import java.util.ArrayList; -import java.util.Collection; - -/** - * @author Hannes - */ -public class CounterclockwiseFreeSpaceRectangle extends FreeSpaceRectangle { - - public CounterclockwiseFreeSpaceRectangle(final int x, final int y, final int width, final int height) { - super(x, y, width, height); - } - - @Override - public Collection divideUp(final CustomRectangle r) { - //System.out.println("Main: " + r.toString()); - //System.out.println("THIS: " + this.toString()); - final Collection rectangles = new ArrayList<>(); - if (!this.contains(r)) { - return rectangles; - } - final FreeSpaceFactory factory = new FreeSpaceFactory(); - - //Left - int x = 0; - int y = 0; - int tmpWidth = (int) ((r.getX() + r.getWidth()) - this.getX()); - int tmpHeight = (int) (r.getY() - this.getY()); - - if (tmpHeight > 0 && tmpWidth > 0) { - rectangles.add(factory.getFreeSpaceRect(x, y, tmpWidth, tmpHeight)); - //System.out.println("Left: " + factory.getFreeSpaceRect(x, y, tmpWidth, tmpHeight).toString()); - } - //Top - x = (int) (r.getX() + r.getWidth()); - y = (int) this.getY(); - tmpWidth = (int) (this.getX() + this.getWidth() - (r.getX() + r.getWidth())); - tmpHeight = (int) (r.getY() + r.getHeight() - this.getY()); - - if (tmpHeight > 0 && tmpWidth > 0) { - rectangles.add(factory.getFreeSpaceRect(x, y, tmpWidth, tmpHeight)); - //System.out.println("Top: " + factory.getFreeSpaceRect(x, y, tmpWidth, tmpHeight).toString()); - } - //Right - x = (int) (r.getX()); - y = (int) (r.getY() + r.getHeight()); - tmpWidth = (int) (this.getX() + this.getWidth() - r.getX()); - tmpHeight = (int) (this.getY() + this.getHeight() - (r.getY() + r.getHeight())); - - if (tmpHeight > 0 && tmpWidth > 0) { - rectangles.add(factory.getFreeSpaceRect(x, y, tmpWidth, tmpHeight)); - //System.out.println("Right: " + factory.getFreeSpaceRect(x, y, tmpWidth, tmpHeight).toString()); - } - - //Bottom - x = (int) this.getX(); - y = (int) (r.getY()); - tmpWidth = (int) (r.getX() - this.getX()); - tmpHeight = (int) (this.getY() + this.getHeight() - r.getY()); - - if (tmpHeight > 0 && tmpWidth > 0) { - rectangles.add(factory.getFreeSpaceRect(x, y, tmpWidth, tmpHeight)); - //System.out.println("Bottom: " + factory.getFreeSpaceRect(x, y, tmpWidth, tmpHeight).toString()); - } - return rectangles; - } -} diff --git a/src/xkcd/rectangle/freespace/FreeSpaceFactory.java b/src/xkcd/rectangle/freespace/FreeSpaceFactory.java deleted file mode 100644 index 8062fdd..0000000 --- a/src/xkcd/rectangle/freespace/FreeSpaceFactory.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package xkcd.rectangle.freespace; - -/** - * @author Hannes - */ -public class FreeSpaceFactory { - private int counter; - - public FreeSpaceFactory() { - counter = 0; - } - - public FreeSpaceRectangle getFreeSpaceRect(final int x, final int y, final int width, final int height) { - counter++; - switch (counter % 2) { - case 1: - return new ClockwiseSplitFreeSpaceRectangle(x, y, width, height); - //case 0 - default: - return new CounterclockwiseFreeSpaceRectangle(x, y, width, height); - } - } -} diff --git a/src/xkcd/rectangle/freespace/FreeSpaceRectangle.java b/src/xkcd/rectangle/freespace/FreeSpaceRectangle.java deleted file mode 100644 index 1db7b51..0000000 --- a/src/xkcd/rectangle/freespace/FreeSpaceRectangle.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package xkcd.rectangle.freespace; - -import java.util.Collection; -import xkcd.rectangle.CustomRectangle; - -/** - * - * @author Hannes - */ -public abstract class FreeSpaceRectangle extends CustomRectangle { - - public FreeSpaceRectangle(int x, int y, int width, int height) { - super(x, y, width, height); - } - - /** - * Method returns the smaller rectangles that will be generated if 'r' is placed inside the xkcd.rectangle - * If r is outsdie of this xkcd.rectangle the Collection will conly contain this. - * Otherwise it will only contain subrectangles. - * @param r - * the xkcd.rectangle which is placed and arround which shall be split - * @return - * xkcd.rectangle - */ - public abstract Collection divideUp(CustomRectangle r); -} diff --git a/src/xkcd/rectangle/freespace/LeftRightSplitFreeSpaceRectangle.java b/src/xkcd/rectangle/freespace/LeftRightSplitFreeSpaceRectangle.java deleted file mode 100644 index 740208a..0000000 --- a/src/xkcd/rectangle/freespace/LeftRightSplitFreeSpaceRectangle.java +++ /dev/null @@ -1,17 +0,0 @@ -package xkcd.rectangle.freespace; - -import xkcd.rectangle.CustomRectangle; - -import java.util.Collection; - -public class LeftRightSplitFreeSpaceRectangle extends FreeSpaceRectangle { - - public LeftRightSplitFreeSpaceRectangle(final int x, final int y, final int width, final int height) { - super(x, y, width, height); - } - - @Override - public Collection divideUp(final CustomRectangle r) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } -} diff --git a/src/xkcd/rectangle/freespace/OptimalSplitFreeSpaceRectangle.java b/src/xkcd/rectangle/freespace/OptimalSplitFreeSpaceRectangle.java deleted file mode 100644 index d12ebf0..0000000 --- a/src/xkcd/rectangle/freespace/OptimalSplitFreeSpaceRectangle.java +++ /dev/null @@ -1,20 +0,0 @@ -package xkcd.rectangle.freespace; - -import xkcd.rectangle.CustomRectangle; - -import java.util.Collection; - -/** - * @author Hannes - */ -public class OptimalSplitFreeSpaceRectangle extends FreeSpaceRectangle { - - public OptimalSplitFreeSpaceRectangle(final int x, final int y, final int width, final int height) { - super(x, y, width, height); - } - - @Override - public Collection divideUp(final CustomRectangle r) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } -} diff --git a/src/xkcd/rectangle/freespace/TopBottomSplitFreeSpaceRectangle.java b/src/xkcd/rectangle/freespace/TopBottomSplitFreeSpaceRectangle.java deleted file mode 100644 index e556e03..0000000 --- a/src/xkcd/rectangle/freespace/TopBottomSplitFreeSpaceRectangle.java +++ /dev/null @@ -1,21 +0,0 @@ -package xkcd.rectangle.freespace; - -import xkcd.rectangle.CustomRectangle; - -import java.util.Collection; - -/** - * @param - * @author Hannes - */ -public class TopBottomSplitFreeSpaceRectangle extends FreeSpaceRectangle { - - public TopBottomSplitFreeSpaceRectangle(final int x, final int y, final int width, final int height) { - super(x, y, width, height); - } - - @Override - public Collection divideUp(final CustomRectangle r) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } -} diff --git a/src/xkcd/rectangle/imagepath/PathRectangle.java b/src/xkcd/rectangle/imagepath/PathRectangle.java deleted file mode 100644 index effb0bb..0000000 --- a/src/xkcd/rectangle/imagepath/PathRectangle.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package xkcd.rectangle.imagepath; - -import xkcd.rectangle.CustomRectangle; - -import java.io.File; -import java.io.FileNotFoundException; - -/** - * @author Hannes - */ -public class PathRectangle extends CustomRectangle { - private final File path; - - public PathRectangle(final File filePath, final int x, final int y, final int width, final int height) throws FileNotFoundException { - super(x, y, width, height); - path = filePath; - if (!path.exists()) { - throw new FileNotFoundException("The filepath is not valid"); - } - } - - /** - * @return the path - */ - public File getPath() { - return path; - } - - @Override - public String toString() { - return super.toString() + " Path: " + path.toString(); - } -}