📄 area.java
字号:
* the outline itself. Since the returned object represents * the bounding box with integers, the bounding box can only be * as tight as the nearest integer coordinates that encompass * the geometry of the Shape. * @return the bounding <code>Rectangle</code> for the * <code>Area</code>. */ public Rectangle getBounds() { return getCachedBounds().getBounds(); } /** * Returns an exact copy of this <code>Area</code> object. * @return Created clone object */ public Object clone() { return new Area(this); } /** * Tests whether the geometries of the two <code>Area</code> objects * are equal. * @param other the <code>Area</code> to be compared to this * <code>Area</code> * @return <code>true</code> if the two geometries are equal; * <code>false</code> otherwise. */ public boolean equals(Area other) { // REMIND: A *much* simpler operation should be possible... // Should be able to do a curve-wise comparison since all Areas // should evaluate their curves in the same top-down order. if (other == this) { return true; } if (other == null) { return false; } Vector c = new AreaOp.XorOp().calculate(this.curves, other.curves); return c.isEmpty(); } /** * Transforms the geometry of this <code>Area</code> using the specified * {@link AffineTransform}. The geometry is transformed in place, which * permanently changes the enclosed area defined by this object. * @param t the transformation used to transform the area */ public void transform(AffineTransform t) { // REMIND: A simpler operation can be performed for some types // of transform. // REMIND: this could be simplified by "breaking out" the // PathIterator code from the constructor curves = new Area(t.createTransformedShape(this)).curves; invalidateBounds(); } /** * Creates a new <code>Area</code> object that contains the same * geometry as this <code>Area</code> transformed by the specified * <code>AffineTransform</code>. This <code>Area</code> object * is unchanged. * @param t the specified <code>AffineTransform</code> used to transform * the new <code>Area</code> * @return a new <code>Area</code> object representing the transformed * geometry. */ public Area createTransformedArea(AffineTransform t) { // REMIND: A simpler operation can be performed for some types // of transform. // REMIND: this could be simplified by "breaking out" the // PathIterator code from the constructor return new Area(t.createTransformedShape(this)); } /** * Tests if a specifed point lies inside the boundary of * this <code>Area</code> object. * @param x, y the specified point * @return <code>true</code> if the point lies completely within the * interior of the <code>Area</code>; * <code>false</code> otherwise. */ public boolean contains(double x, double y) { if (!getCachedBounds().contains(x, y)) { return false; } Enumeration enum = curves.elements(); int crossings = 0; while (enum.hasMoreElements()) { Curve c = (Curve) enum.nextElement(); crossings += c.crossingsFor(x, y); } return ((crossings & 1) == 1); } /** * Tests if a specified {@link Point2D} lies inside the boundary of the * this <code>Area</code> object. * @param p the <code>Point2D</code> to test * @return <code>true</code> if the specified <code>Point2D</code> * lies completely within the interior of the <code>Area</code>; * <code>false</code> otherwise. */ public boolean contains(Point2D p) { return contains(p.getX(), p.getY()); } /** * Tests whether or not the interior of this <code>Area</code> object * completely contains the specified rectangular area. * @param x, y the coordinates of the upper left corner of * the specified rectangular area * @param w the width of the specified rectangular area * @param h the height of the specified rectangular area * @return <code>true</code> if the specified rectangular area * lies completely within the interior of the <code>Area</code>; * <code>false</code> otherwise. */ public boolean contains(double x, double y, double w, double h) { if (w < 0 || h < 0) { return false; } if (!getCachedBounds().contains(x, y, w, h)) { return false; } Crossings c = Crossings.findCrossings(curves, x, y, x+w, y+h); return (c != null && c.covers(y, y+h)); } /** * Tests whether or not the interior of this <code>Area</code> object * completely contains the specified <code>Rectangle2D</code>. * @param p the <code>Rectangle2D</code> to test * @return <code>true</code> if the <code>Rectangle2D</code> lies * completely within the interior of the <code>Area</code>; * <code>false</code> otherwise. */ public boolean contains(Rectangle2D p) { return contains(p.getX(), p.getY(), p.getWidth(), p.getHeight()); } /** * Tests whether the interior of this <code>Area</code> object * intersects the interior of the specified rectangular area. * @param x, y the coordinates of the upper left corner of * the specified rectangular area * @param w the width of the specified rectangular area * @param h the height of teh specified rectangular area * @return <code>true</code> if the interior intersects the specified * rectangular area; <code>false</code> otherwise; */ public boolean intersects(double x, double y, double w, double h) { if (w < 0 || h < 0) { return false; } if (!getCachedBounds().intersects(x, y, w, h)) { return false; } Crossings c = Crossings.findCrossings(curves, x, y, x+w, y+h); return (c == null || !c.isEmpty()); } /** * Tests whether the interior of this <code>Area</code> object * intersects the interior of the specified <code>Rectangle2D</code>. * @param p the <code>Rectangle2D</code> to test for intersection * @return <code>true</code> if the interior intersects the * specified <code>Rectangle2D</code>; * <code>false</code> otherwise. */ public boolean intersects(Rectangle2D p) { return intersects(p.getX(), p.getY(), p.getWidth(), p.getHeight()); } /** * Creates a {@link PathIterator} for the outline of this * <code>Area</code> object. This <code>Area</code> object is unchanged. * @param at an optional <code>AffineTransform</code> to be applied to * the coordinates as they are returned in the iteration, or * <code>null</code> if untransformed coordinates are desired * @return the <code>PathIterator</code> object that returns the * geometry of the outline of this <code>Area</code>, one * segment at a time. */ public PathIterator getPathIterator(AffineTransform at) { return new AreaIterator(curves, at); } /** * Creates a <code>PathIterator</code> for the flattened outline of * this <code>Area</code> object. Only uncurved path segments * represented by the SEG_MOVETO, SEG_LINETO, and SEG_CLOSE point * types are returned by the iterator. This <code>Area</code> * object is unchanged. * @param at an optional <code>AffineTransform</code> to be * applied to the coordinates as they are returned in the * iteration, or <code>null</code> if untransformed coordinates * are desired * @param flatness the maximum amount that the control points * for a given curve can vary from colinear before a subdivided * curve is replaced by a straight line connecting the endpoints * @return the <code>PathIterator</code> object that returns the * geometry of the outline of this <code>Area</code>, one segment * at a time. */ public PathIterator getPathIterator(AffineTransform at, double flatness) { return new FlatteningPathIterator(getPathIterator(at), flatness); }}class AreaIterator implements PathIterator { private AffineTransform transform; private Vector curves; private int index; private Curve prevcurve; private Curve thiscurve; public AreaIterator(Vector curves, AffineTransform at) { this.curves = curves; this.transform = at; if (curves.size() >= 1) { thiscurve = (Curve) curves.get(0); } } public int getWindingRule() { // REMIND: Which is better, EVEN_ODD or NON_ZERO? // The paths calculated could be classified either way. //return WIND_EVEN_ODD; return WIND_NON_ZERO; } public boolean isDone() { return (prevcurve == null && thiscurve == null); } public void next() { if (prevcurve != null) { prevcurve = null; } else { prevcurve = thiscurve; index++; if (index < curves.size()) { thiscurve = (Curve) curves.get(index); if (thiscurve.getOrder() != 0 && prevcurve.getX1() == thiscurve.getX0() && prevcurve.getY1() == thiscurve.getY0()) { prevcurve = null; } } else { thiscurve = null; } } } public int currentSegment(float coords[]) { double dcoords[] = new double[6]; int segtype = currentSegment(dcoords); int numpoints = (segtype == SEG_CLOSE ? 0 : (segtype == SEG_QUADTO ? 2 : (segtype == SEG_CUBICTO ? 3 : 1))); for (int i = 0; i < numpoints * 2; i++) { coords[i] = (float) dcoords[i]; } return segtype; } public int currentSegment(double coords[]) { int segtype; int numpoints; if (prevcurve != null) { // Need to finish off junction between curves if (thiscurve == null || thiscurve.getOrder() == 0) { return SEG_CLOSE; } coords[0] = thiscurve.getX0(); coords[1] = thiscurve.getY0(); segtype = SEG_LINETO; numpoints = 1; } else if (thiscurve == null) { throw new NoSuchElementException("area iterator out of bounds"); } else { segtype = thiscurve.getSegment(coords); numpoints = thiscurve.getOrder(); if (numpoints == 0) { numpoints = 1; } } if (transform != null) { transform.transform(coords, 0, coords, 0, numpoints); } return segtype; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -