예제 #1
0
        private static bool SubdividePoints(float[] points, BezierCalculation bezierFunction, float t0, Vector2 p0, float t1, Vector2 p1, out float midT, out Vector2 midPoint, float errorSquared)
        {
            midT = (t1 + t0) / 2;
            float midX = (p1.X + p0.X) / 2;
            float midY = (p1.Y + p0.Y) / 2;

            midPoint = bezierFunction(midT, points);
            float xError          = midPoint.X - midX;
            float yError          = midPoint.Y - midY;
            float midErrorSquared = (xError * xError) + (yError * yError);

            return(midErrorSquared > errorSquared);
        }
예제 #2
0
파일: Path.cs 프로젝트: cm4ker/LottieSharp
        static void AddBezier(float[] points, BezierCalculation bezierFunction, List <Vector2> segmentPoints,
                              List <float> lengths, float errorSquared, bool doubleCheckDivision)
        {
            points[7] = points[5];
            points[6] = points[4];
            points[5] = points[3];
            points[4] = points[2];
            points[3] = points[1];
            points[2] = points[0];
            points[1] = 0;
            points[0] = 0;

            var tToPoint = new List <KeyValuePair <float, Vector2> >
            {
                new KeyValuePair <float, Vector2>(0, bezierFunction(0, points)),
                new KeyValuePair <float, Vector2>(1, bezierFunction(1, points))
            };

            for (int i = 0; i < tToPoint.Count - 1; i++)
            {
                bool needsSubdivision;
                do
                {
                    needsSubdivision = SubdividePoints(points, bezierFunction, tToPoint[i].Key, tToPoint[i].Value,
                                                       tToPoint[i + 1].Key,
                                                       tToPoint[i + 1].Value, out var midT, out var midPoint, errorSquared);
                    if (!needsSubdivision && doubleCheckDivision)
                    {
                        needsSubdivision = SubdividePoints(points, bezierFunction, tToPoint[i].Key, tToPoint[i].Value,
                                                           midT,
                                                           midPoint, out _, out _, errorSquared);
                        if (needsSubdivision)
                        {
                            // Found an inflection point. No need to double-check.
                            doubleCheckDivision = false;
                        }
                    }

                    if (needsSubdivision)
                    {
                        tToPoint.Insert(i + 1, new KeyValuePair <float, Vector2>(midT, midPoint));
                    }
                } while (needsSubdivision);
            }

            // Now that each division can use linear interpolation with less than the allowed error
            foreach (var iter in tToPoint)
            {
                AddLine(segmentPoints, lengths, new[] { iter.Value.X, iter.Value.Y });
            }
        }
예제 #3
0
        static void AddBezier(float[] points, BezierCalculation bezierFunction, List <Vector2> segmentPoints,
                              List <float> lengths, float errorSquared, bool doubleCheckDivision)
        {
            points[7] = points[5];
            points[6] = points[4];
            points[5] = points[3];
            points[4] = points[2];
            points[3] = points[1];
            points[2] = points[0];
            points[1] = 0;
            points[0] = 0;

            var tToPoint = new List <KeyValuePair <float, Vector2> >
            {
                new(0, bezierFunction(0, points)),
                new(1, bezierFunction(1, points))
            };