commit 50ab3a0c314f96fd5665e366028e21b59cf2c8ae Author: Hannes <13hannes11@gmail.com> Date: Fri Jul 15 14:13:55 2016 +0200 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4eb8642 --- /dev/null +++ b/.gitignore @@ -0,0 +1,91 @@ +# Created by https://www.gitignore.io/api/intellij,java,windows + +### Intellij ### +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff: +.idea/workspace.xml +.idea/tasks.xml +.idea/dictionaries +.idea/vcs.xml +.idea/jsLibraryMappings.xml + +# Sensitive or high-churn files: +.idea/dataSources.ids +.idea/dataSources.xml +.idea/dataSources.local.xml +.idea/sqlDataSources.xml +.idea/dynamic.xml +.idea/uiDesigner.xml + +# Gradle: +.idea/gradle.xml +.idea/libraries + +# Mongo Explorer plugin: +.idea/mongoSettings.xml + +## File-based project format: +*.iws + +## Plugin-specific files: + +# IntelliJ +/out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +### Intellij Patch ### +# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 + +# *.iml +# modules.xml +# .idea/misc.xml +# *.ipr + + +### Windows ### +# Windows image file caches +Thumbs.db +ehthumbs.db + +# Folder config file +Desktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msm +*.msp + +# Windows shortcuts +*.lnk + + +### Java ### +*.class + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.ear + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* \ No newline at end of file diff --git a/XKCDPoster.iml b/XKCDPoster.iml new file mode 100644 index 0000000..d5c0743 --- /dev/null +++ b/XKCDPoster.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/src/ImageMegapixelComparator.java b/src/ImageMegapixelComparator.java new file mode 100644 index 0000000..d0ec52f --- /dev/null +++ b/src/ImageMegapixelComparator.java @@ -0,0 +1,22 @@ +/* + * 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; + +import java.awt.image.BufferedImage; +import java.util.Comparator; + +/** + * + * @author Hannes + */ +public class ImageMegapixelComparator implements Comparator { + + @Override + public int compare(BufferedImage o1, BufferedImage o2) { + return o2.getWidth() * o2.getHeight() - o1.getWidth() * o1.getHeight(); + } + +} diff --git a/src/Main.java b/src/Main.java new file mode 100644 index 0000000..cf48562 --- /dev/null +++ b/src/Main.java @@ -0,0 +1,29 @@ +import xkcd.construction.ImageArranger; +import xkcd.construction.ImageDataLoader; +import xkcd.construction.ImageSticher; +import xkcd.rectangle.imagepath.PathRectangle; + +import java.io.File; +import java.io.IOException; +import java.util.Collection; + +public class Main { + + static final String PATH = "C:\\Users\\Hannes\\xkcd\\"; + + public static void main(final String[] args) throws IOException { + System.out.println("Loading Now!"); + final ImageDataLoader loader = new ImageDataLoader(); + Collection images = loader.load(new File(PATH)); + + System.out.println("Arranging Now!"); + final ImageArranger arranger = new ImageArranger(); + images = arranger.arrangeRectangles(images, 3D / 2D); + System.out.println("Count: " + images.size()); + + System.out.println("Saving Now!"); + final ImageSticher sticher = new ImageSticher(images); + sticher.saveImage(new File("C:\\Users\\Hannes\\Desktop\\savedNew.png")); + System.out.println("DONE!"); + } +} diff --git a/src/RectangleImage.java b/src/RectangleImage.java new file mode 100644 index 0000000..93cf1bf --- /dev/null +++ b/src/RectangleImage.java @@ -0,0 +1,58 @@ +/* + * 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; + +import java.awt.Rectangle; +import java.awt.image.BufferedImage; + +/** + * + * @author Hannes + */ +public class RectangleImage { + Rectangle r; + + public RectangleImage(BufferedImage image, int x, int y) { + r = new Rectangle(x, y, image.getWidth(), image.getHeight()); + } + public RectangleImage(Rectangle rec){ + r = rec; + } + + public int getHeight() { + return r.height; + } + + public int getWidth() { + return r.width; + } + + public int getBoundY() { + return r.y + r.height; + } + + public int getBoundX() { + return r.x + r.width; + } + + public int getX() { + return r.x; + } + + public int getY() { + return r.y; + } + + public Rectangle getRectangle() { + return r; + } + public void setY(int y){ + r.y = y; + } + public boolean intersects(RectangleImage image) { + return r.intersects(image.getRectangle()); + } +} diff --git a/src/xkcd/construction/ImageArranger.java b/src/xkcd/construction/ImageArranger.java new file mode 100644 index 0000000..00c86dc --- /dev/null +++ b/src/xkcd/construction/ImageArranger.java @@ -0,0 +1,260 @@ +/* + * 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.FreeSpaceFactory; +import xkcd.rectangle.freespace.FreeSpaceRectangle; +import xkcd.rectangle.imagepath.PathRectangle; + +import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.util.*; + +/** + * @author Hannes + */ +public class ImageArranger { + + private double ratio; + private final boolean top; + private final boolean left; + + private FreeSpaceRectangle currentBounds; + + private final TreeSet freeSpaceArea; + + private final TreeSet widthSortedSet; + private final TreeSet heightSortedSet; + + private final Collection placed; + + public ImageArranger() { + ratio = 1D; + currentBounds = null; + + left = false; //Bug with left = true + top = false; + + widthSortedSet = new TreeSet<>(new WidthFirstComparator()); + heightSortedSet = new TreeSet<>(new HeightFirstComparator()); + + freeSpaceArea = new TreeSet<>(new AreaComparator()); + + 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) { + System.out.println("Size: " + rectangles); + ratio = heightToWidthRatio; + + widthSortedSet.addAll(rectangles); + heightSortedSet.addAll(rectangles); + + freeSpaceArea.add(new ClockwiseSplitFreeSpaceRectangle(0, 0, 30000, 15000)); + //expandAndPlace(getNextPathRectangle(widthSortedSet.last(), heightSortedSet.last())); + while (widthSortedSet.size() > 0 && heightSortedSet.size() > 0) { + //expandAndPlace(getNextPathRectangle(widthSortedSet.last(), heightSortedSet.last())); + + final Iterator heightIterator = heightSortedSet.descendingIterator(); + final Iterator widthIterator = widthSortedSet.descendingIterator(); + + final Collection pathRectToRemove = new LinkedList<>(); + boolean oneFree = false; + + while (heightIterator.hasNext() || widthIterator.hasNext()) { + PathRectangle tmpPathRect = null; + if (heightIterator.hasNext()) { + tmpPathRect = heightIterator.next(); + } + if (widthIterator.hasNext()) { + if (tmpPathRect == null) { + tmpPathRect = widthIterator.next(); + } else { + tmpPathRect = getNextPathRectangle(widthIterator.next(), tmpPathRect); + } + } + final Collection freeSpaceToAdd = new ArrayList<>(); + for (final Iterator iterator = freeSpaceArea.iterator(); iterator.hasNext(); ) { + final FreeSpaceRectangle nextFree = iterator.next(); + if (nextFree.couldContain(tmpPathRect) && !placed.contains(tmpPathRect)) { + //place(nextFree, tmpPathRect, freeSpaceToAdd); + oneFree = true; + + iterator.remove(); + tmpPathRect.setX((int) nextFree.getX()); + tmpPathRect.setY((int) nextFree.getY()); + + + freeSpaceToAdd.addAll(nextFree.divideUp(tmpPathRect)); + placed.add(tmpPathRect); + System.out.println("Size: " + placed.size()); + //DEBUG + if (Math.abs(tmpPathRect.getWidth() - 612) < 1.0 && Math.abs(tmpPathRect.getHeight() - 6370) < 1.0) + System.out.print("EXISTS"); + //ENDDEBUG + System.out.println(tmpPathRect); + //System.out.println("Freespace to add: " + freeSpaceToAdd.size()); + + + pathRectToRemove.add(tmpPathRect); + + break; + } + } + freeSpaceArea.addAll(freeSpaceToAdd); + } + if (!oneFree) { + System.out.println("No Space Left"); + break; + } + widthSortedSet.removeAll(pathRectToRemove); + heightSortedSet.removeAll(pathRectToRemove); + //TODO: freeSpaceArea.clear(); + } + 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; + } + + /* + private void place(FreeSpaceRectangle freeSpace, PathRectangle toPlace,){ + freeSpaceArea.remove(freeSpace); + freeSpaceArea.addAll(freeSpace.divideUp(toPlace)); + + heightSortedSet.remove(toPlace); + widthSortedSet.remove(toPlace); + placed.add(toPlace); + + toPlace.setX((int) freeSpace.getX()); + toPlace.setY((int) freeSpace.getY()); + }*/ + + private void expandAndPlace(final PathRectangle rect) { + final FreeSpaceFactory factory = new FreeSpaceFactory(); + if (currentBounds == null) { + currentBounds = factory.getFreeSpaceRect(0, 0, (int) rect.getWidth(), (int) rect.getHeight()); + + rect.setX(0); + rect.setY(0); + + addPlaced(rect); + } else { + final FreeSpaceRectangle tmpNewFree = factory.getFreeSpaceRect((int) currentBounds.getX(), (int) currentBounds.getY(), + (int) currentBounds.getWidth(), + (int) currentBounds.getHeight()); + //Top or Bottom + if (rect.height > rect.width) { + + tmpNewFree.setHeight((int) (currentBounds.getHeight() + rect.getHeight())); + tmpNewFree.setWidth((int) (tmpNewFree.getHeight() * ratio)); + + if (top) { + final int x = (int) currentBounds.getX(); + final int y = (int) (currentBounds.getY() - rect.getHeight()); + + rect.setX(x); + rect.setY(y); + tmpNewFree.setX(x); + tmpNewFree.setY(y); + } else { + rect.setX((int) currentBounds.getX()); + rect.setY((int) (currentBounds.getY() + currentBounds.getHeight())); + } + //top = !top; + } // Left and Right + else { + tmpNewFree.setWidth((int) (currentBounds.getWidth() + rect.getWidth())); + tmpNewFree.setHeight((int) (tmpNewFree.getWidth() / ratio)); + if (left) { + //TODO look for bug + final int x = (int) (currentBounds.getX() - rect.getWidth()); + final int y = (int) currentBounds.getY(); + + rect.setX(x); + rect.setY(y); + tmpNewFree.setX(x); + tmpNewFree.setY(y); + } else { + rect.setX((int) (currentBounds.getX() + currentBounds.getWidth())); + rect.setY((int) currentBounds.getY()); + } + //left = !left; + } + addPlaced(rect); + for (final FreeSpaceRectangle freeSpaceRect : tmpNewFree.divideUp(rect)) { + freeSpaceArea.addAll(freeSpaceRect.divideUp(currentBounds)); + freeSpaceArea.remove(freeSpaceRect); + } + currentBounds = tmpNewFree; + } + } + + private void addPlaced(final PathRectangle rect) { + widthSortedSet.remove(rect); + heightSortedSet.remove(rect); + placed.add(rect); + System.out.println(rect); + } +} diff --git a/src/xkcd/construction/ImageDataLoader.java b/src/xkcd/construction/ImageDataLoader.java new file mode 100644 index 0000000..8be25c1 --- /dev/null +++ b/src/xkcd/construction/ImageDataLoader.java @@ -0,0 +1,60 @@ +/* + * 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.rectangle.imagepath.PathRectangle; + +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; + +/** + * @author Hannes + */ +public class ImageDataLoader { + public ImageDataLoader() { + } + + public Collection load(final File path) { + final Collection rectangles = new ArrayList<>(); + + rectangles.addAll(loadFromDirectory(path)); + + return rectangles; + } + + private Collection loadFromDirectory(final File directory) { + final Collection rectangles = new ArrayList<>(); + + for (final File fileEntry : directory.listFiles()) { + if (fileEntry.isDirectory()) { + rectangles.addAll(loadFromDirectory(fileEntry)); + } else { + if (loadFile(fileEntry) != null) { + rectangles.add(loadFile(fileEntry)); + } + } + } + return rectangles; + } + + private PathRectangle loadFile(final File file) { + try { + final BufferedImage tmpImage = ImageIO.read(file); + //TODO use correct rotation data of an Image and rotate image if necessary + if (tmpImage == null) { + return null; + } + return new PathRectangle(file, 0, 0, tmpImage.getWidth(), tmpImage.getHeight()); + + } catch (final IOException ex) { + return null; + } + } +} diff --git a/src/xkcd/construction/ImageSticher.java b/src/xkcd/construction/ImageSticher.java new file mode 100644 index 0000000..b281f29 --- /dev/null +++ b/src/xkcd/construction/ImageSticher.java @@ -0,0 +1,79 @@ +/* + * 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.rectangle.imagepath.PathRectangle; + +import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.util.Collection; + +/** + * @author Hannes + */ +public class ImageSticher { + private final double scaleTo = 1D; + private static final int IMAGE_TYPE = BufferedImage.TYPE_4BYTE_ABGR; + private static final Color BACKGROUND_COLOR = Color.BLACK; + + private BufferedImage collage; + private final Collection rectangles; + + public ImageSticher(final Collection rect) { + this.rectangles = rect; + System.out.println("Count: " + rectangles.size()); + this.initBufferedImage(); + } + + public void saveImage(final File saveFile) throws IOException { + initBufferedImage(); + for (final PathRectangle rectangle : rectangles) { + try { + final BufferedImage image = loadImage(rectangle.getPath()); + //System.out.println(rectangle); + //DEBUG + if (Math.abs(rectangle.getX()) < 1.0 && Math.abs(rectangle.getX() - 6370) < 1.0) + System.out.print("EXISTS"); + //ENDDEBUG + collage.getGraphics().drawImage(image, (int) (rectangle.getX() * scaleTo), (int) (rectangle.getY() * scaleTo), + (int) (rectangle.getWidth() * scaleTo), (int) (rectangle.getHeight() * scaleTo), null); + } catch (final IOException ex) { + System.err.println(ex.getMessage()); + } + } + ImageIO.write(collage, "png", saveFile); + } + + private void initBufferedImage() { + int width = 0; + int height = 0; + for (final PathRectangle rectangle : rectangles) { + final int tmpWidth = (int) (rectangle.getWidth() + rectangle.getX()); + final int tmpHeight = (int) (rectangle.getHeight() + rectangle.getY()); + + + if (tmpWidth > width) { + width = tmpWidth; + } + if (tmpHeight > height) { + height = tmpHeight; + } + } + + collage = new BufferedImage((int) (width * scaleTo), (int) (height * scaleTo), IMAGE_TYPE); + + //collage.getGraphics().setColor(BACKGROUND_COLOR); + //collage.getGraphics().drawRect(0, 0, collage.getWidth(), collage.getHeight()); + //collage.getGraphics().fillRect(0, 0, collage.getWidth(), collage.getHeight()); + } + + private BufferedImage loadImage(final File filePath) throws IOException { + return ImageIO.read(filePath); + } +} diff --git a/src/xkcd/construction/comparator/AreaComparator.java b/src/xkcd/construction/comparator/AreaComparator.java new file mode 100644 index 0000000..49ece57 --- /dev/null +++ b/src/xkcd/construction/comparator/AreaComparator.java @@ -0,0 +1,22 @@ +/* + * 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 java.util.Comparator; +import xkcd.rectangle.CustomRectangle; + +/** + * + * @author Hannes + */ +public class AreaComparator implements Comparator { + + @Override + public int compare(CustomRectangle o1, CustomRectangle o2) { + return Double.compare(o1.width * o1.height, o2.width * o2.height); + } + +} diff --git a/src/xkcd/construction/comparator/HeightFirstComparator.java b/src/xkcd/construction/comparator/HeightFirstComparator.java new file mode 100644 index 0000000..100b6e5 --- /dev/null +++ b/src/xkcd/construction/comparator/HeightFirstComparator.java @@ -0,0 +1,26 @@ +/* + * 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 java.util.Comparator; +import xkcd.rectangle.CustomRectangle; + +/** + * + * @author Hannes + */ +public class HeightFirstComparator implements Comparator { + + @Override + public int compare(CustomRectangle o1, CustomRectangle o2) { + if (Double.compare(o1.getHeight(), o2.getHeight()) == 0) { + return Double.compare(o1.getWidth(), o2.getWidth()); + } else { + return Double.compare(o1.getHeight(), o2.getHeight()); + } + } + +} diff --git a/src/xkcd/construction/comparator/WidthFirstComparator.java b/src/xkcd/construction/comparator/WidthFirstComparator.java new file mode 100644 index 0000000..48b48ff --- /dev/null +++ b/src/xkcd/construction/comparator/WidthFirstComparator.java @@ -0,0 +1,26 @@ +/* + * 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 java.util.Comparator; +import xkcd.rectangle.CustomRectangle; + +/** + * + * @author Hannes + */ +public class WidthFirstComparator implements Comparator { + + @Override + public int compare(CustomRectangle o1, CustomRectangle o2) { + if (Double.compare(o1.getWidth(), o2.getWidth()) == 0) { + 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/xkcd/rectangle/CustomRectangle.java new file mode 100644 index 0000000..3787ffc --- /dev/null +++ b/src/xkcd/rectangle/CustomRectangle.java @@ -0,0 +1,46 @@ +/* + * 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; + +import java.awt.*; + +/** + * @author Hannes + */ +public abstract class CustomRectangle extends Rectangle { + + public CustomRectangle(final int x, final int y, final int width, final int height) { + super(x, y, width, height); + } + + + public final void setX(final int x) { + this.setLocation(x, (int) this.getY()); + } + + public final void setY(final int y) { + this.setLocation((int) this.getX(), y); + } + + public final void setWidth(final int width) { + this.setSize(width, (int) this.getHeight()); + } + + public final void setHeight(final int height) { + this.setSize((int) this.getWidth(), height); + } + + public final boolean couldContain(final Rectangle rect) { + return (rect.getWidth() <= this.getWidth() && rect.getHeight() <= this.getHeight()); + } + + @Override + public String toString() { + String str = ""; + str += "X: " + this.getX() + " Y: " + this.getY() + " w: " + this.getWidth() + " h: " + this.getHeight(); + return str; + } +} diff --git a/src/xkcd/rectangle/freespace/ClockwiseSplitFreeSpaceRectangle.java b/src/xkcd/rectangle/freespace/ClockwiseSplitFreeSpaceRectangle.java new file mode 100644 index 0000000..e2a6c3d --- /dev/null +++ b/src/xkcd/rectangle/freespace/ClockwiseSplitFreeSpaceRectangle.java @@ -0,0 +1,70 @@ +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 new file mode 100644 index 0000000..2033c94 --- /dev/null +++ b/src/xkcd/rectangle/freespace/CounterclockwiseFreeSpaceRectangle.java @@ -0,0 +1,70 @@ +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 new file mode 100644 index 0000000..8062fdd --- /dev/null +++ b/src/xkcd/rectangle/freespace/FreeSpaceFactory.java @@ -0,0 +1,28 @@ +/* + * 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 new file mode 100644 index 0000000..1db7b51 --- /dev/null +++ b/src/xkcd/rectangle/freespace/FreeSpaceRectangle.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 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 new file mode 100644 index 0000000..740208a --- /dev/null +++ b/src/xkcd/rectangle/freespace/LeftRightSplitFreeSpaceRectangle.java @@ -0,0 +1,17 @@ +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 new file mode 100644 index 0000000..d12ebf0 --- /dev/null +++ b/src/xkcd/rectangle/freespace/OptimalSplitFreeSpaceRectangle.java @@ -0,0 +1,20 @@ +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 new file mode 100644 index 0000000..e556e03 --- /dev/null +++ b/src/xkcd/rectangle/freespace/TopBottomSplitFreeSpaceRectangle.java @@ -0,0 +1,21 @@ +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 new file mode 100644 index 0000000..effb0bb --- /dev/null +++ b/src/xkcd/rectangle/imagepath/PathRectangle.java @@ -0,0 +1,38 @@ +/* + * 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(); + } +}