Cubic.circularArc constructor
Generates a bezier curve that approximates a circular arc, with p0 and p1 as the starting and ending anchor points. The curve generated is the smallest of the two possible arcs around the entire 360-degree circle. Arcs of greater than 180 degrees should use more than one arc together. Note that p0 and p1 should be equidistant from the center.
Implementation
// TODO: consider a more general function (maybe in addition to this) that
// allows caller to get a list of curves surpassing 180 degrees.
factory Cubic.circularArc(
double centerX,
double centerY,
double x0,
double y0,
double x1,
double y1,
) {
final p0d = directionVector(x0 - centerX, y0 - centerY);
final p1d = directionVector(x1 - centerX, y1 - centerY);
final rotatedP0 = p0d.rotate90();
final rotatedP1 = p1d.rotate90();
final clockwise = rotatedP0.dotProductXY(x1 - centerX, y1 - centerY) >= 0;
final cosa = p0d.dotProduct(p1d);
// p0 ~= p1
if (cosa > 0.999) {
return Cubic.straightLine(x0, y0, x1, y1);
}
final k = distance(x0 - centerX, y0 - centerY) *
4 /
3 *
(math.sqrt(2 * (1 - cosa)) - math.sqrt(1 - cosa * cosa)) /
(1 - cosa) *
(clockwise ? 1 : -1);
return Cubic(
x0,
y0,
x0 + rotatedP0.x * k,
y0 + rotatedP0.y * k,
x1 - rotatedP1.x * k,
y1 - rotatedP1.y * k,
x1,
y1,
);
}