]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scenegraph/src/com/infomatiq/jsi/Rectangle.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.scenegraph / src / com / infomatiq / jsi / Rectangle.java
diff --git a/bundles/org.simantics.scenegraph/src/com/infomatiq/jsi/Rectangle.java b/bundles/org.simantics.scenegraph/src/com/infomatiq/jsi/Rectangle.java
new file mode 100644 (file)
index 0000000..a02cb36
--- /dev/null
@@ -0,0 +1,442 @@
+//   Rectangle.java\r
+//   Java Spatial Index Library\r
+//   Copyright (C) 2002-2005 Infomatiq Limited\r
+//  \r
+//  This library is free software; you can redistribute it and/or\r
+//  modify it under the terms of the GNU Lesser General Public\r
+//  License as published by the Free Software Foundation; either\r
+//  version 2.1 of the License, or (at your option) any later version.\r
+//  \r
+//  This library is distributed in the hope that it will be useful,\r
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+//  Lesser General Public License for more details.\r
+//  \r
+//  You should have received a copy of the GNU Lesser General Public\r
+//  License along with this library; if not, write to the Free Software\r
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA\r
+\r
+package com.infomatiq.jsi;\r
+\r
+\r
+\r
+/**\r
+ * Currently hardcoded to 2 dimensions, but could be extended.\r
+ * \r
+ * @author  aled@sourceforge.net\r
+ * @version 1.0b8\r
+ */\r
+public class Rectangle {\r
+  \r
+  /**\r
+   * use primitives instead of arrays for the coordinates of the rectangle,\r
+   * to reduce memory requirements.\r
+   */\r
+  public float minX, minY, maxX, maxY;\r
+  \r
+  public Rectangle() {\r
+    minX = Float.MAX_VALUE;\r
+    minY = Float.MAX_VALUE;\r
+    maxX = -Float.MAX_VALUE;\r
+    maxY = -Float.MAX_VALUE;\r
+  }\r
+  \r
+  /**\r
+   * Constructor.\r
+   * \r
+   * @param x1 coordinate of any corner of the rectangle\r
+   * @param y1 (see x1)\r
+   * @param x2 coordinate of the opposite corner\r
+   * @param y2 (see x2)\r
+   */\r
+  public Rectangle(float x1, float y1, float x2, float y2) {\r
+    set(x1, y1, x2, y2);\r
+  }\r
+\r
+ /**\r
+   * Sets the size of the rectangle.\r
+   * \r
+   * @param x1 coordinate of any corner of the rectangle\r
+   * @param y1 (see x1)\r
+   * @param x2 coordinate of the opposite corner\r
+   * @param y2 (see x2)\r
+   */\r
+  public void set(float x1, float y1, float x2, float y2) {\r
+    minX = Math.min(x1, x2);\r
+    maxX = Math.max(x1, x2);\r
+    minY = Math.min(y1, y2);\r
+    maxY = Math.max(y1, y2);\r
+  }\r
+  \r
+  /**\r
+   * Sets the size of this rectangle to equal the passed rectangle.\r
+   */\r
+  public void set(Rectangle r) {\r
+    minX = r.minX;\r
+    minY = r.minY;\r
+    maxX = r.maxX;\r
+    maxY = r.maxY;  \r
+  }\r
+   \r
+  /**\r
+   * Make a copy of this rectangle\r
+   * \r
+   * @return copy of this rectangle\r
+   */\r
+  public Rectangle copy() {\r
+    return new Rectangle(minX, minY, maxX, maxY); \r
+  }\r
+  \r
+  /**\r
+   * Determine whether an edge of this rectangle overlies the equivalent \r
+   * edge of the passed rectangle\r
+   */\r
+  public boolean edgeOverlaps(Rectangle r) {\r
+    return minX == r.minX || maxX == r.maxX || minY == r.minY || maxY == r.maxY;\r
+  }\r
+  \r
+  /**\r
+   * Determine whether this rectangle intersects the passed rectangle\r
+   * \r
+   * @param r The rectangle that might intersect this rectangle\r
+   * \r
+   * @return true if the rectangles intersect, false if they do not intersect\r
+   */\r
+  public boolean intersects(Rectangle r) {\r
+    return maxX >= r.minX && minX <= r.maxX && maxY >= r.minY && minY <= r.maxY;\r
+  }\r
\r
+  /**\r
+   * Determine whether or not two rectangles intersect\r
+   * \r
+   * @param r1MinX minimum X coordinate of rectangle 1\r
+   * @param r1MinY minimum Y coordinate of rectangle 1\r
+   * @param r1MaxX maximum X coordinate of rectangle 1\r
+   * @param r1MaxY maximum Y coordinate of rectangle 1\r
+   * @param r2MinX minimum X coordinate of rectangle 2\r
+   * @param r2MinY minimum Y coordinate of rectangle 2\r
+   * @param r2MaxX maximum X coordinate of rectangle 2\r
+   * @param r2MaxY maximum Y coordinate of rectangle 2\r
+   * \r
+   * @return true if r1 intersects r2, false otherwise.\r
+   */\r
+  static public boolean intersects(float r1MinX, float r1MinY, float r1MaxX, float r1MaxY,\r
+                                 float r2MinX, float r2MinY, float r2MaxX, float r2MaxY) { \r
+    return r1MaxX >= r2MinX && r1MinX <= r2MaxX && r1MaxY >= r2MinY && r1MinY <= r2MaxY;                           \r
+  }\r
+  \r
+  /**\r
+   * Determine whether this rectangle contains the passed rectangle\r
+   * \r
+   * @param r The rectangle that might be contained by this rectangle\r
+   * \r
+   * @return true if this rectangle contains the passed rectangle, false if\r
+   *         it does not\r
+   */\r
+  public boolean contains(Rectangle r) {\r
+    return maxX >= r.maxX && minX <= r.minX && maxY >= r.maxY && minY <= r.minY;   \r
+  }\r
+  \r
+  /**\r
+   * Determine whether or not one rectangle contains another.\r
+   * \r
+   * @param r1MinX minimum X coordinate of rectangle 1\r
+   * @param r1MinY minimum Y coordinate of rectangle 1\r
+   * @param r1MaxX maximum X coordinate of rectangle 1\r
+   * @param r1MaxY maximum Y coordinate of rectangle 1\r
+   * @param r2MinX minimum X coordinate of rectangle 2\r
+   * @param r2MinY minimum Y coordinate of rectangle 2\r
+   * @param r2MaxX maximum X coordinate of rectangle 2\r
+   * @param r2MaxY maximum Y coordinate of rectangle 2\r
+   * \r
+   * @return true if r1 contains r2, false otherwise.\r
+   */\r
+  static public boolean contains(float r1MinX, float r1MinY, float r1MaxX, float r1MaxY,\r
+                                 float r2MinX, float r2MinY, float r2MaxX, float r2MaxY) {\r
+    return r1MaxX >= r2MaxX && r1MinX <= r2MinX && r1MaxY >= r2MaxY && r1MinY <= r2MinY;                              \r
+  }\r
\r
+  /**\r
+   * Determine whether this rectangle is contained by the passed rectangle\r
+   * \r
+   * @param r The rectangle that might contain this rectangle\r
+   * \r
+   * @return true if the passed rectangle contains this rectangle, false if\r
+   *         it does not\r
+   */\r
+  public boolean containedBy(Rectangle r) {\r
+    return r.maxX >= maxX && r.minX <= minX && r.maxY >= maxY && r.minY <= minY;   \r
+  }\r
+  \r
+  /**\r
+   * Return the distance between this rectangle and the passed point.\r
+   * If the rectangle contains the point, the distance is zero.\r
+   * \r
+   * @param p Point to find the distance to\r
+   * \r
+   * @return distance beween this rectangle and the passed point.\r
+   */\r
+  public float distance(Point p) {\r
+    float distanceSquared = 0;\r
+    \r
+    float temp = minX - p.x;\r
+    if (temp < 0) {\r
+      temp = p.x - maxX;\r
+    }\r
+    \r
+    if (temp > 0) {\r
+      distanceSquared += (temp * temp);\r
+    }\r
+\r
+    temp = minY - p.y;\r
+    if (temp < 0) {\r
+      temp = p.y - maxY;\r
+    }\r
+\r
+    if (temp > 0) {\r
+      distanceSquared += (temp * temp);\r
+    }\r
+         \r
+    return (float) Math.sqrt(distanceSquared);\r
+  }\r
+  \r
+  /**\r
+   * Return the distance between a rectangle and a point.\r
+   * If the rectangle contains the point, the distance is zero.\r
+   * \r
+   * @param minX minimum X coordinate of rectangle\r
+   * @param minY minimum Y coordinate of rectangle\r
+   * @param maxX maximum X coordinate of rectangle\r
+   * @param maxY maximum Y coordinate of rectangle\r
+   * @param pX X coordinate of point\r
+   * @param pY Y coordinate of point\r
+   * \r
+   * @return distance beween this rectangle and the passed point.\r
+   */\r
+  static public float distance(float minX, float minY, float maxX, float maxY, float pX, float pY) {\r
+    return (float) Math.sqrt(distanceSq(minX, minY, maxX, maxY, pX, pY));\r
+  }\r
+  \r
+  static public float distanceSq(float minX, float minY, float maxX, float maxY, float pX, float pY) {\r
+    float distanceSqX = 0;\r
+    float distanceSqY = 0;\r
+    \r
+    if (minX > pX) {\r
+      distanceSqX = minX - pX;\r
+      distanceSqX *= distanceSqX;\r
+    } else if (pX > maxX) {\r
+      distanceSqX = pX - maxX;\r
+      distanceSqX *= distanceSqX;\r
+    }\r
+   \r
+    if (minY > pY) {\r
+      distanceSqY = minY - pY;\r
+      distanceSqY *= distanceSqY;\r
+    } else if (pY > maxY) {\r
+      distanceSqY = pY - maxY;\r
+      distanceSqY *= distanceSqY;\r
+    }\r
+   \r
+    return distanceSqX + distanceSqY;\r
+  }\r
+  \r
+  /**\r
+   * Return the distance between this rectangle and the passed rectangle.\r
+   * If the rectangles overlap, the distance is zero.\r
+   * \r
+   * @param r Rectangle to find the distance to\r
+   * \r
+   * @return distance between this rectangle and the passed rectangle\r
+   */\r
+\r
+  public float distance(Rectangle r) {\r
+    float distanceSquared = 0;\r
+    float greatestMin = Math.max(minX, r.minX);\r
+    float leastMax    = Math.min(maxX, r.maxX);\r
+    if (greatestMin > leastMax) {\r
+      distanceSquared += ((greatestMin - leastMax) * (greatestMin - leastMax)); \r
+    }\r
+    greatestMin = Math.max(minY, r.minY);\r
+    leastMax    = Math.min(maxY, r.maxY);\r
+    if (greatestMin > leastMax) {\r
+      distanceSquared += ((greatestMin - leastMax) * (greatestMin - leastMax)); \r
+    }\r
+    return (float) Math.sqrt(distanceSquared);\r
+  }\r
+\r
+  /**\r
+   * Calculate the area by which this rectangle would be enlarged if\r
+   * added to the passed rectangle. Neither rectangle is altered.\r
+   * \r
+   * @param r Rectangle to union with this rectangle, in order to \r
+   *          compute the difference in area of the union and the\r
+   *          original rectangle\r
+   * \r
+   * @return enlargement\r
+   */\r
+  public float enlargement(Rectangle r) {\r
+    float enlargedArea = (Math.max(maxX, r.maxX) - Math.min(minX, r.minX)) *\r
+                         (Math.max(maxY, r.maxY) - Math.min(minY, r.minY));\r
+                         \r
+    return enlargedArea - area();\r
+  }\r
+  \r
+  /**\r
+    * Calculate the area by which a rectangle would be enlarged if\r
+    * added to the passed rectangle..\r
+    * \r
+    * @param r1MinX minimum X coordinate of rectangle 1\r
+    * @param r1MinY minimum Y coordinate of rectangle 1\r
+    * @param r1MaxX maximum X coordinate of rectangle 1\r
+    * @param r1MaxY maximum Y coordinate of rectangle 1\r
+    * @param r2MinX minimum X coordinate of rectangle 2\r
+    * @param r2MinY minimum Y coordinate of rectangle 2\r
+    * @param r2MaxX maximum X coordinate of rectangle 2\r
+    * @param r2MaxY maximum Y coordinate of rectangle 2\r
+    * \r
+    * @return enlargement\r
+    */\r
+  static public float enlargement(float r1MinX, float r1MinY, float r1MaxX, float r1MaxY,\r
+                                  float r2MinX, float r2MinY, float r2MaxX, float r2MaxY) { \r
+    float r1Area = (r1MaxX - r1MinX) * (r1MaxY - r1MinY);                    \r
+    \r
+    if (r1Area == Float.POSITIVE_INFINITY) {\r
+      return 0; // cannot enlarge an infinite rectangle...\r
+    }\r
+    \r
+    if (r2MinX < r1MinX) r1MinX = r2MinX;   \r
+    if (r2MinY < r1MinY) r1MinY = r2MinY;   \r
+    if (r2MaxX > r1MaxX) r1MaxX = r2MaxX;                               \r
+    if (r2MaxY > r1MaxY) r1MaxY = r2MaxY;\r
+    \r
+    float r1r2UnionArea = (r1MaxX - r1MinX) * (r1MaxY - r1MinY);\r
+          \r
+    if (r1r2UnionArea == Float.POSITIVE_INFINITY) {\r
+      // if a finite rectangle is enlarged and becomes infinite,\r
+      // then the enlargement must be infinite.\r
+      return Float.POSITIVE_INFINITY;\r
+    }\r
+    return r1r2UnionArea - r1Area;                              \r
+  }\r
+  \r
+  /**\r
+   * Compute the area of this rectangle.\r
+   * \r
+   * @return The area of this rectangle\r
+   */\r
+  public float area() {\r
+    return (maxX - minX) * (maxY - minY);\r
+  }\r
+  \r
+  /**\r
+   * Compute the area of a rectangle.\r
+   * \r
+   * @param minX the minimum X coordinate of the rectangle\r
+   * @param minY the minimum Y coordinate of the rectangle\r
+   * @param maxX the maximum X coordinate of the rectangle\r
+   * @param maxY the maximum Y coordinate of the rectangle\r
+   * \r
+   * @return The area of the rectangle\r
+   */\r
+  static public float area(float minX, float minY, float maxX, float maxY) {\r
+    return (maxX - minX) * (maxY - minY);\r
+  }\r
+  \r
+  /**\r
+   * Computes the union of this rectangle and the passed rectangle, storing\r
+   * the result in this rectangle.\r
+   * \r
+   * @param r Rectangle to add to this rectangle\r
+   */\r
+  public void add(Rectangle r) {\r
+    if (r.minX < minX) minX = r.minX;\r
+    if (r.maxX > maxX) maxX = r.maxX;\r
+    if (r.minY < minY) minY = r.minY;\r
+    if (r.maxY > maxY) maxY = r.maxY;\r
+  }\r
+  \r
+  /**\r
+   * Computes the union of this rectangle and the passed point, storing\r
+   * the result in this rectangle.\r
+   * \r
+   * @param p Point to add to this rectangle\r
+   */\r
+  public void add(Point p) {\r
+    if (p.x < minX) minX = p.x;\r
+    if (p.x > maxX) maxX = p.x;\r
+    if (p.y < minY) minY = p.y;\r
+    if (p.y > maxY) maxY = p.y;\r
+  }\r
+  \r
+  /**\r
+   * Find the the union of this rectangle and the passed rectangle.\r
+   * Neither rectangle is altered\r
+   * \r
+   * @param r The rectangle to union with this rectangle\r
+   */\r
+  public Rectangle union(Rectangle r) {\r
+    Rectangle union = this.copy();\r
+    union.add(r);\r
+    return union; \r
+  }\r
+  \r
+  /**\r
+   * Determine whether this rectangle is equal to a given object.\r
+   * Equality is determined by the bounds of the rectangle.\r
+   * \r
+   * @param o The object to compare with this rectangle\r
+   */\r
+  public boolean equals(Object o) {\r
+    boolean equals = false;\r
+    if (o instanceof Rectangle) {\r
+      Rectangle r = (Rectangle) o;\r
+      if (minX == r.minX && minY == r.minY && maxX == r.maxX && maxY == r.maxY) {\r
+        equals = true;\r
+      }\r
+    } \r
+    return equals;       \r
+  }\r
+\r
+  /** \r
+   * Determine whether this rectangle is the same as another object\r
+   * \r
+   * Note that two rectangles can be equal but not the same object, \r
+   * if they both have the same bounds.\r
+   * \r
+   * @param o The object to compare with this rectangle.\r
+   */  \r
+  public boolean sameObject(Object o) {\r
+    return super.equals(o); \r
+  }\r
+  \r
+  /**\r
+   * Return a string representation of this rectangle, in the form: \r
+   * (1.2, 3.4), (5.6, 7.8)\r
+   * \r
+   * @return String String representation of this rectangle.\r
+   */\r
+  public String toString() {\r
+    return "(" + minX + ", " + minY + "), (" + maxX + ", " + maxY + ")";\r
+  }\r
+  \r
+  /**\r
+   * Utility methods (not used by JSI); added to \r
+   * enable this to be used as a generic rectangle class \r
+   */\r
+  public float width() {\r
+    return maxX - minX;\r
+  }\r
+  \r
+  public float height() {\r
+    return maxY - minY;\r
+  }\r
+  \r
+  public float aspectRatio() {\r
+    return width() / height();\r
+  }\r
+  \r
+  public Point centre() {\r
+    return new Point((minX + maxX) / 2, (minY + maxY) / 2);\r
+  }\r
+  \r
+}\r