Пример #1
0
        public void AppendCubicBezier(Point q, Point r, Point s, int figureIndex)
        {
            PathFigureEditor pathFigureEditor = this.CreatePathFigureEditor(figureIndex);

            if (!PathFigureUtilities.IsOpen(pathFigureEditor.PathFigure))
            {
                throw new InvalidOperationException(ExceptionStringTable.FigureMustBeOpenToAppendACubicCurve);
            }
            pathFigureEditor.CubicCurveTo(q, r, s);
        }
Пример #2
0
        private void OpenFit2DFromTo(int first, Vector unitTangentFirst, int last, Vector unitTangentLast, bool onlyCubics)
        {
            int length = last - first + 1;
            int num1   = length - 1;
            PathFigureEditor pathFigureEditor = new PathFigureEditor(this.figure);

            if (length == 2)
            {
                if (onlyCubics)
                {
                    double num2 = VectorUtilities.Distance(this.sample[first], this.sample[last]) / 3.0;
                    Point  p1   = this.sample[first] + unitTangentFirst * num2;
                    Point  p2   = this.sample[last] - unitTangentLast * num2;
                    pathFigureEditor.CubicCurveTo(p1, p2, this.sample[last]);
                }
                else
                {
                    pathFigureEditor.LineTo(this.sample[last]);
                }
            }
            else if (length == 3)
            {
                int    index1  = first + 1;
                Vector vector1 = this.sample[first] - this.sample[index1];
                Vector vector2 = this.sample[last] - this.sample[index1];
                Vector vector3 = vector1;
                vector3.Normalize();
                Vector vector4 = vector2;
                vector4.Normalize();
                Vector vector5 = vector3 + vector4;
                Vector vector6;
                if (VectorUtilities.IsZero(vector5))
                {
                    vector6 = this.sample[last] - this.sample[first];
                    vector6.Normalize();
                }
                else
                {
                    vector6 = VectorUtilities.UnitNormal(vector5);
                }
                if (VectorUtilities.Dot(vector6, this.sample[last] - this.sample[first]) < 0.0)
                {
                    vector6 *= -1.0;
                }
                this.OpenFit2DFromTo(first, unitTangentFirst, index1, vector6, onlyCubics);
                int index2 = PathFigureUtilities.PointCount(this.figure) - 1;
                this.OpenFit2DFromTo(index1, vector6, last, unitTangentLast, onlyCubics);
                this.SetupCollinearHandlesConstraint(index2, onlyCubics);
            }
            else
            {
                double[][] numArray1 = new double[length][];
                for (int index = 0; index < length; ++index)
                {
                    numArray1[index] = new double[4];
                }
                double   num2      = 1.0 / (this.chordLength[last] - this.chordLength[first]);
                double[] numArray2 = new double[length];
                for (int index = 0; index <= num1; ++index)
                {
                    numArray2[index] = (this.chordLength[first + index] - this.chordLength[first]) * num2;
                }
                double[] numArray3 = new double[4];
                numArray3[0] = 1.0;
                for (int index1 = 0; index1 <= num1; ++index1)
                {
                    numArray3[1] = 1.0 - numArray2[index1];
                    for (int index2 = 2; index2 <= 3; ++index2)
                    {
                        numArray3[index2] = numArray3[index2 - 1] * numArray3[1];
                    }
                    numArray1[index1][0] = numArray3[3];
                    double num3   = numArray2[index1];
                    int    index3 = 1;
                    while (index3 <= 3)
                    {
                        numArray1[index1][index3] = (double)BezierCurveFitter.pascalTriangle[3][index3] * num3 * numArray3[3 - index3];
                        ++index3;
                        num3 *= numArray2[index1];
                    }
                }
                double[][] numArray4 = new double[4][];
                for (int index = 0; index < 4; ++index)
                {
                    numArray4[index] = new double[4];
                }
                for (int index1 = 0; index1 <= 3; ++index1)
                {
                    for (int index2 = 0; index2 <= index1; ++index2)
                    {
                        for (int index3 = 0; index3 <= num1; ++index3)
                        {
                            numArray4[index1][index2] += numArray1[index3][index2] * numArray1[index3][index1];
                        }
                        if (index1 != index2)
                        {
                            numArray4[index2][index1] = numArray4[index1][index2];
                        }
                    }
                }
                double[][] m = new double[2][]
                {
                    new double[2]
                    {
                        numArray4[1][1],
                        numArray4[1][2] * VectorUtilities.Dot(unitTangentFirst, unitTangentLast)
                    },
                    new double[2]
                    {
                        numArray4[1][2],
                        numArray4[2][2]
                    }
                };
                double[] v           = new double[2];
                Vector[] vectorArray = new Vector[4];
                for (int index1 = 0; index1 < 4; ++index1)
                {
                    for (int index2 = 0; index2 <= num1; ++index2)
                    {
                        vectorArray[index1].X += numArray1[index2][index1] * this.sample[index2 + first].X;
                        vectorArray[index1].Y += numArray1[index2][index1] * this.sample[index2 + first].Y;
                    }
                }
                Vector vector1 = new Vector(this.sample[first].X, this.sample[first].Y);
                Vector vector2 = new Vector(this.sample[last].X, this.sample[last].Y);
                Vector b1      = (numArray4[1][0] + numArray4[1][1]) * vector1 + (numArray4[1][2] + numArray4[1][3]) * vector2 - vectorArray[1];
                v[0] = -VectorUtilities.Dot(unitTangentFirst, b1);
                Vector b2 = (numArray4[2][0] + numArray4[2][1]) * vector1 + (numArray4[2][2] + numArray4[2][3]) * vector2 - vectorArray[2];
                v[1] = -VectorUtilities.Dot(unitTangentLast, b2);
                bool flag = BezierCurveFitter.Solve2By2LinearSystem(m, v);
                int  firstBadVertexInQ = 0;
                if (flag && v[0] > 0.0 && v[1] < 0.0)
                {
                    Point[] controlPoints = new Point[4];
                    controlPoints[0] = this.sample[first];
                    controlPoints[1] = controlPoints[0] + v[0] * unitTangentFirst;
                    controlPoints[3] = this.sample[last];
                    controlPoints[2] = controlPoints[3] + v[1] * unitTangentLast;
                    List <Point> list = new List <Point>(128);
                    BezierCurveFlattener.FlattenCubic(controlPoints, this.distanceTolerance, list, false);
                    double[] cumulatedChordLength = VectorUtilities.GetCumulatedChordLength(list, 0, list.Count - 1);
                    if (VectorUtilities.ArePolylinesClose(list, cumulatedChordLength, 0, list.Count - 1, this.sample, this.chordLength, first, last, this.distanceTolerance, ref firstBadVertexInQ))
                    {
                        pathFigureEditor.CubicCurveTo(controlPoints[1], controlPoints[2], controlPoints[3]);
                        return;
                    }
                }
                int    num4 = (first + last) / 2;
                Vector tangentVectorAtSplit = this.GetUnitTangentVectorAtSplit(num4);
                this.OpenFit2DFromTo(first, unitTangentFirst, num4, tangentVectorAtSplit, onlyCubics);
                int index4 = PathFigureUtilities.PointCount(this.figure) - 1;
                this.OpenFit2DFromTo(num4, tangentVectorAtSplit, last, unitTangentLast, onlyCubics);
                this.SetupCollinearHandlesConstraint(index4, onlyCubics);
            }
        }
Пример #3
0
        private void SetPathUsingMapping(PathGeometry path)
        {
            SceneViewModel viewModel = this.targetElement.ViewModel;

            using (viewModel.AnimationProxyManager != null ? viewModel.AnimationProxyManager.ExpandAllProxiesInActiveContainer() : (IDisposable)null)
            {
                foreach (PathAction action in this.changeList.Changes)
                {
                    System.Windows.Media.Geometry geometry = this.targetElement.GetLocalOrDefaultValueAsWpf((IPropertyId)this.pathProperty) as System.Windows.Media.Geometry;
                    if (geometry == null && this.targetElement.IsValueExpression((IPropertyId)this.pathProperty))
                    {
                        geometry = this.targetElement.ViewModel.DefaultView.ConvertToWpfValue(this.targetElement.ViewModel.CreateInstance(this.targetElement.GetLocalValueAsSceneNode((IPropertyId)this.pathProperty).DocumentNodePath)) as System.Windows.Media.Geometry;
                        if (geometry == null)
                        {
                            geometry = this.targetElement.GetComputedValueAsWpf((IPropertyId)this.pathProperty) as System.Windows.Media.Geometry;
                            if (geometry == null)
                            {
                                return;
                            }
                        }
                    }
                    PathGeometry oldGeometry = new PathGeometry();
                    oldGeometry.AddGeometry(geometry.Clone());
                    PathGeometry pathGeometry = new PathGeometry();
                    pathGeometry.AddGeometry(geometry);
                    PathFigureEditor   pathFigureEditor   = new PathFigureEditor(pathGeometry.Figures[action.Figure]);
                    PathGeometryEditor pathGeometryEditor = new PathGeometryEditor(pathGeometry);
                    switch (action.Action)
                    {
                    case PathActionType.InsertPoint:
                        pathFigureEditor.SubdivideSegment(action.PointIndex, action.Parameter);
                        break;

                    case PathActionType.DeletePoint:
                        pathFigureEditor.RemovePoint(action.PointIndex);
                        break;

                    case PathActionType.DeleteSegment:
                        if (action.Segment == 0 && pathFigureEditor.PathFigure.Segments.Count > 1)
                        {
                            pathFigureEditor.RemoveFirstSegment();
                            break;
                        }
                        pathFigureEditor.RemoveLastSegment();
                        break;

                    case PathActionType.PromoteSegment:
                        pathFigureEditor.PromoteSegment(action.PointIndex);
                        break;

                    case PathActionType.Rotate:
                        pathFigureEditor.Rotate();
                        break;

                    case PathActionType.Open:
                        pathFigureEditor.Open(action.PointIndex);
                        break;

                    case PathActionType.Split:
                        pathFigureEditor.Split(action.PointIndex);
                        break;

                    case PathActionType.SplitAndAdd:
                        pathGeometryEditor.SplitFigure(action.Figure, action.PointIndex);
                        break;

                    case PathActionType.RemoveFigure:
                        pathGeometryEditor.RemoveFigure(action.Figure);
                        break;

                    case PathActionType.AppendSegment:
                        PathAppendLineAction appendLineAction;
                        if ((appendLineAction = action as PathAppendLineAction) != null)
                        {
                            Point point = appendLineAction.Point;
                            if (action.Figure < path.Figures.Count && action.Segment < path.Figures[action.Figure].Segments.Count)
                            {
                                LineSegment lineSegment = path.Figures[action.Figure].Segments[action.Segment] as LineSegment;
                                if (lineSegment != null)
                                {
                                    point = lineSegment.Point;
                                }
                            }
                            pathFigureEditor.LineTo(point);
                            break;
                        }
                        PathAppendQuadraticBezierAction quadraticBezierAction;
                        if ((quadraticBezierAction = action as PathAppendQuadraticBezierAction) != null)
                        {
                            Point point1 = quadraticBezierAction.Point1;
                            Point point2 = quadraticBezierAction.Point2;
                            if (action.Figure < path.Figures.Count && action.Segment < path.Figures[action.Figure].Segments.Count)
                            {
                                QuadraticBezierSegment quadraticBezierSegment = path.Figures[action.Figure].Segments[action.Segment] as QuadraticBezierSegment;
                                if (quadraticBezierSegment != null)
                                {
                                    point1 = quadraticBezierSegment.Point1;
                                    point2 = quadraticBezierSegment.Point2;
                                }
                            }
                            pathFigureEditor.QuadraticCurveTo(point1, point2);
                            break;
                        }
                        PathAppendBezierAction appendBezierAction;
                        if ((appendBezierAction = action as PathAppendBezierAction) != null)
                        {
                            Point point1 = appendBezierAction.Point1;
                            Point point2 = appendBezierAction.Point2;
                            Point point3 = appendBezierAction.Point3;
                            if (action.Figure < path.Figures.Count && action.Segment < path.Figures[action.Figure].Segments.Count)
                            {
                                BezierSegment bezierSegment = path.Figures[action.Figure].Segments[action.Segment] as BezierSegment;
                                if (bezierSegment != null)
                                {
                                    point1 = bezierSegment.Point1;
                                    point2 = bezierSegment.Point2;
                                    point3 = bezierSegment.Point3;
                                }
                            }
                            pathFigureEditor.CubicCurveTo(point1, point2, point3);
                            break;
                        }
                        break;

                    case PathActionType.Close:
                        pathFigureEditor.CloseWithLineSegment();
                        break;

                    case PathActionType.Join:
                        pathGeometryEditor.JoinFigure(action.Figure, action.PointIndex);
                        break;

                    case PathActionType.Reverse:
                        pathFigureEditor.Reverse();
                        break;
                    }
                    this.targetElement.SetLocalValueAsWpf((IPropertyId)this.pathProperty, (object)pathGeometry);
                    this.ApplyAnimationChanges(oldGeometry, pathGeometry, action);
                    if (action.Action == PathActionType.PromoteSegment && action.Segment < pathGeometry.Figures[action.Figure].Segments.Count)
                    {
                        this.targetElement.ViewModel.Document.OnUpdatedEditTransaction();
                        this.SetKeyframesForSegment(path, action.Figure, action.Segment);
                    }
                }
                this.RemoveInvalidAnimations(PathGeometryUtilities.GetPathGeometryFromGeometry((System.Windows.Media.Geometry) this.targetElement.GetLocalOrDefaultValueAsWpf((IPropertyId)this.pathProperty)));
            }
        }