summaryrefslogtreecommitdiffstats
path: root/awt/java/awt/Polygon.java
diff options
context:
space:
mode:
Diffstat (limited to 'awt/java/awt/Polygon.java')
-rw-r--r--awt/java/awt/Polygon.java494
1 files changed, 494 insertions, 0 deletions
diff --git a/awt/java/awt/Polygon.java b/awt/java/awt/Polygon.java
new file mode 100644
index 0000000..6f3fc97
--- /dev/null
+++ b/awt/java/awt/Polygon.java
@@ -0,0 +1,494 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.PathIterator;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.io.Serializable;
+import java.util.NoSuchElementException;
+
+import org.apache.harmony.awt.gl.*;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Polygon class defines an closed area specified by n vertices and
+ * n edges. The coordinates of the vertices are specified by x, y arrays.
+ * The edges are the line segments from the point (x[i], y[i]) to the point
+ * (x[i+1], y[i+1]), for -1 < i < (n-1) plus the line segment from
+ * the point (x[n-1], y[n-1]) to the point (x[0], y[0]) point.
+ * The Polygon is empty if the number of vertices is zero.
+ */
+public class Polygon implements Shape, Serializable {
+
+ /** The Constant serialVersionUID. */
+ private static final long serialVersionUID = -6460061437900069969L;
+
+ /** The points buffer capacity. */
+ private static final int BUFFER_CAPACITY = 4;
+
+ /** The number of Polygon vertices.*/
+ public int npoints;
+
+ /** The array of X coordinates of the vertices. */
+ public int[] xpoints;
+
+ /** The array of Y coordinates of the vertices. */
+ public int[] ypoints;
+
+ /**
+ * The smallest Rectangle that completely contains this Polygon.
+ */
+ protected Rectangle bounds;
+
+ /*
+ * Polygon path iterator
+ */
+ /**
+ * The internal Class Iterator.
+ */
+ class Iterator implements PathIterator {
+
+ /** The source Polygon object. */
+ public Polygon p;
+
+ /** The path iterator transformation. */
+ public AffineTransform t;
+
+ /** The current segmenet index. */
+ public int index;
+
+ /**
+ * Constructs a new Polygon.Iterator for the given polygon and transformation
+ *
+ * @param at - the AffineTransform object to apply rectangle path
+ * @param p the p
+ */
+ public Iterator(AffineTransform at, Polygon p) {
+ this.p = p;
+ this.t = at;
+ if (p.npoints == 0) {
+ index = 1;
+ }
+ }
+
+ public int getWindingRule() {
+ return WIND_EVEN_ODD;
+ }
+
+ public boolean isDone() {
+ return index > p.npoints;
+ }
+
+ public void next() {
+ index++;
+ }
+
+ public int currentSegment(double[] coords) {
+ if (isDone()) {
+ // awt.110=Iterator out of bounds
+ throw new NoSuchElementException(Messages.getString("awt.110")); //$NON-NLS-1$
+ }
+ if (index == p.npoints) {
+ return SEG_CLOSE;
+ }
+ coords[0] = p.xpoints[index];
+ coords[1] = p.ypoints[index];
+ if (t != null) {
+ t.transform(coords, 0, coords, 0, 1);
+ }
+ return index == 0 ? SEG_MOVETO : SEG_LINETO;
+ }
+
+ public int currentSegment(float[] coords) {
+ if (isDone()) {
+ // awt.110=Iterator out of bounds
+ throw new NoSuchElementException(Messages.getString("awt.110")); //$NON-NLS-1$
+ }
+ if (index == p.npoints) {
+ return SEG_CLOSE;
+ }
+ coords[0] = p.xpoints[index];
+ coords[1] = p.ypoints[index];
+ if (t != null) {
+ t.transform(coords, 0, coords, 0, 1);
+ }
+ return index == 0 ? SEG_MOVETO : SEG_LINETO;
+ }
+ }
+
+ /**
+ * Instantiates a new empty polygon.
+ */
+ public Polygon() {
+ xpoints = new int[BUFFER_CAPACITY];
+ ypoints = new int[BUFFER_CAPACITY];
+ }
+
+ /**
+ * Instantiates a new polygon with the specified number of vertices,
+ * and the given arrays of x, y vertex coordinates. The length of
+ * each coordinate array may not be less than the specified number of
+ * vertices but may be greater. Only the first n elements are used from
+ * each coordinate array.
+ *
+ * @param xpoints the array of X vertex coordinates.
+ * @param ypoints the array of Y vertex coordinates.
+ * @param npoints the number vertices of the polygon.
+ * @throws IndexOutOfBoundsException if the length of xpoints or ypoints
+ * is less than n.
+ * @throws NegativeArraySizeException if n is negative.
+ */
+ public Polygon(int[] xpoints, int[] ypoints, int npoints) {
+ if (npoints > xpoints.length || npoints > ypoints.length) {
+ // awt.111=Parameter npoints is greater than array length
+ throw new IndexOutOfBoundsException(Messages.getString("awt.111")); //$NON-NLS-1$
+ }
+ if (npoints < 0) {
+ // awt.112=Negative number of points
+ throw new NegativeArraySizeException(Messages.getString("awt.112")); //$NON-NLS-1$
+ }
+ this.npoints = npoints;
+ this.xpoints = new int[npoints];
+ this.ypoints = new int[npoints];
+ System.arraycopy(xpoints, 0, this.xpoints, 0, npoints);
+ System.arraycopy(ypoints, 0, this.ypoints, 0, npoints);
+ }
+
+ /**
+ * Resets the current Polygon to an empty Polygon. More precisely,
+ * the number of Polygon vertices is set to zero, but x, y coordinates
+ * arrays are not affected.
+ */
+ public void reset() {
+ npoints = 0;
+ bounds = null;
+ }
+
+ /**
+ * Invalidates the data that depends on the vertex coordinates.
+ * This method should be called after direct manipulations
+ * of the x, y vertex coordinates arrays to avoid unpredictable
+ * results of methods which rely on the bounding box.
+ */
+ public void invalidate() {
+ bounds = null;
+ }
+
+ /**
+ * Adds the point to the Polygon and updates the bounding box
+ * accordingly.
+ *
+ * @param px the X coordinate of the added vertex.
+ * @param py the Y coordinate of the added vertex.
+ */
+ public void addPoint(int px, int py) {
+ if (npoints == xpoints.length) {
+ int[] tmp;
+
+ tmp = new int[xpoints.length + BUFFER_CAPACITY];
+ System.arraycopy(xpoints, 0, tmp, 0, xpoints.length);
+ xpoints = tmp;
+
+ tmp = new int[ypoints.length + BUFFER_CAPACITY];
+ System.arraycopy(ypoints, 0, tmp, 0, ypoints.length);
+ ypoints = tmp;
+ }
+
+ xpoints[npoints] = px;
+ ypoints[npoints] = py;
+ npoints++;
+
+ if (bounds != null) {
+ bounds.setFrameFromDiagonal(
+ Math.min(bounds.getMinX(), px),
+ Math.min(bounds.getMinY(), py),
+ Math.max(bounds.getMaxX(), px),
+ Math.max(bounds.getMaxY(), py));
+ }
+ }
+
+ /**
+ * Gets the bounding rectangle of the Polygon. The bounding rectangle
+ * is the smallest rectangle which contains the Polygon.
+ *
+ * @return the bounding rectangle of the Polygon.
+ *
+ * @see java.awt.Shape#getBounds()
+ */
+ public Rectangle getBounds() {
+ if (bounds != null) {
+ return bounds;
+ }
+ if (npoints == 0) {
+ return new Rectangle();
+ }
+
+ int bx1 = xpoints[0];
+ int by1 = ypoints[0];
+ int bx2 = bx1;
+ int by2 = by1;
+
+ for (int i = 1; i < npoints; i++) {
+ int x = xpoints[i];
+ int y = ypoints[i];
+ if (x < bx1) {
+ bx1 = x;
+ } else if (x > bx2) {
+ bx2 = x;
+ }
+ if (y < by1) {
+ by1 = y;
+ } else if (y > by2) {
+ by2 = y;
+ }
+ }
+
+ return bounds = new Rectangle(bx1, by1, bx2 - bx1, by2 - by1);
+ }
+
+ /**
+ * Gets the bounding rectangle of the Polygon. The bounding rectangle
+ * is the smallest rectangle which contains the Polygon.
+ *
+ * @return the bounding rectangle of the Polygon.
+ *
+ * @deprecated Use getBounds() method.
+ */
+ @Deprecated
+ public Rectangle getBoundingBox() {
+ return getBounds();
+ }
+
+ /**
+ * Gets the Rectangle2D which represents Polygon bounds.
+ * The bounding rectangle is the smallest rectangle which contains
+ * the Polygon.
+ *
+ * @return the bounding rectangle of the Polygon.
+ *
+ * @see java.awt.Shape#getBounds2D()
+ */
+ public Rectangle2D getBounds2D() {
+ return getBounds().getBounds2D();
+ }
+
+ /**
+ * Translates all vertices of Polygon the specified distances
+ * along X, Y axis.
+ *
+ * @param mx the distance to translate horizontally.
+ * @param my the distance to translate vertically.
+ */
+ public void translate(int mx, int my) {
+ for (int i = 0; i < npoints; i++) {
+ xpoints[i] += mx;
+ ypoints[i] += my;
+ }
+ if (bounds != null) {
+ bounds.translate(mx, my);
+ }
+ }
+
+ /**
+ * Checks whether or not the point given by the coordinates x, y lies inside
+ * the Polygon.
+ *
+ * @param x the X coordinate of the point to check.
+ * @param y the Y coordinate of the point to check.
+ *
+ * @return true, if the specified point lies inside the Polygon,
+ * otherwise false.
+ *
+ * @deprecated Use contains(int, int) method.
+ */
+ @Deprecated
+ public boolean inside(int x, int y) {
+ return contains((double) x, (double) y);
+ }
+
+ /**
+ * Checks whether or not the point given by the coordinates x, y lies inside
+ * the Polygon.
+ *
+ * @param x the X coordinate of the point to check.
+ * @param y the Y coordinate of the point to check.
+ *
+ * @return true, if the specified point lies inside the Polygon,
+ * otherwise false.
+ */
+ public boolean contains(int x, int y) {
+ return contains((double) x, (double) y);
+ }
+
+ /**
+ * Checks whether or not the point with specified double coordinates
+ * lies inside the Polygon.
+ *
+ * @param x the X coordinate of the point to check.
+ * @param y the Y coordinate of the point to check.
+ *
+ * @return true, if the point given by the double coordinates
+ * lies inside the Polygon, otherwise false.
+ *
+ * @see java.awt.Shape#contains(double, double)
+ */
+ public boolean contains(double x, double y) {
+ return Crossing.isInsideEvenOdd(Crossing.crossShape(this, x, y));
+ }
+
+ /**
+ * Checks whether or not the rectangle determined by the parameters
+ * [x, y, width, height] lies inside the Polygon.
+ *
+ * @param x the X coordinate of the rectangles's left upper
+ * corner as a double.
+ * @param y the Y coordinate of the rectangles's left upper
+ * corner as a double.
+ * @param width the width of rectangle as a double.
+ * @param width the height of rectangle as a double.
+ *
+ * @return true, if the specified rectangle lies inside the Polygon,
+ * otherwise false.
+ *
+ * @see java.awt.Shape#contains(double, double, double, double)
+ */
+ public boolean contains(double x, double y, double width, double height) {
+ int cross = Crossing.intersectShape(this, x, y, width, height);
+ return cross != Crossing.CROSSING && Crossing.isInsideEvenOdd(cross);
+ }
+
+ /**
+ * Checks whether or not the rectangle determined by the parameters
+ * [x, y, width, height] intersects the interior of
+ * the Polygon.
+ *
+ * @param x the X coordinate of the rectangles's left upper
+ * corner as a double.
+ * @param y the Y coordinate of the rectangles's left upper
+ * corner as a double.
+ * @param width the width of rectangle as a double.
+ * @param width the height of rectangle as a double.
+ *
+ * @return true, if the specified rectangle intersects the interior of
+ * the Polygon, otherwise false.
+ *
+ * @see java.awt.Shape#intersects(double, double, double, double)
+ */
+ public boolean intersects(double x, double y, double width, double height) {
+ int cross = Crossing.intersectShape(this, x, y, width, height);
+ return cross == Crossing.CROSSING || Crossing.isInsideEvenOdd(cross);
+ }
+
+ /**
+ * Checks whether or not the specified rectangle lies inside the Polygon.
+ *
+ * @param rect the Rectangle2D object.
+ *
+ * @return true, if the specified rectangle lies inside the Polygon,
+ * otherwise false.
+ *
+ * @see java.awt.Shape#contains(java.awt.geom.Rectangle2D)
+ */
+ public boolean contains(Rectangle2D rect) {
+ return contains(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
+ }
+
+ /**
+ * Checks whether or not the specified Point lies inside the Polygon.
+ *
+ * @param point the Point object.
+ *
+ * @return true, if the specified Point lies inside the Polygon,
+ * otherwise false.
+ */
+ public boolean contains(Point point) {
+ return contains(point.getX(), point.getY());
+ }
+
+ /**
+ * Checks whether or not the specified Point2D lies inside the Polygon.
+ *
+ * @param point the Point2D object.
+ *
+ * @return true, if the specified Point2D lies inside the Polygon,
+ * otherwise false.
+ *
+ * @see java.awt.Shape#contains(java.awt.geom.Point2D)
+ */
+ public boolean contains(Point2D point) {
+ return contains(point.getX(), point.getY());
+ }
+
+ /**
+ * Checks whether or not the interior of rectangle specified by
+ * the Rectangle2D object intersects the interior of the Polygon.
+ *
+ * @param rect the Rectangle2D object.
+ *
+ * @return true, if the Rectangle2D intersects the interior of
+ * the Polygon, otherwise false.
+ *
+ * @see java.awt.Shape#intersects(java.awt.geom.Rectangle2D)
+ */
+ public boolean intersects(Rectangle2D rect) {
+ return intersects(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
+ }
+
+ /**
+ * Gets the PathIterator object which gives the coordinates of
+ * the polygon, transformed according to the specified AffineTransform.
+ *
+ * @param t the specified AffineTransform object, or null.
+ *
+ * @return PathIterator object for the Polygon.
+ *
+ * @see java.awt.Shape#getPathIterator(java.awt.geom.AffineTransform)
+ */
+ public PathIterator getPathIterator(AffineTransform t) {
+ return new Iterator(t, this);
+ }
+
+ /**
+ * Gets the PathIterator object which gives the coordinates of
+ * the polygon, transformed according to the specified AffineTransform.
+ * The flatness parameter is ignored.
+ *
+ * @param t the specified AffineTransform object, or null.
+ * @param flatness the maximum number of the control points for
+ * a given curve which varies from colinear before a subdivided curve
+ * is replaced by a straight line connecting the endpoints.
+ * This parameter is ignored for the Polygon class.
+ *
+ * @return PathIterator object for the Polygon.
+ *
+ * @see java.awt.Shape#getPathIterator(java.awt.geom.AffineTransform, double)
+ */
+ public PathIterator getPathIterator(AffineTransform t, double flatness) {
+ return new Iterator(t, this);
+ }
+
+}
+