diff options
Diffstat (limited to 'awt/java/awt/Polygon.java')
-rw-r--r-- | awt/java/awt/Polygon.java | 494 |
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); + } + +} + |