/** * Tests whether the geometries of the two <code>Area</code> objects * are equal. * This method will return false if the argument is null. * @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. * @since 1.2 */ 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(); }
/** * Tests whether the geometries of the two {@code Area} objects * are equal. * This method will return false if the argument is null. * @param other the {@code Area} to be compared to this * {@code Area} * @return {@code true} if the two geometries are equal; * {@code false} otherwise. * @since 1.2 */ 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<Curve> c = new AreaOp.XorOp().calculate(this.curves, other.curves); return c.isEmpty(); }
private static Vector pathToCurves(PathIterator pi) { Vector curves = new Vector(); int windingRule = pi.getWindingRule(); // coords array is big enough for holding: // coordinates returned from currentSegment (6) // OR // two subdivided quadratic curves (2+4+4=10) // AND // 0-1 horizontal splitting parameters // OR // 2 parametric equation derivative coefficients // OR // three subdivided cubic curves (2+6+6+6=20) // AND // 0-2 horizontal splitting parameters // OR // 3 parametric equation derivative coefficients double coords[] = new double[23]; double movx = 0, movy = 0; double curx = 0, cury = 0; double newx, newy; while (!pi.isDone()) { switch (pi.currentSegment(coords)) { case PathIterator.SEG_MOVETO: Curve.insertLine(curves, curx, cury, movx, movy); curx = movx = coords[0]; cury = movy = coords[1]; Curve.insertMove(curves, movx, movy); break; case PathIterator.SEG_LINETO: newx = coords[0]; newy = coords[1]; Curve.insertLine(curves, curx, cury, newx, newy); curx = newx; cury = newy; break; case PathIterator.SEG_QUADTO: newx = coords[2]; newy = coords[3]; Curve.insertQuad(curves, curx, cury, coords); curx = newx; cury = newy; break; case PathIterator.SEG_CUBICTO: newx = coords[4]; newy = coords[5]; Curve.insertCubic(curves, curx, cury, coords); curx = newx; cury = newy; break; case PathIterator.SEG_CLOSE: Curve.insertLine(curves, curx, cury, movx, movy); curx = movx; cury = movy; break; } pi.next(); } Curve.insertLine(curves, curx, cury, movx, movy); AreaOp operator; if (windingRule == PathIterator.WIND_EVEN_ODD) { operator = new AreaOp.EOWindOp(); } else { operator = new AreaOp.NZWindOp(); } return operator.calculate(curves, EmptyCurves); }
private static Vector<Curve> pathToCurves(PathIterator pi) { Vector<Curve> curves = new Vector<>(); int windingRule = pi.getWindingRule(); // coords array is big enough for holding: // coordinates returned from currentSegment (6) // OR // two subdivided quadratic curves (2+4+4=10) // AND // 0-1 horizontal splitting parameters // OR // 2 parametric equation derivative coefficients // OR // three subdivided cubic curves (2+6+6+6=20) // AND // 0-2 horizontal splitting parameters // OR // 3 parametric equation derivative coefficients double coords[] = new double[23]; double movx = 0, movy = 0; double curx = 0, cury = 0; double newx, newy; while (!pi.isDone()) { switch (pi.currentSegment(coords)) { case PathIterator.SEG_MOVETO: Curve.insertLine(curves, curx, cury, movx, movy); curx = movx = coords[0]; cury = movy = coords[1]; Curve.insertMove(curves, movx, movy); break; case PathIterator.SEG_LINETO: newx = coords[0]; newy = coords[1]; Curve.insertLine(curves, curx, cury, newx, newy); curx = newx; cury = newy; break; case PathIterator.SEG_QUADTO: newx = coords[2]; newy = coords[3]; Curve.insertQuad(curves, curx, cury, coords); curx = newx; cury = newy; break; case PathIterator.SEG_CUBICTO: newx = coords[4]; newy = coords[5]; Curve.insertCubic(curves, curx, cury, coords); curx = newx; cury = newy; break; case PathIterator.SEG_CLOSE: Curve.insertLine(curves, curx, cury, movx, movy); curx = movx; cury = movy; break; } pi.next(); } Curve.insertLine(curves, curx, cury, movx, movy); AreaOp operator; if (windingRule == PathIterator.WIND_EVEN_ODD) { operator = new AreaOp.EOWindOp(); } else { operator = new AreaOp.NZWindOp(); } return operator.calculate(curves, EmptyCurves); }
/** * Adds the shape of the specified <code>Area</code> to the * shape of this <code>Area</code>. * The resulting shape of this <code>Area</code> will include * the union of both shapes, or all areas that were contained * in either this or the specified <code>Area</code>. * <pre> * // Example: * Area a1 = new Area([triangle 0,0 => 8,0 => 0,8]); * Area a2 = new Area([triangle 0,0 => 8,0 => 8,8]); * a1.add(a2); * * a1(before) + a2 = a1(after) * * ################ ################ ################ * ############## ############## ################ * ############ ############ ################ * ########## ########## ################ * ######## ######## ################ * ###### ###### ###### ###### * #### #### #### #### * ## ## ## ## * </pre> * @param rhs the <code>Area</code> to be added to the * current shape * @throws NullPointerException if <code>rhs</code> is null * @since 1.2 */ public void add(Area rhs) { curves = new AreaOp.AddOp().calculate(this.curves, rhs.curves); invalidateBounds(); }
/** * Subtracts the shape of the specified <code>Area</code> from the * shape of this <code>Area</code>. * The resulting shape of this <code>Area</code> will include * areas that were contained only in this <code>Area</code> * and not in the specified <code>Area</code>. * <pre> * // Example: * Area a1 = new Area([triangle 0,0 => 8,0 => 0,8]); * Area a2 = new Area([triangle 0,0 => 8,0 => 8,8]); * a1.subtract(a2); * * a1(before) - a2 = a1(after) * * ################ ################ * ############## ############## ## * ############ ############ #### * ########## ########## ###### * ######## ######## ######## * ###### ###### ###### * #### #### #### * ## ## ## * </pre> * @param rhs the <code>Area</code> to be subtracted from the * current shape * @throws NullPointerException if <code>rhs</code> is null * @since 1.2 */ public void subtract(Area rhs) { curves = new AreaOp.SubOp().calculate(this.curves, rhs.curves); invalidateBounds(); }
/** * Sets the shape of this <code>Area</code> to the intersection of * its current shape and the shape of the specified <code>Area</code>. * The resulting shape of this <code>Area</code> will include * only areas that were contained in both this <code>Area</code> * and also in the specified <code>Area</code>. * <pre> * // Example: * Area a1 = new Area([triangle 0,0 => 8,0 => 0,8]); * Area a2 = new Area([triangle 0,0 => 8,0 => 8,8]); * a1.intersect(a2); * * a1(before) intersect a2 = a1(after) * * ################ ################ ################ * ############## ############## ############ * ############ ############ ######## * ########## ########## #### * ######## ######## * ###### ###### * #### #### * ## ## * </pre> * @param rhs the <code>Area</code> to be intersected with this * <code>Area</code> * @throws NullPointerException if <code>rhs</code> is null * @since 1.2 */ public void intersect(Area rhs) { curves = new AreaOp.IntOp().calculate(this.curves, rhs.curves); invalidateBounds(); }
/** * Sets the shape of this <code>Area</code> to be the combined area * of its current shape and the shape of the specified <code>Area</code>, * minus their intersection. * The resulting shape of this <code>Area</code> will include * only areas that were contained in either this <code>Area</code> * or in the specified <code>Area</code>, but not in both. * <pre> * // Example: * Area a1 = new Area([triangle 0,0 => 8,0 => 0,8]); * Area a2 = new Area([triangle 0,0 => 8,0 => 8,8]); * a1.exclusiveOr(a2); * * a1(before) xor a2 = a1(after) * * ################ ################ * ############## ############## ## ## * ############ ############ #### #### * ########## ########## ###### ###### * ######## ######## ################ * ###### ###### ###### ###### * #### #### #### #### * ## ## ## ## * </pre> * @param rhs the <code>Area</code> to be exclusive ORed with this * <code>Area</code>. * @throws NullPointerException if <code>rhs</code> is null * @since 1.2 */ public void exclusiveOr(Area rhs) { curves = new AreaOp.XorOp().calculate(this.curves, rhs.curves); invalidateBounds(); }