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); }
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 }); } }
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)) };