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); }
public Point GetPoint(IList <Point> points) { return(GeometryHelper.Lerp(points[Index], points[Index + 1], Ratio)); }