internal static void FlattenFigure(PathFigure figure, IList <Point> points, double tolerance,
                                           bool removeRepeat)
        {
            if (figure == null)
            {
                throw new ArgumentNullException(nameof(figure));
            }
            if (points == null)
            {
                throw new ArgumentNullException(nameof(points));
            }
            if (tolerance < 0.0)
            {
                throw new ArgumentOutOfRangeException(nameof(tolerance));
            }
            var list = removeRepeat ? new List <Point>() : points;

            list.Add(figure.StartPoint);
            foreach (var data in figure.AllSegments())
            {
                data.PathSegment.FlattenSegment(list, data.StartPoint, tolerance);
            }
            if (figure.IsClosed)
            {
                list.Add(figure.StartPoint);
            }
            if (removeRepeat && list.Count > 0)
            {
                points.Add(list[0]);
                for (var i = 1; i < list.Count; i++)
                {
                    if (!MathHelper.IsVerySmall(GeometryHelper.SquaredDistance(points.Last(), list[i])))
                    {
                        points.Add(list[i]);
                    }
                }
            }
        }
        private static void DoCubicMidpointSubdivision(Point[] controlPoints, uint depth, double leftParameter, double rightParameter, double inverseErrorTolerance, ICollection <Point> resultPolyline, ICollection <double> resultParameters)
        {
            Point[] pointArray  = { controlPoints[0], controlPoints[1], controlPoints[2], controlPoints[3] };
            var     pointArray2 = new Point[4];

            pointArray2[3] = pointArray[3];
            pointArray[3]  = GeometryHelper.Midpoint(pointArray[3], pointArray[2]);
            pointArray[2]  = GeometryHelper.Midpoint(pointArray[2], pointArray[1]);
            pointArray[1]  = GeometryHelper.Midpoint(pointArray[1], pointArray[0]);
            pointArray2[2] = pointArray[3];
            pointArray[3]  = GeometryHelper.Midpoint(pointArray[3], pointArray[2]);
            pointArray[2]  = GeometryHelper.Midpoint(pointArray[2], pointArray[1]);
            pointArray2[1] = pointArray[3];
            pointArray[3]  = GeometryHelper.Midpoint(pointArray[3], pointArray[2]);
            pointArray2[0] = pointArray[3];
            depth--;
            var num = (leftParameter + rightParameter) * 0.5;

            if (depth > 0)
            {
                DoCubicMidpointSubdivision(pointArray, depth, leftParameter, num, inverseErrorTolerance,
                                           resultPolyline, resultParameters);
                resultPolyline.Add(pointArray2[0]);
                resultParameters?.Add(num);
                DoCubicMidpointSubdivision(pointArray2, depth, num, rightParameter, inverseErrorTolerance,
                                           resultPolyline, resultParameters);
            }
            else
            {
                DoCubicForwardDifferencing(pointArray, leftParameter, num, inverseErrorTolerance,
                                           resultPolyline, resultParameters);
                resultPolyline.Add(pointArray2[0]);
                resultParameters?.Add(num);
                DoCubicForwardDifferencing(pointArray2, num, rightParameter, inverseErrorTolerance,
                                           resultPolyline, resultParameters);
            }
        }
        private static void DoCubicForwardDifferencing(Point[] controlPoints, double leftParameter, double rightParameter, double inverseErrorTolerance, ICollection <Point> resultPolyline, ICollection <double> resultParameters)
        {
            double num14;
            var    num    = controlPoints[1].X - controlPoints[0].X;
            var    num2   = controlPoints[1].Y - controlPoints[0].Y;
            var    num3   = controlPoints[2].X - controlPoints[1].X;
            var    num4   = controlPoints[2].Y - controlPoints[1].Y;
            var    num5   = controlPoints[3].X - controlPoints[2].X;
            var    num6   = controlPoints[3].Y - controlPoints[2].Y;
            var    num7   = num3 - num;
            var    num8   = num4 - num2;
            var    num9   = num5 - num3;
            var    num10  = num6 - num4;
            var    num11  = num9 - num7;
            var    num12  = num10 - num8;
            var    vector = controlPoints[3].Subtract(controlPoints[0]);
            var    length = vector.Length;

            if (!MathHelper.IsVerySmall(length))
            {
                num14 = Math.Max(0.0,
                                 Math.Max(Math.Abs((num7 * vector.Y - num8 * vector.X) / length),
                                          Math.Abs((num9 * vector.Y - num10 * vector.X) / length)));
            }
            else
            {
                num14 = Math.Max(0.0,
                                 Math.Max(GeometryHelper.Distance(controlPoints[1], controlPoints[0]),
                                          GeometryHelper.Distance(controlPoints[2], controlPoints[0])));
            }
            uint num15 = 0;

            if (num14 > 0.0)
            {
                var d = num14 * inverseErrorTolerance;
                num15 = d < 2147483647.0 ? Log4UnsignedInt32((uint)(d + 0.5)) : Log4Double(d);
            }

            var exp   = (int)-num15;
            var num18 = exp + exp;
            var num19 = num18 + exp;
            var num20 = MathHelper.DoubleFromMantissaAndExponent(3.0 * num7, num18);
            var num21 = MathHelper.DoubleFromMantissaAndExponent(3.0 * num8, num18);
            var num22 = MathHelper.DoubleFromMantissaAndExponent(6.0 * num11, num19);
            var num23 = MathHelper.DoubleFromMantissaAndExponent(6.0 * num12, num19);
            var num24 = MathHelper.DoubleFromMantissaAndExponent(3.0 * num, exp) + num20 +
                        0.16666666666666666 * num22;
            var num25 = MathHelper.DoubleFromMantissaAndExponent(3.0 * num2, exp) + num21 +
                        0.16666666666666666 * num23;
            var num26 = 2.0 * num20 + num22;
            var num27 = 2.0 * num21 + num23;
            var x     = controlPoints[0].X;
            var y     = controlPoints[0].Y;
            var item  = new Point(0.0, 0.0);
            var num30 = 1 << (int)num15;
            var num31 = num30 > 0 ? (rightParameter - leftParameter) / num30 : 0.0;
            var num32 = leftParameter;

            for (var i = 1; i < num30; i++)
            {
                x     += num24;
                y     += num25;
                item.X = x;
                item.Y = y;
                resultPolyline.Add(item);
                num32 += num31;
                resultParameters?.Add(num32);
                num24 += num26;
                num25 += num27;
                num26 += num22;
                num27 += num23;
            }
        }
 public static void FlattenQuadratic(Point[] controlPoints, double errorTolerance, ICollection <Point> resultPolyline, bool skipFirstPoint, ICollection <double> resultParameters = null)
 {
     if (resultPolyline == null)
     {
         throw new ArgumentNullException(nameof(resultPolyline));
     }
     if (controlPoints == null)
     {
         throw new ArgumentNullException(nameof(controlPoints));
     }
     if (controlPoints.Length != 3)
     {
         throw new ArgumentOutOfRangeException(nameof(controlPoints));
     }
     EnsureErrorTolerance(ref errorTolerance);
     Point[] pointArray = { controlPoints[0], GeometryHelper.Lerp(controlPoints[0], controlPoints[1], 0.66666666666666663), GeometryHelper.Lerp(controlPoints[1], controlPoints[2], 0.33333333333333331), controlPoints[2] };
     FlattenCubic(pointArray, errorTolerance, resultPolyline, skipFirstPoint, resultParameters);
 }
示例#5
0
 public Point GetPoint(IList <Point> points)
 {
     return(GeometryHelper.Lerp(points[Index], points[Index + 1], Ratio));
 }