in packages/maker.js/src/core/paths.ts [62:178]
constructor(...args: any[]) {
function getSpan(origin: IPoint): IArcSpan {
var startAngle = angle.ofPointInDegrees(origin, args[clockwise ? 1 : 0]);
var endAngle = angle.ofPointInDegrees(origin, args[clockwise ? 0 : 1]);
if (endAngle < startAngle) {
endAngle += 360;
}
return {
origin: origin,
startAngle: startAngle,
endAngle: endAngle,
size: endAngle - startAngle
};
}
switch (args.length) {
case 5:
//SVG style arc designation
var pointA = args[0] as IPoint;
var pointB = args[1] as IPoint;
this.radius = args[2] as number;
var largeArc = args[3] as boolean;
var clockwise = args[4] as boolean;
var span: IArcSpan;
//make sure arc can reach. if not, scale up.
var smallestRadius = measure.pointDistance(pointA, pointB) / 2;
if (round(this.radius - smallestRadius) <= 0) {
this.radius = smallestRadius;
span = getSpan(point.average(pointA, pointB));
} else {
//find the 2 potential origins
var origins = path.intersection(
new Circle(pointA, this.radius),
new Circle(pointB, this.radius)
);
var spans: IArcSpan[] = [];
for (var i = origins.intersectionPoints.length; i--;) {
span = getSpan(origins.intersectionPoints[i])
//insert sorted by size ascending
if (spans.length == 0 || span.size > spans[0].size) {
spans.push(span);
} else {
spans.unshift(span);
}
}
var index = largeArc ? 1 : 0;
span = spans[index];
}
this.origin = span.origin;
this.startAngle = span.startAngle;
this.endAngle = span.endAngle;
break;
case 4:
this.origin = args[0];
this.radius = args[1];
this.startAngle = args[2];
this.endAngle = args[3];
break;
case 3:
if (isPoint(args[2])) {
//from 3 points
Circle.apply(this, args);
var angles: number[] = [];
for (var i = 0; i < 3; i++) {
angles.push(angle.ofPointInDegrees(this.origin, args[i]));
}
this.startAngle = angles[0];
this.endAngle = angles[2];
//swap start and end angles if this arc does not contain the midpoint
if (!measure.isBetweenArcAngles(angles[1], this, false)) {
this.startAngle = angles[2];
this.endAngle = angles[0];
}
//do not fall through if this was 3 points
break;
}
//fall through to below if 2 points
case 2:
//from 2 points (and optional clockwise flag)
var clockwise = args[2] as boolean;
Circle.call(this, args[0], args[1]);
this.startAngle = angle.ofPointInDegrees(this.origin, args[clockwise ? 1 : 0]);
this.endAngle = angle.ofPointInDegrees(this.origin, args[clockwise ? 0 : 1]);
break;
}
//do this after Circle.apply / Circle.call to make sure this is an arc
this.type = pathType.Arc;
}