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);
 }