pathFromCubics function
Returns a Path built from the given cubics.
This is the building block behind RoundedPolygon.toPath and Morph.toPath, and is useful when working with a list of curves obtained from Morph.toCubics directly.
startAngle places the start point of the first curve at that angle, in
radians, around rotationPivot, rotating the whole path to get it there.
Zero is to the right of the pivot and pi / 2 below it, since y grows
downwards.
The default of zero is special: it skips the rotation entirely and leaves
the curves as given.
If repeatPath is true, the curves are added twice before the Path is
closed. This is useful when the caller would like to draw parts of the path
while offsetting the start and stop positions, for example when phasing and
rotating a path to simulate motion as a star-shaped circular progress
indicator advances.
If closePath is false, the returned Path is left open.
rotationPivot is the point startAngle rotates the path around, and the
point its angle is measured from. It defaults to the origin, which suits
curves laid out around Offset.zero.
Implementation
Path pathFromCubics(
List<CubicBezier> cubics, {
double startAngle = 0.0,
bool repeatPath = false,
bool closePath = true,
Offset rotationPivot = .zero,
Path? path,
}) {
if (path != null) {
path.reset();
} else {
path = Path();
}
if (cubics.isEmpty) return path;
final firstCubic = cubics.first;
path.moveTo(firstCubic.anchor0X, firstCubic.anchor0Y);
for (final cubic in cubics) {
path.cubicTo(
cubic.control0X,
cubic.control0Y,
cubic.control1X,
cubic.control1Y,
cubic.anchor1X,
cubic.anchor1Y,
);
}
if (repeatPath) {
path.lineTo(firstCubic.anchor0X, firstCubic.anchor0Y);
for (final cubic in cubics) {
path.cubicTo(
cubic.control0X,
cubic.control0Y,
cubic.control1X,
cubic.control1Y,
cubic.anchor1X,
cubic.anchor1Y,
);
}
}
if (closePath) path.close();
if (startAngle != 0.0) {
final angleToFirstCubic = math.atan2(
firstCubic.anchor0Y - rotationPivot.dy,
firstCubic.anchor0X - rotationPivot.dx,
);
// Rotate the path around the pivot so that it starts from the given angle.
final transform = Matrix4.identity()
..translateByDouble(rotationPivot.dx, rotationPivot.dy, 0.0, 1.0)
..rotateZ(-angleToFirstCubic + startAngle)
..translateByDouble(-rotationPivot.dx, -rotationPivot.dy, 0.0, 1.0);
path = path.transform(transform.storage);
}
return path;
}