public static bool CompareAlgorithmsOnChordMonotoneCubic(Point[] controlPoints, double errorTolerance) { if (!BezierCurveFlattener.IsCubicChordMonotone(controlPoints, errorTolerance * errorTolerance)) { return(false); } List <Point> list1 = new List <Point>(16); List <Point> list2 = new List <Point>(16); list1.Add(controlPoints[0]); list2.Add(controlPoints[0]); double x = controlPoints[3].X - controlPoints[2].X + controlPoints[1].X - controlPoints[0].X; double y = controlPoints[3].Y - controlPoints[2].Y + controlPoints[1].Y - controlPoints[0].Y; double num = 1.0 / errorTolerance; uint depth = BezierCurveFlattener.Log8UnsignedInt32((uint)(FloatingPointArithmetic.Hypotenuse(x, y) * num + 0.5)); if (depth > 0U) { --depth; } if (depth > 0U) { BezierCurveFlattener.DoCubicMidpointSubdivision(controlPoints, depth, 0.75 * num, list1); } else { BezierCurveFlattener.DoCubicForwardDifferencing(controlPoints, 0.75 * num, list1); } BezierCurveFlattener.AdaptiveForwardDifferencingCubicFlattener differencingCubicFlattener = new BezierCurveFlattener.AdaptiveForwardDifferencingCubicFlattener(controlPoints, errorTolerance, errorTolerance, false); Point p = new Point(); while (differencingCubicFlattener.Next(ref p)) { list2.Add(p); } list1.Add(controlPoints[3]); list2.Add(controlPoints[3]); double[] cumulatedChordLength1 = VectorUtilities.GetCumulatedChordLength(list1, 0, list1.Count - 1); double[] cumulatedChordLength2 = VectorUtilities.GetCumulatedChordLength(list2, 0, list2.Count - 1); int firstBadVertexInQ = 0; return(VectorUtilities.ArePolylinesClose(list1, cumulatedChordLength1, 0, list1.Count - 1, list2, cumulatedChordLength2, 0, list2.Count - 1, errorTolerance, ref firstBadVertexInQ)); }
public static void FlattenCubic(Point[] controlPoints, double errorTolerance, List <Point> resultPolyline, bool connect, List <double> resultParameters) { if (!connect || resultPolyline.Count == 0) { resultPolyline.Add(controlPoints[0]); resultParameters.Add(0.0); } if (BezierCurveFlattener.IsCubicChordMonotone(controlPoints, errorTolerance * errorTolerance)) { BezierCurveFlattener.AdaptiveForwardDifferencingCubicFlattener differencingCubicFlattener = new BezierCurveFlattener.AdaptiveForwardDifferencingCubicFlattener(controlPoints, errorTolerance, errorTolerance, true); Point p = new Point(); double u = 0.0; while (differencingCubicFlattener.Next(ref p, ref u)) { resultPolyline.Add(p); resultParameters.Add(u); } } else { double x = controlPoints[3].X - controlPoints[2].X + controlPoints[1].X - controlPoints[0].X; double y = controlPoints[3].Y - controlPoints[2].Y + controlPoints[1].Y - controlPoints[0].Y; double num = 1.0 / errorTolerance; uint depth = BezierCurveFlattener.Log8UnsignedInt32((uint)(FloatingPointArithmetic.Hypotenuse(x, y) * num + 0.5)); if (depth > 0U) { --depth; } if (depth > 0U) { BezierCurveFlattener.DoCubicMidpointSubdivision(controlPoints, depth, 0.0, 1.0, 0.75 * num, resultPolyline, resultParameters); } else { BezierCurveFlattener.DoCubicForwardDifferencing(controlPoints, 0.0, 1.0, 0.75 * num, resultPolyline, resultParameters); } } resultPolyline.Add(controlPoints[3]); resultParameters.Add(1.0); }