From a4044c7cecd1c47f4358868441b3a6756d66d396 Mon Sep 17 00:00:00 2001 From: Michael Bayne Date: Mon, 13 Jun 2011 13:14:23 -0700 Subject: [PATCH] Versions of those of the utility classes that are int-appropriate, specialized on int. --- .../java/pythagoras/i/AbstractDimension.java | 39 ++++ src/main/java/pythagoras/i/AbstractPoint.java | 59 ++++++ .../java/pythagoras/i/AbstractRectangle.java | 193 ++++++++++++++++++ src/main/java/pythagoras/i/Dimension.java | 65 ++++++ src/main/java/pythagoras/i/Dimensions.java | 18 ++ src/main/java/pythagoras/i/IDimension.java | 26 +++ src/main/java/pythagoras/i/IPoint.java | 32 +++ src/main/java/pythagoras/i/IRectangle.java | 90 ++++++++ src/main/java/pythagoras/i/IShape.java | 39 ++++ src/main/java/pythagoras/i/Point.java | 79 +++++++ src/main/java/pythagoras/i/Points.java | 49 +++++ src/main/java/pythagoras/i/Rectangle.java | 183 +++++++++++++++++ src/main/java/pythagoras/i/Rectangles.java | 33 +++ 13 files changed, 905 insertions(+) create mode 100644 src/main/java/pythagoras/i/AbstractDimension.java create mode 100644 src/main/java/pythagoras/i/AbstractPoint.java create mode 100644 src/main/java/pythagoras/i/AbstractRectangle.java create mode 100644 src/main/java/pythagoras/i/Dimension.java create mode 100644 src/main/java/pythagoras/i/Dimensions.java create mode 100644 src/main/java/pythagoras/i/IDimension.java create mode 100644 src/main/java/pythagoras/i/IPoint.java create mode 100644 src/main/java/pythagoras/i/IRectangle.java create mode 100644 src/main/java/pythagoras/i/IShape.java create mode 100644 src/main/java/pythagoras/i/Point.java create mode 100644 src/main/java/pythagoras/i/Points.java create mode 100644 src/main/java/pythagoras/i/Rectangle.java create mode 100644 src/main/java/pythagoras/i/Rectangles.java diff --git a/src/main/java/pythagoras/i/AbstractDimension.java b/src/main/java/pythagoras/i/AbstractDimension.java new file mode 100644 index 0000000..469352d --- /dev/null +++ b/src/main/java/pythagoras/i/AbstractDimension.java @@ -0,0 +1,39 @@ +// +// Pythagoras - a collection of geometry classes +// http://github.com/samskivert/pythagoras + +package pythagoras.i; + +/** + * Provides most of the implementation of {@link IDimension}, obtaining only width and height from + * the derived class. + */ +public abstract class AbstractDimension implements IDimension +{ + @Override // from interface IDimension + public Dimension clone () { + return new Dimension(this); + } + + @Override + public int hashCode () { + return getWidth() ^ getHeight(); + } + + @Override + public boolean equals (Object obj) { + if (obj == this) { + return true; + } + if (obj instanceof AbstractDimension) { + AbstractDimension d = (AbstractDimension)obj; + return (d.getWidth() == getWidth() && d.getHeight() == getHeight()); + } + return false; + } + + @Override + public String toString () { + return Dimensions.dimenToString(getWidth(), getHeight()); + } +} diff --git a/src/main/java/pythagoras/i/AbstractPoint.java b/src/main/java/pythagoras/i/AbstractPoint.java new file mode 100644 index 0000000..db1d342 --- /dev/null +++ b/src/main/java/pythagoras/i/AbstractPoint.java @@ -0,0 +1,59 @@ +// +// Pythagoras - a collection of geometry classes +// http://github.com/samskivert/pythagoras + +package pythagoras.i; + +/** + * Provides most of the implementation of {@link IPoint}, obtaining only the location from the + * derived class. + */ +public abstract class AbstractPoint implements IPoint +{ + @Override // from interface IPoint + public int distanceSq (int px, int py) { + return Points.distanceSq(getX(), getY(), px, py); + } + + @Override // from interface IPoint + public int distanceSq (IPoint p) { + return Points.distanceSq(getX(), getY(), p.getX(), p.getY()); + } + + @Override // from interface IPoint + public int distance (int px, int py) { + return Points.distance(getX(), getY(), px, py); + } + + @Override // from interface IPoint + public int distance (IPoint p) { + return Points.distance(getX(), getY(), p.getX(), p.getY()); + } + + @Override // from interface IPoint + public Point clone () { + return new Point(this); + } + + @Override + public boolean equals (Object obj) { + if (obj == this) { + return true; + } + if (obj instanceof AbstractPoint) { + AbstractPoint p = (AbstractPoint)obj; + return getX() == p.getX() && getY() == p.getY(); + } + return false; + } + + @Override + public int hashCode () { + return getX() ^ getY(); + } + + @Override + public String toString () { + return Points.pointToString(getX(), getY()); + } +} diff --git a/src/main/java/pythagoras/i/AbstractRectangle.java b/src/main/java/pythagoras/i/AbstractRectangle.java new file mode 100644 index 0000000..5b66437 --- /dev/null +++ b/src/main/java/pythagoras/i/AbstractRectangle.java @@ -0,0 +1,193 @@ +// +// Pythagoras - a collection of geometry classes +// http://github.com/samskivert/pythagoras + +package pythagoras.i; + +import java.util.NoSuchElementException; + +/** + * Provides most of the implementation of {@link IRectangle}, obtaining only the location and + * dimensions from the derived class. + */ +public abstract class AbstractRectangle implements IRectangle +{ + @Override // from IRectangle + public int getMinX () { + return getX(); + } + + @Override // from IRectangle + public int getMinY () { + return getY(); + } + + @Override // from IRectangle + public int getMaxX () { + return getX() + getWidth() - 1; + } + + @Override // from IRectangle + public int getMaxY () { + return getY() + getHeight() - 1; + } + + @Override // from interface IRectangle + public Point getLocation () { + return getLocation(new Point()); + } + + @Override // from interface IRectangle + public Point getLocation (Point target) { + target.setLocation(getX(), getY()); + return target; + } + + @Override // from interface IRectangle + public Dimension getSize () { + return getSize(new Dimension()); + } + + @Override // from interface IRectangle + public Dimension getSize (Dimension target) { + target.setSize(getWidth(), getHeight()); + return target; + } + + @Override // from interface IRectangle + public Rectangle intersection (int rx, int ry, int rw, int rh) { + int x1 = Math.max(getX(), rx); + int y1 = Math.max(getY(), ry); + int x2 = Math.min(getMaxX(), rx + rw - 1); + int y2 = Math.min(getMaxY(), ry + rh - 1); + return new Rectangle(x1, y1, x2 - x1, y2 - y1); + } + + @Override // from interface IRectangle + public Rectangle intersection (IRectangle r) { + return intersection(r.getX(), r.getY(), r.getWidth(), r.getHeight()); + } + + @Override // from interface IRectangle + public Rectangle union (IRectangle r) { + Rectangle rect = new Rectangle(this); + rect.add(r); + return rect; + } + + @Override // from interface IRectangle + public int outcode (int px, int py) { + int code = 0; + + if (getWidth() <= 0) { + code |= OUT_LEFT | OUT_RIGHT; + } else if (px < getX()) { + code |= OUT_LEFT; + } else if (px > getMaxX()) { + code |= OUT_RIGHT; + } + + if (getHeight() <= 0) { + code |= OUT_TOP | OUT_BOTTOM; + } else if (py < getY()) { + code |= OUT_TOP; + } else if (py > getMaxY()) { + code |= OUT_BOTTOM; + } + + return code; + } + + @Override // from interface IRectangle + public int outcode (IPoint p) { + return outcode(p.getX(), p.getY()); + } + + @Override // from interface IRectangle + public Rectangle clone () { + return new Rectangle(this); + } + + @Override // from interface IShape + public boolean isEmpty () { + return getWidth() <= 0 || getHeight() <= 0; + } + + @Override // from interface IShape + public boolean contains (int px, int py) { + if (isEmpty()) return false; + + int x = getX(), y = getY(); + if (px < x || py < y) return false; + + px -= x; + py -= y; + return px < getWidth() && py < getHeight(); + } + + @Override // from interface IShape + public boolean contains (IPoint point) { + return contains(point.getX(), point.getY()); + } + + @Override // from interface IShape + public boolean contains (int rx, int ry, int rw, int rh) { + if (isEmpty()) return false; + + int x1 = getX(), y1 = getY(), x2 = x1 + getWidth(), y2 = y1 + getHeight(); + return (x1 <= rx) && (rx + rw <= x2) && (y1 <= ry) && (ry + rh <= y2); + } + + @Override // from interface IShape + public boolean contains (IRectangle rect) { + return contains(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight()); + } + + @Override // from interface IShape + public boolean intersects (int rx, int ry, int rw, int rh) { + if (isEmpty()) return false; + + int x1 = getX(), y1 = getY(), x2 = x1 + getWidth(), y2 = y1 + getHeight(); + return (rx + rw > x1) && (rx < x2) && (ry + rh > y1) && (ry < y2); + } + + @Override // from interface IShape + public boolean intersects (IRectangle rect) { + return intersects(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight()); + } + + @Override // from interface IShape + public Rectangle getBounds () { + return getBounds(new Rectangle()); + } + + @Override // from interface IShape + public Rectangle getBounds (Rectangle target) { + target.setBounds(getX(), getY(), getWidth(), getHeight()); + return target; + } + + @Override // from Object + public boolean equals (Object obj) { + if (obj == this) { + return true; + } + if (obj instanceof AbstractRectangle) { + AbstractRectangle r = (AbstractRectangle)obj; + return r.getX() == getX() && r.getY() == getY() && + r.getWidth() == getWidth() && r.getHeight() == getHeight(); + } + return false; + } + + @Override // from Object + public int hashCode () { + return getX() ^ getY() ^ getWidth() ^ getHeight(); + } + + @Override // from Object + public String toString () { + return Dimensions.dimenToString(getWidth(), getHeight()) + + Points.pointToString(getX(), getY()); + } +} diff --git a/src/main/java/pythagoras/i/Dimension.java b/src/main/java/pythagoras/i/Dimension.java new file mode 100644 index 0000000..1d0ed0f --- /dev/null +++ b/src/main/java/pythagoras/i/Dimension.java @@ -0,0 +1,65 @@ +// +// Pythagoras - a collection of geometry classes +// http://github.com/samskivert/pythagoras + +package pythagoras.i; + +import java.io.Serializable; + +/** + * Represents a magnitude in two dimensions. + */ +public class Dimension extends AbstractDimension implements Serializable +{ + /** The magnitude in the x-dimension. */ + public int width; + + /** The magnitude in the y-dimension. */ + public int height; + + /** + * Creates a dimension with magnitude (0, 0). + */ + public Dimension () { + this(0, 0); + } + + /** + * Creates a dimension with the specified width and height. + */ + public Dimension (int width, int height) { + setSize(width, height); + } + + /** + * Creates a dimension with width and height equal to the supplied dimension. + */ + public Dimension (IDimension d) { + this(d.getWidth(), d.getHeight()); + } + + /** + * Sets the magnitudes of this dimension to the specified width and height. + */ + public void setSize (int width, int height) { + this.width = width; + this.height = height; + } + + /** + * Sets the magnitudes of this dimension to be equal to the supplied dimension. + */ + public void setSize (IDimension d) { + setSize(d.getWidth(), d.getHeight()); + } + + @Override // from interface IDimension + public int getWidth () { + return width; + } + + @Override // from interface IDimension + public int getHeight () { + return height; + } +} diff --git a/src/main/java/pythagoras/i/Dimensions.java b/src/main/java/pythagoras/i/Dimensions.java new file mode 100644 index 0000000..8536d11 --- /dev/null +++ b/src/main/java/pythagoras/i/Dimensions.java @@ -0,0 +1,18 @@ +// +// Pythagoras - a collection of geometry classes +// http://github.com/samskivert/pythagoras + +package pythagoras.i; + +/** + * Dimension-related utility methods. + */ +public class Dimensions +{ + /** + * Returns a string describing the supplied dimension, of the form {@code widthxheight}. + */ + public static String dimenToString (int width, int height) { + return width + "x" + height; + } +} diff --git a/src/main/java/pythagoras/i/IDimension.java b/src/main/java/pythagoras/i/IDimension.java new file mode 100644 index 0000000..2fdfc5f --- /dev/null +++ b/src/main/java/pythagoras/i/IDimension.java @@ -0,0 +1,26 @@ +// +// Pythagoras - a collection of geometry classes +// http://github.com/samskivert/pythagoras + +package pythagoras.i; + +/** + * Provides read-only access to a {@link Dimension}. + */ +public interface IDimension extends Cloneable +{ + /** + * Returns the magnitude in the x-dimension. + */ + int getWidth (); + + /** + * Returns the magnitude in the y-dimension. + */ + int getHeight (); + + /** + * Returns a mutable copy of this dimension. + */ + Dimension clone (); +} diff --git a/src/main/java/pythagoras/i/IPoint.java b/src/main/java/pythagoras/i/IPoint.java new file mode 100644 index 0000000..b9e8f7b --- /dev/null +++ b/src/main/java/pythagoras/i/IPoint.java @@ -0,0 +1,32 @@ +// +// Pythagoras - a collection of geometry classes +// http://github.com/samskivert/pythagoras + +package pythagoras.i; + +/** + * Provides read-only access to a {@link Point}. + */ +public interface IPoint extends Cloneable +{ + /** Returns this point's x-coordinate. */ + int getX (); + + /** Returns this point's y-coordinate. */ + int getY (); + + /** Returns the squared Euclidian distance between this point and the specified point. */ + int distanceSq (int px, int py); + + /** Returns the squared Euclidian distance between this point and the supplied point. */ + int distanceSq (IPoint p); + + /** Returns the Euclidian distance between this point and the specified point. */ + int distance (int px, int py); + + /** Returns the Euclidian distance between this point and the supplied point. */ + int distance (IPoint p); + + /** Returns a mutable copy of this point. */ + Point clone (); +} diff --git a/src/main/java/pythagoras/i/IRectangle.java b/src/main/java/pythagoras/i/IRectangle.java new file mode 100644 index 0000000..a0641ab --- /dev/null +++ b/src/main/java/pythagoras/i/IRectangle.java @@ -0,0 +1,90 @@ +// +// Pythagoras - a collection of geometry classes +// http://github.com/samskivert/pythagoras + +package pythagoras.i; + +/** + * Provides read-only access to a {@link Rectangle}. + */ +public interface IRectangle extends IShape, Cloneable +{ + /** The bitmask that indicates that a point lies to the left of this rectangle. See + * {@link #outcode}. */ + int OUT_LEFT = 1; + + /** The bitmask that indicates that a point lies above this rectangle. See {@link #outcode}. */ + int OUT_TOP = 2; + + /** The bitmask that indicates that a point lies to the right of this rectangle. See + * {@link #outcode}. */ + int OUT_RIGHT = 4; + + /** The bitmask that indicates that a point lies below this rectangle. See {@link #outcode}. */ + int OUT_BOTTOM = 8; + + /** Returns the x-coordinate of the upper-left corner of the framing rectangle. */ + int getX (); + + /** Returns the y-coordinate of the upper-left corner of the framing rectangle. */ + int getY (); + + /** Returns the width of the framing rectangle. */ + int getWidth (); + + /** Returns the height of the framing rectangle. */ + int getHeight (); + + /** Returns the minimum x-coordinate of the framing rectangle. */ + int getMinX (); + + /** Returns the minimum y-coordinate of the framing rectangle. */ + int getMinY (); + + /** Returns the maximum x-coordinate of the framing rectangle. Note: this method + * differs from its inting-point counterparts in that it considers {@code (x + width - 1)} to + * be a rectangle's maximum x-coordinate. */ + int getMaxX (); + + /** Returns the maximum y-coordinate of the framing rectangle. Note: this method + * differs from its inting-point counterparts in that it considers {@code (y + height - 1)} + * to be a rectangle's maximum x-coordinate. */ + int getMaxY (); + + /** Returns a copy of this rectangle's upper-left corner. */ + Point getLocation (); + + /** Initializes the supplied point with this rectangle's upper-left corner. + * @return the supplied point. */ + Point getLocation (Point target); + + /** Returns a copy of this rectangle's size. */ + Dimension getSize (); + + /** Initializes the supplied dimension with this rectangle's size. + * @return the supplied dimension. */ + Dimension getSize (Dimension target); + + /** Returns the intersection of the specified rectangle and this rectangle (i.e. the largest + * rectangle contained in both this and the specified rectangle). */ + Rectangle intersection (int rx, int ry, int rw, int rh); + + /** Returns the intersection of the supplied rectangle and this rectangle (i.e. the largest + * rectangle contained in both this and the supplied rectangle). */ + Rectangle intersection (IRectangle r); + + /** Returns the union of the supplied rectangle and this rectangle (i.e. the smallest rectangle + * that contains both this and the supplied rectangle). */ + Rectangle union (IRectangle r); + + /** Returns a set of flags indicating where the specified point lies in relation to the bounds + * of this rectangle. See {@link #OUT_LEFT}, etc. */ + int outcode (int px, int py); + + /** Returns a set of flags indicating where the supplied point lies in relation to the bounds of + * this rectangle. See {@link #OUT_LEFT}, etc. */ + int outcode (IPoint point); + + /** Returns a mutable copy of this rectangle. */ + Rectangle clone (); +} diff --git a/src/main/java/pythagoras/i/IShape.java b/src/main/java/pythagoras/i/IShape.java new file mode 100644 index 0000000..a97ba0a --- /dev/null +++ b/src/main/java/pythagoras/i/IShape.java @@ -0,0 +1,39 @@ +// +// Pythagoras - a collection of geometry classes +// http://github.com/samskivert/pythagoras + +package pythagoras.i; + +/** + * An interface provided by all shapes. + */ +public interface IShape +{ + /** Returns true if this shape encloses no area. */ + boolean isEmpty (); + + /** Returns true if this shape contains the specified point. */ + boolean contains (int x, int y); + + /** Returns true if this shape contains the supplied point. */ + boolean contains (IPoint point); + + /** Returns true if this shape completely contains the specified rectangle. */ + boolean contains (int x, int y, int width, int height); + + /** Returns true if this shape completely contains the supplied rectangle. */ + boolean contains (IRectangle r); + + /** Returns true if this shape intersects the specified rectangle. */ + boolean intersects (int x, int y, int width, int height); + + /** Returns true if this shape intersects the supplied rectangle. */ + boolean intersects (IRectangle r); + + /** Returns a copy of the bounding rectangle for this shape. */ + Rectangle getBounds (); + + /** Initializes the supplied rectangle with this shape's bounding rectangle. + * @return the supplied rectangle. */ + Rectangle getBounds (Rectangle target); +} diff --git a/src/main/java/pythagoras/i/Point.java b/src/main/java/pythagoras/i/Point.java new file mode 100644 index 0000000..6871ccd --- /dev/null +++ b/src/main/java/pythagoras/i/Point.java @@ -0,0 +1,79 @@ +// +// Pythagoras - a collection of geometry classes +// http://github.com/samskivert/pythagoras + +package pythagoras.i; + +import java.io.Serializable; + +/** + * Represents a point on a plane. + */ +public class Point extends AbstractPoint implements Serializable +{ + /** The x-coordinate of the point. */ + public int x; + + /** The y-coordinate of the point. */ + public int y; + + /** + * Constructs a point at (0, 0). + */ + public Point () { + } + + /** + * Constructs a point at the specified coordinates. + */ + public Point (int x, int y) { + setLocation(x, y); + } + + /** + * Constructs a point with coordinates equal to the supplied point. + */ + public Point (IPoint p) { + setLocation(p.getX(), p.getY()); + } + + /** + * Sets the coordinates of this point to be equal to those of the supplied point. + */ + public void setLocation (IPoint p) { + setLocation(p.getX(), p.getY()); + } + + /** + * Sets the coordinates of this point to the supplied values. + */ + public void setLocation (int x, int y) { + this.x = x; + this.y = y; + } + + /** + * A synonym for {@link #setLocation}. + */ + public void move (int x, int y) { + setLocation(x, y); + } + + /** + * Translates this point by the specified offset. + */ + public void translate (int dx, int dy) { + x += dx; + y += dy; + } + + @Override // from interface IPoint + public int getX () { + return x; + } + + @Override // from interface IPoint + public int getY () { + return y; + } +} diff --git a/src/main/java/pythagoras/i/Points.java b/src/main/java/pythagoras/i/Points.java new file mode 100644 index 0000000..bfc6a9d --- /dev/null +++ b/src/main/java/pythagoras/i/Points.java @@ -0,0 +1,49 @@ +// +// Pythagoras - a collection of geometry classes +// http://github.com/samskivert/pythagoras + +package pythagoras.i; + +/** + * Point-related utility methods. + */ +public class Points +{ + /** + * Returns the squared Euclidian distance between the specified two points. + */ + public static int distanceSq (int x1, int y1, int x2, int y2) { + x2 -= x1; + y2 -= y1; + return x2 * x2 + y2 * y2; + } + + /** + * Returns the Euclidian distance between the specified two points, truncated to the nearest + * integer. + */ + public static int distance (int x1, int y1, int x2, int y2) { + return (int)Math.sqrt(distanceSq(x1, y1, x2, y2)); + } + + /** + * Returns the Manhattan distance between the specified two points. + */ + public static int manhattanDistance (int x1, int y1, int x2, int y2) + { + return Math.abs(x2 - x1) + Math.abs(y2 - y1); + } + + /** + * Returns a string describing the supplied point, of the form {@code +x+y}, {@code +x-y}, + * {@code -x-y}, etc. + */ + public static String pointToString (int x, int y) { + StringBuilder buf = new StringBuilder(); + if (x >= 0) buf.append("+"); + buf.append(x); + if (y >= 0) buf.append("+"); + buf.append(y); + return buf.toString(); + } +} diff --git a/src/main/java/pythagoras/i/Rectangle.java b/src/main/java/pythagoras/i/Rectangle.java new file mode 100644 index 0000000..19cbbbf --- /dev/null +++ b/src/main/java/pythagoras/i/Rectangle.java @@ -0,0 +1,183 @@ +// +// Pythagoras - a collection of geometry classes +// http://github.com/samskivert/pythagoras + +package pythagoras.i; + +import java.io.Serializable; + +/** + * Represents an area in two dimensions. + */ +public class Rectangle extends AbstractRectangle implements Serializable +{ + /** The x-coordinate of the rectangle's upper left corner. */ + public int x; + + /** The y-coordinate of the rectangle's upper left corner. */ + public int y; + + /** The width of the rectangle. */ + public int width; + + /** The height of the rectangle. */ + public int height; + + /** + * Constructs a rectangle at (0,0) and with dimensions (0,0). + */ + public Rectangle () { + } + + /** + * Constructs a rectangle with the supplied upper-left corner and dimensions (0,0). + */ + public Rectangle (IPoint p) { + setBounds(p.getX(), p.getY(), 0, 0); + } + + /** + * Constructs a rectangle with upper-left corner at (0,) and the supplied dimensions. + */ + public Rectangle (IDimension d) { + setBounds(0, 0, d.getWidth(), d.getHeight()); + } + + /** + * Constructs a rectangle with upper-left corner at the supplied point and with the supplied + * dimensions. + */ + public Rectangle (IPoint p, IDimension d) { + setBounds(p.getX(), p.getY(), d.getWidth(), d.getHeight()); + } + + /** + * Constructs a rectangle with the specified upper-left corner and dimensions. + */ + public Rectangle (int x, int y, int width, int height) { + setBounds(x, y, width, height); + } + + /** + * Constructs a rectangle with bounds equal to the supplied rectangle. + */ + public Rectangle (IRectangle r) { + setBounds(r.getX(), r.getY(), r.getWidth(), r.getHeight()); + } + + /** + * Sets the upper-left corner of this rectangle to the specified point. + */ + public void setLocation (int x, int y) { + this.x = x; + this.y = y; + } + + /** + * Sets the upper-left corner of this rectangle to the supplied point. + */ + public void setLocation (IPoint p) { + setLocation(p.getX(), p.getY()); + } + + /** + * Sets the size of this rectangle to the specified dimensions. + */ + public void setSize (int width, int height) { + this.width = width; + this.height = height; + } + + /** + * Sets the size of this rectangle to the supplied dimensions. + */ + public void setSize (IDimension d) { + setSize(d.getWidth(), d.getHeight()); + } + + /** + * Sets the bounds of this rectangle to the specified bounds. + */ + public void setBounds (int x, int y, int width, int height) { + this.x = x; + this.y = y; + this.height = height; + this.width = width; + } + + /** + * Sets the bounds of this rectangle to those of the supplied rectangle. + */ + public void setBounds (IRectangle r) { + setBounds(r.getX(), r.getY(), r.getWidth(), r.getHeight()); + } + + /** + * Grows the bounds of this rectangle by the specified amount (i.e. the upper-left corner moves + * by the specified amount in the negative x and y direction and the width and height grow by + * twice the specified amount). + */ + public void grow (int dx, int dy) { + x -= dx; + y -= dy; + width += dx + dx; + height += dy + dy; + } + + /** + * Translates the upper-left corner of this rectangle by the specified amount. + */ + public void translate (int mx, int my) { + x += mx; + y += my; + } + + /** + * Expands the bounds of this rectangle to contain the specified point. + */ + public void add (int px, int py) { + int x1 = Math.min(x, px); + int x2 = Math.max(x + width, px); + int y1 = Math.min(y, py); + int y2 = Math.max(y + height, py); + setBounds(x1, y1, x2 - x1, y2 - y1); + } + + /** + * Expands the bounds of this rectangle to contain the supplied point. + */ + public void add (IPoint p) { + add(p.getX(), p.getY()); + } + + /** + * Expands the bounds of this rectangle to contain the supplied rectangle. + */ + public void add (IRectangle r) { + int x1 = Math.min(x, r.getX()); + int x2 = Math.max(x + width, r.getX() + r.getWidth()); + int y1 = Math.min(y, r.getY()); + int y2 = Math.max(y + height, r.getY() + r.getHeight()); + setBounds(x1, y1, x2 - x1, y2 - y1); + } + + @Override // from interface IRectangle + public int getX () { + return x; + } + + @Override // from interface IRectangle + public int getY () { + return y; + } + + @Override // from interface IRectangle + public int getWidth () { + return width; + } + + @Override // from interface IRectangle + public int getHeight () { + return height; + } +} diff --git a/src/main/java/pythagoras/i/Rectangles.java b/src/main/java/pythagoras/i/Rectangles.java new file mode 100644 index 0000000..0eee539 --- /dev/null +++ b/src/main/java/pythagoras/i/Rectangles.java @@ -0,0 +1,33 @@ +// +// Pythagoras - a collection of geometry classes +// http://github.com/samskivert/pythagoras + +package pythagoras.i; + +/** + * Rectangle-related utility methods. + */ +public class Rectangles +{ + /** + * Intersects the supplied two rectangles, writing the result into {@code dst}. + */ + public static void intersect (IRectangle src1, IRectangle src2, Rectangle dst) { + int x1 = Math.max(src1.getMinX(), src2.getMinX()); + int y1 = Math.max(src1.getMinY(), src2.getMinY()); + int x2 = Math.min(src1.getMaxX(), src2.getMaxX()); + int y2 = Math.min(src1.getMaxY(), src2.getMaxY()); + dst.setBounds(x1, y1, x2 - x1, y2 - y1); + } + + /** + * Unions the supplied two rectangles, writing the result into {@code dst}. + */ + public static void union (IRectangle src1, IRectangle src2, Rectangle dst) { + int x1 = Math.min(src1.getMinX(), src2.getMinX()); + int y1 = Math.min(src1.getMinY(), src2.getMinY()); + int x2 = Math.max(src1.getMaxX(), src2.getMaxX()); + int y2 = Math.max(src1.getMaxY(), src2.getMaxY()); + dst.setBounds(x1, y1, x2 - x1, y2 - y1); + } +}