67 lines
No EOL
3 KiB
JavaScript
67 lines
No EOL
3 KiB
JavaScript
/*
|
|
Copyright © 2020 Xah Lee, © 2023 P.M Kuipers
|
|
Permission is hereby granted, free of charge, to any person obtaining a
|
|
copy of this software and associated documentation files (the “Software”),
|
|
to deal in the Software without restriction, including without limitation
|
|
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
and/or sell copies of the Software, and to permit persons to whom the
|
|
Software is furnished to do so, subject to the following conditions:
|
|
The above copyright notice and this permission notice shall be included
|
|
in all copies or substantial portions of the Software.
|
|
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
DEALINGS IN THE SOFTWARE.
|
|
URL: SVG Circle Arc http://xahlee.info/js/svg_circle_arc.html
|
|
*/
|
|
|
|
const cos = Math.cos;
|
|
const sin = Math.sin;
|
|
const π = Math.PI;
|
|
|
|
const fMatrixTimes = (([[a, b], [c, d]], [x, y]) => [a * x + b * y, c * x + d * y]);
|
|
const fRotateMatrix = (x => [[cos(x), -sin(x)], [sin(x), cos(x)]]);
|
|
const fVecAdd = (([a1, a2], [b1, b2]) => [a1 + b1, a2 + b2]);
|
|
|
|
// Function modified by pmkuipers for text params
|
|
/**
|
|
* Create svg path text for an arc
|
|
* @param {*} center [cx,cy] center of ellipse
|
|
* @param {*} radius [rx,ry] major minor radius
|
|
* @param {*} angle [t1, Δ] start angle, in radian, angle to sweep, in radian. positive.
|
|
* @param {*} φ rotation on the whole, in radian
|
|
* @returns {string} a SVG path description that represent a ellipse. Text describing the arc path in an svg path element
|
|
*/
|
|
const svgarcpath = (([cx, cy], [rx, ry], [t1, Δ], φ) => {
|
|
Δ = Δ % (2 * π);
|
|
const rotMatrix = fRotateMatrix(φ);
|
|
const [sX, sY] = (fVecAdd(fMatrixTimes(rotMatrix, [rx * cos(t1), ry * sin(t1)]), [cx, cy]));
|
|
const [eX, eY] = (fVecAdd(fMatrixTimes(rotMatrix, [rx * cos(t1 + Δ), ry * sin(t1 + Δ)]), [cx, cy]));
|
|
const fA = ((Δ > π) ? 1 : 0);
|
|
const fS = ((Δ > 0) ? 1 : 0);
|
|
if (isNaN(eY) || isNaN(eX)) {
|
|
return "";
|
|
} else {
|
|
return "M " + sX + " " + sY + " A " + [rx, ry, φ / (2 * π) * 360, fA, fS, eX, eY].join(" ");
|
|
}
|
|
});
|
|
|
|
/**
|
|
* Create an svg arc element
|
|
* @param {*} center [cx,cy] center of ellipse
|
|
* @param {*} radius [rx,ry] major minor radius
|
|
* @param {*} angle [t1, Δ] start angle, in radian, angle to sweep, in radian. positive.
|
|
* @param {*} φ rotation on the whole, in radian
|
|
* @returns {string} a SVG path element that represent a ellipse.
|
|
*/
|
|
const svgarc = (([cx, cy], [rx, ry], [t1, Δ], φ) => {
|
|
const path2wk2r = document.createElementNS("http://www.w3.org/2000/svg", "path");
|
|
const d = svgarcpath([cx, cy], [rx, ry], [t1, Δ], φ);
|
|
path2wk2r.setAttribute("d", d);
|
|
return path2wk2r;
|
|
});
|
|
|
|
export {svgarc, svgarcpath}; |