commit e3c4be2602e3cdae98a35d022df04cb3559d425f Author: Michael Bayne Date: Wed Jun 8 11:47:52 2011 -0700 Beginnings of new geometry library. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/NOTICE b/NOTICE new file mode 100644 index 0000000..c61635f --- /dev/null +++ b/NOTICE @@ -0,0 +1,15 @@ +The Pythagoras project is derived from code from the Apache Harmony Project, +for which the following notice applies: + +Copyright 2006, 2010 The Apache Software Foundation. + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). + +Portions of Apache Harmony were originally developed by Intel Corporation and +are licensed to the Apache Software Foundation under the "Software Grant and +Corporate Contribution License Agreement" and for which the following copyright +notices apply + (C) Copyright 2005 Intel Corporation + (C) Copyright 2005-2006 Intel Corporation + (C) Copyright 2006 Intel Corporation diff --git a/README.md b/README.md new file mode 100644 index 0000000..6204765 --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +# Pythagoras + +Pythagoras is a collection of geometry classes, the implementations of which +were adapted from the Apache Harmony project. The Pythagoras library aims to +provide performant, portable geometry routines for projects that cannot make +use of `java.awt.geom` (for example for use in GWT projects or Android +projects). + +## License + +Pythagoras is released under the Apache License, Version 2.0 which can be found +in the `LICENSE` file and at http://www.apache.org/licenses/LICENSE-2.0 on the +web. diff --git a/build.xml b/build.xml new file mode 100644 index 0000000..24f7d09 --- /dev/null +++ b/build.xml @@ -0,0 +1,109 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/etc/SOURCE_HEADER b/etc/SOURCE_HEADER new file mode 100644 index 0000000..14c7bde --- /dev/null +++ b/etc/SOURCE_HEADER @@ -0,0 +1,4 @@ +// +// Pythagoras - a collection of geometry classes +// http://github.com/samskivert/pythagoras + diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..fb4598d --- /dev/null +++ b/pom.xml @@ -0,0 +1,127 @@ + + + 4.0.0 + com.samskivert + pythagoras + jar + 1.0-SNAPSHOT + pythagoras + + Portable geometry routines, adapted from Apache Harmony geometry classes. + + http://github.com/samskivert/pythagoras/ + + http://github.com/samsivert/pythagoras/issues + + + + org.sonatype.oss + oss-parent + 5 + + + + + GNU Lesser General Public License (LGPL), Version 2 with Classpath Exception + http://openjdk.java.net/legal/gplv2+ce.html + repo + + + + + + samskivert + Michael Bayne + mdb@samskivert.com + + + + + scm:git:git://github.com/samskivert/pythagoras.git + scm:git:git@github.com:samskivert/pythagoras.git + http://github.com/samskivert/pythagoras/ + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.3.2 + + 1.6 + 1.6 + true + true + true + + -Xlint" "-Xlint:-serial" "-Xlint:-path + + + + org.apache.maven.plugins + maven-resources-plugin + 2.4.3 + + UTF-8 + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.7 + + true + public + + + + org.apache.maven.plugins + maven-jar-plugin + 2.3.1 + + + org.apache.maven.plugins + maven-install-plugin + 2.3.1 + + + org.apache.maven.plugins + maven-deploy-plugin + 2.5 + + + + + + + release-sign-artifacts + + performReleasetrue + + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.1 + + + sign-artifacts + verify + + sign + + + + + mdb@samskivert.com + + + + + + + diff --git a/src/main/java/pythagoras/f/Dimension.java b/src/main/java/pythagoras/f/Dimension.java new file mode 100644 index 0000000..fd8c618 --- /dev/null +++ b/src/main/java/pythagoras/f/Dimension.java @@ -0,0 +1,96 @@ +// +// Pythagoras - a collection of geometry classes +// http://github.com/samskivert/pythagoras + +package pythagoras.f; + +import java.io.Serializable; + +/** + * Represents a magnitude in two dimensions. + */ +public class Dimension implements IDimension, Serializable +{ + /** The magnitude in the x-dimension. */ + public float width; + + /** The magnitude in the y-dimension. */ + public float height; + + /** + * Creates a dimension with magnitude (0, 0). + */ + public Dimension () { + this(0, 0); + } + + /** + * Creates a dimension with the specified width and height. + */ + public Dimension (float width, float 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 (float width, float 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 float getWidth () { + return width; + } + + @Override // from interface IDimension + public float getHeight () { + return height; + } + + @Override // from interface IDimension + public Dimension clone () { + try { + return (Dimension)super.clone(); + } catch (CloneNotSupportedException cnse) { + throw new AssertionError(cnse); + } + } + + @Override + public int hashCode () { + return Float.floatToIntBits(width) ^ Float.floatToIntBits(height); + } + + @Override + public boolean equals (Object obj) { + if (obj == this) { + return true; + } + if (obj instanceof Dimension) { + Dimension d = (Dimension)obj; + return (d.width == width && d.height == height); + } + return false; + } + + @Override + public String toString () { + return Geometry.dimenToString(width, height); + } +} diff --git a/src/main/java/pythagoras/f/Geometry.java b/src/main/java/pythagoras/f/Geometry.java new file mode 100644 index 0000000..d4fc77c --- /dev/null +++ b/src/main/java/pythagoras/f/Geometry.java @@ -0,0 +1,47 @@ +// +// Pythagoras - a collection of geometry classes +// http://github.com/samskivert/pythagoras + +package pythagoras.f; + +/** + * Contains geometry routines that don't fit more nicely into specialized classes. + */ +public class Geometry +{ + /** + * Returns the squared Euclidian distance between the specified two points. + */ + public static float distanceSq (float x1, float y1, float x2, float y2) { + x2 -= x1; + y2 -= y1; + return x2 * x2 + y2 * y2; + } + + /** + * Returns the Euclidian distance between the specified two points. + */ + public static float distance (float x1, float y1, float x2, float y2) { + return (float)Math.sqrt(distanceSq(x1, y1, x2, y2)); + } + + /** + * Returns a string describing the supplied point, of the form +x+y, + * +x-y, -x-y, etc. + */ + public static String pointToString (float x, float y) { + StringBuilder buf = new StringBuilder(); + if (x >= 0) buf.append("+"); + buf.append(x); + if (y >= 0) buf.append("+"); + buf.append(y); + return buf.toString(); + } + + /** + * Returns a string describing the supplied dimension, of the form widthxheight. + */ + public static String dimenToString (float width, float height) { + return width + "x" + height; + } +} diff --git a/src/main/java/pythagoras/f/IDimension.java b/src/main/java/pythagoras/f/IDimension.java new file mode 100644 index 0000000..d546383 --- /dev/null +++ b/src/main/java/pythagoras/f/IDimension.java @@ -0,0 +1,26 @@ +// +// Pythagoras - a collection of geometry classes +// http://github.com/samskivert/pythagoras + +package pythagoras.f; + +/** + * Provides read-only access to a {@link Dimension}. + */ +public interface IDimension extends Cloneable +{ + /** + * Returns the magnitude in the x-dimension. + */ + float getWidth (); + + /** + * Returns the magnitude in the y-dimension. + */ + float getHeight (); + + /** + * Clones this dimension. + */ + Dimension clone (); +} diff --git a/src/main/java/pythagoras/f/IPoint.java b/src/main/java/pythagoras/f/IPoint.java new file mode 100644 index 0000000..7a4359f --- /dev/null +++ b/src/main/java/pythagoras/f/IPoint.java @@ -0,0 +1,46 @@ +// +// Pythagoras - a collection of geometry classes +// http://github.com/samskivert/pythagoras + +package pythagoras.f; + +/** + * Provides read-only access to a {@link Point}. + */ +public interface IPoint extends Cloneable +{ + /** + * Returns this point's x-coordinate. + */ + float getX (); + + /** + * Returns this point's y-coordinate. + */ + float getY (); + + /** + * Returns the squared Euclidian distance between this point and the specified point. + */ + float distanceSq (float px, float py); + + /** + * Returns the squared Euclidian distance between this point and the supplied point. + */ + float distanceSq (IPoint p); + + /** + * Returns the Euclidian distance between this point and the specified point. + */ + float distance (float px, float py); + + /** + * Returns the Euclidian distance between this point and the supplied point. + */ + float distance (IPoint p); + + /** + * Clones this point. + */ + Point clone (); +} diff --git a/src/main/java/pythagoras/f/IRectangle.java b/src/main/java/pythagoras/f/IRectangle.java new file mode 100644 index 0000000..5e8eaf2 --- /dev/null +++ b/src/main/java/pythagoras/f/IRectangle.java @@ -0,0 +1,99 @@ +// +// Pythagoras - a collection of geometry classes +// http://github.com/samskivert/pythagoras + +package pythagoras.f; + +/** + * Provides read-only access to a {@link Rectangle}. + */ +public interface IRectangle extends Shape, 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 rectangle's upper left corner. + */ + float getX (); + + /** + * Returns the y-coordinate of the rectangle's upper left corner. + */ + float getY (); + + /** + * Returns the width of the rectangle. + */ + float getWidth (); + + /** + * Returns the height of the rectangle. + */ + float getHeight (); + + /** + * Returns true if this rectangle does not have > 0 width and height. + */ + boolean isEmpty (); + + /** + * Returns this rectangle's upper-left corner. Note that this constructs a new instance, + * because a {@link Rectangle} is not an {@link IPoint} and cannot efficiently masquerade as + * one. + */ + Point getLocation (); + + /** + * Returns the size of this rectangle as a newly constructed dimension. Note that this + * constructs a new instance, because a {@link Rectangle} is not an {@link IDimension} and + * cannot efficiently masquerade as one. + */ + Dimension getSize (); + + /** + * 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 (float rx, float ry, float rw, float 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 (double px, double 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); + + /** + * Clones this rectangle. + */ + Rectangle clone (); +} diff --git a/src/main/java/pythagoras/f/Point.java b/src/main/java/pythagoras/f/Point.java new file mode 100644 index 0000000..59e9c65 --- /dev/null +++ b/src/main/java/pythagoras/f/Point.java @@ -0,0 +1,131 @@ +// +// Pythagoras - a collection of geometry classes +// http://github.com/samskivert/pythagoras + +package pythagoras.f; + +import java.io.Serializable; + +/** + * Represents a point on a plane. + */ +public class Point implements IPoint, Serializable +{ + /** The x-coordinate of the point. */ + public float x; + + /** The y-coordinate of the point. */ + public float y; + + /** + * Constructs a point at (0, 0). + */ + public Point () { + setLocation(0, 0); + } + + /** + * Constructs a point at the specified coordinates. + */ + public Point (float x, float 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 (float x, float y) { + this.x = x; + this.y = y; + } + + /** + * A synonym for {@link #setLocation}. + */ + public void move (float x, float y) { + setLocation(x, y); + } + + /** + * Translates this point by the specified offset. + */ + public void translate (float dx, float dy) { + x += dx; + y += dy; + } + + @Override // from interface IPoint + public float getX () { + return x; + } + + @Override // from interface IPoint + public float getY () { + return y; + } + + @Override // from interface IPoint + public float distanceSq (float px, float py) { + return Geometry.distanceSq(x, y, px, py); + } + + @Override // from interface IPoint + public float distanceSq (IPoint p) { + return Geometry.distanceSq(x, y, p.getX(), p.getY()); + } + + @Override // from interface IPoint + public float distance (float px, float py) { + return Geometry.distance(x, y, px, py); + } + + @Override // from interface IPoint + public float distance (IPoint p) { + return Geometry.distance(x, y, p.getX(), p.getY()); + } + + @Override // from interface IPoint + public Point clone () { + try { + return (Point)super.clone(); + } catch (CloneNotSupportedException cnse) { + throw new AssertionError(cnse); + } + } + + @Override + public boolean equals (Object obj) { + if (obj == this) { + return true; + } + if (obj instanceof Point) { + Point p = (Point)obj; + return x == p.x && y == p.y; + } + return false; + } + + @Override + public int hashCode () { + return Float.floatToIntBits(x) ^ Float.floatToIntBits(y); + } + + @Override + public String toString () { + return Geometry.pointToString(x, y); + } +} diff --git a/src/main/java/pythagoras/f/Rectangle.java b/src/main/java/pythagoras/f/Rectangle.java new file mode 100644 index 0000000..ef4d965 --- /dev/null +++ b/src/main/java/pythagoras/f/Rectangle.java @@ -0,0 +1,327 @@ +// +// Pythagoras - a collection of geometry classes +// http://github.com/samskivert/pythagoras + +package pythagoras.f; + +import java.io.Serializable; + +/** + * Represents an area in two dimensions. + */ +public class Rectangle implements IRectangle, Serializable +{ + /** The x-coordinate of the rectangle's upper left corner. */ + public float x; + + /** The y-coordinate of the rectangle's upper left corner. */ + public float y; + + /** The width of the rectangle. */ + public float width; + + /** The height of the rectangle. */ + public float height; + + /** + * Constructs a rectangle at (0,0) and with dimensions (0,0). + */ + public Rectangle () { + setBounds(0, 0, 0, 0); + } + + /** + * Constructs a rectangle with the supplied upper-left corner and dimensions (0,0). + */ + public Rectangle (Point p) { + setBounds(p.x, p.y, 0, 0); + } + + /** + * Constructs a rectangle with upper-left corner at (0,) and the supplied dimensions. + */ + public Rectangle (Dimension d) { + setBounds(0, 0, d.width, d.height); + } + + /** + * Constructs a rectangle with upper-left corner at the supplied point and with the supplied + * dimensions. + */ + public Rectangle (Point p, Dimension d) { + setBounds(p.x, p.y, d.width, d.height); + } + + /** + * Constructs a rectangle with the specified upper-left corner and dimensions. + */ + public Rectangle (float x, float y, float width, float height) { + setBounds(x, y, width, height); + } + + /** + * Constructs a rectangle with bounds equal to the supplied rectangle. + */ + public Rectangle (Rectangle r) { + setBounds(r.x, r.y, r.width, r.height); + } + + /** + * Sets the size of this rectangle to the specified dimensions. + */ + public void setSize (float width, float height) { + this.width = width; + this.height = height; + } + + /** + * Sets the size of this rectangle to the supplied dimensions. + */ + public void setSize (Dimension d) { + setSize(d.width, d.height); + } + + /** + * Sets the upper-left corner of this rectangle to the specified point. + */ + public void setLocation (float x, float 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 bounds of this rectangle to the specified bounds. + */ + public void setBounds (float x, float y, float width, float 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 (float dx, float 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 (float mx, float my) { + x += mx; + y += my; + } + + /** + * Expands the bounds of this rectangle to contain the specified point. + */ + public void add (float px, float py) { + float x1 = Math.min(x, px); + float x2 = Math.max(x + width, px); + float y1 = Math.min(y, py); + float 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) { + float x1 = Math.min(x, r.getX()); + float x2 = Math.max(x + width, r.getX() + r.getWidth()); + float y1 = Math.min(y, r.getY()); + float y2 = Math.max(y + height, r.getY() + r.getHeight()); + setBounds(x1, y1, x2 - x1, y2 - y1); + } + + @Override // from interface IRectangle + public float getX () + { + return x; + } + + @Override // from interface IRectangle + public float getY () + { + return y; + } + + @Override // from interface IRectangle + public float getWidth () + { + return width; + } + + @Override // from interface IRectangle + public float getHeight () + { + return height; + } + + @Override // from interface IRectangle + public boolean isEmpty () { + return width <= 0 || height <= 0; + } + + @Override // from interface IRectangle + public Point getLocation () { + return new Point(x, y); + } + + @Override // from interface IRectangle + public Dimension getSize () { + return new Dimension(width, height); + } + + @Override // from interface IRectangle + public Rectangle intersection (float rx, float ry, float rw, float rh) { + float x1 = Math.max(x, rx); + float y1 = Math.max(y, ry); + float x2 = Math.min(x + width, rx + rw); + float y2 = Math.min(y + height, ry + rh); + 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 (double px, double py) { + int code = 0; + + if (width <= 0) { + code |= OUT_LEFT | OUT_RIGHT; + } else if (px < x) { + code |= OUT_LEFT; + } else if (px > x + width) { + code |= OUT_RIGHT; + } + + if (height <= 0) { + code |= OUT_TOP | OUT_BOTTOM; + } else if (py < y) { + code |= OUT_TOP; + } else if (py > y + height) { + 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 () { + try { + return (Rectangle)super.clone(); + } catch (CloneNotSupportedException cnse) { + throw new AssertionError(cnse); + } + } + + @Override // from interface Shape + public boolean contains (float px, float py) { + if (isEmpty()) { + return false; + } + if (px < x || py < y) { + return false; + } + px -= x; + py -= y; + return px < width && py < height; + } + + @Override // from interface Shape + public boolean contains (IPoint p) { + return contains(p.getX(), p.getY()); + } + + @Override // from interface Shape + public boolean contains (float rx, float ry, float rw, float rh) { + return contains(rx, ry) && contains(rx + rw - 1, ry + rh - 1); + } + + @Override // from interface Shape + public boolean contains (IRectangle r) { + return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight()); + } + + @Override // from interface Shape + public boolean intersects (float rx, float ry, float rw, float rh) { + return !intersection(rx, ry, rw, rh).isEmpty(); // TODO: don't create garbage + } + + @Override // from interface Shape + public boolean intersects (IRectangle r) { + return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight()); + } + + @Override // from interface Shape + public IRectangle getBounds () { + return this; + } + + @Override + public boolean equals (Object obj) { + if (obj == this) { + return true; + } + if (obj instanceof Rectangle) { + Rectangle r = (Rectangle)obj; + return r.x == x && r.y == y && r.width == width && r.height == height; + } + return false; + } + + @Override + public int hashCode () { + return Float.floatToIntBits(x) ^ Float.floatToIntBits(y) ^ + Float.floatToIntBits(width) ^ Float.floatToIntBits(height); + } + + @Override + public String toString () { + return Geometry.dimenToString(width, height) + Geometry.pointToString(x, y); + } +} diff --git a/src/main/java/pythagoras/f/Shape.java b/src/main/java/pythagoras/f/Shape.java new file mode 100644 index 0000000..426d5dc --- /dev/null +++ b/src/main/java/pythagoras/f/Shape.java @@ -0,0 +1,63 @@ +// +// Pythagoras - a collection of geometry classes +// http://github.com/samskivert/pythagoras + +package pythagoras.f; + +/** + * An interface provided by all shapes. + */ +public interface Shape +{ + /** + * Returns true if this shape contains the specified point. + */ + boolean contains (float x, float 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 (float x, float y, float w, float h); + + /** + * 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 (float x, float y, float w, float h); + + /** + * Returns true if this shape intersects the supplied rectangle. + */ + boolean intersects (IRectangle r); + + /** + * Returns the bounding rectangle for this shape. + */ + IRectangle getBounds (); + + // /** + // * Returns an iterator over the path described by this shape. + // * + // * @param at if supplied, the points in the path are transformed using this. + // */ + // PathIterator getPathIterator (AffineTransform at); + + // /** + // * Returns an iterator over the path described by this shape. + // * + // * @param at if supplied, the points in the path are transformed using this. + // * @param flatness when approximating curved segments with lines, this controls the maximum + // * distance the lines are allowed to deviate from the approximated curve, thus a higher + // * flatness value generally allows for a path with fewer segments. + // */ + // PathIterator getPathIterator (AffineTransform at, float flatness); +}