{"version":3,"file":"buildArcToSvg.mjs","sources":["../../../../../src/scene/graphics/shared/buildCommands/buildArcToSvg.ts"],"sourcesContent":["import { buildAdaptiveBezier } from './buildAdaptiveBezier';\n\nconst TAU = Math.PI * 2;\n\nconst out = {\n    centerX: 0,\n    centerY: 0,\n    ang1: 0,\n    ang2: 0\n};\n\nconst mapToEllipse = (\n    { x, y }: {x: number, y: number},\n    rx: number, ry: number,\n    cosPhi: number, sinPhi: number,\n    centerX: number, centerY: number,\n    out: {x: number, y: number}\n): {x: number, y: number} =>\n{\n    x *= rx;\n    y *= ry;\n\n    const xp = (cosPhi * x) - (sinPhi * y);\n    const yp = (sinPhi * x) + (cosPhi * y);\n\n    out.x = xp + centerX;\n    out.y = yp + centerY;\n\n    return out;\n};\n\nfunction approxUnitArc(ang1: number, ang2: number): {x: number, y: number}[]\n{\n    // If 90 degree circular arc, use a constant\n    // as derived from http://spencermortensen.com/articles/bezier-circle\n\n    const a1 = ang2 === -1.5707963267948966 ? -0.551915024494 : 4 / 3 * Math.tan(ang2 / 4);\n\n    const a = ang2 === 1.5707963267948966 ? 0.551915024494 : a1;\n\n    const x1 = Math.cos(ang1);\n    const y1 = Math.sin(ang1);\n    const x2 = Math.cos(ang1 + ang2);\n    const y2 = Math.sin(ang1 + ang2);\n\n    return [\n        {\n            x: x1 - (y1 * a),\n            y: y1 + (x1 * a)\n        },\n        {\n            x: x2 + (y2 * a),\n            y: y2 - (x2 * a)\n        },\n        {\n            x: x2,\n            y: y2\n        }\n    ];\n}\n\nconst vectorAngle = (ux: number, uy: number, vx: number, vy: number) =>\n{\n    const sign = ((ux * vy) - (uy * vx) < 0) ? -1 : 1;\n\n    let dot = (ux * vx) + (uy * vy);\n\n    if (dot > 1)\n    {\n        dot = 1;\n    }\n\n    if (dot < -1)\n    {\n        dot = -1;\n    }\n\n    return sign * Math.acos(dot);\n};\n\nconst getArcCenter = (\n    px: number,\n    py: number,\n    cx: number,\n    cy: number,\n    rx: number,\n    ry: number,\n    largeArcFlag: number,\n    sweepFlag: number,\n    sinPhi: number,\n    cosPhi: number,\n    pxp: number,\n    pyp: number,\n    out: {\n        centerX: number,\n        centerY: number,\n        ang1: number,\n        ang2: number\n    }\n// eslint-disable-next-line max-params\n) =>\n{\n    const rxSq = Math.pow(rx, 2);\n    const rySq = Math.pow(ry, 2);\n    const pxpSq = Math.pow(pxp, 2);\n    const pypSq = Math.pow(pyp, 2);\n\n    let radicant = (rxSq * rySq) - (rxSq * pypSq) - (rySq * pxpSq);\n\n    if (radicant < 0)\n    {\n        radicant = 0;\n    }\n\n    radicant /= (rxSq * pypSq) + (rySq * pxpSq);\n    radicant = Math.sqrt(radicant) * (largeArcFlag === sweepFlag ? -1 : 1);\n\n    const centerXp = radicant * rx / ry * pyp;\n    const centerYp = radicant * -ry / rx * pxp;\n\n    const centerX = (cosPhi * centerXp) - (sinPhi * centerYp) + ((px + cx) / 2);\n    const centerY = (sinPhi * centerXp) + (cosPhi * centerYp) + ((py + cy) / 2);\n\n    const vx1 = (pxp - centerXp) / rx;\n    const vy1 = (pyp - centerYp) / ry;\n    const vx2 = (-pxp - centerXp) / rx;\n    const vy2 = (-pyp - centerYp) / ry;\n\n    const ang1 = vectorAngle(1, 0, vx1, vy1);\n    let ang2 = vectorAngle(vx1, vy1, vx2, vy2);\n\n    if (sweepFlag === 0 && ang2 > 0)\n    {\n        ang2 -= TAU;\n    }\n\n    if (sweepFlag === 1 && ang2 < 0)\n    {\n        ang2 += TAU;\n    }\n\n    out.centerX = centerX;\n    out.centerY = centerY;\n    out.ang1 = ang1;\n    out.ang2 = ang2;\n};\n\n/**\n * @param points\n * @param px\n * @param py\n * @param cx\n * @param cy\n * @param rx\n * @param ry\n * @param xAxisRotation\n * @param largeArcFlag\n * @param sweepFlag\n * @internal\n */\nexport function buildArcToSvg(\n    points: number[],\n    px: number,\n    py: number,\n    cx: number,\n    cy: number,\n    rx: number,\n    ry: number,\n    xAxisRotation = 0,\n    largeArcFlag = 0,\n    sweepFlag = 0\n): void\n{\n    if (rx === 0 || ry === 0)\n    {\n        return;\n    }\n\n    const sinPhi = Math.sin(xAxisRotation * TAU / 360);\n    const cosPhi = Math.cos(xAxisRotation * TAU / 360);\n\n    const pxp = (cosPhi * (px - cx) / 2) + (sinPhi * (py - cy) / 2);\n    const pyp = (-sinPhi * (px - cx) / 2) + (cosPhi * (py - cy) / 2);\n\n    if (pxp === 0 && pyp === 0)\n    {\n        return;\n    }\n\n    rx = Math.abs(rx);\n    ry = Math.abs(ry);\n\n    const lambda = (Math.pow(pxp, 2) / Math.pow(rx, 2)) + (Math.pow(pyp, 2) / Math.pow(ry, 2));\n\n    if (lambda > 1)\n    {\n        rx *= Math.sqrt(lambda);\n        ry *= Math.sqrt(lambda);\n    }\n\n    getArcCenter(\n        px,\n        py,\n        cx,\n        cy,\n        rx,\n        ry,\n        largeArcFlag,\n        sweepFlag,\n        sinPhi,\n        cosPhi,\n        pxp,\n        pyp,\n        out\n    );\n\n    let { ang1, ang2 } = out;\n    const { centerX, centerY } = out;\n\n    // If 'ang2' == 90.0000000001, then `ratio` will devalue to\n    // 1.0000000001. This causes `segments` to be greater than one, which is an\n    // unnecessary split, and adds extra points to the bezier curve. To alleviate\n    // this issue, we round to 1.0 when the ratio is close to 1.0.\n    let ratio = Math.abs(ang2) / (TAU / 4);\n\n    if (Math.abs(1.0 - ratio) < 0.0000001)\n    {\n        ratio = 1.0;\n    }\n\n    const segments = Math.max(Math.ceil(ratio), 1);\n\n    ang2 /= segments;\n\n    let lastX = points[points.length - 2];\n    let lastY = points[points.length - 1];\n\n    const outCurvePoint = { x: 0, y: 0 };\n\n    for (let i = 0; i < segments; i++)\n    {\n        const curve = approxUnitArc(ang1, ang2);\n\n        const { x: x1, y: y1 } = mapToEllipse(curve[0], rx, ry, cosPhi, sinPhi, centerX, centerY, outCurvePoint);\n        const { x: x2, y: y2 } = mapToEllipse(curve[1], rx, ry, cosPhi, sinPhi, centerX, centerY, outCurvePoint);\n        const { x, y } = mapToEllipse(curve[2], rx, ry, cosPhi, sinPhi, centerX, centerY, outCurvePoint);\n\n        buildAdaptiveBezier(\n            points,\n            lastX, lastY,\n            x1, y1, x2, y2, x, y\n        );\n\n        lastX = x;\n        lastY = y;\n\n        ang1 += ang2;\n    }\n}\n"],"names":["out"],"mappings":"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"}