Пример #1
0
        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);
        }
Пример #2
0
 private void FitSegments(PathGeometryEditor pathEditor, IncrementalFitter.IncrementalFittingData data)
 {
     Point[] pointArray = (Point[])null;
     if (data.points.Count > 3)
     {
         pointArray = this.ComputeBezierFit(data);
     }
     if (data.prevBezier != null)
     {
         Point[] bezierFit = this.ComputeBezierFit(data.prevBezier);
         if (PathGeometryUtilities.IsEmpty(pathEditor.PathGeometry))
         {
             pathEditor.StartFigure(bezierFit[0]);
         }
         pathEditor.AppendCubicBezier(bezierFit[1], bezierFit[2], bezierFit[3]);
     }
     if (data.points.Count == 2)
     {
         if (PathGeometryUtilities.IsEmpty(pathEditor.PathGeometry))
         {
             pathEditor.StartFigure(data.points[0]);
         }
         pathEditor.AppendLineSegment(data.points[1]);
     }
     else if (data.points.Count == 3)
     {
         if (PathGeometryUtilities.IsEmpty(pathEditor.PathGeometry))
         {
             pathEditor.StartFigure(data.points[0]);
         }
         pathEditor.AppendQuadraticBezier(data.points[1], data.points[2]);
     }
     else
     {
         if (data.points.Count <= 3)
         {
             return;
         }
         if (PathGeometryUtilities.IsEmpty(pathEditor.PathGeometry))
         {
             pathEditor.StartFigure(pointArray[0]);
         }
         pathEditor.AppendCubicBezier(pointArray[1], pointArray[2], pointArray[3]);
     }
 }
Пример #3
0
        public PathGeometry ClosedFit(List <Point> input, bool inputMayContainRepeats, double cornerThreshold, double distanceTolerance, bool onlyCubics)
        {
            if (input.Count < 3)
            {
                throw new ArgumentException(ExceptionStringTable.InputCollectionMustContainAtLeastThreePoints, "input");
            }
            PathGeometry       path = this.OpenFit(input, inputMayContainRepeats, cornerThreshold, distanceTolerance, onlyCubics);
            PathGeometryEditor pathGeometryEditor = new PathGeometryEditor(path);
            PathFigureEditor   pathFigureEditor   = new PathFigureEditor(path.Figures[0]);

            if (onlyCubics)
            {
                pathFigureEditor.CloseWithCubicBezier();
                this.figure = path.Figures[0];
                this.SetupCollinearHandlesConstraint(0, false);
            }
            else
            {
                pathFigureEditor.CloseWithLineSegment();
            }
            return(path);
        }
Пример #4
0
        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);
        }