JSFiddle - React, Tailwind, and code Playground
HTML
<body>
<svg id="svg">
<g id="arcgroup" stroke="#F00" stroke-width="2" fill="none">
</g>
<g id="curvegroup" stroke="#000" stroke-width="2" fill="none" transform="translate(100,0)">
</g>
</svg>
</body>
CSS
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
svg,
canvas {
height: 100%;
width: 100%;
position: absolute;
left: 0;
top: 0;
}
svg {
opacity: 0.5;
}
JavaScript
function clamp(value, min, max) {
return Math.min(Math.max(value, min), max)
}
function svgAngle(ux, uy, vx, vy) {
var dot = ux * vx + uy * vy;
var len = Math.sqrt(ux * ux + uy * uy) * Math.sqrt(vx * vx + vy * vy);
var ang = Math.acos(clamp(dot / len, -1, 1));
if ((ux * vy - uy * vx) < 0)
ang = -ang;
return ang;
}
function generateBezierPoints(rx, ry, phi, flagA, flagS, x1, y1, x2, y2) {
var rX = Math.abs(rx);
var rY = Math.abs(ry);
var dx2 = (x1 - x2) / 2;
var dy2 = (y1 - y2) / 2;
var x1p = Math.cos(phi) * dx2 + Math.sin(phi) * dy2;
var y1p = -Math.sin(phi) * dx2 + Math.cos(phi) * dy2;
var rxs = rX * rX;
var rys = rY * rY;
var x1ps = x1p * x1p;
var y1ps = y1p * y1p;
var cr = x1ps / rxs + y1ps / rys;
if (cr > 1) {
var s = Math.sqrt(cr);
rX = s * rX;
rY = s * rY;
rxs = rX * rX;
rys = rY * rY;
curvegroup.setAttributeNS(null, "stroke", "#0F0");
} else {
curvegroup.setAttributeNS(null, "stroke", "#00F");
}
var dq = (rxs * y1ps + rys * x1ps);
var pq = (rxs * rys - dq) / dq;
var q = Math.sqrt(Math.max(0, pq));
if (flagA === flagS)
q = -q;
var cxp = q * rX * y1p / rY;
var cyp = -q * rY * x1p / rX;
var cx = Math.cos(phi) * cxp - Math.sin(phi) * cyp + (x1 + x2) / 2.0;
var cy = Math.sin(phi) * cxp + Math.cos(phi) * cyp + (y1 + y2) / 2.0;
var theta = svgAngle(1, 0, (x1p - cxp) / rX, (y1p - cyp) / rY);
var delta = svgAngle(
(x1p - cxp) / rX, (y1p - cyp) / rY,
(-x1p - cxp) / rX, (-y1p - cyp) / rY);
delta = delta - Math.PI * 2 * Math.floor(delta / (Math.PI * 2));
if (!flagS)
delta -= 2 * Math.PI;
var n1 = theta,
n2 = delta;
n2 = theta + delta;
// E(n)
// cx +acosθcosη−bsinθsinη
// cy +asinθcosη+bcosθsinη
function E(n) {
var enx = cx + rx * Math.cos(phi) * Math.cos(n) - ry * Math.sin(phi) * Math.sin(n);
var eny = cy + rx * Math.sin(phi) * Math.cos(n) + ry * Math.cos(phi) * Math.sin(n);
return {
x: enx,
y: eny
...