📄 polygon.java
字号:
* @param y the Y coordinate of the point to test * @return true if the point is inside this polygon * @see #contains(double, double) * @since 1.1 */ public boolean contains(int x, int y) { return contains((double) x, (double) y); } /** * Tests whether or not the specified point is inside this polygon. * * @param x the X coordinate of the point to test * @param y the Y coordinate of the point to test * @return true if the point is inside this polygon * @see #contains(double, double) * @deprecated use {@link #contains(int, int)} instead */ public boolean inside(int x, int y) { return contains((double) x, (double) y); } /** * Returns a high-precision bounding box of this polygon. This is the * smallest rectangle with sides parallel to the X axis that will contain * this polygon. * * @return the bounding box for this polygon * @see #getBounds() * @since 1.2 */ public Rectangle2D getBounds2D() { // For polygons, the integer version is exact! return getBounds(); } /** * Tests whether or not the specified point is inside this polygon. * * @param x the X coordinate of the point to test * @param y the Y coordinate of the point to test * @return true if the point is inside this polygon * @since 1.2 */ public boolean contains(double x, double y) { return ((evaluateCrossings(x, y, false, BIG_VALUE) & 1) != 0); } /** * Tests whether or not the specified point is inside this polygon. * * @param p the point to test * @return true if the point is inside this polygon * @throws NullPointerException if p is null * @see #contains(double, double) * @since 1.2 */ public boolean contains(Point2D p) { return contains(p.getX(), p.getY()); } /** * Test if a high-precision rectangle intersects the shape. This is true * if any point in the rectangle is in the shape. This implementation is * precise. * * @param x the x coordinate of the rectangle * @param y the y coordinate of the rectangle * @param w the width of the rectangle, treated as point if negative * @param h the height of the rectangle, treated as point if negative * @return true if the rectangle intersects this shape * @since 1.2 */ public boolean intersects(double x, double y, double w, double h) { /* Does any edge intersect? */ if (evaluateCrossings(x, y, false, w) != 0 /* top */ || evaluateCrossings(x, y + h, false, w) != 0 /* bottom */ || evaluateCrossings(x + w, y, true, h) != 0 /* right */ || evaluateCrossings(x, y, true, h) != 0) /* left */ return true; /* No intersections, is any point inside? */ if ((evaluateCrossings(x, y, false, BIG_VALUE) & 1) != 0) return true; return false; } /** * Test if a high-precision rectangle intersects the shape. This is true * if any point in the rectangle is in the shape. This implementation is * precise. * * @param r the rectangle * @return true if the rectangle intersects this shape * @throws NullPointerException if r is null * @see #intersects(double, double, double, double) * @since 1.2 */ public boolean intersects(Rectangle2D r) { return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight()); } /** * Test if a high-precision rectangle lies completely in the shape. This is * true if all points in the rectangle are in the shape. This implementation * is precise. * * @param x the x coordinate of the rectangle * @param y the y coordinate of the rectangle * @param w the width of the rectangle, treated as point if negative * @param h the height of the rectangle, treated as point if negative * @return true if the rectangle is contained in this shape * @since 1.2 */ public boolean contains(double x, double y, double w, double h) { if (! getBounds2D().intersects(x, y, w, h)) return false; /* Does any edge intersect? */ if (evaluateCrossings(x, y, false, w) != 0 /* top */ || evaluateCrossings(x, y + h, false, w) != 0 /* bottom */ || evaluateCrossings(x + w, y, true, h) != 0 /* right */ || evaluateCrossings(x, y, true, h) != 0) /* left */ return false; /* No intersections, is any point inside? */ if ((evaluateCrossings(x, y, false, BIG_VALUE) & 1) != 0) return true; return false; } /** * Test if a high-precision rectangle lies completely in the shape. This is * true if all points in the rectangle are in the shape. This implementation * is precise. * * @param r the rectangle * @return true if the rectangle is contained in this shape * @throws NullPointerException if r is null * @see #contains(double, double, double, double) * @since 1.2 */ public boolean contains(Rectangle2D r) { return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight()); } /** * Return an iterator along the shape boundary. If the optional transform * is provided, the iterator is transformed accordingly. Each call returns * a new object, independent from others in use. This class is not * threadsafe to begin with, so the path iterator is not either. * * @param transform an optional transform to apply to the iterator * @return a new iterator over the boundary * @since 1.2 */ public PathIterator getPathIterator(final AffineTransform transform) { return new PathIterator() { /** The current vertex of iteration. */ private int vertex; public int getWindingRule() { return WIND_EVEN_ODD; } public boolean isDone() { return vertex > npoints; } public void next() { vertex++; } public int currentSegment(float[] coords) { if (vertex >= npoints) return SEG_CLOSE; coords[0] = xpoints[vertex]; coords[1] = ypoints[vertex]; if (transform != null) transform.transform(coords, 0, coords, 0, 1); return vertex == 0 ? SEG_MOVETO : SEG_LINETO; } public int currentSegment(double[] coords) { if (vertex >= npoints) return SEG_CLOSE; coords[0] = xpoints[vertex]; coords[1] = ypoints[vertex]; if (transform != null) transform.transform(coords, 0, coords, 0, 1); return vertex == 0 ? SEG_MOVETO : SEG_LINETO; } }; } /** * Return an iterator along the flattened version of the shape boundary. * Since polygons are already flat, the flatness parameter is ignored, and * the resulting iterator only has SEG_MOVETO, SEG_LINETO and SEG_CLOSE * points. If the optional transform is provided, the iterator is * transformed accordingly. Each call returns a new object, independent * from others in use. This class is not threadsafe to begin with, so the * path iterator is not either. * * @param transform an optional transform to apply to the iterator * @param flatness the maximum distance for deviation from the real boundary * @return a new iterator over the boundary * @since 1.2 */ public PathIterator getPathIterator(AffineTransform transform, double flatness) { return getPathIterator(transform); } /** * Helper for contains, intersects, calculates the number of intersections * between the polygon and a line extending from the point (x, y) along * the positive X, or Y axis, within a given interval. * * @return the winding number. * @see #contains(double, double) */ private int evaluateCrossings(double x, double y, boolean useYaxis, double distance) { double x0; double x1; double y0; double y1; double epsilon = 0.0; int crossings = 0; int[] xp; int[] yp; if (useYaxis) { xp = ypoints; yp = xpoints; double swap; swap = y; y = x; x = swap; } else { xp = xpoints; yp = ypoints; } /* Get a value which is small but not insignificant relative the path. */ epsilon = 1E-7; x0 = xp[0] - x; y0 = yp[0] - y; for (int i = 1; i < npoints; i++) { x1 = xp[i] - x; y1 = yp[i] - y; if (y0 == 0.0) y0 -= epsilon; if (y1 == 0.0) y1 -= epsilon; if (y0 * y1 < 0) if (Line2D.linesIntersect(x0, y0, x1, y1, epsilon, 0.0, distance, 0.0)) ++crossings; x0 = xp[i] - x; y0 = yp[i] - y; } // end segment x1 = xp[0] - x; y1 = yp[0] - y; if (y0 == 0.0) y0 -= epsilon; if (y1 == 0.0) y1 -= epsilon; if (y0 * y1 < 0) if (Line2D.linesIntersect(x0, y0, x1, y1, epsilon, 0.0, distance, 0.0)) ++crossings; return crossings; }} // class Polygon
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -