computeLength method
Computes an approximation of the arc length of this cubic starting
from start
.
Implementation
double computeLength(Point start) {
// Mike Reed just made this up! The nerve of him.
// One difference from Skia is just setting a default tolerance of 3. This
// is good enough for a particular test SVG that has this curve:
// M65 33c0 17.673-14.326 32-32 32S1 50.673 1 33C1 15.327 15.326 1 33 1s32 14.327 32 32z
// Lower values end up getting the end points wrong when dashing a path.
const double tolerance = 1 / 2 * 3;
double _compute(
Point p1,
Point cp1,
Point cp2,
Point p2,
double distance,
) {
// If it's "too curvy," cut it in half
if (Point.distance(cp1, Point.lerp(p1, p2, 1 / 3)) > tolerance ||
Point.distance(cp2, Point.lerp(p1, p2, 2 / 3)) > tolerance) {
final List<Point> points = subdivide(p1, cp1, cp2, p2, .5);
distance = _compute(
points[0],
points[1],
points[2],
points[3],
distance,
);
distance = _compute(
points[3],
points[4],
points[5],
points[6],
distance,
);
} else {
// It's collinear enough to just treat as a line.
distance += Point.distance(p1, p2);
}
return distance;
}
return _compute(start, Point(x1, y1), Point(x2, y2), Point(x3, y3), 0);
}