/// <summary> /// Creates a bounding parallelogram on a curve segment /// We suppose here that the segment is convex or concave from start to end, /// that is the region bounded by the straight segment seg[start], seg[end] and the curve seg is convex /// </summary> internal static bool CreateParallelogramOnSubSeg(double start, double end, ICurve seg, ref Parallelogram box, Point startPoint, Point endPoint) { if (seg is CubicBezierSegment) { return(CreateParallelogramOnSubSegOnBezierSeg(start, end, seg, ref box)); } Point tan1 = seg.Derivative(start); Point tan2 = seg.Derivative(end); Point tan2Perp = Point.P(-tan2.Y, tan2.X); Point p = endPoint - startPoint; double numerator = p * tan2Perp; double denumerator = (tan1 * tan2Perp); double x;// = (p * tan2Perp) / (tan1 * tan2Perp); if (Math.Abs(numerator) < ApproximateComparer.DistanceEpsilon) { x = 0; } else if (Math.Abs(denumerator) < ApproximateComparer.DistanceEpsilon) { //it is degenerated; adjacent sides are parallel, but //since p * tan2Perp is big it does not contain e return(false); } else { x = numerator / denumerator; } tan1 *= x; box = new Parallelogram(startPoint, tan1, endPoint - startPoint - tan1); #if DEBUGCURVES if (!box.Contains(seg[end])) { throw new InvalidOperationException();//"the box does not contain the end of the segment"); } #endif double delta = (end - start) / 64; for (int i = 1; i < 64; i++) { if (!box.Contains(seg[start + delta * i])) { return(false); } } return(true); }
internal static bool CreateParallelogramOnSubSegOnBezierSeg(double start, double end, ICurve seg, ref Parallelogram box) { CubicBezierSegment trimSeg = seg.Trim(start, end) as CubicBezierSegment; B b = trimSeg.B; Point a = b(1) - b(0); box = new Parallelogram(b(0), a, b(3) - b(0)); if (box.Contains(b(2))) { return(true); } box = new Parallelogram(b(3), b(2) - b(3), b(0) - b(3)); if (box.Contains(b(1))) { return(true); } return(false); }
internal static bool CreateParallelogramOnSubSegOnBezierSeg(double start, double end, ICurve seg, ref Parallelogram box) { CubicBezierSegment trimSeg = seg.Trim(start, end) as CubicBezierSegment; B b = trimSeg.B; Point a = b(1) - b(0); box = new Parallelogram(b(0), a, b(3) - b(0)); if (box.Contains(b(2))) return true; box = new Parallelogram(b(3), b(2) - b(3), b(0) - b(3)); if (box.Contains(b(1))) return true; return false; }
/// <summary> /// Creates a bounding parallelogram on a curve segment /// We suppose here that the segment is convex or concave from start to end, /// that is the region bounded by the straight segment seg[start], seg[end] and the curve seg is convex /// </summary> internal static bool CreateParallelogramOnSubSeg(double start, double end, ICurve seg, ref Parallelogram box, Point startPoint, Point endPoint) { if (seg is CubicBezierSegment) return CreateParallelogramOnSubSegOnBezierSeg(start, end, seg, ref box); Point tan1 = seg.Derivative(start); Point tan2 = seg.Derivative(end); Point tan2Perp = Point.P(-tan2.Y, tan2.X); Point p = endPoint - startPoint; double numerator = p * tan2Perp; double denumerator = (tan1 * tan2Perp); double x;// = (p * tan2Perp) / (tan1 * tan2Perp); if (Math.Abs(numerator) < ApproximateComparer.DistanceEpsilon) x = 0; else if (Math.Abs(denumerator) < ApproximateComparer.DistanceEpsilon) { //it is degenerated; adjacent sides are parallel, but //since p * tan2Perp is big it does not contain e return false; } else x = numerator / denumerator; tan1 *= x; box = new Parallelogram(startPoint, tan1, endPoint - startPoint - tan1); #if DEBUGCURVES if (!box.Contains(seg[end])) { throw new InvalidOperationException();//"the box does not contain the end of the segment"); } #endif double delta = (end - start) / 64; for (int i = 1; i < 64; i++) { if (!box.Contains(seg[start + delta * i])) return false; } return true; }