public static bool IsCloseSegmentDegenerate(PathFigure figure) { if (figure.Segments.Count == 0) { return(false); } Point lastPoint = PathSegmentUtilities.GetLastPoint(figure.Segments[figure.Segments.Count - 1]); return(VectorUtilities.ArePathPointsVeryClose(PathFigureUtilities.FirstPoint(figure), lastPoint)); }
public void Add(Point pt, long time) { if (this.current.points.Count > 0 && VectorUtilities.ArePathPointsVeryClose(this.current.points[this.current.points.Count - 1], pt)) { return; } this.current.points.Add(pt); int count = this.current.points.Count; if (count >= 3) { this.current.endTangent.X = 0.0; this.current.endTangent.Y = 0.0; for (int index = Math.Max(0, count - 6); index < count - 1; ++index) { this.current.endTangent += (this.current.points[count - 1] - this.current.points[index]) / (double)(count - 1 - Math.Max(0, count - 6)); } if (this.IsSamplePointACorner(this.current.points[count - 3], this.current.points[count - 2], this.current.points[count - 1], Math.Cos(2.0 * Math.PI * (this.cornerTolerance / 360.0)))) { this.current.points.RemoveAt(this.current.points.Count - 1); this.current.endTangent = new Vector(0.0, 0.0); this.FitSegments(new PathGeometryEditor(this.path), this.current); this.current.cornerSegment = true; this.current.prevBezier = (IncrementalFitter.IncrementalFittingData)null; this.current.points.Clear(); this.current.points.Add(pt); } } if (this.current.points.Count < 4) { return; } Point[] bezierFit1 = this.ComputeBezierFit(this.current); if (this.ComputeMaxError(this.current.points, bezierFit1) <= this.curveTolerance) { return; } if (this.current.prevBezier != null) { PathGeometryEditor pathGeometryEditor = new PathGeometryEditor(this.path); Point[] bezierFit2 = this.ComputeBezierFit(this.current.prevBezier); if (PathGeometryUtilities.IsEmpty(pathGeometryEditor.PathGeometry)) { pathGeometryEditor.StartFigure(bezierFit2[0]); } pathGeometryEditor.AppendCubicBezier(bezierFit2[1], bezierFit2[2], bezierFit2[3]); } this.current.prevBezier = (IncrementalFitter.IncrementalFittingData) this.current.Clone(); this.current.prevBezier.prevBezier = (IncrementalFitter.IncrementalFittingData)null; this.current.cornerSegment = false; this.current.startTangent = bezierFit1[2] - bezierFit1[3]; this.current.startTangent.Normalize(); this.current.points.Clear(); this.current.points.Add(pt); }
public PathGeometry OpenFit(List <Point> input, bool inputMayContainRepeats, double cornerThreshold, double distanceTolerance, bool onlyCubics, bool enforceStartTangent, Vector startTangent, bool enforceEndTangent, Vector endTangent) { if (cornerThreshold <= 0.0 || cornerThreshold >= Math.PI) { throw new ArgumentOutOfRangeException("cornerThreshold", (object)cornerThreshold, "Corner threshold must be strictly between zero and Pi."); } if (distanceTolerance <= 0.0) { throw new ArgumentOutOfRangeException("distanceTolerance", (object)distanceTolerance, "Distance tolerance must be strictly greater than zero."); } this.enforceStartTangent = enforceStartTangent; this.enforceEndTangent = enforceEndTangent; if (this.enforceStartTangent && startTangent.LengthSquared < FloatingPointArithmetic.SquaredDistanceTolerance && (this.enforceEndTangent && endTangent.LengthSquared < FloatingPointArithmetic.SquaredDistanceTolerance)) { throw new ArgumentException(ExceptionStringTable.CannotEnforceZeroLengthTangents); } if (this.enforceEndTangent) { endTangent.Normalize(); this.endTangent = endTangent; } if (this.enforceStartTangent) { startTangent.Normalize(); this.startTangent = startTangent; } this.sample = input; if (inputMayContainRepeats && input.Count > 1) { this.sample = new List <Point>(input.Count); this.sample.Add(input[0]); for (int index = 1; index < input.Count; ++index) { if (!VectorUtilities.ArePathPointsVeryClose(input[index], input[index - 1])) { this.sample.Add(input[index]); } } } PathGeometry path = new PathGeometry(); PathGeometryEditor pathGeometryEditor = new PathGeometryEditor(path); if (this.sample.Count > 0) { pathGeometryEditor.StartFigure(this.sample[0]); this.figure = path.Figures[0]; } PathFigureEditor pathFigureEditor = new PathFigureEditor(this.figure); if (this.sample.Count == 2) { if (VectorUtilities.Distance(this.sample[0], this.sample[1]) >= distanceTolerance) { if (onlyCubics) { pathFigureEditor.LinearCubicCurveTo(this.sample[1]); } else { pathFigureEditor.LineTo(this.sample[1]); } } } else if (this.sample.Count > 2) { int lastIndex = this.sample.Count - 1; this.chordLength = VectorUtilities.GetCumulatedChordLength(this.sample, 0, lastIndex); this.distanceTolerance = distanceTolerance; double cosThreshold = Math.Cos(cornerThreshold); int num = 0; int index = 1; while (true) { while (index >= lastIndex || this.IsSamplePointACorner(index, cosThreshold)) { if (index == num + 1) { if (onlyCubics) { pathFigureEditor.LinearCubicCurveTo(this.sample[index]); } else { pathFigureEditor.LineTo(this.sample[index]); } } else { this.OpenFit2DFromTo(num, this.GetUnitTangentVectorFirst(num), index, this.GetUnitTangentVectorLast(index), onlyCubics); } num = index; ++index; if (num >= lastIndex) { goto label_33; } } ++index; } } label_33: return(path); }