//////////////////////////////////////////////////////////////////////////// //--------------------------------- REVISIONS ------------------------------ // Date Name Tracking # Description // --------- ------------------- ------------- ---------------------- // 13JUN2009 James Shen Initial Creation //////////////////////////////////////////////////////////////////////////// private static ArrayList PathToCurves(PathIterator pi) { ArrayList curves = new ArrayList(); 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 var coords = new int[23]; double movx = 0, movy = 0; double curx = 0, cury = 0; while (!pi.IsDone()) { double newx; double newy; 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]; var dblCoords = new double[coords.Length]; for (int i = 0; i < coords.Length; i++) { dblCoords[i] = coords[i]; } Curve.InsertQuad(curves, curx, cury, dblCoords); curx = newx; cury = newy; } break; case PathIterator.SEG_CUBICTO: { newx = coords[4]; newy = coords[5]; var dblCoords = new double[coords.Length]; for (int i = 0; i < coords.Length; i++) { dblCoords[i] = coords[i]; } Curve.InsertCubic(curves, curx, cury, dblCoords); 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 op; if (windingRule == PathIterator.WIND_EVEN_ODD) { op = new AreaOp.EoWindOp(); } else { op = new AreaOp.NzWindOp(); } return(op.Calculate(curves, EmptyCurves)); }
public static Crossings FindCrossings(PathIterator pi, double xlo, double ylo, double xhi, double yhi) { Crossings cross; if (pi.GetWindingRule() == PathIterator.WIND_EVEN_ODD) { cross = new EvenOdd(xlo, ylo, xhi, yhi); } else { cross = new NonZero(xlo, ylo, xhi, yhi); } // 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 var coords = new int[23]; double movx = 0; double movy = 0; double curx = 0; double cury = 0; while (!pi.IsDone()) { int type = pi.CurrentSegment(coords); double newx; double newy; switch (type) { case PathIterator.SEG_MOVETO: if (movy != cury && cross.AccumulateLine(curx, cury, movx, movy)) { return(null); } movx = curx = coords[0]; movy = cury = coords[1]; break; case PathIterator.SEG_LINETO: newx = coords[0]; newy = coords[1]; if (cross.AccumulateLine(curx, cury, newx, newy)) { return(null); } curx = newx; cury = newy; break; case PathIterator.SEG_QUADTO: { newx = coords[2]; newy = coords[3]; var dblCoords = new double[coords.Length]; for (int i = 0; i < coords.Length; i++) { dblCoords[i] = coords[i]; } if (cross.AccumulateQuad(curx, cury, dblCoords)) { return(null); } curx = newx; cury = newy; } break; case PathIterator.SEG_CUBICTO: { newx = coords[4]; newy = coords[5]; var dblCoords = new double[coords.Length]; for (int i = 0; i < coords.Length; i++) { dblCoords[i] = coords[i]; } if (cross.AccumulateCubic(curx, cury, dblCoords)) { return(null); } curx = newx; cury = newy; break; } case PathIterator.SEG_CLOSE: if (movy != cury && cross.AccumulateLine(curx, cury, movx, movy)) { return(null); } curx = movx; cury = movy; break; } pi.Next(); } if (movy != cury) { if (cross.AccumulateLine(curx, cury, movx, movy)) { return(null); } } return(cross); }
public static Crossings FindCrossings(PathIterator pi, double xlo, double ylo, double xhi, double yhi) { Crossings cross; if (pi.GetWindingRule() == PathIterator.WIND_EVEN_ODD) { cross = new EvenOdd(xlo, ylo, xhi, yhi); } else { cross = new NonZero(xlo, ylo, xhi, yhi); } // 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 var coords = new int[23]; double movx = 0; double movy = 0; double curx = 0; double cury = 0; while (!pi.IsDone()) { int type = pi.CurrentSegment(coords); double newx; double newy; switch (type) { case PathIterator.SEG_MOVETO: if (movy != cury && cross.AccumulateLine(curx, cury, movx, movy)) { return null; } movx = curx = coords[0]; movy = cury = coords[1]; break; case PathIterator.SEG_LINETO: newx = coords[0]; newy = coords[1]; if (cross.AccumulateLine(curx, cury, newx, newy)) { return null; } curx = newx; cury = newy; break; case PathIterator.SEG_QUADTO: { newx = coords[2]; newy = coords[3]; var dblCoords = new double[coords.Length]; for (int i = 0; i < coords.Length; i++) { dblCoords[i] = coords[i]; } if (cross.AccumulateQuad(curx, cury, dblCoords)) { return null; } curx = newx; cury = newy; } break; case PathIterator.SEG_CUBICTO: { newx = coords[4]; newy = coords[5]; var dblCoords = new double[coords.Length]; for (int i = 0; i < coords.Length; i++) { dblCoords[i] = coords[i]; } if (cross.AccumulateCubic(curx, cury, dblCoords)) { return null; } curx = newx; cury = newy; break; } case PathIterator.SEG_CLOSE: if (movy != cury && cross.AccumulateLine(curx, cury, movx, movy)) { return null; } curx = movx; cury = movy; break; } pi.Next(); } if (movy != cury) { if (cross.AccumulateLine(curx, cury, movx, movy)) { return null; } } return cross; }
//////////////////////////////////////////////////////////////////////////// //--------------------------------- REVISIONS ------------------------------ // Date Name Tracking # Description // --------- ------------------- ------------- ---------------------- // 13JUN2009 James Shen Initial Creation //////////////////////////////////////////////////////////////////////////// private static ArrayList PathToCurves(PathIterator pi) { ArrayList curves = new ArrayList(); 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 var coords = new int[23]; double movx = 0, movy = 0; double curx = 0, cury = 0; while (!pi.IsDone()) { double newx; double newy; 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]; var dblCoords = new double[coords.Length]; for (int i = 0; i < coords.Length; i++) { dblCoords[i] = coords[i]; } Curve.InsertQuad(curves, curx, cury, dblCoords); curx = newx; cury = newy; } break; case PathIterator.SEG_CUBICTO: { newx = coords[4]; newy = coords[5]; var dblCoords = new double[coords.Length]; for (int i = 0; i < coords.Length; i++) { dblCoords[i] = coords[i]; } Curve.InsertCubic(curves, curx, cury, dblCoords); 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 op; if (windingRule == PathIterator.WIND_EVEN_ODD) { op = new AreaOp.EoWindOp(); } else { op = new AreaOp.NzWindOp(); } return op.Calculate(curves, EmptyCurves); }
//////////////////////////////////////////////////////////////////////////// //--------------------------------- REVISIONS ------------------------------ // Date Name Tracking # Description // --------- ------------------- ------------- ---------------------- // 13JUN2009 James Shen Initial Creation //////////////////////////////////////////////////////////////////////////// /** * Tests if the interior of the specified {@link PathIterator} * intersects the interior of a specified set of rectangular * coordinates. * <p> * This method provides a basic facility for implementors of * the {@link IShape} interface to implement support for the * {@link IShape#intersects(int, int, int, int)} method. * <p> * This method object may conservatively return true in * cases where the specified rectangular area intersects a * segment of the path, but that segment does not represent a * boundary between the interior and exterior of the path. * Such a case may occur if some set of segments of the * path are retraced in the reverse direction such that the * two sets of segments cancel each other out without any * interior area between them. * To determine whether segments represent true boundaries of * the interior of the path would require extensive calculations * involving all of the segments of the path and the winding * rule and are thus beyond the scope of this implementation. * * @param pi the specified {@code PathIterator} * @param x the specified X coordinate * @param y the specified Y coordinate * @param w the width of the specified rectangular coordinates * @param h the height of the specified rectangular coordinates * @return {@code true} if the specified {@code PathIterator} and * the interior of the specified set of rectangular * coordinates intersect each other; {@code false} otherwise. */ public static bool Intersects(PathIterator pi, int x, int y, int w, int h) { if (Double.IsNaN(x + w) || Double.IsNaN(y + h)) { /* [xy]+[wh] is NaN if any of those values are NaN, * or if adding the two together would produce NaN * by virtue of adding opposing Infinte values. * Since we need to add them below, their sum must * not be NaN. * We return false because NaN always produces a * negative response to tests */ return false; } if (w <= 0 || h <= 0) { return false; } int mask = (pi.GetWindingRule() == WIND_NON_ZERO ? -1 : 2); int crossings = Curve.RectCrossingsForPath(pi, x, y, x + w, y + h); return (crossings == Curve.RECT_INTERSECTS || (crossings & mask) != 0); }
//////////////////////////////////////////////////////////////////////////// //--------------------------------- REVISIONS ------------------------------ // Date Name Tracking # Description // --------- ------------------- ------------- ---------------------- // 13JUN2009 James Shen Initial Creation //////////////////////////////////////////////////////////////////////////// /** * Tests if the specified coordinates are inside the closed * boundary of the specified {@link PathIterator}. * <p> * This method provides a basic facility for implementors of * the {@link IShape} interface to implement support for the * {@link IShape#contains(int, int)} method. * * @param pi the specified {@code PathIterator} * @param x the specified X coordinate * @param y the specified Y coordinate * @return {@code true} if the specified coordinates are inside the * specified {@code PathIterator}; {@code false} otherwise */ public static bool Contains(PathIterator pi, int x, int y) { if (x * 0 + y * 0 == 0) { /* N * 0 is 0 only if N is finite. * Here we know that both x and y are finite. */ int mask = (pi.GetWindingRule() == WIND_NON_ZERO ? -1 : 1); int cross = Curve.PointCrossingsForPath(pi, x, y); return ((cross & mask) != 0); } /* Either x or y was infinite or NaN. * A NaN always produces a negative response to any test * and Infinity values cannot be "inside" any path so * they should return false as well. */ return false; }