, Javascript:
const PI = Math.PI;
const HALF_PI = Math.PI / 2;
const TWO_PI = Math.PI * 2;
const DEG_TO_RAD = Math.PI / 180;
const RAD_TO_DEG = 180 / Math.PI;
const getQuadrant = (_angle) => {
const angle = _angle % (TWO_PI);
if (angle > 0.0 && angle < HALF_PI) return 0;
if (angle >= HALF_PI && angle < PI) return 1;
if (angle >= PI && angle < PI + HALF_PI) return 2;
return 3;
};
const getArcBoundingBox = (ini, end, radius, margin = 0) => {
const iniQuad = getQuadrant(ini);
const endQuad = getQuadrant(end);
const ix = Math.cos(ini) * radius;
const iy = Math.sin(ini) * radius;
const ex = Math.cos(end) * radius;
const ey = Math.sin(end) * radius;
const minX = Math.min(ix, ex);
const minY = Math.min(iy, ey);
const maxX = Math.max(ix, ex);
const maxY = Math.max(iy, ey);
const r = radius;
const xMax = [[maxX, r, r, r], [maxX, maxX, r, r], [maxX, maxX, maxX, r], [maxX, maxX, maxX, maxX]];
const yMax = [[maxY, maxY, maxY, maxY], [r, maxY, r, r], [r, maxY, maxY, r], [r, maxY, maxY, maxY]];
const xMin = [[minX, -r, minX, minX], [minX, minX, minX, minX], [-r, -r, minX, -r], [-r, -r, minX, minX]];
const yMin = [[minY, -r, -r, minY], [minY, minY, -r, minY], [minY, minY, minY, minY], [-r, -r, -r, minY]];
const x1 = xMin[endQuad][iniQuad];
const y1 = yMin[endQuad][iniQuad];
const x2 = xMax[endQuad][iniQuad];
const y2 = yMax[endQuad][iniQuad];
const x = x1 - margin;
const y = y1 - margin;
const w = x2 - x1 + margin * 2;
const h = y2 - y1 + margin * 2;
return { x, y, w, h };
};
jsfiddle: https://jsfiddle.net/brunoimbrizi/y3to5s6n/45/