You've already forked wakapi-readme-stats
108 lines
2.8 KiB
JavaScript
108 lines
2.8 KiB
JavaScript
import {DegToRad, HalfPi, Tau} from '../util/constants';
|
|
|
|
export var segmentCache = {};
|
|
export var bezierCache = {};
|
|
|
|
var join = [].join;
|
|
|
|
// Copied from Inkscape svgtopdf, thanks!
|
|
export function segments(x, y, rx, ry, large, sweep, rotateX, ox, oy) {
|
|
var key = join.call(arguments);
|
|
if (segmentCache[key]) {
|
|
return segmentCache[key];
|
|
}
|
|
|
|
var th = rotateX * DegToRad;
|
|
var sin_th = Math.sin(th);
|
|
var cos_th = Math.cos(th);
|
|
rx = Math.abs(rx);
|
|
ry = Math.abs(ry);
|
|
var px = cos_th * (ox - x) * 0.5 + sin_th * (oy - y) * 0.5;
|
|
var py = cos_th * (oy - y) * 0.5 - sin_th * (ox - x) * 0.5;
|
|
var pl = (px*px) / (rx*rx) + (py*py) / (ry*ry);
|
|
if (pl > 1) {
|
|
pl = Math.sqrt(pl);
|
|
rx *= pl;
|
|
ry *= pl;
|
|
}
|
|
|
|
var a00 = cos_th / rx;
|
|
var a01 = sin_th / rx;
|
|
var a10 = (-sin_th) / ry;
|
|
var a11 = (cos_th) / ry;
|
|
var x0 = a00 * ox + a01 * oy;
|
|
var y0 = a10 * ox + a11 * oy;
|
|
var x1 = a00 * x + a01 * y;
|
|
var y1 = a10 * x + a11 * y;
|
|
|
|
var d = (x1-x0) * (x1-x0) + (y1-y0) * (y1-y0);
|
|
var sfactor_sq = 1 / d - 0.25;
|
|
if (sfactor_sq < 0) sfactor_sq = 0;
|
|
var sfactor = Math.sqrt(sfactor_sq);
|
|
if (sweep == large) sfactor = -sfactor;
|
|
var xc = 0.5 * (x0 + x1) - sfactor * (y1-y0);
|
|
var yc = 0.5 * (y0 + y1) + sfactor * (x1-x0);
|
|
|
|
var th0 = Math.atan2(y0-yc, x0-xc);
|
|
var th1 = Math.atan2(y1-yc, x1-xc);
|
|
|
|
var th_arc = th1-th0;
|
|
if (th_arc < 0 && sweep === 1) {
|
|
th_arc += Tau;
|
|
} else if (th_arc > 0 && sweep === 0) {
|
|
th_arc -= Tau;
|
|
}
|
|
|
|
var segs = Math.ceil(Math.abs(th_arc / (HalfPi + 0.001)));
|
|
var result = [];
|
|
for (var i=0; i<segs; ++i) {
|
|
var th2 = th0 + i * th_arc / segs;
|
|
var th3 = th0 + (i+1) * th_arc / segs;
|
|
result[i] = [xc, yc, th2, th3, rx, ry, sin_th, cos_th];
|
|
}
|
|
|
|
return (segmentCache[key] = result);
|
|
}
|
|
|
|
export function bezier(params) {
|
|
var key = join.call(params);
|
|
if (bezierCache[key]) {
|
|
return bezierCache[key];
|
|
}
|
|
|
|
var cx = params[0],
|
|
cy = params[1],
|
|
th0 = params[2],
|
|
th1 = params[3],
|
|
rx = params[4],
|
|
ry = params[5],
|
|
sin_th = params[6],
|
|
cos_th = params[7];
|
|
|
|
var a00 = cos_th * rx;
|
|
var a01 = -sin_th * ry;
|
|
var a10 = sin_th * rx;
|
|
var a11 = cos_th * ry;
|
|
|
|
var cos_th0 = Math.cos(th0);
|
|
var sin_th0 = Math.sin(th0);
|
|
var cos_th1 = Math.cos(th1);
|
|
var sin_th1 = Math.sin(th1);
|
|
|
|
var th_half = 0.5 * (th1 - th0);
|
|
var sin_th_h2 = Math.sin(th_half * 0.5);
|
|
var t = (8/3) * sin_th_h2 * sin_th_h2 / Math.sin(th_half);
|
|
var x1 = cx + cos_th0 - t * sin_th0;
|
|
var y1 = cy + sin_th0 + t * cos_th0;
|
|
var x3 = cx + cos_th1;
|
|
var y3 = cy + sin_th1;
|
|
var x2 = x3 + t * sin_th1;
|
|
var y2 = y3 - t * cos_th1;
|
|
|
|
return (bezierCache[key] = [
|
|
a00 * x1 + a01 * y1, a10 * x1 + a11 * y1,
|
|
a00 * x2 + a01 * y2, a10 * x2 + a11 * y2,
|
|
a00 * x3 + a01 * y3, a10 * x3 + a11 * y3
|
|
]);
|
|
}
|