function endpointToCenterParameterization(
x1,
y1,
x2,
y2,
largeArcFlag,
sweepFlag,
srx,
sry,
xAxisRotationDeg
) {
const xAxisRotation = degToRad(xAxisRotationDeg);
const cosphi = Math.cos(xAxisRotation);
const sinphi = Math.sin(xAxisRotation);
const [x1p, y1p] = mat2DotVec2(
[cosphi, sinphi, -sinphi, cosphi],
[(x1 - x2) / 2, (y1 - y2) / 2]
);
const [rx, ry] = correctRadii(srx, sry, x1p, y1p);
const sign = largeArcFlag !== sweepFlag ? 1 : -1;
const n = pow(rx) * pow(ry) - pow(rx) * pow(y1p) - pow(ry) * pow(x1p);
const d = pow(rx) * pow(y1p) + pow(ry) * pow(x1p);
const [cxp, cyp] = vec2Scale(
[(rx * y1p) / ry, (-ry * x1p) / rx],
sign * Math.sqrt(Math.abs(n / d))
);
const [cx, cy] = vec2Add(
mat2DotVec2([cosphi, -sinphi, sinphi, cosphi], [cxp, cyp]),
[(x1 + x2) / 2, (y1 + y2) / 2]
);
const a = [(x1p - cxp) / rx, (y1p - cyp) / ry];
const b = [(-x1p - cxp) / rx, (-y1p - cyp) / ry];
const startAngle = vec2Angle([1, 0], a);
const deltaAngle0 = vec2Angle(a, b) % (2 * Math.PI);
const deltaAngle =
!sweepFlag && deltaAngle0 > 0
? deltaAngle0 - 2 * Math.PI
: sweepFlag && deltaAngle0 < 0
? deltaAngle0 + 2 * Math.PI
: deltaAngle0;
const endAngle = startAngle + deltaAngle;
return {
cx,
cy,
rx,
ry,
startAngle,
endAngle,
xAxisRotation,
anticlockwise: deltaAngle < 0
};
}