elliptical_arc = {
const RADIANS = Math.PI/180;
const {cos, sin, sqrt} = Math;
return function(rx, ry, x_axis_rotation, large_arc_flag, sweep_flag, x, y) {
const
psi = RADIANS*x_axis_rotation,
c = cos(psi),
s = sin(psi),
a = 2*rx,
b = 2*ry,
ab_inv = 1/(a*b),
qx = (c*c)*(b*b) + (s*s)*(a*a),
qy = (s*s)*(b*b) + (c*c)*(a*a),
qxy = c*s*(b - a)*(b + a),
v2 = (ab_inv*ab_inv)*(qx*x*x + qy*y*y + 2*qxy*x*y),
Jvx = ab_inv*(qxy*x + qy*y),
Jvy = -ab_inv*(qx*x + qxy*y),
rc_sign = 1 - 2*(+large_arc_flag),
rs_sign = -1 + 2*(+sweep_flag);
let rc = 0, rs = rs_sign;
if (v2 < 1)
rc = rc_sign * sqrt(1 - v2),
rs = rs_sign * sqrt(v2);
const rc_m1 = 1 - rc;
return function(t) {
const
p1 = (rc_m1*t + rc)*t,
p2 = (rs - rs*t)*t,
p3_inv = 1/((rc_m1*t - rc_m1)*2*t + 1),
wc = p1*p3_inv,
ws = p2*p3_inv;
return [x*wc + Jvx*ws, y*wc + Jvy*ws];
}
}
}