Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import java.awt.geom.Rectangle2D;
- import java.util.ArrayList;
- import java.util.Collection;
- import java.util.Iterator;
- import java.util.List;
- import java.util.NavigableSet;
- import java.util.SortedSet;
- import java.util.TreeSet;
- /**
- * A new approach to calculate the area of rectangles.
- *
- * Problem: We have a collection of Rectangle2D objects. We want to know
- * the area which they occupy. We must respect that they may overlap.
- *
- * Solution: Assume that the rectangles are all rectangular arranged; so the minX, minY,
- * maxX and maxY lines form a rectangular irregular grid. We iterate through
- * all the rectangles and determine which fields of the grid are filled by the
- * content of least one rectangle. In a final loop we will collect together
- * all grid fields which are filled. The sum of the area of these grid fields
- * will be the total area the given rectangles will occupy.
- *
- */
- public class AreaCalculator
- {
- /**
- * The calculation function. Takes a collection of Rectangle2D as argument and returns
- * the occupied area
- *
- * @param rectangles
- * @return
- */
- public static double getArea(Collection<Rectangle2D> rectangles)
- {
- // check boundaries
- if (rectangles == null || rectangles.isEmpty())
- return 0;
- if (rectangles.size() == 1) {
- Rectangle2D r = rectangles.iterator().next();
- return r.getWidth() * r.getHeight();
- }
- // determine the grid
- NavigableSet<Double> horizGridLines = new TreeSet<Double>();
- NavigableSet<Double> vertGridLines = new TreeSet<Double>();
- for(Rectangle2D r : rectangles) {
- horizGridLines.add(r.getMinX());
- horizGridLines.add(r.getMaxX());
- vertGridLines.add(r.getMinY());
- vertGridLines.add(r.getMaxY());
- }
- // store the indizes of filled grid fields in a tree set
- SortedSet<GridLocation> usedLocations = new TreeSet<AreaCalculator.GridLocation>();
- // iterate through the given rectangles and determine the filled grid fields
- double ret = 0; // the value which will be returned
- for(Rectangle2D rect : rectangles) {
- NavigableSet<Double> xValues =
- horizGridLines.subSet(rect.getMinX(), true, rect.getMaxX(), true);
- NavigableSet<Double> yValues =
- vertGridLines.subSet(rect.getMinY(), true, rect.getMaxY(), true);
- Iterator<Double> xit = xValues.iterator();
- double curX = xit.next();
- while(xit.hasNext()) {
- double nextX = xit.next();
- double width = nextX - curX;
- Iterator<Double> yit = yValues.iterator();
- double curY = yit.next();
- while(yit.hasNext()) {
- double nextY = yit.next();
- double height = nextY - curY;
- if (usedLocations.add(new GridLocation(curX, curY))) {
- ret += width*height;
- }
- curY = nextY;
- }
- curX = nextX;
- }
- }
- return ret;
- }
- /**
- * A help class for storing a pair of two double values in a navigable set.
- */
- private static class GridLocation implements Comparable<GridLocation>
- {
- private final double x;
- private final double y;
- public GridLocation(double x, double y)
- {
- this.x = x;
- this.y = y;
- }
- @Override
- public int compareTo(GridLocation o)
- {
- int order = Double.compare(x, o.x);
- if (order != 0)
- return order;
- return Double.compare(y, o.y);
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement