changed package names to follow common standards

This commit is contained in:
Hannes
2017-11-10 00:30:37 +01:00
parent bdeea31043
commit 0cbc960c2a
28 changed files with 532 additions and 513 deletions

View File

@@ -1,3 +1,5 @@
package org.kuchelmeister.xkcd.poster;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.Collection; import java.util.Collection;
@@ -6,10 +8,10 @@ import java.util.LinkedList;
import javax.swing.JFileChooser; import javax.swing.JFileChooser;
import javax.swing.filechooser.FileFilter; import javax.swing.filechooser.FileFilter;
import xkcd.construction.ImageArranger; import org.kuchelmeister.xkcd.poster.construction.ImageArranger;
import xkcd.construction.ImageDataLoader; import org.kuchelmeister.xkcd.poster.construction.ImageDataLoader;
import xkcd.construction.ImageSticher; import org.kuchelmeister.xkcd.poster.construction.ImageSticher;
import xkcd.rectangle.imagepath.PathRectangle; import org.kuchelmeister.xkcd.poster.rectangle.imagepath.PathRectangle;
public class Main { public class Main {

View File

@@ -3,7 +3,7 @@
* To change this template file, choose Tools | Templates * To change this template file, choose Tools | Templates
* and open the template in the editor. * and open the template in the editor.
*/ */
package xkcd; package org.kuchelmeister.xkcd.poster;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;

View File

@@ -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<PathRectangle> 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<PathRectangle> arrangeRectangles(final Collection<PathRectangle> 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<PathRectangle> arrangeRectangles(final Collection<PathRectangle> rectangles, final int width,
final int height) {
// System.out.println("Size: " + rectangles);
placed.clear();
final TreeSet<PathRectangle> widthSortedSet = new TreeSet<>(new WidthFirstComparator());
final TreeSet<PathRectangle> heightSortedSet = new TreeSet<>(new HeightFirstComparator());
final TreeSet<FreeSpaceRectangle> 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();
// <DEBUG>
/*
* 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(); }
*/
// </DEGUB>
return placed;
}
private PathRectangle getNextPathRectangle(final PathRectangle widthRec, final PathRectangle heightRect) {
return (widthRec.getWidth() > heightRect.getHeight()) ? widthRec : heightRect;
}
}

View File

@@ -3,7 +3,7 @@
* To change this template file, choose Tools | Templates * To change this template file, choose Tools | Templates
* and open the template in the editor. * and open the template in the editor.
*/ */
package xkcd.construction; package org.kuchelmeister.xkcd.poster.construction;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.File; import java.io.File;
@@ -13,7 +13,7 @@ import java.util.LinkedList;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import xkcd.rectangle.imagepath.PathRectangle; import org.kuchelmeister.xkcd.poster.rectangle.imagepath.PathRectangle;
/** /**
* @author Hannes * @author Hannes

View File

@@ -3,7 +3,7 @@
* To change this template file, choose Tools | Templates * To change this template file, choose Tools | Templates
* and open the template in the editor. * and open the template in the editor.
*/ */
package xkcd.construction; package org.kuchelmeister.xkcd.poster.construction;
import java.awt.Color; import java.awt.Color;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
@@ -13,7 +13,7 @@ import java.util.Collection;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import xkcd.rectangle.imagepath.PathRectangle; import org.kuchelmeister.xkcd.poster.rectangle.imagepath.PathRectangle;
/** /**
* @author Hannes * @author Hannes

View File

@@ -3,9 +3,9 @@
* To change this template file, choose Tools | Templates * To change this template file, choose Tools | Templates
* and open the template in the editor. * 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; import java.util.Comparator;

View File

@@ -3,9 +3,9 @@
* To change this template file, choose Tools | Templates * To change this template file, choose Tools | Templates
* and open the template in the editor. * 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; import java.util.Comparator;

View File

@@ -3,7 +3,7 @@
* To change this template file, choose Tools | Templates * To change this template file, choose Tools | Templates
* and open the template in the editor. * 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.awt.image.BufferedImage;
import java.util.Comparator; import java.util.Comparator;

View File

@@ -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<CustomRectangle> {
@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());
}
}
}

View File

@@ -3,7 +3,7 @@
* To change this template file, choose Tools | Templates * To change this template file, choose Tools | Templates
* and open the template in the editor. * and open the template in the editor.
*/ */
package xkcd.rectangle; package org.kuchelmeister.xkcd.poster.rectangle;
import java.awt.*; import java.awt.*;

View File

@@ -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<FreeSpaceRectangle> divideUp(final CustomRectangle r) {
// System.out.println("Main: " + r.toString());
// System.out.println("THIS: " + this.toString());
final Collection<FreeSpaceRectangle> 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;
}
}

View File

@@ -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<FreeSpaceRectangle> divideUp(final CustomRectangle r) {
// System.out.println("Main: " + r.toString());
// System.out.println("THIS: " + this.toString());
final Collection<FreeSpaceRectangle> 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;
}
}

View File

@@ -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);
}
}
}

View File

@@ -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<FreeSpaceRectangle> divideUp(CustomRectangle r);
}

View File

@@ -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<FreeSpaceRectangle> divideUp(final CustomRectangle r) {
throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, choose
// Tools | Templates.
}
}

View File

@@ -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<FreeSpaceRectangle> divideUp(final CustomRectangle r) {
throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, choose
// Tools | Templates.
}
}

View File

@@ -0,0 +1,22 @@
package org.kuchelmeister.xkcd.poster.rectangle.freespace;
import java.util.Collection;
import org.kuchelmeister.xkcd.poster.rectangle.CustomRectangle;
/**
* @param <T>
* @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<FreeSpaceRectangle> divideUp(final CustomRectangle r) {
throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, choose
// Tools | Templates.
}
}

View File

@@ -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();
}
}

View File

@@ -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<PathRectangle> 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<PathRectangle> arrangeRectangles(final Collection<PathRectangle> 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<PathRectangle> arrangeRectangles(final Collection<PathRectangle> rectangles, final int width, final int height) {
//System.out.println("Size: " + rectangles);
placed.clear();
final TreeSet<PathRectangle> widthSortedSet = new TreeSet<>(new WidthFirstComparator());
final TreeSet<PathRectangle> heightSortedSet = new TreeSet<>(new HeightFirstComparator());
final TreeSet<FreeSpaceRectangle> 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();
//<DEBUG>
/*
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();
}
*/
//</DEGUB>
return placed;
}
private PathRectangle getNextPathRectangle(final PathRectangle widthRec, final PathRectangle heightRect) {
return (widthRec.getWidth() > heightRect.getHeight())
? widthRec : heightRect;
}
}

View File

@@ -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<CustomRectangle> {
@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());
}
}
}

View File

@@ -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<FreeSpaceRectangle> divideUp(final CustomRectangle r) {
//System.out.println("Main: " + r.toString());
//System.out.println("THIS: " + this.toString());
final Collection<FreeSpaceRectangle> 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;
}
}

View File

@@ -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<FreeSpaceRectangle> divideUp(final CustomRectangle r) {
//System.out.println("Main: " + r.toString());
//System.out.println("THIS: " + this.toString());
final Collection<FreeSpaceRectangle> 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;
}
}

View File

@@ -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);
}
}
}

View File

@@ -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<FreeSpaceRectangle> divideUp(CustomRectangle r);
}

View File

@@ -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<FreeSpaceRectangle> divideUp(final CustomRectangle r) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}

View File

@@ -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<FreeSpaceRectangle> divideUp(final CustomRectangle r) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}

View File

@@ -1,21 +0,0 @@
package xkcd.rectangle.freespace;
import xkcd.rectangle.CustomRectangle;
import java.util.Collection;
/**
* @param <T>
* @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<FreeSpaceRectangle> divideUp(final CustomRectangle r) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}

View File

@@ -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();
}
}