curvy 2.0.0-alpha.13 → 2.0.0-alpha.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/characteristic/index.mjs +1 -1
- package/dist/curve/cubic2d.d.ts +102 -3
- package/dist/curve/curve2d.d.ts +81 -0
- package/dist/curve/index.mjs +1 -1
- package/dist/curve/linear2d.d.ts +122 -3
- package/dist/curve/quadratic2d.d.ts +103 -3
- package/dist/curve/rationalCubic2d.d.ts +100 -38
- package/dist/interval/index.mjs +2 -2
- package/dist/matrix/index.mjs +47 -1
- package/dist/matrix/index.mjs.map +1 -1
- package/dist/matrix/matrix3x3.d.ts +87 -1
- package/dist/matrix/matrix4x4.d.ts +57 -6
- package/dist/matrix/traits.d.ts +34 -0
- package/dist/monotonicity/index.mjs +1 -1
- package/dist/monotonicity/monotonicity.d.ts +25 -0
- package/dist/number.d.ts +53 -0
- package/dist/number.mjs +56 -1
- package/dist/number.mjs.map +1 -1
- package/dist/path/cubic2d.d.ts +22 -0
- package/dist/path/index.mjs +25 -149
- package/dist/path/index.mjs.map +1 -1
- package/dist/path/linear2d.d.ts +24 -0
- package/dist/path/path2d.d.ts +54 -0
- package/dist/path/quadratic2d.d.ts +22 -0
- package/dist/path/rationalCubic2d.d.ts +21 -0
- package/dist/polynomial/index.mjs +2 -2
- package/dist/shared/affine2d-Dvna84gc.mjs +332 -0
- package/dist/shared/affine2d-Dvna84gc.mjs.map +1 -0
- package/dist/shared/{characteristic-BkEr-rr8.mjs → characteristic--7nC4Q_a.mjs} +4 -5
- package/dist/shared/characteristic--7nC4Q_a.mjs.map +1 -0
- package/dist/shared/{cubic-BL6dpuHh.mjs → cubic-BiGuAnZ0.mjs} +56 -27
- package/dist/shared/cubic-BiGuAnZ0.mjs.map +1 -0
- package/dist/shared/{interval-Dm35Xhy4.mjs → interval-Dcqpo73t.mjs} +5 -5
- package/dist/shared/interval-Dcqpo73t.mjs.map +1 -0
- package/dist/shared/{interval2d-AtneyI45.mjs → interval2d-C2Pk66-2.mjs} +3 -3
- package/dist/shared/{interval2d-AtneyI45.mjs.map → interval2d-C2Pk66-2.mjs.map} +1 -1
- package/dist/shared/matrix3x3.internal-Cod-r7H3.mjs +233 -0
- package/dist/shared/matrix3x3.internal-Cod-r7H3.mjs.map +1 -0
- package/dist/shared/{matrix4x4-BWmf4lZM.mjs → matrix4x4-BrqgYZCD.mjs} +72 -223
- package/dist/shared/matrix4x4-BrqgYZCD.mjs.map +1 -0
- package/dist/shared/monotonicity-DNxBoC7F.mjs +64 -0
- package/dist/shared/monotonicity-DNxBoC7F.mjs.map +1 -0
- package/dist/shared/{quadratic-DPrUsFCp.mjs → quadratic-BmMqkvxx.mjs} +2 -2
- package/dist/shared/{quadratic-DPrUsFCp.mjs.map → quadratic-BmMqkvxx.mjs.map} +1 -1
- package/dist/shared/{rationalCubic2d-CeHgpNht.mjs → rationalCubic2d-CZSwwKtS.mjs} +591 -125
- package/dist/shared/rationalCubic2d-CZSwwKtS.mjs.map +1 -0
- package/dist/shared/{rationalCubic2d-H1J2Fjyy.mjs → rationalCubic2d-bveuGqBZ.mjs} +282 -326
- package/dist/shared/rationalCubic2d-bveuGqBZ.mjs.map +1 -0
- package/dist/shared/{solution-B2JdOZpe.mjs → solution-BW0BBMXI.mjs} +22 -6
- package/dist/shared/solution-BW0BBMXI.mjs.map +1 -0
- package/dist/shared/{vector2-CSkaMXvp.mjs → vector2-DuA3EmfL.mjs} +5 -3
- package/dist/shared/vector2-DuA3EmfL.mjs.map +1 -0
- package/dist/shared/{vector2.internal-DP1nTBdS.mjs → vector2.internal-rPnW0RCx.mjs} +10 -5
- package/dist/shared/vector2.internal-rPnW0RCx.mjs.map +1 -0
- package/dist/shared/{vector3-CR2LPV03.mjs → vector3-oxtggkDp.mjs} +2 -2
- package/dist/shared/{vector3-CR2LPV03.mjs.map → vector3-oxtggkDp.mjs.map} +1 -1
- package/dist/shared/vector3.internal-CfWHl9SG.mjs +135 -0
- package/dist/shared/vector3.internal-CfWHl9SG.mjs.map +1 -0
- package/dist/shared/{vector4-PO_7EYd-.mjs → vector4-DGHuCvTV.mjs} +2 -2
- package/dist/shared/{vector4-PO_7EYd-.mjs.map → vector4-DGHuCvTV.mjs.map} +1 -1
- package/dist/shared/vector4.internal-DH5DzNYO.mjs +116 -0
- package/dist/shared/vector4.internal-DH5DzNYO.mjs.map +1 -0
- package/dist/solution/index.mjs +1 -1
- package/dist/solution/solution.d.ts +16 -0
- package/dist/splines/basis2d.d.ts +64 -0
- package/dist/splines/bezier2d.d.ts +72 -0
- package/dist/splines/cardinal2d.d.ts +78 -0
- package/dist/splines/hermite2d.d.ts +76 -0
- package/dist/splines/index.mjs +109 -15
- package/dist/splines/index.mjs.map +1 -1
- package/dist/splines/linear2d.d.ts +65 -0
- package/dist/splines/rationalBezier2d.d.ts +76 -0
- package/dist/transform/affine2d.d.ts +339 -0
- package/dist/transform/affine2d.internal.d.ts +2 -0
- package/dist/transform/index.d.ts +3 -0
- package/dist/transform/index.mjs +2 -0
- package/dist/transform/traits.d.ts +19 -0
- package/dist/vector/index.mjs +3 -3
- package/dist/vector/vector2.d.ts +49 -0
- package/package.json +5 -1
- package/dist/shared/characteristic-BkEr-rr8.mjs.map +0 -1
- package/dist/shared/cubic-BL6dpuHh.mjs.map +0 -1
- package/dist/shared/interval-Dm35Xhy4.mjs.map +0 -1
- package/dist/shared/matrix4x4-BWmf4lZM.mjs.map +0 -1
- package/dist/shared/monotonicity-BdebFOtv.mjs +0 -34
- package/dist/shared/monotonicity-BdebFOtv.mjs.map +0 -1
- package/dist/shared/rationalCubic2d-CeHgpNht.mjs.map +0 -1
- package/dist/shared/rationalCubic2d-H1J2Fjyy.mjs.map +0 -1
- package/dist/shared/solution-B2JdOZpe.mjs.map +0 -1
- package/dist/shared/vector2-CSkaMXvp.mjs.map +0 -1
- package/dist/shared/vector2.internal-DP1nTBdS.mjs.map +0 -1
- package/dist/shared/vector4.internal-BJ1QN2Ck.mjs +0 -246
- package/dist/shared/vector4.internal-BJ1QN2Ck.mjs.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rationalCubic2d-CZSwwKtS.mjs","names":["fromPolynomials","fromCoefficients","LinearPolynomial.make","fromEndpoints","isLinearCurve2d","derivative","Vector2.make","solve","LinearPolynomial.solve","solveAtX","LinearPolynomial.solveInverse","Solution.clip","Interval.unit","Solution.map","solveAtY","length","boundingBox","Interval2d.make","LinearPolynomial.unitRange","startPoint","endPoint","xRange","yRange","toPathDataSegment","isMonotonicX","LinearPolynomial.isMonotonic","isIncreasingX","LinearPolynomial.isIncreasing","isDecreasingX","LinearPolynomial.isDecreasing","isMonotonicY","isIncreasingY","isDecreasingY","isMonotonic","isIncreasing","isDecreasing","fail","asMonotonic","asIncreasing","asDecreasing","transform","fromPolynomials","internal.fromPolynomials","fromCoefficients","internal.fromCoefficients","internal.fromEndpoints","internal.isLinearCurve2d","derivative","internal.derivative","solve","internal.solve","length","internal.length","boundingBox","internal.boundingBox","startPoint","internal.startPoint","endPoint","internal.endPoint","xRange","internal.xRange","yRange","internal.yRange","toPathDataSegment","internal.toPathDataSegment","solveAtX","internal.solveAtX","solveAtY","internal.solveAtY","isMonotonicX","internal.isMonotonicX","isIncreasingX","internal.isIncreasingX","isDecreasingX","internal.isDecreasingX","isMonotonicY","internal.isMonotonicY","isIncreasingY","internal.isIncreasingY","isDecreasingY","internal.isDecreasingY","isMonotonic","internal.isMonotonic","isIncreasing","internal.isIncreasing","isDecreasing","internal.isDecreasing","asMonotonic","internal.asMonotonic","asIncreasing","internal.asIncreasing","asDecreasing","internal.asDecreasing","transform","internal.transform","Ops","fromPolynomials","fromCoefficients","QuadraticPolynomial.make","fromBezierPoints","isQuadraticCurve2d","solve","Vector2.make","QuadraticPolynomial.solve","solveAtX","QuadraticPolynomial.solveInverse","Solution.clipApprox","Interval.unit","Solution.map","solveAtY","derivative","LinearCurve2d.fromPolynomials","QuadraticPolynomial.derivative","length","Interval.size","LinearCurve2d.length","LinearPolynomial.make","Interval.scaleShift","Interval.biunit","Vector2.magnitude","LinearCurve2d.solve","curvature","LinearCurve2d.derivative","Vector2.cross","boundingBox","Interval2d.make","QuadraticPolynomial.unitRange","startPoint","endPoint","xRange","yRange","toPathDataSegment","isMonotonicX","QuadraticPolynomial.isMonotonic","isIncreasingX","QuadraticPolynomial.isIncreasing","isDecreasingX","QuadraticPolynomial.isDecreasing","isMonotonicY","isIncreasingY","isDecreasingY","isMonotonic","isIncreasing","isDecreasing","fail","asMonotonic","asIncreasing","asDecreasing","transform","fromPolynomials","internal.fromPolynomials","fromCoefficients","internal.fromCoefficients","fromBezierPoints","internal.fromBezierPoints","internal.isQuadraticCurve2d","solve","internal.solve","length","internal.length","solveAtX","internal.solveAtX","solveAtY","internal.solveAtY","derivative","internal.derivative","curvature","internal.curvature","boundingBox","internal.boundingBox","startPoint","internal.startPoint","endPoint","internal.endPoint","xRange","internal.xRange","yRange","internal.yRange","toPathDataSegment","internal.toPathDataSegment","isMonotonicX","internal.isMonotonicX","isIncreasingX","internal.isIncreasingX","isDecreasingX","internal.isDecreasingX","isMonotonicY","internal.isMonotonicY","isIncreasingY","internal.isIncreasingY","isDecreasingY","internal.isDecreasingY","isMonotonic","internal.isMonotonic","isIncreasing","internal.isIncreasing","isDecreasing","internal.isDecreasing","asMonotonic","internal.asMonotonic","asIncreasing","internal.asIncreasing","asDecreasing","internal.asDecreasing","transform","internal.transform","Ops","fromPolynomials","fromCoefficients","CubicPolynomial.make","fromBezierPoints","Characteristic.apply","Characteristic.cubicBezier","Vector4.transpose","isCubicCurve2d","solve","Vector2.make","CubicPolynomial.solve","solveAtX","CubicPolynomial.solveInverse","Solution.clipApprox","Interval.unit","Solution.map","CubicPolynomial.toSolver","solveAtY","QuadraticCurve2d.fromPolynomials","CubicPolynomial.derivative","length","Interval.size","QuadraticCurve2d.length","QuadraticPolynomial.make","Interval.scaleShift","Interval.biunit","Vector2.magnitude","QuadraticCurve2d.solve","curvature","LinearCurve2d.solve","QuadraticCurve2d.derivative","Vector2.cross","boundingBox","Interval2d.make","CubicPolynomial.unitRange","startPoint","endPoint","xRange","yRange","toPathDataSegment","isMonotonicX","CubicPolynomial.isMonotonic","isIncreasingX","CubicPolynomial.isIncreasing","isDecreasingX","CubicPolynomial.isDecreasing","isMonotonicY","isIncreasingY","isDecreasingY","isMonotonic","isIncreasing","isDecreasing","fail","asMonotonic","asIncreasing","asDecreasing","transform","fromPolynomials","internal.fromPolynomials","internal.fromCoefficients","fromBezierPoints","internal.fromBezierPoints","internal.isCubicCurve2d","solve","internal.solve","internal.length","solveAtX","internal.solveAtX","solveAtY","internal.solveAtY","internal.curvature","boundingBox","internal.boundingBox","startPoint","internal.startPoint","endPoint","internal.endPoint","internal.xRange","internal.yRange","internal.toPathDataSegment","isMonotonicX","internal.isMonotonicX","isIncreasingX","internal.isIncreasingX","isDecreasingX","internal.isDecreasingX","isMonotonicY","internal.isMonotonicY","isIncreasingY","internal.isIncreasingY","isDecreasingY","internal.isDecreasingY","isMonotonic","internal.isMonotonic","isIncreasing","internal.isIncreasing","isDecreasing","internal.isDecreasing","asMonotonic","internal.asMonotonic","asIncreasing","internal.asIncreasing","asDecreasing","internal.asDecreasing","transform","internal.transform","isRationalCubicCurve2d","fromPolynomials","Vector2.makeWeighted","fromBezierPoints","Characteristic.apply","Characteristic.cubicBezier","Vector4.transpose","fromSlopesAndCurvatures","CubicPolynomial.make","solve","CubicPolynomial.solve","Vector2.make","startPoint","endPoint","solveAtX","CubicPolynomial.roots","Solution.clipApprox","Interval.unit","Solution.map","solveAtY","xMonotonicity","yMonotonicity","isMonotonicX","Monotonicity.isStrict","isIncreasingX","isDecreasingX","isMonotonicY","isIncreasingY","isDecreasingY","isMonotonic","isIncreasing","isDecreasing","asMonotonicX","asIncreasingX","asDecreasingX","asMonotonicY","asIncreasingY","asDecreasingY","asMonotonic","asIncreasing","asDecreasing","transform","boundingBox","Interval2d.make","CubicPolynomial.unitRange","subdivide","Interval2d.union","CubicCurve2d.fromBezierPoints","CubicPolynomial.subdivide","Interval2d.fromVectors","CubicCurve2d.fromPolynomials","CubicCurve2d.boundingBox","Interval2d.maxDistance","approximateAsCubicCurves","internal.isRationalCubicCurve2d","internal.fromPolynomials","internal.fromBezierPoints","internal.fromSlopesAndCurvatures","internal.solve","internal.startPoint","internal.endPoint","internal.solveAtX","internal.solveAtY","internal.subdivide","internal.boundingBox","internal.xMonotonicity","internal.yMonotonicity","internal.isMonotonicX","internal.isIncreasingX","internal.isDecreasingX","internal.isMonotonicY","internal.isIncreasingY","internal.isDecreasingY","internal.isMonotonic","internal.isIncreasing","internal.isDecreasing","internal.asMonotonicX","internal.asIncreasingX","internal.asDecreasingX","internal.asMonotonicY","internal.asIncreasingY","internal.asDecreasingY","internal.asMonotonic","internal.asIncreasing","internal.asDecreasing","internal.transform","internal.approximateAsCubicCurves"],"sources":["../../src/curve/linear2d.internal.ts","../../src/curve/linear2d.ts","../../src/curve/quadratic2d.internal.ts","../../src/curve/quadratic2d.ts","../../src/curve/cubic2d.internal.ts","../../src/curve/cubic2d.ts","../../src/curve/rationalCubic2d.internal.ts","../../src/curve/rationalCubic2d.ts"],"sourcesContent":["import * as Interval2d from '../interval/interval2d.ts'\nimport * as Interval from '../interval/interval.ts'\nimport type * as Affine2d from '../transform/affine2d.ts'\nimport { dual, Pipeable } from '../utils.ts'\nimport * as LinearPolynomial from '../polynomial/linear.ts'\nimport type { Decreasing, Increasing, Monotonic } from '../polynomial/traits.ts'\nimport * as Solution from '../solution/solution.ts'\nimport * as Vector2 from '../vector/vector2.ts'\nimport type { LinearCurve2d } from './linear2d.ts'\n\nexport const LinearCurve2dTypeId: unique symbol = Symbol('curvy/curve/linear2d')\nexport type LinearCurve2dTypeId = typeof LinearCurve2dTypeId\n\n/** @internal */\nexport class LinearCurve2dImpl extends Pipeable implements LinearCurve2d<unknown, unknown> {\n readonly [LinearCurve2dTypeId]: LinearCurve2dTypeId = LinearCurve2dTypeId\n\n readonly x: LinearPolynomial.LinearPolynomial\n readonly y: LinearPolynomial.LinearPolynomial\n\n constructor(c0: LinearPolynomial.LinearPolynomial, c1: LinearPolynomial.LinearPolynomial) {\n super()\n this.x = c0\n this.y = c1\n }\n\n get [0]() {\n return this.x\n }\n\n get [1]() {\n return this.y\n }\n}\n\n/** @internal */\nexport const fromPolynomials: (\n c0: LinearPolynomial.LinearPolynomial,\n c1: LinearPolynomial.LinearPolynomial,\n) => LinearCurve2d = (c0, c1) => new LinearCurve2dImpl(c0, c1)\n\n/** @internal */\nexport const fromCoefficients: (c0: Vector2.Vector2, c1: Vector2.Vector2) => LinearCurve2d = (\n c0,\n c1,\n) => new LinearCurve2dImpl(LinearPolynomial.make(c0.x, c1.x), LinearPolynomial.make(c0.y, c1.y))\n\n// Linear Bernstein basis: B(t) = (1-t)·p0 + t·p1\n// Expanding to monomial form gives c0 = p0, c1 = p1 - p0.\n/** @internal */\nexport const fromEndpoints: (p0: Vector2.Vector2, p1: Vector2.Vector2) => LinearCurve2d = (\n p0,\n p1,\n) =>\n new LinearCurve2dImpl(\n LinearPolynomial.make(p0.x, p1.x - p0.x),\n LinearPolynomial.make(p0.y, p1.y - p0.y),\n )\n\n/** @internal */\nexport const isLinearCurve2d = (c: unknown): c is LinearCurve2d =>\n typeof c === 'object' && c !== null && LinearCurve2dTypeId in c\n\n/** @internal */\nexport const derivative = (c: LinearCurve2d) => Vector2.make(c.x.c1, c.y.c1)\n\n/** @internal */\nexport const solve = dual<\n (t: number) => (c: LinearCurve2d) => Vector2.Vector2,\n (c: LinearCurve2d, t: number) => Vector2.Vector2\n>(2, (c: LinearCurve2d, t: number) =>\n Vector2.make(LinearPolynomial.solve(c.x, t), LinearPolynomial.solve(c.y, t)),\n)\n\n// solveAtX: invert the x polynomial to find t, then evaluate y at t — only\n// returning the result when t lies in the curve's parameter domain [0, 1].\n// A linear curve crosses any vertical line at most once, so the result is\n// always 0 or 1 element.\n/** @internal */\nexport const solveAtX = dual(2, (c: LinearCurve2d, x: number) =>\n LinearPolynomial.solveInverse(c.x, x).pipe(\n Solution.clip(Interval.unit),\n Solution.map((t) => LinearPolynomial.solve(c.y, t)),\n ),\n)\n\n/** @internal */\nexport const solveAtY = dual(2, (c: LinearCurve2d, y: number) =>\n LinearPolynomial.solveInverse(c.y, y).pipe(\n Solution.clip(Interval.unit),\n Solution.map((t) => LinearPolynomial.solve(c.x, t)),\n ),\n)\n\n/** @internal */\nexport const length = dual(\n 2,\n (c: LinearCurve2d, i: Interval.Interval) =>\n Math.sqrt(c.x.c1 ** 2 + c.y.c1 ** 2) * Math.abs(i.end - i.start),\n)\n\n/** @internal */\nexport const boundingBox = (\n c: LinearCurve2d,\n): Interval2d.Interval2d<Interval.Closed, Interval.Closed> =>\n Interval2d.make(LinearPolynomial.unitRange(c.x), LinearPolynomial.unitRange(c.y))\n\n/** @internal */\nexport const startPoint = (c: LinearCurve2d): Vector2.Vector2 => Vector2.make(c.x.c0, c.y.c0)\n\n/** @internal */\nexport const endPoint = (c: LinearCurve2d): Vector2.Vector2 =>\n Vector2.make(c.x.c0 + c.x.c1, c.y.c0 + c.y.c1)\n\n/** @internal */\nexport const xRange = (c: LinearCurve2d): Interval.Closed => LinearPolynomial.unitRange(c.x)\n\n/** @internal */\nexport const yRange = (c: LinearCurve2d): Interval.Closed => LinearPolynomial.unitRange(c.y)\n\n/** @internal */\nexport const toPathDataSegment = (c: LinearCurve2d): string => {\n const endX = c.x.c0 + c.x.c1\n const endY = c.y.c0 + c.y.c1\n return `L ${endX},${endY}`\n}\n\n// Per-axis trait refiners delegate to the polynomial-level check on a single\n// axis and brand only that axis. The combined refiners (below) fan out to\n// both axes.\n/** @internal */\nexport const isMonotonicX = <XT, YT>(\n c: LinearCurve2d<XT, YT>,\n): c is LinearCurve2d<XT & Monotonic, YT> => LinearPolynomial.isMonotonic(c.x)\n\n/** @internal */\nexport const isIncreasingX = <XT, YT>(\n c: LinearCurve2d<XT, YT>,\n): c is LinearCurve2d<XT & Increasing, YT> => LinearPolynomial.isIncreasing(c.x)\n\n/** @internal */\nexport const isDecreasingX = <XT, YT>(\n c: LinearCurve2d<XT, YT>,\n): c is LinearCurve2d<XT & Decreasing, YT> => LinearPolynomial.isDecreasing(c.x)\n\n/** @internal */\nexport const isMonotonicY = <XT, YT>(\n c: LinearCurve2d<XT, YT>,\n): c is LinearCurve2d<XT, YT & Monotonic> => LinearPolynomial.isMonotonic(c.y)\n\n/** @internal */\nexport const isIncreasingY = <XT, YT>(\n c: LinearCurve2d<XT, YT>,\n): c is LinearCurve2d<XT, YT & Increasing> => LinearPolynomial.isIncreasing(c.y)\n\n/** @internal */\nexport const isDecreasingY = <XT, YT>(\n c: LinearCurve2d<XT, YT>,\n): c is LinearCurve2d<XT, YT & Decreasing> => LinearPolynomial.isDecreasing(c.y)\n\n/** @internal */\nexport const isMonotonic = <XT, YT>(\n c: LinearCurve2d<XT, YT>,\n): c is LinearCurve2d<XT & Monotonic, YT & Monotonic> => isMonotonicX(c) && isMonotonicY(c)\n\n/** @internal */\nexport const isIncreasing = <XT, YT>(\n c: LinearCurve2d<XT, YT>,\n): c is LinearCurve2d<XT & Increasing, YT & Increasing> => isIncreasingX(c) && isIncreasingY(c)\n\n/** @internal */\nexport const isDecreasing = <XT, YT>(\n c: LinearCurve2d<XT, YT>,\n): c is LinearCurve2d<XT & Decreasing, YT & Decreasing> => isDecreasingX(c) && isDecreasingY(c)\n\nconst fail = (m: string): never => {\n throw new Error(m)\n}\n\n/** @internal */\nexport const asMonotonic = <XT, YT>(\n c: LinearCurve2d<XT, YT>,\n): LinearCurve2d<XT & Monotonic, YT & Monotonic> =>\n isMonotonic(c) ? c : fail('linear curve is not monotonic in both axes')\n\n/** @internal */\nexport const asIncreasing = <XT, YT>(\n c: LinearCurve2d<XT, YT>,\n): LinearCurve2d<XT & Increasing, YT & Increasing> =>\n isIncreasing(c) ? c : fail('linear curve is not increasing in both axes')\n\n/** @internal */\nexport const asDecreasing = <XT, YT>(\n c: LinearCurve2d<XT, YT>,\n): LinearCurve2d<XT & Decreasing, YT & Decreasing> =>\n isDecreasing(c) ? c : fail('linear curve is not decreasing in both axes')\n\n// Affine transform on a coefficient-form curve: f(p(t)) = A·p(t) + b expands\n// to (A·c0 + b) + (A·c1)·t. The constant coefficient receives the full affine\n// (translation included), higher coefficients see only the linear part.\n/** @internal */\nexport const transform = dual<\n (a: Affine2d.Affine2d) => (c: LinearCurve2d) => LinearCurve2d,\n (c: LinearCurve2d, a: Affine2d.Affine2d) => LinearCurve2d\n>(2, (c: LinearCurve2d, a: Affine2d.Affine2d) => {\n const m = a.matrix\n return new LinearCurve2dImpl(\n LinearPolynomial.make(m.m00 * c.x.c0 + m.m01 * c.y.c0 + m.m02, m.m00 * c.x.c1 + m.m01 * c.y.c1),\n LinearPolynomial.make(m.m10 * c.x.c0 + m.m11 * c.y.c0 + m.m12, m.m10 * c.x.c1 + m.m11 * c.y.c1),\n )\n})\n","import type { Interval2d } from '../interval/interval2d.ts'\nimport type { TwoDimensional } from '../dimensions.ts'\nimport type { Closed, Interval } from '../interval/interval.ts'\nimport type { Pipeable } from '../utils.ts'\nimport type { LinearPolynomial } from '../polynomial/linear.ts'\nimport type { Decreasing, Increasing, Monotonic } from '../polynomial/traits.ts'\nimport type * as Solution from '../solution/solution.ts'\nimport type { Affine2d } from '../transform/affine2d.ts'\nimport type { Vector2 } from '../vector/vector2.ts'\nimport type { Curve2dOps } from './curve2d.ts'\nimport type { LinearCurve2dTypeId } from './linear2d.internal.ts'\nimport * as internal from './linear2d.internal.ts'\n\nexport type { Monotonic, Increasing, Decreasing } from '../polynomial/traits.ts'\n\n/**\n * A linear curve in 2D space.\n *\n * All fields are readonly and immutable, and all operations create new instances.\n *\n * The two type parameters carry the trait sets of the curve's per-axis\n * polynomials. Refiners like `isMonotonic` lift each axis's monotonicity into\n * the curve's combined trait set.\n *\n * @since 1.0.0\n */\nexport interface LinearCurve2d<out XTraits = unknown, out YTraits = unknown>\n extends Pipeable, TwoDimensional<LinearPolynomial<XTraits>, LinearPolynomial<YTraits>> {\n readonly [LinearCurve2dTypeId]: LinearCurve2dTypeId\n}\n\n/**\n * Creates a new `LinearCurve2d` instance from polynomial parameters.\n *\n * @param x - The x polynomial.\n * @param y - The y polynomial.\n * @returns A new `LinearCurve2d` instance.\n * @since 1.0.0\n */\nexport const fromPolynomials: (x: LinearPolynomial, y: LinearPolynomial) => LinearCurve2d =\n internal.fromPolynomials\n\n/**\n * Creates a new `LinearCurve2d` instance from monomial coefficient vectors.\n *\n * Each argument bundles the per-axis coefficient at the given power: `c0`\n * holds the x⁰ term, `c1` holds the x¹ term. The resulting curve evaluates to\n * `c0 + c1·t` per axis.\n *\n * @param c0 - The x⁰ coefficients (x and y).\n * @param c1 - The x¹ coefficients (x and y).\n * @returns A new `LinearCurve2d` instance.\n * @since 2.0.0\n */\nexport const fromCoefficients: (c0: Vector2, c1: Vector2) => LinearCurve2d =\n internal.fromCoefficients\n\n/**\n * Creates a new `LinearCurve2d` instance from a pair of endpoints.\n *\n * `p0` is the curve at `t = 0`, `p1` is the curve at `t = 1`. The\n * implementation converts to the curve's internal monomial form (slope-form\n * polynomial in `t`) in closed form.\n *\n * @param p0 - The curve's start point.\n * @param p1 - The curve's end point.\n * @returns A new `LinearCurve2d` instance whose curve matches the line from `p0` to `p1`.\n * @since 2.0.0\n */\nexport const fromEndpoints: (p0: Vector2, p1: Vector2) => LinearCurve2d = internal.fromEndpoints\n\n/**\n * Checks if a value is a `LinearCurve2d`.\n *\n * @param c - The value to check.\n * @returns `true` if the value is a `LinearCurve2d`, `false` otherwise.\n * @since 1.0.0\n */\nexport const isLinearCurve2d: (c: unknown) => c is LinearCurve2d = internal.isLinearCurve2d\n\n/**\n * Gets the derivative of a linear curve as a vector\n *\n * @param c - The linear curve to get the derivative of.\n * @returns The derivative of the linear curve as a vector.\n * @since 1.0.0\n */\nexport const derivative: (c: LinearCurve2d) => Vector2 = internal.derivative\n\nexport const solve: {\n /**\n * Solves the linear curve for a given parameter t.\n *\n * @param t - The parameter value.\n * @returns A function that takes a linear curve and returns the point on the curve at parameter t.\n * @since 1.0.0\n */\n (t: number): (c: LinearCurve2d) => Vector2\n /**\n * Solves the linear curve for a given parameter t.\n *\n * @param c - The linear curve to solve.\n * @param t - The parameter value.\n * @returns The point on the curve at parameter t.\n * @since 1.0.0\n */\n (c: LinearCurve2d, t: number): Vector2\n} = internal.solve\n\nexport const length: {\n /**\n * Calculates (approximates) the length of a linear curve.\n *\n * @param c - The linear curve to calculate the length of.\n * @param i - The interval to calculate the length over.\n * @returns The length of the linear curve over the given interval.\n * @since 1.0.0\n */\n (c: LinearCurve2d, i: Interval): number\n /**\n * Calculates (approximates) the length of a linear curve.\n *\n * @param i - The interval to calculate the length over.\n * @returns A function that takes a linear curve and returns the length of the linear curve over the given interval.\n * @since 1.0.0\n */\n (i: Interval): (c: LinearCurve2d) => number\n} = internal.length\n\n/**\n * Computes the axis-aligned bounding box of the curve over its parameter\n * domain `[0, 1]`. For a linear curve this is the closed box enclosing the\n * two endpoints.\n *\n * @param c - The linear curve.\n * @returns A closed `Box2d` enclosing the curve.\n * @since 2.0.0\n */\nexport const boundingBox: (c: LinearCurve2d) => Interval2d<Closed, Closed> = internal.boundingBox\n\n/**\n * Evaluates the curve at `t = 0` in closed form — `(c.x.c0, c.y.c0)`.\n *\n * @param c - The linear curve.\n * @returns The point at the start of the curve's parameter domain.\n * @since 2.0.0\n */\nexport const startPoint: (c: LinearCurve2d) => Vector2 = internal.startPoint\n\n/**\n * Evaluates the curve at `t = 1` in closed form — `(c.x.c0 + c.x.c1, c.y.c0 + c.y.c1)`.\n *\n * @param c - The linear curve.\n * @returns The point at the end of the curve's parameter domain.\n * @since 2.0.0\n */\nexport const endPoint: (c: LinearCurve2d) => Vector2 = internal.endPoint\n\n/**\n * The tight `[min, max]` range of x over the curve's parameter domain `[0, 1]`.\n * For a linear curve this is the closed interval bounded by the two endpoints'\n * x coordinates.\n *\n * @param c - The linear curve.\n * @returns The closed range of x over `[0, 1]`.\n * @since 2.0.0\n */\nexport const xRange: (c: LinearCurve2d) => Closed = internal.xRange\n\n/**\n * The tight `[min, max]` range of y over the curve's parameter domain `[0, 1]`.\n * For a linear curve this is the closed interval bounded by the two endpoints'\n * y coordinates.\n *\n * @param c - The linear curve.\n * @returns The closed range of y over `[0, 1]`.\n * @since 2.0.0\n */\nexport const yRange: (c: LinearCurve2d) => Closed = internal.yRange\n\n/**\n * Renders the curve as a single SVG path-data drawing command — for a linear\n * curve, `L endX,endY`. Does not include a leading `M`; callers (typically a\n * path-level `toPathData`) decide whether to emit a move based on continuity\n * with the previous segment.\n *\n * @param c - The linear curve.\n * @returns The SVG drawing command for this segment, without a leading `M`.\n * @since 2.0.0\n */\nexport const toPathDataSegment: (c: LinearCurve2d) => string = internal.toPathDataSegment\n\nexport const solveAtX: {\n /**\n * Evaluates the curve's y value at a given x. A linear curve crosses any\n * vertical line at most once (within the curve's parameter domain `[0, 1]`),\n * so the result is at most one y. Returns the empty tuple when x is outside\n * the curve's range or when the curve's x polynomial is constant.\n *\n * @param c - The linear curve.\n * @param x - The x coordinate.\n * @returns The y value at x, or empty when x is undefined for this curve.\n * @since 2.0.0\n */\n <XT, YT>(c: LinearCurve2d<XT, YT>, x: number): Solution.AtMostOne<number>\n /** @since 2.0.0 */\n (x: number): <XT, YT>(c: LinearCurve2d<XT, YT>) => Solution.AtMostOne<number>\n} = internal.solveAtX as never\n\nexport const solveAtY: {\n /**\n * Evaluates the curve's x value at a given y. A linear curve crosses any\n * horizontal line at most once (within the curve's parameter domain\n * `[0, 1]`), so the result is at most one x.\n *\n * @param c - The linear curve.\n * @param y - The y coordinate.\n * @returns The x value at y, or empty when y is undefined for this curve.\n * @since 2.0.0\n */\n <XT, YT>(c: LinearCurve2d<XT, YT>, y: number): Solution.AtMostOne<number>\n /** @since 2.0.0 */\n (y: number): <XT, YT>(c: LinearCurve2d<XT, YT>) => Solution.AtMostOne<number>\n} = internal.solveAtY as never\n\n/**\n * Type-narrowing predicate: refines the curve's x-axis trait to include\n * `Monotonic` when the x polynomial is strictly monotonic. The y-axis trait\n * is unchanged.\n *\n * @since 2.0.0\n */\nexport const isMonotonicX: <XT, YT>(\n c: LinearCurve2d<XT, YT>,\n) => c is LinearCurve2d<XT & Monotonic, YT> = internal.isMonotonicX\n\n/**\n * Type-narrowing predicate: refines the curve's x-axis trait to include\n * `Increasing`.\n *\n * @since 2.0.0\n */\nexport const isIncreasingX: <XT, YT>(\n c: LinearCurve2d<XT, YT>,\n) => c is LinearCurve2d<XT & Increasing, YT> = internal.isIncreasingX\n\n/**\n * Type-narrowing predicate: refines the curve's x-axis trait to include\n * `Decreasing`.\n *\n * @since 2.0.0\n */\nexport const isDecreasingX: <XT, YT>(\n c: LinearCurve2d<XT, YT>,\n) => c is LinearCurve2d<XT & Decreasing, YT> = internal.isDecreasingX\n\n/**\n * Type-narrowing predicate: refines the curve's y-axis trait to include\n * `Monotonic`. The x-axis trait is unchanged.\n *\n * @since 2.0.0\n */\nexport const isMonotonicY: <XT, YT>(\n c: LinearCurve2d<XT, YT>,\n) => c is LinearCurve2d<XT, YT & Monotonic> = internal.isMonotonicY\n\n/**\n * Type-narrowing predicate: refines the curve's y-axis trait to include\n * `Increasing`.\n *\n * @since 2.0.0\n */\nexport const isIncreasingY: <XT, YT>(\n c: LinearCurve2d<XT, YT>,\n) => c is LinearCurve2d<XT, YT & Increasing> = internal.isIncreasingY\n\n/**\n * Type-narrowing predicate: refines the curve's y-axis trait to include\n * `Decreasing`.\n *\n * @since 2.0.0\n */\nexport const isDecreasingY: <XT, YT>(\n c: LinearCurve2d<XT, YT>,\n) => c is LinearCurve2d<XT, YT & Decreasing> = internal.isDecreasingY\n\n/**\n * Type-narrowing predicate: refines both axes' traits to include `Monotonic`\n * when both the x and y polynomials are strictly monotonic. When both axes\n * are monotonic, the curve is invertible in either direction.\n *\n * @since 2.0.0\n */\nexport const isMonotonic: <XT, YT>(\n c: LinearCurve2d<XT, YT>,\n) => c is LinearCurve2d<XT & Monotonic, YT & Monotonic> = internal.isMonotonic\n\n/**\n * Type-narrowing predicate: refines both axes' traits to include `Increasing`.\n *\n * @since 2.0.0\n */\nexport const isIncreasing: <XT, YT>(\n c: LinearCurve2d<XT, YT>,\n) => c is LinearCurve2d<XT & Increasing, YT & Increasing> = internal.isIncreasing\n\n/**\n * Type-narrowing predicate: refines both axes' traits to include `Decreasing`.\n *\n * @since 2.0.0\n */\nexport const isDecreasing: <XT, YT>(\n c: LinearCurve2d<XT, YT>,\n) => c is LinearCurve2d<XT & Decreasing, YT & Decreasing> = internal.isDecreasing\n\n/**\n * Asserts monotonicity in both axes, throwing on failure.\n *\n * @since 2.0.0\n */\nexport const asMonotonic: <XT, YT>(\n c: LinearCurve2d<XT, YT>,\n) => LinearCurve2d<XT & Monotonic, YT & Monotonic> = internal.asMonotonic\n\n/**\n * Asserts that both axes are strictly increasing, throwing on failure.\n *\n * @since 2.0.0\n */\nexport const asIncreasing: <XT, YT>(\n c: LinearCurve2d<XT, YT>,\n) => LinearCurve2d<XT & Increasing, YT & Increasing> = internal.asIncreasing\n\n/**\n * Asserts that both axes are strictly decreasing, throwing on failure.\n *\n * @since 2.0.0\n */\nexport const asDecreasing: <XT, YT>(\n c: LinearCurve2d<XT, YT>,\n) => LinearCurve2d<XT & Decreasing, YT & Decreasing> = internal.asDecreasing\n\nexport const transform: {\n /**\n * Applies an `Affine2d` transform to a `LinearCurve2d`, returning a new\n * curve whose image is the affine image of the original. The transformation\n * is exact: linear curves are degree-1 in every basis, and affine maps\n * commute with the basis.\n *\n * @param c - The linear curve.\n * @param a - The affine transform.\n * @returns The transformed linear curve.\n * @since 2.0.0\n */\n (c: LinearCurve2d, a: Affine2d): LinearCurve2d\n /**\n * Applies an `Affine2d` transform to a `LinearCurve2d`.\n *\n * @param a - The affine transform.\n * @returns A function that takes a `LinearCurve2d` and returns the transformed curve.\n * @since 2.0.0\n */\n (a: Affine2d): (c: LinearCurve2d) => LinearCurve2d\n} = internal.transform\n\n/**\n * The {@link Curve2dOps} bundle for `LinearCurve2d`. Used by\n * `LinearPath2d` (and any user code building a generic `Path2d` over linear\n * curves) to wire up the path-level operation surface.\n *\n * @since 2.0.0\n */\nexport const Ops: Curve2dOps<LinearCurve2d> = {\n solve,\n startPoint,\n endPoint,\n length,\n boundingBox,\n solveAtX,\n solveAtY,\n toPathDataSegment,\n isIncreasingX,\n isDecreasingX,\n isIncreasingY,\n isDecreasingY,\n transform,\n}\n","import * as Interval2d from '../interval/interval2d.ts'\nimport * as Interval from '../interval/interval.ts'\nimport type * as Affine2d from '../transform/affine2d.ts'\nimport type { Decreasing, Increasing, Monotonic } from '../polynomial/traits.ts'\nimport {\n GL32_W0,\n GL32_W1,\n GL32_W2,\n GL32_W3,\n GL32_W4,\n GL32_W5,\n GL32_W6,\n GL32_W7,\n GL32_W8,\n GL32_W9,\n GL32_W10,\n GL32_W11,\n GL32_W12,\n GL32_W13,\n GL32_W14,\n GL32_W15,\n GL32_X0,\n GL32_X1,\n GL32_X2,\n GL32_X3,\n GL32_X4,\n GL32_X5,\n GL32_X6,\n GL32_X7,\n GL32_X8,\n GL32_X9,\n GL32_X10,\n GL32_X11,\n GL32_X12,\n GL32_X13,\n GL32_X14,\n GL32_X15,\n} from '../length.ts'\nimport { dual, Pipeable } from '../utils.ts'\nimport * as LinearPolynomial from '../polynomial/linear.ts'\nimport * as QuadraticPolynomial from '../polynomial/quadratic.ts'\nimport * as Solution from '../solution/solution.ts'\nimport * as Vector2 from '../vector/vector2.ts'\nimport * as LinearCurve2d from './linear2d.ts'\nimport type { QuadraticCurve2d } from './quadratic2d.ts'\n\nexport const QuadraticCurve2dTypeId: unique symbol = Symbol('curvy/curve/quadratic2d')\nexport type QuadraticCurve2dTypeId = typeof QuadraticCurve2dTypeId\n\n/** @internal */\nexport class QuadraticCurve2dImpl extends Pipeable implements QuadraticCurve2d<unknown, unknown> {\n readonly [QuadraticCurve2dTypeId]: QuadraticCurve2dTypeId = QuadraticCurve2dTypeId\n\n readonly x: QuadraticPolynomial.QuadraticPolynomial\n readonly y: QuadraticPolynomial.QuadraticPolynomial\n\n constructor(\n c0: QuadraticPolynomial.QuadraticPolynomial,\n c1: QuadraticPolynomial.QuadraticPolynomial,\n ) {\n super()\n this.x = c0\n this.y = c1\n }\n\n get [0]() {\n return this.x\n }\n\n get [1]() {\n return this.y\n }\n}\n\n/** @internal */\nexport const fromPolynomials: (\n c0: QuadraticPolynomial.QuadraticPolynomial,\n c1: QuadraticPolynomial.QuadraticPolynomial,\n) => QuadraticCurve2d = (c0, c1) => new QuadraticCurve2dImpl(c0, c1)\n\n/** @internal */\nexport const fromCoefficients: (\n c0: Vector2.Vector2,\n c1: Vector2.Vector2,\n c2: Vector2.Vector2,\n) => QuadraticCurve2d = (c0, c1, c2) =>\n new QuadraticCurve2dImpl(\n QuadraticPolynomial.make(c0.x, c1.x, c2.x),\n QuadraticPolynomial.make(c0.y, c1.y, c2.y),\n )\n\n// Quadratic Bernstein basis: B(t) = (1-t)²·p0 + 2(1-t)t·p1 + t²·p2\n// Expanding to monomial form gives:\n// c0 = p0\n// c1 = -2p0 + 2p1\n// c2 = p0 - 2p1 + p2\n/** @internal */\nexport const fromBezierPoints: (\n p0: Vector2.Vector2,\n p1: Vector2.Vector2,\n p2: Vector2.Vector2,\n) => QuadraticCurve2d = (p0, p1, p2) =>\n new QuadraticCurve2dImpl(\n QuadraticPolynomial.make(p0.x, -2 * p0.x + 2 * p1.x, p0.x - 2 * p1.x + p2.x),\n QuadraticPolynomial.make(p0.y, -2 * p0.y + 2 * p1.y, p0.y - 2 * p1.y + p2.y),\n )\n\n/** @internal */\nexport const isQuadraticCurve2d = (c: unknown): c is QuadraticCurve2d =>\n typeof c === 'object' && c !== null && QuadraticCurve2dTypeId in c\n\n/** @internal */\nexport const solve = dual<\n (t: number) => (c: QuadraticCurve2d) => Vector2.Vector2,\n (c: QuadraticCurve2d, t: number) => Vector2.Vector2\n>(2, (c: QuadraticCurve2d, t: number) =>\n Vector2.make(QuadraticPolynomial.solve(c.x, t), QuadraticPolynomial.solve(c.y, t)),\n)\n\n// solveAtX: invert the x polynomial to find ts within the unit interval, then\n// evaluate y at each surviving t. Result order matches solveInverse order\n// (t-ascending).\n/** @internal */\nexport const solveAtX = dual(2, (c: QuadraticCurve2d, x: number) =>\n QuadraticPolynomial.solveInverse(c.x, x).pipe(\n Solution.clipApprox(Interval.unit),\n Solution.map((t) => QuadraticPolynomial.solve(c.y, t)),\n ),\n)\n\n/** @internal */\nexport const solveAtY = dual(2, (c: QuadraticCurve2d, y: number) =>\n QuadraticPolynomial.solveInverse(c.y, y).pipe(\n Solution.clipApprox(Interval.unit),\n Solution.map((t) => QuadraticPolynomial.solve(c.x, t)),\n ),\n)\n\n/** @internal */\nexport const derivative = (c: QuadraticCurve2d) =>\n LinearCurve2d.fromPolynomials(\n QuadraticPolynomial.derivative(c.x),\n QuadraticPolynomial.derivative(c.y),\n )\n\n/** @internal */\nexport const length = dual(2, (c: QuadraticCurve2d, i: Interval.Interval) => {\n if (Interval.size(i) === 0) {\n return 0\n }\n\n if (c.x.c2 === 0 && c.y.c2 === 0) {\n return LinearCurve2d.length(\n LinearCurve2d.fromPolynomials(\n LinearPolynomial.make(c.x.c0, c.x.c1),\n LinearPolynomial.make(c.y.c0, c.y.c1),\n ),\n i,\n )\n }\n\n const d = derivative(c)\n\n const { scale, shift } = Interval.scaleShift(Interval.biunit, i)\n\n return (\n (GL32_W0 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * -GL32_X0)) +\n GL32_W0 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * GL32_X0)) +\n GL32_W1 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * -GL32_X1)) +\n GL32_W1 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * GL32_X1)) +\n GL32_W2 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * -GL32_X2)) +\n GL32_W2 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * GL32_X2)) +\n GL32_W3 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * -GL32_X3)) +\n GL32_W3 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * GL32_X3)) +\n GL32_W4 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * -GL32_X4)) +\n GL32_W4 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * GL32_X4)) +\n GL32_W5 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * -GL32_X5)) +\n GL32_W5 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * GL32_X5)) +\n GL32_W6 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * -GL32_X6)) +\n GL32_W6 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * GL32_X6)) +\n GL32_W7 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * -GL32_X7)) +\n GL32_W7 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * GL32_X7)) +\n GL32_W8 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * -GL32_X8)) +\n GL32_W8 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * GL32_X8)) +\n GL32_W9 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * -GL32_X9)) +\n GL32_W9 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * GL32_X9)) +\n GL32_W10 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * -GL32_X10)) +\n GL32_W10 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * GL32_X10)) +\n GL32_W11 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * -GL32_X11)) +\n GL32_W11 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * GL32_X11)) +\n GL32_W12 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * -GL32_X12)) +\n GL32_W12 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * GL32_X12)) +\n GL32_W13 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * -GL32_X13)) +\n GL32_W13 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * GL32_X13)) +\n GL32_W14 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * -GL32_X14)) +\n GL32_W14 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * GL32_X14)) +\n GL32_W15 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * -GL32_X15)) +\n GL32_W15 * Vector2.magnitude(LinearCurve2d.solve(d, shift + scale * GL32_X15))) *\n scale\n )\n})\n\n/** @internal */\nexport const curvature = dual(2, (c: QuadraticCurve2d, t: number) => {\n const d = derivative(c)\n const v = LinearCurve2d.solve(d, t)\n const a = LinearCurve2d.derivative(d)\n\n const vMag = Vector2.magnitude(v)\n\n if (vMag === 0) {\n return 0\n }\n\n return Math.abs(Vector2.cross(v, a)) / vMag ** 3\n})\n\n/** @internal */\nexport const boundingBox = (\n c: QuadraticCurve2d,\n): Interval2d.Interval2d<Interval.Closed, Interval.Closed> =>\n Interval2d.make(QuadraticPolynomial.unitRange(c.x), QuadraticPolynomial.unitRange(c.y))\n\n/** @internal */\nexport const startPoint = (c: QuadraticCurve2d): Vector2.Vector2 => Vector2.make(c.x.c0, c.y.c0)\n\n/** @internal */\nexport const endPoint = (c: QuadraticCurve2d): Vector2.Vector2 =>\n Vector2.make(c.x.c0 + c.x.c1 + c.x.c2, c.y.c0 + c.y.c1 + c.y.c2)\n\n/** @internal */\nexport const xRange = (c: QuadraticCurve2d): Interval.Closed => QuadraticPolynomial.unitRange(c.x)\n\n/** @internal */\nexport const yRange = (c: QuadraticCurve2d): Interval.Closed => QuadraticPolynomial.unitRange(c.y)\n\n// Quadratic Bernstein basis: P(t) = (1-t)²·p0 + 2(1-t)t·p1 + t²·p2\n// expanded to monomial form gives c0 = p0, c1 = -2p0 + 2p1, c2 = p0 - 2p1 + p2,\n// so the inverse is p0 = c0, p1 = c0 + c1/2, p2 = c0 + c1 + c2.\n/** @internal */\nexport const toPathDataSegment = (c: QuadraticCurve2d): string => {\n const ctrlX = c.x.c0 + c.x.c1 / 2\n const ctrlY = c.y.c0 + c.y.c1 / 2\n const endX = c.x.c0 + c.x.c1 + c.x.c2\n const endY = c.y.c0 + c.y.c1 + c.y.c2\n return `Q ${ctrlX},${ctrlY} ${endX},${endY}`\n}\n\n// Per-axis trait refiners delegate to the polynomial-level check on a single\n// axis (over the unit interval) and brand only that axis. The combined\n// refiners (below) fan out to both axes.\n/** @internal */\nexport const isMonotonicX = <XT, YT>(\n c: QuadraticCurve2d<XT, YT>,\n): c is QuadraticCurve2d<XT & Monotonic, YT> => QuadraticPolynomial.isMonotonic(c.x, Interval.unit)\n\n/** @internal */\nexport const isIncreasingX = <XT, YT>(\n c: QuadraticCurve2d<XT, YT>,\n): c is QuadraticCurve2d<XT & Increasing, YT> =>\n QuadraticPolynomial.isIncreasing(c.x, Interval.unit)\n\n/** @internal */\nexport const isDecreasingX = <XT, YT>(\n c: QuadraticCurve2d<XT, YT>,\n): c is QuadraticCurve2d<XT & Decreasing, YT> =>\n QuadraticPolynomial.isDecreasing(c.x, Interval.unit)\n\n/** @internal */\nexport const isMonotonicY = <XT, YT>(\n c: QuadraticCurve2d<XT, YT>,\n): c is QuadraticCurve2d<XT, YT & Monotonic> => QuadraticPolynomial.isMonotonic(c.y, Interval.unit)\n\n/** @internal */\nexport const isIncreasingY = <XT, YT>(\n c: QuadraticCurve2d<XT, YT>,\n): c is QuadraticCurve2d<XT, YT & Increasing> =>\n QuadraticPolynomial.isIncreasing(c.y, Interval.unit)\n\n/** @internal */\nexport const isDecreasingY = <XT, YT>(\n c: QuadraticCurve2d<XT, YT>,\n): c is QuadraticCurve2d<XT, YT & Decreasing> =>\n QuadraticPolynomial.isDecreasing(c.y, Interval.unit)\n\n/** @internal */\nexport const isMonotonic = <XT, YT>(\n c: QuadraticCurve2d<XT, YT>,\n): c is QuadraticCurve2d<XT & Monotonic, YT & Monotonic> => isMonotonicX(c) && isMonotonicY(c)\n\n/** @internal */\nexport const isIncreasing = <XT, YT>(\n c: QuadraticCurve2d<XT, YT>,\n): c is QuadraticCurve2d<XT & Increasing, YT & Increasing> => isIncreasingX(c) && isIncreasingY(c)\n\n/** @internal */\nexport const isDecreasing = <XT, YT>(\n c: QuadraticCurve2d<XT, YT>,\n): c is QuadraticCurve2d<XT & Decreasing, YT & Decreasing> => isDecreasingX(c) && isDecreasingY(c)\n\nconst fail = (m: string): never => {\n throw new Error(m)\n}\n\n/** @internal */\nexport const asMonotonic = <XT, YT>(\n c: QuadraticCurve2d<XT, YT>,\n): QuadraticCurve2d<XT & Monotonic, YT & Monotonic> =>\n isMonotonic(c) ? c : fail('quadratic curve is not monotonic in both axes')\n\n/** @internal */\nexport const asIncreasing = <XT, YT>(\n c: QuadraticCurve2d<XT, YT>,\n): QuadraticCurve2d<XT & Increasing, YT & Increasing> =>\n isIncreasing(c) ? c : fail('quadratic curve is not increasing in both axes')\n\n/** @internal */\nexport const asDecreasing = <XT, YT>(\n c: QuadraticCurve2d<XT, YT>,\n): QuadraticCurve2d<XT & Decreasing, YT & Decreasing> =>\n isDecreasing(c) ? c : fail('quadratic curve is not decreasing in both axes')\n\n// Affine transform on coefficient form: only c0 (the constant term) receives\n// the translation; c1, c2 receive only the linear part of the affine map.\n/** @internal */\nexport const transform = dual<\n (a: Affine2d.Affine2d) => (c: QuadraticCurve2d) => QuadraticCurve2d,\n (c: QuadraticCurve2d, a: Affine2d.Affine2d) => QuadraticCurve2d\n>(2, (c: QuadraticCurve2d, a: Affine2d.Affine2d) => {\n const m = a.matrix\n return new QuadraticCurve2dImpl(\n QuadraticPolynomial.make(\n m.m00 * c.x.c0 + m.m01 * c.y.c0 + m.m02,\n m.m00 * c.x.c1 + m.m01 * c.y.c1,\n m.m00 * c.x.c2 + m.m01 * c.y.c2,\n ),\n QuadraticPolynomial.make(\n m.m10 * c.x.c0 + m.m11 * c.y.c0 + m.m12,\n m.m10 * c.x.c1 + m.m11 * c.y.c1,\n m.m10 * c.x.c2 + m.m11 * c.y.c2,\n ),\n )\n})\n","import type { Interval2d } from '../interval/interval2d.ts'\nimport type { TwoDimensional } from '../dimensions.ts'\nimport type { Closed, Interval } from '../interval/interval.ts'\nimport type { Pipeable } from '../utils.ts'\nimport type { QuadraticPolynomial } from '../polynomial/quadratic.ts'\nimport type { Decreasing, Increasing, Monotonic } from '../polynomial/traits.ts'\nimport type * as Solution from '../solution/solution.ts'\nimport type { Affine2d } from '../transform/affine2d.ts'\nimport type { Vector2 } from '../vector/vector2.ts'\nimport type { Curve2dOps } from './curve2d.ts'\nimport type { LinearCurve2d } from './linear2d.ts'\nimport type { QuadraticCurve2dTypeId } from './quadratic2d.internal.ts'\nimport * as internal from './quadratic2d.internal.ts'\n\nexport type { Monotonic, Increasing, Decreasing } from '../polynomial/traits.ts'\n\n/**\n * A quadratic curve in 2D space.\n *\n * All fields are readonly and immutable, and all operations create new instances.\n *\n * The two type parameters carry the trait sets of the curve's per-axis\n * polynomials. Refiners check monotonicity over the unit interval `[0, 1]` —\n * the curve's natural parameter domain.\n *\n * @since 1.0.0\n */\nexport interface QuadraticCurve2d<out XTraits = unknown, out YTraits = unknown>\n extends Pipeable, TwoDimensional<QuadraticPolynomial<XTraits>, QuadraticPolynomial<YTraits>> {\n readonly [QuadraticCurve2dTypeId]: QuadraticCurve2dTypeId\n}\n\n/**\n * Creates a new `QuadraticCurve2d` instance from polynomial parameters.\n *\n * @param c0 - The x polynomial.\n * @param c1 - The y polynomial.\n * @returns A new `QuadraticCurve2d` instance.\n * @since 1.0.0\n */\nexport const fromPolynomials: (\n c0: QuadraticPolynomial,\n c1: QuadraticPolynomial,\n) => QuadraticCurve2d = internal.fromPolynomials\n\n/**\n * Creates a new `QuadraticCurve2d` instance from monomial coefficient vectors.\n *\n * Each argument bundles the per-axis coefficient at the given power: `c0`\n * holds the x⁰ term, `c1` holds the x¹ term, and so on. The resulting curve\n * evaluates to `c0 + c1·t + c2·t²` per axis.\n *\n * @param c0 - The x⁰ coefficients (x and y).\n * @param c1 - The x¹ coefficients (x and y).\n * @param c2 - The x² coefficients (x and y).\n * @returns A new `QuadraticCurve2d` instance.\n * @since 2.0.0\n */\nexport const fromCoefficients: (c0: Vector2, c1: Vector2, c2: Vector2) => QuadraticCurve2d =\n internal.fromCoefficients\n\n/**\n * Creates a new `QuadraticCurve2d` instance from quadratic Bézier control\n * points.\n *\n * The three arguments are the Bernstein-basis control points: `p0` and `p2`\n * are the curve's endpoints and `p1` is the off-curve control handle. The\n * implementation converts to the curve's internal monomial form in closed\n * form.\n *\n * @param p0 - The first control point (curve start).\n * @param p1 - The second control point (control handle).\n * @param p2 - The third control point (curve end).\n * @returns A new `QuadraticCurve2d` instance whose curve matches the given Bézier.\n * @since 2.0.0\n */\nexport const fromBezierPoints: (p0: Vector2, p1: Vector2, p2: Vector2) => QuadraticCurve2d =\n internal.fromBezierPoints\n\n/**\n * Checks if a value is a `QuadraticCurve2d`.\n *\n * @param c - The value to check.\n * @returns `true` if the value is a `QuadraticCurve2d`, `false` otherwise.\n * @since 1.0.0\n */\nexport const isQuadraticCurve2d: (c: unknown) => c is QuadraticCurve2d = internal.isQuadraticCurve2d\n\nexport const solve: {\n /**\n * Solves the quadratic curve for a given parameter t.\n *\n * @param t - The parameter value.\n * @returns A function that takes a quadratic curve and returns the point on the curve at parameter t.\n * @since 1.0.0\n */\n (t: number): (c: QuadraticCurve2d) => Vector2\n /**\n * Solves the quadratic curve for a given parameter t.\n *\n * @param c - The quadratic curve to solve.\n * @param t - The parameter value.\n * @returns The point on the curve at parameter t.\n * @since 1.0.0\n */\n (c: QuadraticCurve2d, t: number): Vector2\n} = internal.solve\n\nexport const length: {\n /**\n * Computes the length of the quadratic curve over a given interval.\n *\n * @param c - The quadratic curve to compute the length of.\n * @param i - The interval over which to compute the length.\n * @returns The length of the quadratic curve over the interval.\n * @since 1.0.0\n */\n (c: QuadraticCurve2d, i: Interval): number\n /**\n * Computes the length of the quadratic curve over a given interval.\n *\n * @param i - The interval over which to compute the length.\n * @returns A function that takes a quadratic curve and returns the length of the curve over the interval.\n * @since 1.0.0\n */\n (i: Interval): (c: QuadraticCurve2d) => number\n} = internal.length\n\nexport const solveAtX: {\n /**\n * Evaluates the curve's y values at a given x. Because the x polynomial is\n * `Monotonic`, the inverse has at most one solution — at most one y value.\n *\n * @param c - The quadratic curve.\n * @param x - The x coordinate.\n * @returns Zero or one y values, in t-ascending order.\n * @since 2.0.0\n */\n <XT extends Monotonic, YT>(c: QuadraticCurve2d<XT, YT>, x: number): Solution.AtMostOne<number>\n /**\n * Evaluates the curve's y values at a given x. The result is the y values\n * the curve passes through where x(t) = the given x — up to two solutions\n * for a quadratic curve.\n *\n * @param c - The quadratic curve.\n * @param x - The x coordinate.\n * @returns The y values at x, in t-ascending order.\n * @since 2.0.0\n */\n <XT, YT>(c: QuadraticCurve2d<XT, YT>, x: number): Solution.AtMostTwo<number>\n /** @since 2.0.0 */\n (x: number): {\n <XT extends Monotonic, YT>(c: QuadraticCurve2d<XT, YT>): Solution.AtMostOne<number>\n <XT, YT>(c: QuadraticCurve2d<XT, YT>): Solution.AtMostTwo<number>\n }\n} = internal.solveAtX as never\n\nexport const solveAtY: {\n /**\n * Evaluates the curve's x values at a given y. Because the y polynomial is\n * `Monotonic`, the inverse has at most one solution.\n *\n * @param c - The quadratic curve.\n * @param y - The y coordinate.\n * @returns Zero or one x values, in t-ascending order.\n * @since 2.0.0\n */\n <XT, YT extends Monotonic>(c: QuadraticCurve2d<XT, YT>, y: number): Solution.AtMostOne<number>\n /**\n * Evaluates the curve's x values at a given y. The result is the x values\n * the curve passes through where y(t) = the given y — up to two solutions\n * for a quadratic curve.\n *\n * @param c - The quadratic curve.\n * @param y - The y coordinate.\n * @returns The x values at y, in t-ascending order.\n * @since 2.0.0\n */\n <XT, YT>(c: QuadraticCurve2d<XT, YT>, y: number): Solution.AtMostTwo<number>\n /** @since 2.0.0 */\n (y: number): {\n <XT, YT extends Monotonic>(c: QuadraticCurve2d<XT, YT>): Solution.AtMostOne<number>\n <XT, YT>(c: QuadraticCurve2d<XT, YT>): Solution.AtMostTwo<number>\n }\n} = internal.solveAtY as never\n\n/**\n * Computes the derivative of a quadratic curve.\n *\n * @param c - The quadratic curve to compute the derivative of.\n * @returns The derivative of the quadratic curve as a linear curve.\n * @since 1.0.0\n */\nexport const derivative: (c: QuadraticCurve2d) => LinearCurve2d = internal.derivative\n\nexport const curvature: {\n /**\n * Computes the curvature of the quadratic curve at a given parameter t.\n *\n * @param c - The quadratic curve to compute the curvature for.\n * @param t - The parameter value.\n * @returns The curvature of the quadratic curve at parameter t.\n * @since 1.0.0\n */\n (c: QuadraticCurve2d, t: number): number\n /**\n * Computes the curvature of the quadratic curve at a given parameter t.\n *\n * @param t - The parameter value.\n * @returns A function that takes a quadratic curve and returns the curvature of the curve at parameter t.\n * @since 1.0.0\n */\n (t: number): (c: QuadraticCurve2d) => number\n} = internal.curvature\n\n/**\n * Computes the axis-aligned bounding box of the curve over its parameter\n * domain `[0, 1]`. Accounts for interior extrema, so the box is tight against\n * the curve and not just the control polygon.\n *\n * @param c - The quadratic curve.\n * @returns A closed `Box2d` enclosing the curve.\n * @since 2.0.0\n */\nexport const boundingBox: (c: QuadraticCurve2d) => Interval2d<Closed, Closed> = internal.boundingBox\n\n/**\n * Evaluates the curve at `t = 0` in closed form — `(c.x.c0, c.y.c0)`.\n *\n * @param c - The quadratic curve.\n * @returns The point at the start of the curve's parameter domain.\n * @since 2.0.0\n */\nexport const startPoint: (c: QuadraticCurve2d) => Vector2 = internal.startPoint\n\n/**\n * Evaluates the curve at `t = 1` in closed form — the sum of the per-axis\n * monomial coefficients.\n *\n * @param c - The quadratic curve.\n * @returns The point at the end of the curve's parameter domain.\n * @since 2.0.0\n */\nexport const endPoint: (c: QuadraticCurve2d) => Vector2 = internal.endPoint\n\n/**\n * The tight `[min, max]` range of x over the curve's parameter domain `[0, 1]`,\n * accounting for an interior extremum if one exists.\n *\n * @param c - The quadratic curve.\n * @returns The closed range of x over `[0, 1]`.\n * @since 2.0.0\n */\nexport const xRange: (c: QuadraticCurve2d) => Closed = internal.xRange\n\n/**\n * The tight `[min, max]` range of y over the curve's parameter domain `[0, 1]`,\n * accounting for an interior extremum if one exists.\n *\n * @param c - The quadratic curve.\n * @returns The closed range of y over `[0, 1]`.\n * @since 2.0.0\n */\nexport const yRange: (c: QuadraticCurve2d) => Closed = internal.yRange\n\n/**\n * Renders the curve as a single SVG path-data drawing command — for a\n * quadratic curve, `Q ctrlX,ctrlY endX,endY`, where the control point is\n * recovered from the monomial coefficients via the inverse Bernstein\n * expansion. Does not include a leading `M`.\n *\n * @param c - The quadratic curve.\n * @returns The SVG drawing command for this segment, without a leading `M`.\n * @since 2.0.0\n */\nexport const toPathDataSegment: (c: QuadraticCurve2d) => string = internal.toPathDataSegment\n\n/**\n * Type-narrowing predicate: refines the curve's x-axis trait to include\n * `Monotonic` when the x polynomial is strictly monotonic on the unit\n * interval `[0, 1]`. The y-axis trait is unchanged.\n *\n * @since 2.0.0\n */\nexport const isMonotonicX: <XT, YT>(\n c: QuadraticCurve2d<XT, YT>,\n) => c is QuadraticCurve2d<XT & Monotonic, YT> = internal.isMonotonicX\n\n/** @since 2.0.0 */\nexport const isIncreasingX: <XT, YT>(\n c: QuadraticCurve2d<XT, YT>,\n) => c is QuadraticCurve2d<XT & Increasing, YT> = internal.isIncreasingX\n\n/** @since 2.0.0 */\nexport const isDecreasingX: <XT, YT>(\n c: QuadraticCurve2d<XT, YT>,\n) => c is QuadraticCurve2d<XT & Decreasing, YT> = internal.isDecreasingX\n\n/**\n * Type-narrowing predicate: refines the curve's y-axis trait to include\n * `Monotonic`. The x-axis trait is unchanged.\n *\n * @since 2.0.0\n */\nexport const isMonotonicY: <XT, YT>(\n c: QuadraticCurve2d<XT, YT>,\n) => c is QuadraticCurve2d<XT, YT & Monotonic> = internal.isMonotonicY\n\n/** @since 2.0.0 */\nexport const isIncreasingY: <XT, YT>(\n c: QuadraticCurve2d<XT, YT>,\n) => c is QuadraticCurve2d<XT, YT & Increasing> = internal.isIncreasingY\n\n/** @since 2.0.0 */\nexport const isDecreasingY: <XT, YT>(\n c: QuadraticCurve2d<XT, YT>,\n) => c is QuadraticCurve2d<XT, YT & Decreasing> = internal.isDecreasingY\n\n/**\n * Type-narrowing predicate: refines both axes' traits to include `Monotonic`\n * when both x and y polynomials are monotonic over the unit interval `[0, 1]`.\n *\n * @since 2.0.0\n */\nexport const isMonotonic: <XT, YT>(\n c: QuadraticCurve2d<XT, YT>,\n) => c is QuadraticCurve2d<XT & Monotonic, YT & Monotonic> = internal.isMonotonic\n\n/** @since 2.0.0 */\nexport const isIncreasing: <XT, YT>(\n c: QuadraticCurve2d<XT, YT>,\n) => c is QuadraticCurve2d<XT & Increasing, YT & Increasing> = internal.isIncreasing\n\n/** @since 2.0.0 */\nexport const isDecreasing: <XT, YT>(\n c: QuadraticCurve2d<XT, YT>,\n) => c is QuadraticCurve2d<XT & Decreasing, YT & Decreasing> = internal.isDecreasing\n\n/** @since 2.0.0 */\nexport const asMonotonic: <XT, YT>(\n c: QuadraticCurve2d<XT, YT>,\n) => QuadraticCurve2d<XT & Monotonic, YT & Monotonic> = internal.asMonotonic\n\n/** @since 2.0.0 */\nexport const asIncreasing: <XT, YT>(\n c: QuadraticCurve2d<XT, YT>,\n) => QuadraticCurve2d<XT & Increasing, YT & Increasing> = internal.asIncreasing\n\n/** @since 2.0.0 */\nexport const asDecreasing: <XT, YT>(\n c: QuadraticCurve2d<XT, YT>,\n) => QuadraticCurve2d<XT & Decreasing, YT & Decreasing> = internal.asDecreasing\n\nexport const transform: {\n /**\n * Applies an `Affine2d` transform to a `QuadraticCurve2d`, returning a new\n * curve whose image is the affine image of the original. Internally the\n * transformation works directly on the curve's monomial coefficients —\n * `c0` receives the full affine, `c1` and `c2` receive only the linear part.\n *\n * @param c - The quadratic curve.\n * @param a - The affine transform.\n * @returns The transformed quadratic curve.\n * @since 2.0.0\n */\n (c: QuadraticCurve2d, a: Affine2d): QuadraticCurve2d\n /**\n * Applies an `Affine2d` transform to a `QuadraticCurve2d`.\n *\n * @param a - The affine transform.\n * @returns A function that takes a `QuadraticCurve2d` and returns the transformed curve.\n * @since 2.0.0\n */\n (a: Affine2d): (c: QuadraticCurve2d) => QuadraticCurve2d\n} = internal.transform\n\n/**\n * The {@link Curve2dOps} bundle for `QuadraticCurve2d`. Used by\n * `QuadraticPath2d` to wire up the path-level operation surface. The\n * `solveAtX` / `solveAtY` entries narrow the curve's potentially-2-element\n * result to `AtMostOne` — path callers enforce that via the path's\n * `MonotonicX`/`MonotonicY` brand.\n *\n * @since 2.0.0\n */\nexport const Ops: Curve2dOps<QuadraticCurve2d> = {\n solve,\n startPoint,\n endPoint,\n length,\n boundingBox,\n solveAtX: (c, x) => internal.solveAtX(c, x) as Solution.AtMostOne<number>,\n solveAtY: (c, y) => internal.solveAtY(c, y) as Solution.AtMostOne<number>,\n toPathDataSegment,\n isIncreasingX,\n isDecreasingX,\n isIncreasingY,\n isDecreasingY,\n transform,\n}\n","import * as Interval2d from '../interval/interval2d.ts'\nimport * as Characteristic from '../characteristic/characteristic.ts'\nimport * as Interval from '../interval/interval.ts'\nimport type * as Affine2d from '../transform/affine2d.ts'\nimport {\n GL32_W0,\n GL32_W1,\n GL32_W2,\n GL32_W3,\n GL32_W4,\n GL32_W5,\n GL32_W6,\n GL32_W7,\n GL32_W8,\n GL32_W9,\n GL32_W10,\n GL32_W11,\n GL32_W12,\n GL32_W13,\n GL32_W14,\n GL32_W15,\n GL32_X0,\n GL32_X1,\n GL32_X2,\n GL32_X3,\n GL32_X4,\n GL32_X5,\n GL32_X6,\n GL32_X7,\n GL32_X8,\n GL32_X9,\n GL32_X10,\n GL32_X11,\n GL32_X12,\n GL32_X13,\n GL32_X14,\n GL32_X15,\n} from '../length.ts'\nimport { dual, Pipeable } from '../utils.ts'\nimport * as CubicPolynomial from '../polynomial/cubic.ts'\nimport * as QuadraticPolynomial from '../polynomial/quadratic.ts'\nimport type { Decreasing, Increasing, Monotonic } from '../polynomial/traits.ts'\nimport * as Solution from '../solution/solution.ts'\nimport * as Vector2 from '../vector/vector2.ts'\nimport * as Vector4 from '../vector/vector4.ts'\nimport type { CubicCurve2d } from './cubic2d.ts'\nimport * as LinearCurve2d from './linear2d.ts'\nimport * as QuadraticCurve2d from './quadratic2d.ts'\n\nexport const CubicCurve2dTypeId: unique symbol = Symbol('curvy/curve/cubic2d')\nexport type CubicCurve2dTypeId = typeof CubicCurve2dTypeId\n\n/** @internal */\nexport class CubicCurve2dImpl extends Pipeable implements CubicCurve2d<unknown, unknown> {\n readonly [CubicCurve2dTypeId]: CubicCurve2dTypeId = CubicCurve2dTypeId\n\n readonly x: CubicPolynomial.CubicPolynomial\n readonly y: CubicPolynomial.CubicPolynomial\n\n constructor(c0: CubicPolynomial.CubicPolynomial, c1: CubicPolynomial.CubicPolynomial) {\n super()\n this.x = c0\n this.y = c1\n }\n\n get [0]() {\n return this.x\n }\n\n get [1]() {\n return this.y\n }\n}\n\n/** @internal */\nexport const fromPolynomials: (\n c0: CubicPolynomial.CubicPolynomial,\n c1: CubicPolynomial.CubicPolynomial,\n) => CubicCurve2d = (c0, c1) => new CubicCurve2dImpl(c0, c1)\n\n/** @internal */\nexport const fromCoefficients: (\n c0: Vector2.Vector2,\n c1: Vector2.Vector2,\n c2: Vector2.Vector2,\n c3: Vector2.Vector2,\n) => CubicCurve2d = (c0, c1, c2, c3) =>\n new CubicCurve2dImpl(\n CubicPolynomial.make(c0.x, c1.x, c2.x, c3.x),\n CubicPolynomial.make(c0.y, c1.y, c2.y, c3.y),\n )\n\n// Applies the cubic Bézier characteristic matrix to the per-axis control\n// vectors, producing monomial polynomials. The matrix encodes the cubic\n// Bernstein → monomial expansion `(c₀, c₁, c₂, c₃) = M · (p₀, p₁, p₂, p₃)`\n// for each axis independently.\n/** @internal */\nexport const fromBezierPoints: (\n p0: Vector2.Vector2,\n p1: Vector2.Vector2,\n p2: Vector2.Vector2,\n p3: Vector2.Vector2,\n) => CubicCurve2d = (p0, p1, p2, p3) =>\n new CubicCurve2dImpl(\n ...Characteristic.apply(\n Characteristic.cubicBezier,\n ...Vector4.transpose([p0, p1, p2, p3], (p) => [p.x, p.y]),\n ),\n )\n\n/** @internal */\nexport const isCubicCurve2d = (c: unknown): c is CubicCurve2d =>\n typeof c === 'object' && c !== null && CubicCurve2dTypeId in c\n\n/** @internal */\nexport const solve = dual<\n (t: number) => (c: CubicCurve2d) => Vector2.Vector2,\n (c: CubicCurve2d, t: number) => Vector2.Vector2\n>(2, (c: CubicCurve2d, t: number) =>\n Vector2.make(CubicPolynomial.solve(c.x, t), CubicPolynomial.solve(c.y, t)),\n)\n\n// solveAtX: invert the x polynomial to find ts within the unit interval, then\n// evaluate y at each surviving t. Result order matches solveInverse order\n// (t-ascending).\n/** @internal */\nexport const solveAtX = dual(2, (c: CubicCurve2d, x: number) =>\n CubicPolynomial.solveInverse(c.x, x).pipe(\n Solution.clipApprox(Interval.unit),\n Solution.map(CubicPolynomial.toSolver(c.y)),\n ),\n)\n\n/** @internal */\nexport const solveAtY = dual(2, (c: CubicCurve2d, y: number) =>\n CubicPolynomial.solveInverse(c.y, y).pipe(\n Solution.clipApprox(Interval.unit),\n Solution.map(CubicPolynomial.toSolver(c.x)),\n ),\n)\n\n/** @internal */\nexport const derivative = (c: CubicCurve2d) =>\n QuadraticCurve2d.fromPolynomials(CubicPolynomial.derivative(c.x), CubicPolynomial.derivative(c.y))\n\n/** @internal */\nexport const length = dual(2, (c: CubicCurve2d, i: Interval.Interval) => {\n if (Interval.size(i) === 0) {\n return 0\n }\n\n if (c.x.c3 === 0 && c.y.c3 === 0) {\n return QuadraticCurve2d.length(\n QuadraticCurve2d.fromPolynomials(\n QuadraticPolynomial.make(c.x.c0, c.x.c1, c.x.c2),\n QuadraticPolynomial.make(c.y.c0, c.y.c1, c.y.c2),\n ),\n i,\n )\n }\n\n const d = derivative(c)\n\n const { scale, shift } = Interval.scaleShift(Interval.biunit, i)\n\n return (\n (GL32_W0 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * -GL32_X0)) +\n GL32_W0 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * GL32_X0)) +\n GL32_W1 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * -GL32_X1)) +\n GL32_W1 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * GL32_X1)) +\n GL32_W2 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * -GL32_X2)) +\n GL32_W2 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * GL32_X2)) +\n GL32_W3 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * -GL32_X3)) +\n GL32_W3 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * GL32_X3)) +\n GL32_W4 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * -GL32_X4)) +\n GL32_W4 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * GL32_X4)) +\n GL32_W5 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * -GL32_X5)) +\n GL32_W5 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * GL32_X5)) +\n GL32_W6 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * -GL32_X6)) +\n GL32_W6 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * GL32_X6)) +\n GL32_W7 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * -GL32_X7)) +\n GL32_W7 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * GL32_X7)) +\n GL32_W8 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * -GL32_X8)) +\n GL32_W8 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * GL32_X8)) +\n GL32_W9 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * -GL32_X9)) +\n GL32_W9 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * GL32_X9)) +\n GL32_W10 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * -GL32_X10)) +\n GL32_W10 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * GL32_X10)) +\n GL32_W11 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * -GL32_X11)) +\n GL32_W11 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * GL32_X11)) +\n GL32_W12 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * -GL32_X12)) +\n GL32_W12 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * GL32_X12)) +\n GL32_W13 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * -GL32_X13)) +\n GL32_W13 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * GL32_X13)) +\n GL32_W14 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * -GL32_X14)) +\n GL32_W14 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * GL32_X14)) +\n GL32_W15 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * -GL32_X15)) +\n GL32_W15 * Vector2.magnitude(QuadraticCurve2d.solve(d, shift + scale * GL32_X15))) *\n scale\n )\n})\n\n/** @internal */\nexport const curvature = dual(2, (c: CubicCurve2d, t: number) => {\n const d = derivative(c)\n\n const v = QuadraticCurve2d.solve(d, t)\n const a = LinearCurve2d.solve(QuadraticCurve2d.derivative(d), t)\n\n const vMag = Vector2.magnitude(v)\n\n if (vMag === 0) {\n return 0\n }\n\n return Math.abs(Vector2.cross(v, a)) / vMag ** 3\n})\n\n/** @internal */\nexport const boundingBox = (\n c: CubicCurve2d,\n): Interval2d.Interval2d<Interval.Closed, Interval.Closed> =>\n Interval2d.make(CubicPolynomial.unitRange(c.x), CubicPolynomial.unitRange(c.y))\n\n/** @internal */\nexport const startPoint = (c: CubicCurve2d): Vector2.Vector2 => Vector2.make(c.x.c0, c.y.c0)\n\n/** @internal */\nexport const endPoint = (c: CubicCurve2d): Vector2.Vector2 =>\n Vector2.make(c.x.c0 + c.x.c1 + c.x.c2 + c.x.c3, c.y.c0 + c.y.c1 + c.y.c2 + c.y.c3)\n\n/** @internal */\nexport const xRange = (c: CubicCurve2d): Interval.Closed => CubicPolynomial.unitRange(c.x)\n\n/** @internal */\nexport const yRange = (c: CubicCurve2d): Interval.Closed => CubicPolynomial.unitRange(c.y)\n\n// Cubic Bernstein basis: P(t) = (1-t)³·p0 + 3(1-t)²t·p1 + 3(1-t)t²·p2 + t³·p3\n// expanded gives c0 = p0, c1 = -3p0 + 3p1, c2 = 3p0 - 6p1 + 3p2,\n// c3 = -p0 + 3p1 - 3p2 + p3, so the inverse is\n// p0 = c0, p1 = c0 + c1/3, p2 = c0 + 2c1/3 + c2/3, p3 = c0 + c1 + c2 + c3.\n/** @internal */\nexport const toPathDataSegment = (c: CubicCurve2d): string => {\n const c0x = c.x.c0\n const c0y = c.y.c0\n const c1x = c.x.c1\n const c1y = c.y.c1\n const c2x = c.x.c2\n const c2y = c.y.c2\n const c3x = c.x.c3\n const c3y = c.y.c3\n const ctrl1X = c0x + c1x / 3\n const ctrl1Y = c0y + c1y / 3\n const ctrl2X = c0x + (2 * c1x) / 3 + c2x / 3\n const ctrl2Y = c0y + (2 * c1y) / 3 + c2y / 3\n const endX = c0x + c1x + c2x + c3x\n const endY = c0y + c1y + c2y + c3y\n return `C ${ctrl1X},${ctrl1Y} ${ctrl2X},${ctrl2Y} ${endX},${endY}`\n}\n\n// Per-axis trait refiners delegate to the polynomial-level check on a single\n// axis (over the unit interval) and brand only that axis. The combined\n// refiners (below) fan out to both axes.\n/** @internal */\nexport const isMonotonicX = <XT, YT>(\n c: CubicCurve2d<XT, YT>,\n): c is CubicCurve2d<XT & Monotonic, YT> => CubicPolynomial.isMonotonic(c.x, Interval.unit)\n\n/** @internal */\nexport const isIncreasingX = <XT, YT>(\n c: CubicCurve2d<XT, YT>,\n): c is CubicCurve2d<XT & Increasing, YT> => CubicPolynomial.isIncreasing(c.x, Interval.unit)\n\n/** @internal */\nexport const isDecreasingX = <XT, YT>(\n c: CubicCurve2d<XT, YT>,\n): c is CubicCurve2d<XT & Decreasing, YT> => CubicPolynomial.isDecreasing(c.x, Interval.unit)\n\n/** @internal */\nexport const isMonotonicY = <XT, YT>(\n c: CubicCurve2d<XT, YT>,\n): c is CubicCurve2d<XT, YT & Monotonic> => CubicPolynomial.isMonotonic(c.y, Interval.unit)\n\n/** @internal */\nexport const isIncreasingY = <XT, YT>(\n c: CubicCurve2d<XT, YT>,\n): c is CubicCurve2d<XT, YT & Increasing> => CubicPolynomial.isIncreasing(c.y, Interval.unit)\n\n/** @internal */\nexport const isDecreasingY = <XT, YT>(\n c: CubicCurve2d<XT, YT>,\n): c is CubicCurve2d<XT, YT & Decreasing> => CubicPolynomial.isDecreasing(c.y, Interval.unit)\n\n/** @internal */\nexport const isMonotonic = <XT, YT>(\n c: CubicCurve2d<XT, YT>,\n): c is CubicCurve2d<XT & Monotonic, YT & Monotonic> => isMonotonicX(c) && isMonotonicY(c)\n\n/** @internal */\nexport const isIncreasing = <XT, YT>(\n c: CubicCurve2d<XT, YT>,\n): c is CubicCurve2d<XT & Increasing, YT & Increasing> => isIncreasingX(c) && isIncreasingY(c)\n\n/** @internal */\nexport const isDecreasing = <XT, YT>(\n c: CubicCurve2d<XT, YT>,\n): c is CubicCurve2d<XT & Decreasing, YT & Decreasing> => isDecreasingX(c) && isDecreasingY(c)\n\nconst fail = (m: string): never => {\n throw new Error(m)\n}\n\n/** @internal */\nexport const asMonotonic = <XT, YT>(\n c: CubicCurve2d<XT, YT>,\n): CubicCurve2d<XT & Monotonic, YT & Monotonic> =>\n isMonotonic(c) ? c : fail('cubic curve is not monotonic in both axes')\n\n/** @internal */\nexport const asIncreasing = <XT, YT>(\n c: CubicCurve2d<XT, YT>,\n): CubicCurve2d<XT & Increasing, YT & Increasing> =>\n isIncreasing(c) ? c : fail('cubic curve is not increasing in both axes')\n\n/** @internal */\nexport const asDecreasing = <XT, YT>(\n c: CubicCurve2d<XT, YT>,\n): CubicCurve2d<XT & Decreasing, YT & Decreasing> =>\n isDecreasing(c) ? c : fail('cubic curve is not decreasing in both axes')\n\n// Affine transform on coefficient form. p(t) = c0 + c1·t + c2·t² + c3·t³, so\n// f(p(t)) = (A·c0 + b) + (A·c1)·t + (A·c2)·t² + (A·c3)·t³. Only the constant\n// coefficient sees the translation; higher coefficients see only the linear\n// part. This is exact in monomial form — no Bernstein round-trip.\n/** @internal */\nexport const transform = dual<\n (a: Affine2d.Affine2d) => (c: CubicCurve2d) => CubicCurve2d,\n (c: CubicCurve2d, a: Affine2d.Affine2d) => CubicCurve2d\n>(2, (c: CubicCurve2d, a: Affine2d.Affine2d) => {\n const m = a.matrix\n return new CubicCurve2dImpl(\n CubicPolynomial.make(\n m.m00 * c.x.c0 + m.m01 * c.y.c0 + m.m02,\n m.m00 * c.x.c1 + m.m01 * c.y.c1,\n m.m00 * c.x.c2 + m.m01 * c.y.c2,\n m.m00 * c.x.c3 + m.m01 * c.y.c3,\n ),\n CubicPolynomial.make(\n m.m10 * c.x.c0 + m.m11 * c.y.c0 + m.m12,\n m.m10 * c.x.c1 + m.m11 * c.y.c1,\n m.m10 * c.x.c2 + m.m11 * c.y.c2,\n m.m10 * c.x.c3 + m.m11 * c.y.c3,\n ),\n )\n})\n","import type { Interval2d } from '../interval/interval2d.ts'\nimport type { TwoDimensional } from '../dimensions.ts'\nimport type { Closed, Interval } from '../interval/interval.ts'\nimport type { Pipeable } from '../utils.ts'\nimport type { CubicPolynomial } from '../polynomial/cubic.ts'\nimport type { Decreasing, Increasing, Monotonic } from '../polynomial/traits.ts'\nimport type * as Solution from '../solution/solution.ts'\nimport type { Affine2d } from '../transform/affine2d.ts'\nimport type { Vector2 } from '../vector/vector2.ts'\nimport type { CubicCurve2dTypeId } from './cubic2d.internal.ts'\nimport * as internal from './cubic2d.internal.ts'\nimport type { Curve2dOps } from './curve2d.ts'\n\nexport type { Monotonic, Increasing, Decreasing } from '../polynomial/traits.ts'\n\n/**\n * A cubic curve in 2D space.\n *\n * All fields are readonly and immutable, and all operations create new instances.\n *\n * The two type parameters carry the trait sets of the curve's per-axis\n * polynomials. Refiners check monotonicity over the unit interval `[0, 1]` —\n * the curve's natural parameter domain.\n *\n * @since 1.0.0\n */\nexport interface CubicCurve2d<out XTraits = unknown, out YTraits = unknown>\n extends Pipeable, TwoDimensional<CubicPolynomial<XTraits>, CubicPolynomial<YTraits>> {\n readonly [CubicCurve2dTypeId]: CubicCurve2dTypeId\n}\n\n/**\n * Creates a new `CubicCurve2d` instance from polynomial parameters.\n *\n * @param x - The x polynomial.\n * @param y - The y polynomial.\n * @returns A new `CubicCurve2d` instance.\n * @since 1.0.0\n */\nexport const fromPolynomials: (x: CubicPolynomial, y: CubicPolynomial) => CubicCurve2d =\n internal.fromPolynomials\n\n/**\n * Creates a new `CubicCurve2d` instance from monomial coefficient vectors.\n *\n * Each argument bundles the per-axis coefficient at the given power: `c0`\n * holds the x⁰ term, `c1` holds the x¹ term, and so on. The resulting curve\n * evaluates to `c0 + c1·t + c2·t² + c3·t³` per axis.\n *\n * @param c0 - The x⁰ coefficients (x and y).\n * @param c1 - The x¹ coefficients (x and y).\n * @param c2 - The x² coefficients (x and y).\n * @param c3 - The x³ coefficients (x and y).\n * @returns A new `CubicCurve2d` instance.\n * @since 2.0.0\n */\nexport const fromCoefficients: (\n c0: Vector2,\n c1: Vector2,\n c2: Vector2,\n c3: Vector2,\n) => CubicCurve2d = internal.fromCoefficients\n\n/**\n * Creates a new `CubicCurve2d` instance from cubic Bézier control points.\n *\n * The four arguments are the Bernstein-basis control points: `p0` and `p3` are\n * the curve's endpoints and `p1` and `p2` are the off-curve control handles.\n * The implementation converts to the curve's internal monomial form in closed\n * form.\n *\n * @param p0 - The first control point (curve start).\n * @param p1 - The second control point (start handle).\n * @param p2 - The third control point (end handle).\n * @param p3 - The fourth control point (curve end).\n * @returns A new `CubicCurve2d` instance whose curve matches the given Bézier.\n * @since 2.0.0\n */\nexport const fromBezierPoints: (\n p0: Vector2,\n p1: Vector2,\n p2: Vector2,\n p3: Vector2,\n) => CubicCurve2d = internal.fromBezierPoints\n\n/**\n * Checks if a value is a `CubicCurve2d`.\n *\n * @param c - The value to check.\n * @returns `true` if the value is a `CubicCurve2d`, `false` otherwise.\n * @since 1.0.0\n */\nexport const isCubicCurve2d: (c: unknown) => c is CubicCurve2d = internal.isCubicCurve2d\n\nexport const solve: {\n /**\n * Solves the cubic curve for a given parameter t.\n *\n * @param t - The parameter value.\n * @returns A function that takes a cubic curve and returns the point on the curve at parameter t.\n * @since 1.0.0\n */\n (t: number): (c: CubicCurve2d) => Vector2\n /**\n * Solves the cubic curve for a given parameter t.\n *\n * @param c - The cubic curve to solve.\n * @param t - The parameter value.\n * @returns The point on the curve at parameter t.\n * @since 1.0.0\n */\n (c: CubicCurve2d, t: number): Vector2\n} = internal.solve\n\nexport const length: {\n /**\n * Calculates (approximates) the length of a cubic curve.\n *\n * @param c - The cubic curve to calculate the length of.\n * @param i - The interval over which to calculate the length.\n * @returns The length of the cubic curve.\n * @since 1.0.0\n */\n (c: CubicCurve2d, i: Interval): number\n /**\n * Calculates (approximates) the length of a cubic curve.\n *\n * @param i - The interval over which to calculate the length.\n * @returns A function that takes a cubic curve and returns the length of the cubic curve.\n * @since 1.0.0\n */\n (i: Interval): (c: CubicCurve2d) => number\n} = internal.length\n\nexport const solveAtX: {\n /**\n * Evaluates the curve's y values at a given x. Because the x polynomial is\n * `Monotonic`, the inverse has at most one solution — at most one y value.\n *\n * @param c - The cubic curve.\n * @param x - The x coordinate.\n * @returns Zero or one y values, in t-ascending order.\n * @since 2.0.0\n */\n <XT extends Monotonic, YT>(c: CubicCurve2d<XT, YT>, x: number): Solution.AtMostOne<number>\n /**\n * Evaluates the curve's y values at a given x. The result is the y values\n * the curve passes through where x(t) = the given x — up to three solutions\n * for a cubic curve.\n *\n * @param c - The cubic curve.\n * @param x - The x coordinate.\n * @returns The y values at x, in t-ascending order.\n * @since 2.0.0\n */\n <XT, YT>(c: CubicCurve2d<XT, YT>, x: number): Solution.AtMostThree<number>\n /** @since 2.0.0 */\n (x: number): {\n <XT extends Monotonic, YT>(c: CubicCurve2d<XT, YT>): Solution.AtMostOne<number>\n <XT, YT>(c: CubicCurve2d<XT, YT>): Solution.AtMostThree<number>\n }\n} = internal.solveAtX as never\n\nexport const solveAtY: {\n /**\n * Evaluates the curve's x values at a given y. Because the y polynomial is\n * `Monotonic`, the inverse has at most one solution.\n *\n * @param c - The cubic curve.\n * @param y - The y coordinate.\n * @returns Zero or one x values, in t-ascending order.\n * @since 2.0.0\n */\n <XT, YT extends Monotonic>(c: CubicCurve2d<XT, YT>, y: number): Solution.AtMostOne<number>\n /**\n * Evaluates the curve's x values at a given y. The result is the x values\n * the curve passes through where y(t) = the given y — up to three solutions\n * for a cubic curve.\n *\n * @param c - The cubic curve.\n * @param y - The y coordinate.\n * @returns The x values at y, in t-ascending order.\n * @since 2.0.0\n */\n <XT, YT>(c: CubicCurve2d<XT, YT>, y: number): Solution.AtMostThree<number>\n /** @since 2.0.0 */\n (y: number): {\n <XT, YT extends Monotonic>(c: CubicCurve2d<XT, YT>): Solution.AtMostOne<number>\n <XT, YT>(c: CubicCurve2d<XT, YT>): Solution.AtMostThree<number>\n }\n} = internal.solveAtY as never\n\nexport const curvature: {\n /**\n * Calculates the curvature of a cubic curve at a given parameter.\n *\n * @param c - The cubic curve to calculate the curvature for.\n * @param t - The parameter value.\n * @returns The curvature of the cubic curve at parameter t.\n * @since 1.0.0\n */\n (c: CubicCurve2d, t: number): number\n /**\n * Calculates the curvature of a cubic curve at a given parameter.\n *\n * @param t - The parameter value.\n * @returns A function that takes a cubic curve and returns the curvature of the cubic curve at parameter t.\n * @since 1.0.0\n */\n (t: number): (c: CubicCurve2d) => number\n} = internal.curvature\n\n/**\n * Computes the axis-aligned bounding box of the curve over its parameter\n * domain `[0, 1]`. Accounts for up to two interior extrema per axis, so the\n * box is tight against the curve and not just the control polygon.\n *\n * @param c - The cubic curve.\n * @returns A closed `Box2d` enclosing the curve.\n * @since 2.0.0\n */\nexport const boundingBox: (c: CubicCurve2d) => Interval2d<Closed, Closed> = internal.boundingBox\n\n/**\n * Evaluates the curve at `t = 0` in closed form — `(c.x.c0, c.y.c0)`.\n *\n * @param c - The cubic curve.\n * @returns The point at the start of the curve's parameter domain.\n * @since 2.0.0\n */\nexport const startPoint: (c: CubicCurve2d) => Vector2 = internal.startPoint\n\n/**\n * Evaluates the curve at `t = 1` in closed form — the sum of the per-axis\n * monomial coefficients.\n *\n * @param c - The cubic curve.\n * @returns The point at the end of the curve's parameter domain.\n * @since 2.0.0\n */\nexport const endPoint: (c: CubicCurve2d) => Vector2 = internal.endPoint\n\n/**\n * The tight `[min, max]` range of x over the curve's parameter domain `[0, 1]`,\n * accounting for up to two interior extrema.\n *\n * @param c - The cubic curve.\n * @returns The closed range of x over `[0, 1]`.\n * @since 2.0.0\n */\nexport const xRange: (c: CubicCurve2d) => Closed = internal.xRange\n\n/**\n * The tight `[min, max]` range of y over the curve's parameter domain `[0, 1]`,\n * accounting for up to two interior extrema.\n *\n * @param c - The cubic curve.\n * @returns The closed range of y over `[0, 1]`.\n * @since 2.0.0\n */\nexport const yRange: (c: CubicCurve2d) => Closed = internal.yRange\n\n/**\n * Renders the curve as a single SVG path-data drawing command — for a cubic\n * curve, `C ctrl1X,ctrl1Y ctrl2X,ctrl2Y endX,endY`. Bernstein control points\n * are recovered from the monomial coefficients in closed form. Does not\n * include a leading `M`.\n *\n * @param c - The cubic curve.\n * @returns The SVG drawing command for this segment, without a leading `M`.\n * @since 2.0.0\n */\nexport const toPathDataSegment: (c: CubicCurve2d) => string = internal.toPathDataSegment\n\n/**\n * Type-narrowing predicate: refines the curve's x-axis trait to include\n * `Monotonic` when the x polynomial is strictly monotonic on the unit\n * interval `[0, 1]`. The y-axis trait is unchanged.\n *\n * @since 2.0.0\n */\nexport const isMonotonicX: <XT, YT>(\n c: CubicCurve2d<XT, YT>,\n) => c is CubicCurve2d<XT & Monotonic, YT> = internal.isMonotonicX\n\n/** @since 2.0.0 */\nexport const isIncreasingX: <XT, YT>(\n c: CubicCurve2d<XT, YT>,\n) => c is CubicCurve2d<XT & Increasing, YT> = internal.isIncreasingX\n\n/** @since 2.0.0 */\nexport const isDecreasingX: <XT, YT>(\n c: CubicCurve2d<XT, YT>,\n) => c is CubicCurve2d<XT & Decreasing, YT> = internal.isDecreasingX\n\n/**\n * Type-narrowing predicate: refines the curve's y-axis trait to include\n * `Monotonic`. The x-axis trait is unchanged.\n *\n * @since 2.0.0\n */\nexport const isMonotonicY: <XT, YT>(\n c: CubicCurve2d<XT, YT>,\n) => c is CubicCurve2d<XT, YT & Monotonic> = internal.isMonotonicY\n\n/** @since 2.0.0 */\nexport const isIncreasingY: <XT, YT>(\n c: CubicCurve2d<XT, YT>,\n) => c is CubicCurve2d<XT, YT & Increasing> = internal.isIncreasingY\n\n/** @since 2.0.0 */\nexport const isDecreasingY: <XT, YT>(\n c: CubicCurve2d<XT, YT>,\n) => c is CubicCurve2d<XT, YT & Decreasing> = internal.isDecreasingY\n\n/**\n * Type-narrowing predicate: refines both axes' traits to include `Monotonic`\n * when both x and y polynomials are monotonic over the unit interval `[0, 1]`.\n *\n * @since 2.0.0\n */\nexport const isMonotonic: <XT, YT>(\n c: CubicCurve2d<XT, YT>,\n) => c is CubicCurve2d<XT & Monotonic, YT & Monotonic> = internal.isMonotonic\n\n/** @since 2.0.0 */\nexport const isIncreasing: <XT, YT>(\n c: CubicCurve2d<XT, YT>,\n) => c is CubicCurve2d<XT & Increasing, YT & Increasing> = internal.isIncreasing\n\n/** @since 2.0.0 */\nexport const isDecreasing: <XT, YT>(\n c: CubicCurve2d<XT, YT>,\n) => c is CubicCurve2d<XT & Decreasing, YT & Decreasing> = internal.isDecreasing\n\n/** @since 2.0.0 */\nexport const asMonotonic: <XT, YT>(\n c: CubicCurve2d<XT, YT>,\n) => CubicCurve2d<XT & Monotonic, YT & Monotonic> = internal.asMonotonic\n\n/** @since 2.0.0 */\nexport const asIncreasing: <XT, YT>(\n c: CubicCurve2d<XT, YT>,\n) => CubicCurve2d<XT & Increasing, YT & Increasing> = internal.asIncreasing\n\n/** @since 2.0.0 */\nexport const asDecreasing: <XT, YT>(\n c: CubicCurve2d<XT, YT>,\n) => CubicCurve2d<XT & Decreasing, YT & Decreasing> = internal.asDecreasing\n\nexport const transform: {\n /**\n * Applies an `Affine2d` transform to a `CubicCurve2d`, returning a new\n * curve whose image is the affine image of the original. Internally the\n * transformation works directly on monomial coefficients — `c0` receives\n * the full affine, `c1`/`c2`/`c3` receive only the linear part.\n *\n * @param c - The cubic curve.\n * @param a - The affine transform.\n * @returns The transformed cubic curve.\n * @since 2.0.0\n */\n (c: CubicCurve2d, a: Affine2d): CubicCurve2d\n /**\n * Applies an `Affine2d` transform to a `CubicCurve2d`.\n *\n * @param a - The affine transform.\n * @returns A function that takes a `CubicCurve2d` and returns the transformed curve.\n * @since 2.0.0\n */\n (a: Affine2d): (c: CubicCurve2d) => CubicCurve2d\n} = internal.transform\n\n/**\n * The {@link Curve2dOps} bundle for `CubicCurve2d`. Used by `CubicPath2d`\n * to wire up the path-level operation surface. The `solveAtX` / `solveAtY`\n * entries narrow the curve's potentially-3-element result to `AtMostOne` —\n * path callers enforce that via the path's `MonotonicX`/`MonotonicY` brand.\n *\n * @since 2.0.0\n */\nexport const Ops: Curve2dOps<CubicCurve2d> = {\n solve,\n startPoint,\n endPoint,\n length,\n boundingBox,\n solveAtX: (c, x) => internal.solveAtX(c, x) as Solution.AtMostOne<number>,\n solveAtY: (c, y) => internal.solveAtY(c, y) as Solution.AtMostOne<number>,\n toPathDataSegment,\n isIncreasingX,\n isDecreasingX,\n isIncreasingY,\n isDecreasingY,\n transform,\n}\n","import * as Characteristic from '../characteristic/characteristic.ts'\nimport * as Interval from '../interval/interval.ts'\nimport * as Interval2d from '../interval/interval2d.ts'\nimport * as Monotonicity from '../monotonicity/monotonicity.ts'\nimport type * as Affine2d from '../transform/affine2d.ts'\nimport { dual, Pipeable } from '../utils.ts'\nimport * as CubicPolynomial from '../polynomial/cubic.ts'\nimport * as Solution from '../solution/solution.ts'\nimport type { Decreasing, Increasing, Monotonic } from '../polynomial/traits.ts'\nimport { invariant } from '../utils.ts'\nimport * as Vector2 from '../vector/vector2.ts'\nimport * as Vector4 from '../vector/vector4.ts'\nimport * as CubicCurve2d from './cubic2d.ts'\nimport type { RationalCubicCurve2d } from './rationalCubic2d.ts'\n\nexport const RationalCubicCurve2dTypeId: unique symbol = Symbol('curvy/curve/rationalCubic2d')\nexport type RationalCubicCurve2dTypeId = typeof RationalCubicCurve2dTypeId\n\n// Phantom property key carrying the per-axis trait tuple. Unlike `CubicCurve2d`\n// where traits flow through to the underlying polynomials, rational curve\n// traits are properties of the projected rational functions x(t)/w(t) and\n// y(t)/w(t) — not of any individual polynomial — so the brand lives on the\n// curve itself.\n/** @internal */\nexport const RationalCurveTraits: unique symbol = Symbol.for('curvy/curve/rationalCubic2d/traits')\n/** @internal */\nexport type RationalCurveTraits = typeof RationalCurveTraits\n\n/** @internal */\nexport class RationalCubicCurve2dImpl\n extends Pipeable\n implements RationalCubicCurve2d<unknown, unknown>\n{\n readonly [RationalCubicCurve2dTypeId]: RationalCubicCurve2dTypeId = RationalCubicCurve2dTypeId\n declare readonly [RationalCurveTraits]: [unknown, unknown]\n\n readonly x: CubicPolynomial.CubicPolynomial\n readonly y: CubicPolynomial.CubicPolynomial\n readonly w: CubicPolynomial.CubicPolynomial\n\n constructor(\n x: CubicPolynomial.CubicPolynomial,\n y: CubicPolynomial.CubicPolynomial,\n w: CubicPolynomial.CubicPolynomial,\n ) {\n super()\n this.x = x\n this.y = y\n this.w = w\n }\n}\n\n/** @internal */\nexport const isRationalCubicCurve2d = (c: unknown): c is RationalCubicCurve2d =>\n typeof c === 'object' && c !== null && RationalCubicCurve2dTypeId in c\n\n/** @internal */\nexport const fromPolynomials = (\n x: CubicPolynomial.CubicPolynomial,\n y: CubicPolynomial.CubicPolynomial,\n w: CubicPolynomial.CubicPolynomial,\n): RationalCubicCurve2d => new RationalCubicCurve2dImpl(x, y, w)\n\n// Endpoint pins for the two-arg `fromBezierPoints` overload — the rational\n// analog of CSS `cubic-bezier(x1, y1, x2, y2)`. Module-level so the two-arg\n// path is allocation-free for the endpoints.\nconst EASING_P0 = Vector2.makeWeighted(0, 0, 1)\nconst EASING_P3 = Vector2.makeWeighted(1, 1, 1)\n\n// Applies the cubic Bézier characteristic matrix in homogeneous space —\n// each control point is lifted to `(w·x, w·y, w)` and the same matrix that\n// drives `CubicCurve2d.fromBezierPoints` runs on each of the three channels\n// independently. The shared `w` polynomial is the projective denominator;\n// at solve time, x(t)/w(t) and y(t)/w(t) project the curve back to the plane.\n//\n// This is Freya Holmér's \"matrix IS the spline\" framing extended to rational:\n// same matrix, three channels instead of two, one projection at the end.\n/** @internal */\nexport const fromBezierPoints = (\n ...args:\n | [p1: Vector2.Weighted, p2: Vector2.Weighted]\n | [p0: Vector2.Weighted, p1: Vector2.Weighted, p2: Vector2.Weighted, p3: Vector2.Weighted]\n): RationalCubicCurve2d => {\n const [p0, p1, p2, p3] = args.length === 2 ? [EASING_P0, args[0], args[1], EASING_P3] : args\n return new RationalCubicCurve2dImpl(\n ...Characteristic.apply(\n Characteristic.cubicBezier,\n // Lift each control point to homogeneous (w·x, w·y, w), then transpose\n // the four lifted CPs into three per-channel Vector4s for the matrix.\n ...Vector4.transpose([p0, p1, p2, p3], (p) => [p.x * p.weight, p.y * p.weight, p.weight]),\n ),\n )\n}\n\n// Rational cubic Hermite easing from endpoint slopes and signed curvatures.\n//\n// Construction: rational cubic with quadratic denominator, embedded in the 2D\n// pipeline by pinning x(t) = t exactly. The 2D embedding stores three cubic\n// polynomials:\n// X(t) = t · W(t) (cubic, with c0 = 0) so x(t) = t\n// Y(t) = cubic numerator\n// W(t) = quadratic denominator (stored as cubic with c3 = 0)\n//\n// Six endpoint constraints — y(0)=0, y(1)=1, y'(0)=m₀, y'(1)=m₁, y''(0), y''(1)\n// — determine the six free Bernstein control values (p₁, p₂, w₀, w₁, w₂) up to\n// overall scaling; p₀ = 0 and p₃ = w₂ are pinned by the endpoint values. We\n// normalize w₀ = 1 and solve a 2×2 linear system for (w₁, w₂); p₁, p₂ then\n// follow algebraically. With those Bernstein control values, conversion to\n// monomial form is closed-form (no root finding required).\n//\n// Curvature inputs are the signed differential-geometric curvatures\n// κ = y''(x) / (1 + y'(x)²)^(3/2). Because x(t) = t, parametric y'(t), y''(t)\n// equal the Cartesian dy/dx, d²y/dx², so the conversion at endpoints is\n// y''(0) = κ₀ · (1 + m₀²)^(3/2) and y''(1) = κ₁ · (1 + m₁²)^(3/2).\n//\n// Throws when:\n// - inputs are non-finite,\n// - the linear system is singular (no unique denominator),\n// - the resulting denominator W has a zero in [0, 1] (curve is singular).\n//\n// Monotonicity is *not* enforced; callers wanting that guarantee should\n// follow construction with `asIncreasing` / `asDecreasing` / `asMonotonic`,\n// which run a rigorous sign check on the result.\n/** @internal */\nexport const fromSlopesAndCurvatures = (\n startSlope: number,\n endSlope: number,\n startCurvature: number,\n endCurvature: number,\n): RationalCubicCurve2d => {\n invariant(Number.isFinite(startSlope), 'fromSlopesAndCurvatures: startSlope must be finite')\n invariant(Number.isFinite(endSlope), 'fromSlopesAndCurvatures: endSlope must be finite')\n invariant(\n Number.isFinite(startCurvature),\n 'fromSlopesAndCurvatures: startCurvature must be finite',\n )\n invariant(Number.isFinite(endCurvature), 'fromSlopesAndCurvatures: endCurvature must be finite')\n\n const m0 = startSlope\n const m1 = endSlope\n\n // y''(0) = κ₀ · (1 + m₀²)^(3/2), y''(1) = κ₁ · (1 + m₁²)^(3/2).\n // (Standard signed-curvature → second-derivative conversion for a graph y(x).)\n const d0 = startCurvature * Math.pow(1 + m0 * m0, 1.5)\n const d1 = endCurvature * Math.pow(1 + m1 * m1, 1.5)\n\n // Linear system from the two curvature constraints, normalized at w₀ = 1:\n // 4·u·w₁ + 2·v·w₂ = d₀\n // 4·v·w₁ + d₁·w₂ = -2·u\n // where u = 1 - m₀, v = 1 - m₁. By Cramer's rule:\n // det = 4·u·d₁ - 8·v²\n // w₁ = (d₀·d₁ + 4·u·v) / det\n // w₂ = (-8·u² - 4·d₀·v) / det\n const u = 1 - m0\n const v = 1 - m1\n const det = 4 * u * d1 - 8 * v * v\n\n // When the input curvatures sit exactly on the boundary `u·d₁ = 2·v²` the\n // constraint system goes singular: either inconsistent (no curve satisfies\n // the constraints) or redundant (a 1-parameter family of curves does). The\n // tolerance below catches inputs that are mathematically redundant but\n // float-perturbed off zero (e.g. y(t) = t², where the conversion from κ to\n // d picks up ε-level error). Use a relative scale so the test scales with\n // the magnitude of the coefficients.\n const detScale = Math.max(Math.abs(4 * u * d1), Math.abs(8 * v * v), 1)\n const SINGULAR_TOLERANCE = 1e-12\n\n let w0: number\n let w1: number\n let w2: number\n\n if (Math.abs(det) > SINGULAR_TOLERANCE * detScale) {\n w0 = 1\n w1 = (d0 * d1 + 4 * u * v) / det\n w2 = (-8 * u * u - 4 * d0 * v) / det\n } else if (u === 0 && v === 0) {\n // m₀ = m₁ = 1: both equations collapse to `0 = d₀` and `0 = d₁`, so the\n // system is consistent iff both curvatures vanish. The only easing\n // satisfying that is linear y(t) = t — return it directly.\n invariant(\n d0 === 0 && d1 === 0,\n `fromSlopesAndCurvatures: inputs (m₀=${m0}, m₁=${m1}, κ₀=${startCurvature}, κ₁=${endCurvature}) yield an inconsistent constraint system`,\n )\n return new RationalCubicCurve2dImpl(\n CubicPolynomial.make(0, 1, 0, 0),\n CubicPolynomial.make(0, 1, 0, 0),\n CubicPolynomial.make(1, 0, 0, 0),\n )\n } else {\n // Singular but not at the linear-easing point. The two rows are\n // proportional; consistency requires the augmented column to match. The\n // residual `−8·u² − 4·v·d₀` is the Cramer numerator of w₂, which must\n // also vanish for the system to be consistent (otherwise w₂ would need\n // to be both finite and 0/0).\n const residual = -8 * u * u - 4 * v * d0\n invariant(\n Math.abs(residual) <= SINGULAR_TOLERANCE * detScale,\n `fromSlopesAndCurvatures: inputs (m₀=${m0}, m₁=${m1}, κ₀=${startCurvature}, κ₁=${endCurvature}) yield an inconsistent constraint system`,\n )\n // Pick the canonical solution from the 1-parameter family: w₂ = 1, then\n // w₁ follows from whichever of the two equations has a nonzero pivot.\n // (At least one of u, v is nonzero here, since u = v = 0 branched above.)\n w0 = 1\n w2 = 1\n w1 = u !== 0 ? (d0 - 2 * v) / (4 * u) : -(2 * u + d1) / (4 * v)\n }\n\n // W(t) must be > 0 throughout [0, 1] for the rational to be well-defined.\n // W(0) = w₀ = 1 > 0 always; check W(1) = w₂ > 0, then guard the interior.\n // W as a quadratic in t has monomial coefficients (c, b, a) below; on [0, 1]\n // its minimum is at an endpoint unless `a > 0` and the vertex `t* = -b/(2a)`\n // lies inside (0, 1), in which case the vertex value is the candidate min.\n invariant(\n w2 > 0,\n `fromSlopesAndCurvatures: inputs (m₀=${m0}, m₁=${m1}, κ₀=${startCurvature}, κ₁=${endCurvature}) yield denominator ≤ 0 at t = 1`,\n )\n const a = w0 - 2 * w1 + w2\n const b = 2 * (w1 - w0)\n if (a > 0) {\n const tStar = -b / (2 * a)\n if (tStar > 0 && tStar < 1) {\n const wStar = w0 + tStar * (b + a * tStar)\n invariant(\n wStar > 0,\n `fromSlopesAndCurvatures: inputs (m₀=${m0}, m₁=${m1}, κ₀=${startCurvature}, κ₁=${endCurvature}) yield denominator ≤ 0 in (0, 1)`,\n )\n }\n }\n\n // Numerator Bernstein control values, from the endpoint value & slope\n // constraints (p₀ = 0, p₃ = w₂, p₁ = m₀·w₀/3, p₂ = ((1-m₁)·w₂ + 2·w₁)/3).\n const p1 = (m0 * w0) / 3\n const p2 = (v * w2 + 2 * w1) / 3\n const p3 = w2\n\n // Bernstein → monomial conversion. For cubic Y with p₀ = 0:\n // Y(t) = 3·p₁·t + 3·(p₂ - 2·p₁)·t² + (p₃ - 3·p₂ + 3·p₁)·t³\n // For quadratic W:\n // W(t) = w₀ + 2·(w₁ - w₀)·t + (w₀ - 2·w₁ + w₂)·t²\n // X(t) = t · W(t) shifts W up one degree.\n const yC1 = 3 * p1\n const yC2 = 3 * (p2 - 2 * p1)\n const yC3 = p3 - 3 * p2 + 3 * p1\n const wC0 = w0\n const wC1 = b\n const wC2 = a\n\n return new RationalCubicCurve2dImpl(\n CubicPolynomial.make(0, wC0, wC1, wC2),\n CubicPolynomial.make(0, yC1, yC2, yC3),\n CubicPolynomial.make(wC0, wC1, wC2, 0),\n )\n}\n\n/** @internal */\nexport const solve = dual<\n (t: number) => (c: RationalCubicCurve2d) => Vector2.Vector2,\n (c: RationalCubicCurve2d, t: number) => Vector2.Vector2\n>(2, (c: RationalCubicCurve2d, t: number) => {\n const w = CubicPolynomial.solve(c.w, t)\n return Vector2.make(CubicPolynomial.solve(c.x, t) / w, CubicPolynomial.solve(c.y, t) / w)\n})\n\n// At t = 0, every cubic polynomial's Horner evaluation is just its c₀ term, so\n// the projection (x(0)/w(0), y(0)/w(0)) collapses to closed-form scalar divides.\n/** @internal */\nexport const startPoint = (c: RationalCubicCurve2d): Vector2.Vector2 =>\n Vector2.make(c.x.c0 / c.w.c0, c.y.c0 / c.w.c0)\n\n// At t = 1, every cubic polynomial's Horner evaluation collapses to the sum\n// of its monomial coefficients, so the projection at the endpoint is the sum\n// per axis divided by the denominator's sum.\n/** @internal */\nexport const endPoint = (c: RationalCubicCurve2d): Vector2.Vector2 => {\n const w = c.w.c0 + c.w.c1 + c.w.c2 + c.w.c3\n return Vector2.make(\n (c.x.c0 + c.x.c1 + c.x.c2 + c.x.c3) / w,\n (c.y.c0 + c.y.c1 + c.y.c2 + c.y.c3) / w,\n )\n}\n\n// Inverse-solve x(t)/w(t) = X by finding roots of X(t) - X·w(t) = 0.\n// Both X(t) and w(t) are cubic in t, so their linear combination is also\n// cubic — solvable with the existing cubic root-finder. Solutions outside\n// the [0, 1] unit interval are discarded; for each surviving t, y(t)/w(t)\n// is evaluated. The brand-aware overload narrows to `AtMostOne` for curves\n// known to be x-monotonic.\n/** @internal */\nexport const solveAtX = dual(\n 2,\n (c: RationalCubicCurve2d, x: number): Solution.Solution<number> =>\n CubicPolynomial.make(\n c.x.c0 - x * c.w.c0,\n c.x.c1 - x * c.w.c1,\n c.x.c2 - x * c.w.c2,\n c.x.c3 - x * c.w.c3,\n ).pipe(\n CubicPolynomial.roots,\n Solution.clipApprox(Interval.unit),\n Solution.map((t) => CubicPolynomial.solve(c.y, t) / CubicPolynomial.solve(c.w, t)),\n ),\n)\n\n/** @internal */\nexport const solveAtY = dual(\n 2,\n (c: RationalCubicCurve2d, y: number): Solution.Solution<number> =>\n CubicPolynomial.make(\n c.y.c0 - y * c.w.c0,\n c.y.c1 - y * c.w.c1,\n c.y.c2 - y * c.w.c2,\n c.y.c3 - y * c.w.c3,\n ).pipe(\n CubicPolynomial.roots,\n Solution.clipApprox(Interval.unit),\n Solution.map((t) => CubicPolynomial.solve(c.x, t) / CubicPolynomial.solve(c.w, t)),\n ),\n)\n\n// Monomial coefficients of the quartic q(t) = N'(t)·D(t) − N(t)·D'(t).\n//\n// Since `r(t) = N(t)/D(t)` and `r'(t) = (N'·D − N·D')/D²`, with D² > 0 wherever\n// D ≠ 0, the sign of `r'` equals the sign of `q` on the unit interval (the\n// documented invariant assumes D is nonvanishing on `[0, 1]`). So per-axis\n// monotonicity of the rational reduces to sign analysis of `q`.\n//\n// `q` is the difference of two degree-5 products, but the leading t⁵ terms of\n// `N'·D` and `N·D'` both equal `3·n₃·d₃` and cancel — so `q` is actually\n// degree 4. (For equal-degree-n rationals, the derivative-numerator has degree\n// `2n − 2`.) Five monomial coefficients suffice.\nconst derivativeNumeratorQuartic = (\n n: CubicPolynomial.CubicPolynomial,\n d: CubicPolynomial.CubicPolynomial,\n): readonly [number, number, number, number, number] => [\n n.c1 * d.c0 - n.c0 * d.c1,\n 2 * (n.c2 * d.c0 - n.c0 * d.c2),\n n.c2 * d.c1 - n.c1 * d.c2 + 3 * (n.c3 * d.c0 - n.c0 * d.c3),\n 2 * (n.c3 * d.c1 - n.c1 * d.c3),\n n.c3 * d.c2 - n.c2 * d.c3,\n]\n\n// Monomial → Bernstein basis conversion for degree 4 on [0, 1].\n//\n// bⱼ = Σᵢ₌₀..ⱼ C(j, i)/C(4, i) · cᵢ\n//\n// Closed-form for n = 4 using C(4,·) = (1, 4, 6, 4, 1). Five outputs.\nconst bernsteinFromQuarticMonomial = (\n c0: number,\n c1: number,\n c2: number,\n c3: number,\n c4: number,\n): readonly [number, number, number, number, number] => [\n c0,\n c0 + c1 / 4,\n c0 + c1 / 2 + c2 / 6,\n c0 + (3 * c1) / 4 + c2 / 2 + c3 / 4,\n c0 + c1 + c2 + c3 + c4,\n]\n\n// At depth 32 the recursion has bracketed any sign change to an interval of\n// width 2⁻³² ≈ 2 × 10⁻¹⁰ — well below floating-point noise for typical\n// curve coefficients. Surviving ambiguity at this depth indicates a\n// tangential zero (touches but does not cross), which we report as\n// `Monotonicity.None`.\nconst BERNSTEIN_SIGN_MAX_DEPTH = 32\n\n// Bernstein sign convexity check on `[0, 1]`, returning the monotonicity\n// implied for a function whose derivative is the polynomial described by\n// these Bernstein coefficients. The encoding of `Monotonicity` is the same\n// 2-bit sign-coverage bitmask used internally here (bit 0 = \"polynomial\n// takes positive values\", bit 1 = \"takes negative values\"), so we can build\n// up the result and return it without translation.\n//\n// Single-level: by the convex-hull property of Bernstein form, a polynomial's\n// range on `[0, 1]` is contained in the convex hull of its Bernstein control\n// values — so the sign coverage of those values upper-bounds the sign\n// coverage of the polynomial. When the control values are sign-uniform we're\n// done; when not, the polynomial *might* still be sign-uniform (the hull is\n// only an outer bound), so we subdivide and check on tighter intervals.\n//\n// Recursive: split at t = 0.5 via de Casteljau (exact in Bernstein basis),\n// classify each half, then OR the coverages — `Increasing | Decreasing`\n// (subintervals of opposite sign) automatically degenerates to `None`,\n// matching the convex-union semantics of the sign sets. The depth cap turns\n// this into a decision procedure except at tangential zeros.\nconst certifyBernsteinSign = (\n bs: readonly [number, number, number, number, number],\n depth = 0,\n): Monotonicity.Monotonicity => {\n let m: Monotonicity.Monotonicity = Monotonicity.Constant\n for (let i = 0; i < 5; i++) {\n const b = bs[i] as number\n if (b > 0) {\n m = (m | Monotonicity.Increasing) as Monotonicity.Monotonicity\n } else if (b < 0) {\n m = (m | Monotonicity.Decreasing) as Monotonicity.Monotonicity\n }\n }\n if (m !== Monotonicity.None) {\n return m\n }\n if (depth >= BERNSTEIN_SIGN_MAX_DEPTH) {\n return Monotonicity.None\n }\n\n // de Casteljau at t = 0.5: each level averages adjacent values. Left half\n // Bernstein coefficients are the first entry of each column; right half are\n // the last entry of each column, read in reverse.\n const [b0, b1, b2, b3, b4] = bs\n const c0 = (b0 + b1) * 0.5\n const c1 = (b1 + b2) * 0.5\n const c2 = (b2 + b3) * 0.5\n const c3 = (b3 + b4) * 0.5\n const d0 = (c0 + c1) * 0.5\n const d1 = (c1 + c2) * 0.5\n const d2 = (c2 + c3) * 0.5\n const e0 = (d0 + d1) * 0.5\n const e1 = (d1 + d2) * 0.5\n const f = (e0 + e1) * 0.5\n\n return (certifyBernsteinSign([b0, c0, d0, e0, f], depth + 1) |\n certifyBernsteinSign([f, e1, d2, c3, b4], depth + 1)) as Monotonicity.Monotonicity\n}\n\nconst axisMonotonicity = (\n numerator: CubicPolynomial.CubicPolynomial,\n denominator: CubicPolynomial.CubicPolynomial,\n): Monotonicity.Monotonicity => {\n const [q0, q1, q2, q3, q4] = derivativeNumeratorQuartic(numerator, denominator)\n return certifyBernsteinSign(bernsteinFromQuarticMonomial(q0, q1, q2, q3, q4))\n}\n\n/** @internal */\nexport const xMonotonicity = (c: RationalCubicCurve2d): Monotonicity.Monotonicity =>\n axisMonotonicity(c.x, c.w)\n\n/** @internal */\nexport const yMonotonicity = (c: RationalCubicCurve2d): Monotonicity.Monotonicity =>\n axisMonotonicity(c.y, c.w)\n\n/** @internal */\nexport const isMonotonicX = <XT, YT>(\n c: RationalCubicCurve2d<XT, YT>,\n): c is RationalCubicCurve2d<XT & Monotonic, YT> => Monotonicity.isStrict(xMonotonicity(c))\n\n/** @internal */\nexport const isIncreasingX = <XT, YT>(\n c: RationalCubicCurve2d<XT, YT>,\n): c is RationalCubicCurve2d<XT & Increasing, YT> => xMonotonicity(c) === Monotonicity.Increasing\n\n/** @internal */\nexport const isDecreasingX = <XT, YT>(\n c: RationalCubicCurve2d<XT, YT>,\n): c is RationalCubicCurve2d<XT & Decreasing, YT> => xMonotonicity(c) === Monotonicity.Decreasing\n\n/** @internal */\nexport const isMonotonicY = <XT, YT>(\n c: RationalCubicCurve2d<XT, YT>,\n): c is RationalCubicCurve2d<XT, YT & Monotonic> => Monotonicity.isStrict(yMonotonicity(c))\n\n/** @internal */\nexport const isIncreasingY = <XT, YT>(\n c: RationalCubicCurve2d<XT, YT>,\n): c is RationalCubicCurve2d<XT, YT & Increasing> => yMonotonicity(c) === Monotonicity.Increasing\n\n/** @internal */\nexport const isDecreasingY = <XT, YT>(\n c: RationalCubicCurve2d<XT, YT>,\n): c is RationalCubicCurve2d<XT, YT & Decreasing> => yMonotonicity(c) === Monotonicity.Decreasing\n\n// Combined refiners compose from per-axis ones via TypeScript's narrowing of\n// the && chain: each per-axis predicate attaches its brand to its own axis,\n// and the intersection accumulates as expected.\n/** @internal */\nexport const isMonotonic = <XT, YT>(\n c: RationalCubicCurve2d<XT, YT>,\n): c is RationalCubicCurve2d<XT & Monotonic, YT & Monotonic> => isMonotonicX(c) && isMonotonicY(c)\n\n/** @internal */\nexport const isIncreasing = <XT, YT>(\n c: RationalCubicCurve2d<XT, YT>,\n): c is RationalCubicCurve2d<XT & Increasing, YT & Increasing> =>\n isIncreasingX(c) && isIncreasingY(c)\n\n/** @internal */\nexport const isDecreasing = <XT, YT>(\n c: RationalCubicCurve2d<XT, YT>,\n): c is RationalCubicCurve2d<XT & Decreasing, YT & Decreasing> =>\n isDecreasingX(c) && isDecreasingY(c)\n\nconst fail = (m: string): never => {\n throw new Error(m)\n}\n\n/** @internal */\nexport const asMonotonicX = <XT, YT>(\n c: RationalCubicCurve2d<XT, YT>,\n): RationalCubicCurve2d<XT & Monotonic, YT> =>\n isMonotonicX(c) ? c : fail('rational cubic curve is not monotonic in x')\n\n/** @internal */\nexport const asIncreasingX = <XT, YT>(\n c: RationalCubicCurve2d<XT, YT>,\n): RationalCubicCurve2d<XT & Increasing, YT> =>\n isIncreasingX(c) ? c : fail('rational cubic curve is not increasing in x')\n\n/** @internal */\nexport const asDecreasingX = <XT, YT>(\n c: RationalCubicCurve2d<XT, YT>,\n): RationalCubicCurve2d<XT & Decreasing, YT> =>\n isDecreasingX(c) ? c : fail('rational cubic curve is not decreasing in x')\n\n/** @internal */\nexport const asMonotonicY = <XT, YT>(\n c: RationalCubicCurve2d<XT, YT>,\n): RationalCubicCurve2d<XT, YT & Monotonic> =>\n isMonotonicY(c) ? c : fail('rational cubic curve is not monotonic in y')\n\n/** @internal */\nexport const asIncreasingY = <XT, YT>(\n c: RationalCubicCurve2d<XT, YT>,\n): RationalCubicCurve2d<XT, YT & Increasing> =>\n isIncreasingY(c) ? c : fail('rational cubic curve is not increasing in y')\n\n/** @internal */\nexport const asDecreasingY = <XT, YT>(\n c: RationalCubicCurve2d<XT, YT>,\n): RationalCubicCurve2d<XT, YT & Decreasing> =>\n isDecreasingY(c) ? c : fail('rational cubic curve is not decreasing in y')\n\n/** @internal */\nexport const asMonotonic = <XT, YT>(\n c: RationalCubicCurve2d<XT, YT>,\n): RationalCubicCurve2d<XT & Monotonic, YT & Monotonic> =>\n isMonotonic(c) ? c : fail('rational cubic curve is not monotonic in both axes')\n\n/** @internal */\nexport const asIncreasing = <XT, YT>(\n c: RationalCubicCurve2d<XT, YT>,\n): RationalCubicCurve2d<XT & Increasing, YT & Increasing> =>\n isIncreasing(c) ? c : fail('rational cubic curve is not increasing in both axes')\n\n/** @internal */\nexport const asDecreasing = <XT, YT>(\n c: RationalCubicCurve2d<XT, YT>,\n): RationalCubicCurve2d<XT & Decreasing, YT & Decreasing> =>\n isDecreasing(c) ? c : fail('rational cubic curve is not decreasing in both axes')\n\n// Affine transform on a rational curve. R(s) = (X(s)/W(s), Y(s)/W(s)), so\n// f(R(s)) = A · (X/W, Y/W) + t\n// = ((A · (X, Y) + t · W) / W)\n// The denominator W is unchanged; each numerator pulls in a translation term\n// weighted by W per-coefficient. Unlike the polynomial case, t·W contributes\n// to every coefficient, not just c0.\n/** @internal */\nexport const transform = dual<\n (a: Affine2d.Affine2d) => (c: RationalCubicCurve2d) => RationalCubicCurve2d,\n (c: RationalCubicCurve2d, a: Affine2d.Affine2d) => RationalCubicCurve2d\n>(2, (c: RationalCubicCurve2d, a: Affine2d.Affine2d) => {\n const m = a.matrix\n return new RationalCubicCurve2dImpl(\n CubicPolynomial.make(\n m.m00 * c.x.c0 + m.m01 * c.y.c0 + m.m02 * c.w.c0,\n m.m00 * c.x.c1 + m.m01 * c.y.c1 + m.m02 * c.w.c1,\n m.m00 * c.x.c2 + m.m01 * c.y.c2 + m.m02 * c.w.c2,\n m.m00 * c.x.c3 + m.m01 * c.y.c3 + m.m02 * c.w.c3,\n ),\n CubicPolynomial.make(\n m.m10 * c.x.c0 + m.m11 * c.y.c0 + m.m12 * c.w.c0,\n m.m10 * c.x.c1 + m.m11 * c.y.c1 + m.m12 * c.w.c1,\n m.m10 * c.x.c2 + m.m11 * c.y.c2 + m.m12 * c.w.c2,\n m.m10 * c.x.c3 + m.m11 * c.y.c3 + m.m12 * c.w.c3,\n ),\n c.w,\n )\n})\n\n// Depth cap for tight bounding box recursion. 2²⁰ ≈ 1M leaves is well past\n// the point where any geometrically meaningful tolerance would still be\n// driving subdivision — the cap is here to guard against tolerances\n// approaching zero.\nconst MAX_BBOX_DEPTH = 20\n\n/** @internal */\nexport const boundingBox = dual<\n (\n tolerance: number,\n ) => (c: RationalCubicCurve2d) => Interval2d.Interval2d<Interval.Closed, Interval.Closed>,\n (\n c: RationalCubicCurve2d,\n tolerance: number,\n ) => Interval2d.Interval2d<Interval.Closed, Interval.Closed>\n>(2, (c: RationalCubicCurve2d, tolerance: number) => {\n invariant(\n Number.isFinite(tolerance) && tolerance > 0,\n 'boundingBox: tolerance must be finite and > 0',\n )\n\n // Polynomial fast path: when W(t) is a constant (all weights equal at the\n // source), the curve coincides with a polynomial cubic and its tight box\n // is exact via the polynomial's per-axis range. No subdivision needed.\n if (c.w.c1 === 0 && c.w.c2 === 0 && c.w.c3 === 0) {\n const w = c.w.c0\n return Interval2d.make(\n CubicPolynomial.unitRange(\n CubicPolynomial.make(c.x.c0 / w, c.x.c1 / w, c.x.c2 / w, c.x.c3 / w),\n ),\n CubicPolynomial.unitRange(\n CubicPolynomial.make(c.y.c0 / w, c.y.c1 / w, c.y.c2 / w, c.y.c3 / w),\n ),\n )\n }\n\n // Per-segment recursion: union of leaf-segment hull AABBs, subdividing until\n // each leaf's hull is within `tolerance` per side of an inner reference that\n // is known to lie inside the curve's true range.\n //\n // The reference is the segment's endpoint AABB: `r(0)` and `r(1)` both lie\n // on the curve and therefore inside its true bounding box. So\n // endpointBox ⊆ trueBox ⊆ hullBox\n // and the gap `hullBox − endpointBox` (per side) upper-bounds the gap\n // `hullBox − trueBox`. When that gap is ≤ tolerance on every side, the\n // leaf's hull box is provably within tolerance of its true range; the\n // union of all leaves is then within tolerance of the curve's tight box.\n const recurse = (\n curr: RationalCubicCurve2d,\n depth: number,\n ): Interval2d.Interval2d<Interval.Closed, Interval.Closed> => {\n const hull = hullBoundingBox(curr)\n\n const w0 = curr.w.c0\n const x0 = curr.x.c0 / w0\n const y0 = curr.y.c0 / w0\n const w1 = curr.w.c0 + curr.w.c1 + curr.w.c2 + curr.w.c3\n const x1 = (curr.x.c0 + curr.x.c1 + curr.x.c2 + curr.x.c3) / w1\n const y1 = (curr.y.c0 + curr.y.c1 + curr.y.c2 + curr.y.c3) / w1\n\n const lowX = Math.min(x0, x1)\n const highX = Math.max(x0, x1)\n const lowY = Math.min(y0, y1)\n const highY = Math.max(y0, y1)\n\n const excess = Math.max(\n lowX - hull.x.start,\n hull.x.end - highX,\n lowY - hull.y.start,\n hull.y.end - highY,\n )\n\n if (excess <= tolerance || depth >= MAX_BBOX_DEPTH) {\n return hull\n }\n\n const [left, right] = subdivide(curr, 0.5)\n return Interval2d.union(recurse(left, depth + 1), recurse(right, depth + 1))\n }\n\n return recurse(c, 0)\n})\n\n// Approximation cap. At depth 20 we'd emit up to 2²⁰ ≈ 1M segments for one\n// input curve — well past any sane target — so the cap is really just a guard\n// against pathological tolerances (e.g. tolerance approaching 0).\nconst MAX_APPROX_DEPTH = 20\n\n// Builds the polynomial-cubic candidate for one rational segment by:\n// 1. Inverting Bernstein → monomial on each of x, y, w to recover the four\n// homogeneous Bézier control points (Xᵢ, Yᵢ, Wᵢ).\n// 2. Projecting each CP back to 2D as (Xᵢ/Wᵢ, Yᵢ/Wᵢ).\n// 3. Lifting those 2D CPs back to a polynomial cubic via fromBezierPoints.\n// The result matches the rational at t=0 and t=1 exactly and matches endpoint\n// tangent directions, but interior shape diverges whenever the weights are\n// not all equal.\nconst buildCubicCandidate = (c: RationalCubicCurve2d): CubicCurve2d.CubicCurve2d => {\n const x0 = c.x.c0\n const x1 = c.x.c0 + c.x.c1 / 3\n const x2 = c.x.c0 + (2 * c.x.c1) / 3 + c.x.c2 / 3\n const x3 = c.x.c0 + c.x.c1 + c.x.c2 + c.x.c3\n\n const y0 = c.y.c0\n const y1 = c.y.c0 + c.y.c1 / 3\n const y2 = c.y.c0 + (2 * c.y.c1) / 3 + c.y.c2 / 3\n const y3 = c.y.c0 + c.y.c1 + c.y.c2 + c.y.c3\n\n const w0 = c.w.c0\n const w1 = c.w.c0 + c.w.c1 / 3\n const w2 = c.w.c0 + (2 * c.w.c1) / 3 + c.w.c2 / 3\n const w3 = c.w.c0 + c.w.c1 + c.w.c2 + c.w.c3\n\n return CubicCurve2d.fromBezierPoints(\n Vector2.make(x0 / w0, y0 / w0),\n Vector2.make(x1 / w1, y1 / w1),\n Vector2.make(x2 / w2, y2 / w2),\n Vector2.make(x3 / w3, y3 / w3),\n )\n}\n\n// Splits a rational cubic at parameter `t ∈ (0, 1)` by applying\n// `CubicPolynomial.subdivide` independently to each of x, y, w. Equivalent to\n// de Casteljau on the homogeneous control polygon but stays in monomial form\n// throughout, so no Bernstein round-trip is required.\n/** @internal */\nexport const subdivide = dual<\n (t: number) => (c: RationalCubicCurve2d) => [RationalCubicCurve2d, RationalCubicCurve2d],\n (c: RationalCubicCurve2d, t: number) => [RationalCubicCurve2d, RationalCubicCurve2d]\n>(2, (c: RationalCubicCurve2d, t: number) => {\n const [leftX, rightX] = CubicPolynomial.subdivide(c.x, t)\n const [leftY, rightY] = CubicPolynomial.subdivide(c.y, t)\n const [leftW, rightW] = CubicPolynomial.subdivide(c.w, t)\n\n return [\n new RationalCubicCurve2dImpl(leftX, leftY, leftW),\n new RationalCubicCurve2dImpl(rightX, rightY, rightW),\n ]\n})\n\n// Loose hull-based bounding box from the rational's projected Bézier control\n// polygon. Private leaf helper for the subdivision-based public `boundingBox`\n// and for the Hausdorff machinery in `approximateAsCubicCurves`.\n//\n// Rational Bézier curves with positive weights satisfy the projected\n// convex-hull property: the curve lies inside the convex hull of the four\n// projected 2D control points (Wᵢ⁻¹·Xᵢ, Wᵢ⁻¹·Yᵢ). Their AABB is a strict\n// superset of the hull, so it is a valid (and cheap) bound on the curve.\n//\n// Looser than the public tight box — for that we'd need the extrema of\n// x(t)/w(t) and y(t)/w(t), each a degree-5 root problem — but tight enough\n// for subdivision-based geometric queries, which compensate via depth.\nconst hullBoundingBox = (\n c: RationalCubicCurve2d,\n): Interval2d.Interval2d<Interval.Closed, Interval.Closed> => {\n // Bernstein control points recovered from monomial coefficients — same\n // inversion as `buildCubicCandidate`.\n const x0 = c.x.c0\n const x1 = c.x.c0 + c.x.c1 / 3\n const x2 = c.x.c0 + (2 * c.x.c1) / 3 + c.x.c2 / 3\n const x3 = c.x.c0 + c.x.c1 + c.x.c2 + c.x.c3\n\n const y0 = c.y.c0\n const y1 = c.y.c0 + c.y.c1 / 3\n const y2 = c.y.c0 + (2 * c.y.c1) / 3 + c.y.c2 / 3\n const y3 = c.y.c0 + c.y.c1 + c.y.c2 + c.y.c3\n\n const w0 = c.w.c0\n const w1 = c.w.c0 + c.w.c1 / 3\n const w2 = c.w.c0 + (2 * c.w.c1) / 3 + c.w.c2 / 3\n const w3 = c.w.c0 + c.w.c1 + c.w.c2 + c.w.c3\n\n return Interval2d.fromVectors(\n Vector2.make(x0 / w0, y0 / w0),\n Vector2.make(x1 / w1, y1 / w1),\n Vector2.make(x2 / w2, y2 / w2),\n Vector2.make(x3 / w3, y3 / w3),\n )\n}\n\n// Certified Hausdorff-within-tolerance check between a rational and a\n// candidate polynomial cubic.\n//\n// `approximateAsCubicCurves` uses this as the stopping criterion: when it\n// returns `true`, every point on the rational is provably within `tolerance`\n// of the candidate, and every point on the candidate is within `tolerance` of\n// the rational. When `false`, the rational is subdivided and the procedure\n// recurses.\n//\n// Implementation: for each direction (rational → candidate, candidate →\n// rational), run a depth-first subdivision on the source side. At each\n// piece, compute\n//\n// lower = dist(witness-on-piece, target)\n// upper = min(\n// lower + maxDist(witness, piece.box), // triangle inequality bound\n// maxDist(piece.box, target.box), // box-pair bound\n// )\n//\n// Both upper bounds are provable; their min is too. The triangle bound\n// shrinks proportionally to source box diameter, so it dominates when source\n// and target overlap (which they usually do here — the candidate matches the\n// rational at endpoints and tangents). Early-terminate on the first piece\n// whose `lower` exceeds `tolerance` (definitive miss) or accept whenever\n// every piece's `upper` ≤ tolerance.\n\nconst MAX_HAUSDORFF_DEPTH = 30\n\n// Coarse sample + bisection on the squared-distance derivative. Returns the\n// minimum squared distance from (qx, qy) to a parametric curve described by\n// `eval_`. Stationary points of (P(s) - q) · P'(s) are local extrema of\n// D²(s); 32 coarse samples reliably bracket the global min for cubic-degree\n// curves (which have at most ~5 critical points of squared distance).\nconst closestSquaredDistance = (\n eval_: (s: number) => { px: number; py: number; tx: number; ty: number },\n qx: number,\n qy: number,\n): number => {\n const coarseSamples = 32\n let sBest = 0\n let d2Best = Number.POSITIVE_INFINITY\n for (let i = 0; i <= coarseSamples; i++) {\n const s = i / coarseSamples\n const { px, py } = eval_(s)\n const dx = px - qx\n const dy = py - qy\n const d2 = dx * dx + dy * dy\n if (d2 < d2Best) {\n d2Best = d2\n sBest = s\n }\n }\n const step = 1 / coarseSamples\n let lo = Math.max(0, sBest - step)\n let hi = Math.min(1, sBest + step)\n const gradient = (s: number): number => {\n const { px, py, tx, ty } = eval_(s)\n return (px - qx) * tx + (py - qy) * ty\n }\n if (gradient(lo) > 0 || gradient(hi) < 0) {\n return d2Best\n }\n for (let i = 0; i < 40; i++) {\n const m = 0.5 * (lo + hi)\n if (gradient(m) > 0) {\n hi = m\n } else {\n lo = m\n }\n if (hi - lo < 1e-12) {\n break\n }\n }\n const s = 0.5 * (lo + hi)\n const { px, py } = eval_(s)\n const dx = px - qx\n const dy = py - qy\n const d2 = dx * dx + dy * dy\n return d2 < d2Best ? d2 : d2Best\n}\n\nconst polynomialEval = (c: CubicCurve2d.CubicCurve2d, s: number) => ({\n px: c.x.c0 + s * (c.x.c1 + s * (c.x.c2 + s * c.x.c3)),\n py: c.y.c0 + s * (c.y.c1 + s * (c.y.c2 + s * c.y.c3)),\n tx: c.x.c1 + s * (2 * c.x.c2 + s * 3 * c.x.c3),\n ty: c.y.c1 + s * (2 * c.y.c2 + s * 3 * c.y.c3),\n})\n\n// R(s) = (X(s)/W(s), Y(s)/W(s)) → R'(s) = ((X'W - XW')/W², (Y'W - YW')/W²)\nconst rationalEval = (c: RationalCubicCurve2d, s: number) => {\n const X = c.x.c0 + s * (c.x.c1 + s * (c.x.c2 + s * c.x.c3))\n const Y = c.y.c0 + s * (c.y.c1 + s * (c.y.c2 + s * c.y.c3))\n const W = c.w.c0 + s * (c.w.c1 + s * (c.w.c2 + s * c.w.c3))\n const Xp = c.x.c1 + s * (2 * c.x.c2 + s * 3 * c.x.c3)\n const Yp = c.y.c1 + s * (2 * c.y.c2 + s * 3 * c.y.c3)\n const Wp = c.w.c1 + s * (2 * c.w.c2 + s * 3 * c.w.c3)\n const w2 = W * W\n return {\n px: X / W,\n py: Y / W,\n tx: (Xp * W - X * Wp) / w2,\n ty: (Yp * W - Y * Wp) / w2,\n }\n}\n\nconst maxDistFromPointToBox = (px: number, py: number, box: Interval2d.Interval2d): number => {\n const xLo = Math.min(box.x.start, box.x.end)\n const xHi = Math.max(box.x.start, box.x.end)\n const yLo = Math.min(box.y.start, box.y.end)\n const yHi = Math.max(box.y.start, box.y.end)\n const dx = Math.max(px - xLo, xHi - px)\n const dy = Math.max(py - yLo, yHi - py)\n return Math.hypot(dx, dy)\n}\n\n// Subdivide a polynomial cubic curve at parameter t by subdividing each\n// per-axis polynomial independently — the polynomial split is exact and in\n// monomial form.\nconst subdividePolynomial = (\n c: CubicCurve2d.CubicCurve2d,\n t: number,\n): [CubicCurve2d.CubicCurve2d, CubicCurve2d.CubicCurve2d] => {\n const [leftX, rightX] = CubicPolynomial.subdivide(c.x, t)\n const [leftY, rightY] = CubicPolynomial.subdivide(c.y, t)\n return [CubicCurve2d.fromPolynomials(leftX, leftY), CubicCurve2d.fromPolynomials(rightX, rightY)]\n}\n\ninterface CertifiedPiece {\n box: Interval2d.Interval2d\n witnessX: number\n witnessY: number\n depth: number\n subdivide(): [CertifiedPiece, CertifiedPiece]\n}\n\nconst rationalPiece = (c: RationalCubicCurve2d, depth = 0): CertifiedPiece => {\n const wMid = CubicPolynomial.solve(c.w, 0.5)\n const witnessX = CubicPolynomial.solve(c.x, 0.5) / wMid\n const witnessY = CubicPolynomial.solve(c.y, 0.5) / wMid\n return {\n box: hullBoundingBox(c),\n witnessX,\n witnessY,\n depth,\n subdivide: () => {\n const [left, right] = subdivide(c, 0.5)\n return [rationalPiece(left, depth + 1), rationalPiece(right, depth + 1)]\n },\n }\n}\n\nconst polynomialPiece = (c: CubicCurve2d.CubicCurve2d, depth = 0): CertifiedPiece => {\n const witnessX = CubicPolynomial.solve(c.x, 0.5)\n const witnessY = CubicPolynomial.solve(c.y, 0.5)\n return {\n box: CubicCurve2d.boundingBox(c),\n witnessX,\n witnessY,\n depth,\n subdivide: () => {\n const [left, right] = subdividePolynomial(c, 0.5)\n return [polynomialPiece(left, depth + 1), polynomialPiece(right, depth + 1)]\n },\n }\n}\n\nconst oneSidedWithinTolerance = (\n initialPiece: CertifiedPiece,\n targetBox: Interval2d.Interval2d,\n targetClosestSquared: (qx: number, qy: number) => number,\n tolerance: number,\n): boolean => {\n const tol2 = tolerance * tolerance\n const stack: Array<CertifiedPiece> = [initialPiece]\n while (stack.length > 0) {\n const piece = stack.pop() as CertifiedPiece\n const lower2 = targetClosestSquared(piece.witnessX, piece.witnessY)\n if (lower2 > tol2) {\n return false\n }\n const lower = Math.sqrt(lower2)\n const triangleUpper = lower + maxDistFromPointToBox(piece.witnessX, piece.witnessY, piece.box)\n const boxPairUpper = Interval2d.maxDistance(piece.box, targetBox)\n const upper = triangleUpper < boxPairUpper ? triangleUpper : boxPairUpper\n if (upper <= tolerance) {\n continue\n }\n if (piece.depth >= MAX_HAUSDORFF_DEPTH) {\n return false\n }\n const [left, right] = piece.subdivide()\n stack.push(left, right)\n }\n return true\n}\n\nconst hausdorffWithinTolerance = (\n rational: RationalCubicCurve2d,\n candidate: CubicCurve2d.CubicCurve2d,\n tolerance: number,\n): boolean => {\n // Algebraic fast path: when the denominator polynomial is constant — every\n // weighted Bézier control point shares the same weight, so the rational\n // reduces to a polynomial cubic — `buildCubicCandidate` is exact. The\n // Bernstein → monomial transform produces exact zero higher coefficients\n // for a uniform input (integer cancellation), and `CubicPolynomial.subdivide`\n // preserves constants, so this check holds at every recursion depth.\n //\n // Without this fast path the subdivision Hausdorff would take ~30 levels\n // to certify the coincident-curve case at sub-pixel tolerances, even\n // though the answer is exactly zero.\n if (rational.w.c1 === 0 && rational.w.c2 === 0 && rational.w.c3 === 0) {\n return true\n }\n\n const candidateBox = CubicCurve2d.boundingBox(candidate)\n if (\n !oneSidedWithinTolerance(\n rationalPiece(rational),\n candidateBox,\n (qx, qy) => closestSquaredDistance((s) => polynomialEval(candidate, s), qx, qy),\n tolerance,\n )\n ) {\n return false\n }\n const rationalBox = hullBoundingBox(rational)\n return oneSidedWithinTolerance(\n polynomialPiece(candidate),\n rationalBox,\n (qx, qy) => closestSquaredDistance((s) => rationalEval(rational, s), qx, qy),\n tolerance,\n )\n}\n\n/** @internal */\nexport const approximateAsCubicCurves = dual<\n (tolerance: number) => (c: RationalCubicCurve2d) => ReadonlyArray<CubicCurve2d.CubicCurve2d>,\n (c: RationalCubicCurve2d, tolerance: number) => ReadonlyArray<CubicCurve2d.CubicCurve2d>\n>(2, (c: RationalCubicCurve2d, tolerance: number) => {\n invariant(\n Number.isFinite(tolerance) && tolerance > 0,\n 'approximateAsCubicCurves: tolerance must be finite and > 0',\n )\n\n const out: Array<CubicCurve2d.CubicCurve2d> = []\n const recurse = (curr: RationalCubicCurve2d, depth: number): void => {\n const candidate = buildCubicCandidate(curr)\n if (depth >= MAX_APPROX_DEPTH || hausdorffWithinTolerance(curr, candidate, tolerance)) {\n out.push(candidate)\n return\n }\n const [left, right] = subdivide(curr, 0.5)\n recurse(left, depth + 1)\n recurse(right, depth + 1)\n }\n recurse(c, 0)\n return out\n})\n","import type { Closed } from '../interval/interval.ts'\nimport type { Interval2d } from '../interval/interval2d.ts'\nimport type { Monotonicity } from '../monotonicity/monotonicity.ts'\nimport type { Pipeable } from '../utils.ts'\nimport type { CubicPolynomial } from '../polynomial/cubic.ts'\nimport type { Decreasing, Increasing, Monotonic } from '../polynomial/traits.ts'\nimport type * as Solution from '../solution/solution.ts'\nimport type { Affine2d } from '../transform/affine2d.ts'\nimport type { Vector2, Weighted } from '../vector/vector2.ts'\nimport type { CubicCurve2d } from './cubic2d.ts'\nimport type { RationalCubicCurve2dTypeId, RationalCurveTraits } from './rationalCubic2d.internal.ts'\nimport * as internal from './rationalCubic2d.internal.ts'\n\nexport type { Decreasing, Increasing, Monotonic } from '../polynomial/traits.ts'\nexport { RationalCurveTraits } from './rationalCubic2d.internal.ts'\n\n/**\n * A rational cubic curve in 2D space.\n *\n * Represented as three cubic polynomials in the parameter `t`: per-axis\n * numerators `x`, `y`, and a shared denominator `w`. Evaluation is\n * `(x(t)/w(t), y(t)/w(t))` — the projection from homogeneous coordinates\n * back to the plane. With all weights equal at the source (e.g. produced\n * from a non-rational Bézier with unit weights), `w` is constant and the\n * curve coincides with a polynomial cubic.\n *\n * The two type parameters carry per-axis monotonicity trait brands attached\n * to the rational functions `x(t)/w(t)` and `y(t)/w(t)`. Unlike\n * `CubicCurve2d`, traits do not flow through to the underlying polynomials —\n * monotonicity of a ratio of cubics is not the same property as monotonicity\n * of either cubic alone, so the brand lives on the curve itself. Brands are\n * attached after construction via the {@link asMonotonic}, {@link asIncreasing},\n * and {@link asDecreasing} families, which verify the property rigorously\n * (Bernstein sign convexity on the derivative-numerator quartic).\n *\n * All fields are readonly and immutable, and all operations create new instances.\n *\n * @since 2.0.0\n */\nexport interface RationalCubicCurve2d<\n out XTraits = unknown,\n out YTraits = unknown,\n> extends Pipeable {\n readonly [RationalCubicCurve2dTypeId]: RationalCubicCurve2dTypeId\n readonly [RationalCurveTraits]: [XTraits, YTraits]\n readonly x: CubicPolynomial\n readonly y: CubicPolynomial\n readonly w: CubicPolynomial\n}\n\n/**\n * Checks if a value is a `RationalCubicCurve2d`.\n *\n * @param c - The value to check.\n * @returns `true` if the value is a `RationalCubicCurve2d`, `false` otherwise.\n * @since 2.0.0\n */\nexport const isRationalCubicCurve2d: (c: unknown) => c is RationalCubicCurve2d =\n internal.isRationalCubicCurve2d\n\n/**\n * Creates a new `RationalCubicCurve2d` from per-axis numerator polynomials\n * and a shared denominator polynomial.\n *\n * @param x - The x numerator polynomial.\n * @param y - The y numerator polynomial.\n * @param w - The shared denominator polynomial (must be non-zero on `[0, 1]`).\n * @returns A new `RationalCubicCurve2d` instance.\n * @since 2.0.0\n */\nexport const fromPolynomials: (\n x: CubicPolynomial,\n y: CubicPolynomial,\n w: CubicPolynomial,\n) => RationalCubicCurve2d = internal.fromPolynomials\n\nexport const fromBezierPoints: {\n /**\n * Creates a new `RationalCubicCurve2d` from four weighted cubic Bézier\n * control points. The four control points are lifted to homogeneous form\n * `(w·x, w·y, w)` and the cubic Bernstein basis is expanded into per-channel\n * monomial coefficients, yielding the curve's `x`, `y`, and `w` polynomials.\n *\n * @param p0 - The first weighted control point (curve start).\n * @param p1 - The second weighted control point (start handle).\n * @param p2 - The third weighted control point (end handle).\n * @param p3 - The fourth weighted control point (curve end).\n * @returns A new `RationalCubicCurve2d` instance.\n * @since 2.0.0\n */\n (p0: Weighted, p1: Weighted, p2: Weighted, p3: Weighted): RationalCubicCurve2d\n /**\n * Creates a new `RationalCubicCurve2d` from two interior weighted Bézier\n * handles, with endpoints pinned at `(0, 0, w=1)` and `(1, 1, w=1)`.\n *\n * Rational analog of CSS's `cubic-bezier(x1, y1, x2, y2)`: same fixed\n * endpoints, same two interior handles, plus per-handle weights for true\n * rational shapes (the polynomial case is recovered with unit weights).\n * The curve interpolates `(0, 0)` at `t = 0` and `(1, 1)` at `t = 1`.\n *\n * @param p1 - The second weighted control point (start handle).\n * @param p2 - The third weighted control point (end handle).\n * @returns A new `RationalCubicCurve2d` instance with pinned endpoints.\n * @since 2.0.0\n */\n (p1: Weighted, p2: Weighted): RationalCubicCurve2d\n} = internal.fromBezierPoints\n\n/**\n * Creates a rational cubic easing curve from endpoint slopes and signed\n * curvatures. The result interpolates `(0, 0)` and `(1, 1)` with `x(t) = t`\n * pinned linearly; the y-axis projection `y(t) = Y(t)/W(t)` uses a cubic\n * numerator over a quadratic denominator, giving six free parameters that\n * exactly match the six endpoint constraints (two values, two slopes, two\n * curvatures).\n *\n * Curvatures are the signed differential-geometric curvatures `κ = y''(x) /\n * (1 + y'(x)²)^(3/2)` — the parameterization-invariant \"bend\" of the easing\n * graph. Positive κ is concave-up. Smoothstep is `(0, 0, 6, -6)`; linear is\n * `(1, 1, 0, 0)` (taken as a redundant-system special case).\n *\n * Monotonicity is not enforced. Callers needing the `Increasing` brand for\n * narrowed inverse-solve returns should follow construction with\n * {@link asIncreasing}, which verifies monotonicity rigorously.\n *\n * @param startSlope - The easing function's slope at the start (`dy/dx` at `x = 0`).\n * @param endSlope - The easing function's slope at the end (`dy/dx` at `x = 1`).\n * @param startCurvature - The signed differential curvature at the start.\n * @param endCurvature - The signed differential curvature at the end.\n * @returns A rational cubic easing curve.\n * @throws When inputs are non-finite, the constraint system is singular, or the resulting denominator vanishes on `[0, 1]`.\n * @since 2.0.0\n */\nexport const fromSlopesAndCurvatures: (\n startSlope: number,\n endSlope: number,\n startCurvature: number,\n endCurvature: number,\n) => RationalCubicCurve2d = internal.fromSlopesAndCurvatures\n\nexport const solve: {\n /**\n * Evaluates the rational cubic curve at parameter `t`. Returns\n * `(x(t)/w(t), y(t)/w(t))` — three Horner evaluations and two divisions.\n *\n * @param c - The curve to evaluate.\n * @param t - The parameter value.\n * @returns The point on the curve at parameter `t`.\n * @since 2.0.0\n */\n (c: RationalCubicCurve2d, t: number): Vector2\n /**\n * Evaluates the rational cubic curve at parameter `t`.\n *\n * @param t - The parameter value.\n * @returns A function that takes a curve and returns the point at `t`.\n * @since 2.0.0\n */\n (t: number): (c: RationalCubicCurve2d) => Vector2\n} = internal.solve\n\n/**\n * Evaluates the curve at `t = 0` in closed form — `(c.x.c0 / c.w.c0, c.y.c0 / c.w.c0)`.\n *\n * @param c - The rational cubic curve.\n * @returns The point at the start of the curve's parameter domain.\n * @since 2.0.0\n */\nexport const startPoint: (c: RationalCubicCurve2d) => Vector2 = internal.startPoint\n\n/**\n * Evaluates the curve at `t = 1` in closed form. Both numerator and denominator\n * Horner evaluations at `t = 1` collapse to the sum of their monomial\n * coefficients, so the projection is `(Σxᵢ / Σwᵢ, Σyᵢ / Σwᵢ)`.\n *\n * @param c - The rational cubic curve.\n * @returns The point at the end of the curve's parameter domain.\n * @since 2.0.0\n */\nexport const endPoint: (c: RationalCubicCurve2d) => Vector2 = internal.endPoint\n\nexport const solveAtX: {\n /**\n * Evaluates the curve's y values at a given x. Because the curve's x axis\n * carries the `Monotonic` brand, the inverse has at most one solution.\n *\n * @param c - The rational cubic curve with monotonic x.\n * @param x - The x coordinate.\n * @returns Zero or one y values.\n * @since 2.0.0\n */\n <XT extends Monotonic, YT>(c: RationalCubicCurve2d<XT, YT>, x: number): Solution.AtMostOne<number>\n /**\n * Evaluates the curve's y values at a given x. Up to three solutions —\n * `(X(t) - x·W(t))` is a cubic polynomial in `t`.\n *\n * @param c - The rational cubic curve.\n * @param x - The x coordinate.\n * @returns The y values at x, in t-ascending order.\n * @since 2.0.0\n */\n <XT, YT>(c: RationalCubicCurve2d<XT, YT>, x: number): Solution.AtMostThree<number>\n /** @since 2.0.0 */\n (x: number): {\n <XT extends Monotonic, YT>(c: RationalCubicCurve2d<XT, YT>): Solution.AtMostOne<number>\n <XT, YT>(c: RationalCubicCurve2d<XT, YT>): Solution.AtMostThree<number>\n }\n} = internal.solveAtX as never\n\nexport const solveAtY: {\n /**\n * Evaluates the curve's x values at a given y. Because the curve's y axis\n * carries the `Monotonic` brand, the inverse has at most one solution.\n *\n * @param c - The rational cubic curve with monotonic y.\n * @param y - The y coordinate.\n * @returns Zero or one x values.\n * @since 2.0.0\n */\n <XT, YT extends Monotonic>(c: RationalCubicCurve2d<XT, YT>, y: number): Solution.AtMostOne<number>\n /**\n * Evaluates the curve's x values at a given y. Up to three solutions.\n *\n * @param c - The rational cubic curve.\n * @param y - The y coordinate.\n * @returns The x values at y, in t-ascending order.\n * @since 2.0.0\n */\n <XT, YT>(c: RationalCubicCurve2d<XT, YT>, y: number): Solution.AtMostThree<number>\n /** @since 2.0.0 */\n (y: number): {\n <XT, YT extends Monotonic>(c: RationalCubicCurve2d<XT, YT>): Solution.AtMostOne<number>\n <XT, YT>(c: RationalCubicCurve2d<XT, YT>): Solution.AtMostThree<number>\n }\n} = internal.solveAtY as never\n\nexport const subdivide: {\n /**\n * Subdivides a rational cubic curve at parameter `t ∈ (0, 1)` into two new\n * rational cubic curves. The first curve's evaluation on `[0, 1]` matches\n * the original's on `[0, t]`; the second matches the original's on `[t, 1]`.\n * Equivalent to de Casteljau subdivision on the homogeneous control polygon,\n * but performed directly on the per-axis monomial polynomials.\n *\n * @param c - The rational cubic curve to subdivide.\n * @param t - The split parameter; must be in the open interval `(0, 1)`.\n * @returns A `[left, right]` tuple of rational cubic curves.\n * @since 2.0.0\n */\n (c: RationalCubicCurve2d, t: number): [RationalCubicCurve2d, RationalCubicCurve2d]\n /**\n * Subdivides a rational cubic curve at parameter `t ∈ (0, 1)`.\n *\n * @param t - The split parameter; must be in the open interval `(0, 1)`.\n * @returns A function that takes a curve and returns its `[left, right]` halves.\n * @since 2.0.0\n */\n (t: number): (c: RationalCubicCurve2d) => [RationalCubicCurve2d, RationalCubicCurve2d]\n} = internal.subdivide\n\nexport const boundingBox: {\n /**\n * Computes a closed axis-aligned bounding box for a rational cubic curve,\n * tight to within `tolerance` per side.\n *\n * Implemented as recursive subdivision: at each leaf the curve segment's\n * loose hull AABB (cheap, always valid) is compared against the segment's\n * endpoint AABB (which the curve provably visits). When the per-side gap\n * between them is ≤ `tolerance`, the leaf returns its hull; otherwise the\n * segment is split at `t = 0.5` and the procedure recurses, unioning the\n * halves.\n *\n * The returned box is provably within `tolerance` of the true tight box on\n * every side, and contains the curve since each leaf hull does. The\n * polynomial cubic case (uniform weights) is handled by a fast path that\n * computes the exact box from per-axis cubic extrema, with no subdivision.\n *\n * @param c - The rational cubic curve.\n * @param tolerance - Maximum allowed slack per side; must be positive.\n * @returns A closed `Interval2d` enclosing the curve, tight to within `tolerance`.\n * @since 2.0.0\n */\n (c: RationalCubicCurve2d, tolerance: number): Interval2d<Closed, Closed>\n /**\n * Computes a closed axis-aligned bounding box for a rational cubic curve.\n *\n * @param tolerance - Maximum allowed slack per side; must be positive.\n * @returns A function that takes a curve and returns its bounding box.\n * @since 2.0.0\n */\n (tolerance: number): (c: RationalCubicCurve2d) => Interval2d<Closed, Closed>\n} = internal.boundingBox\n\n/**\n * Classifies the monotonicity of the curve's `x(t) = X(t)/W(t)` projection on\n * the unit interval `[0, 1]`.\n *\n * Decided via Bernstein sign convexity on the derivative-numerator polynomial\n * `q(t) = X'·W − X·W'`. Since `W² > 0` wherever the curve is well-defined,\n * the sign of `dx/dt` equals the sign of `q`. Although `q` is a difference of\n * degree-5 products, the leading terms cancel and `q` is in fact a quartic —\n * its 5 Bernstein coefficients on `[0, 1]` are evaluated for uniform sign,\n * with de Casteljau subdivision to resolve mixed-sign cases. The procedure is\n * exact except at tangential zeros, where it conservatively reports `None`.\n *\n * Returning `Increasing` or `Decreasing` is the trigger for\n * {@link asMonotonic} / {@link asIncreasing} / {@link asDecreasing}.\n *\n * @param c - The rational cubic curve.\n * @returns The monotonicity of the curve's x projection on `[0, 1]`.\n * @since 2.0.0\n */\nexport const xMonotonicity: (c: RationalCubicCurve2d) => Monotonicity = internal.xMonotonicity\n\n/**\n * Classifies the monotonicity of the curve's `y(t) = Y(t)/W(t)` projection on\n * the unit interval `[0, 1]`. See {@link xMonotonicity} for the method.\n *\n * @param c - The rational cubic curve.\n * @returns The monotonicity of the curve's y projection on `[0, 1]`.\n * @since 2.0.0\n */\nexport const yMonotonicity: (c: RationalCubicCurve2d) => Monotonicity = internal.yMonotonicity\n\n/**\n * Type-narrowing predicate: refines the curve's x-axis trait to include\n * `Monotonic` when `x(t)/w(t)` is strictly monotonic on `[0, 1]`. The y-axis\n * trait is unchanged.\n *\n * Use this when only x-axis monotonicity is required (e.g. to make {@link solveAtX}\n * narrow to `AtMostOne` without also asserting y-axis monotonicity).\n *\n * @param c - The rational cubic curve.\n * @returns `true` when the x projection is strictly monotonic on `[0, 1]`.\n * @since 2.0.0\n */\nexport const isMonotonicX: <XT, YT>(\n c: RationalCubicCurve2d<XT, YT>,\n) => c is RationalCubicCurve2d<XT & Monotonic, YT> = internal.isMonotonicX\n\n/**\n * Type-narrowing predicate: refines the curve's x-axis trait to include\n * `Increasing`.\n *\n * @since 2.0.0\n */\nexport const isIncreasingX: <XT, YT>(\n c: RationalCubicCurve2d<XT, YT>,\n) => c is RationalCubicCurve2d<XT & Increasing, YT> = internal.isIncreasingX\n\n/**\n * Type-narrowing predicate: refines the curve's x-axis trait to include\n * `Decreasing`.\n *\n * @since 2.0.0\n */\nexport const isDecreasingX: <XT, YT>(\n c: RationalCubicCurve2d<XT, YT>,\n) => c is RationalCubicCurve2d<XT & Decreasing, YT> = internal.isDecreasingX\n\n/**\n * Type-narrowing predicate: refines the curve's y-axis trait to include\n * `Monotonic`. The x-axis trait is unchanged. y analog of {@link isMonotonicX}.\n *\n * @since 2.0.0\n */\nexport const isMonotonicY: <XT, YT>(\n c: RationalCubicCurve2d<XT, YT>,\n) => c is RationalCubicCurve2d<XT, YT & Monotonic> = internal.isMonotonicY\n\n/**\n * Type-narrowing predicate: refines the curve's y-axis trait to include\n * `Increasing`.\n *\n * @since 2.0.0\n */\nexport const isIncreasingY: <XT, YT>(\n c: RationalCubicCurve2d<XT, YT>,\n) => c is RationalCubicCurve2d<XT, YT & Increasing> = internal.isIncreasingY\n\n/**\n * Type-narrowing predicate: refines the curve's y-axis trait to include\n * `Decreasing`.\n *\n * @since 2.0.0\n */\nexport const isDecreasingY: <XT, YT>(\n c: RationalCubicCurve2d<XT, YT>,\n) => c is RationalCubicCurve2d<XT, YT & Decreasing> = internal.isDecreasingY\n\n/**\n * Type-narrowing predicate: refines both axes' traits to include `Monotonic`\n * when both `x(t)/w(t)` and `y(t)/w(t)` are strictly monotonic on `[0, 1]`.\n *\n * The constant case is excluded — `Monotonic` is the *strict* brand.\n *\n * @param c - The rational cubic curve.\n * @returns `true` when both axes are strictly monotonic on `[0, 1]`.\n * @since 2.0.0\n */\nexport const isMonotonic: <XT, YT>(\n c: RationalCubicCurve2d<XT, YT>,\n) => c is RationalCubicCurve2d<XT & Monotonic, YT & Monotonic> = internal.isMonotonic\n\n/**\n * Type-narrowing predicate: refines both axes' traits to include `Increasing`\n * when both `x(t)/w(t)` and `y(t)/w(t)` are strictly increasing on `[0, 1]`.\n *\n * @since 2.0.0\n */\nexport const isIncreasing: <XT, YT>(\n c: RationalCubicCurve2d<XT, YT>,\n) => c is RationalCubicCurve2d<XT & Increasing, YT & Increasing> = internal.isIncreasing\n\n/**\n * Type-narrowing predicate: refines both axes' traits to include `Decreasing`\n * when both `x(t)/w(t)` and `y(t)/w(t)` are strictly decreasing on `[0, 1]`.\n *\n * @since 2.0.0\n */\nexport const isDecreasing: <XT, YT>(\n c: RationalCubicCurve2d<XT, YT>,\n) => c is RationalCubicCurve2d<XT & Decreasing, YT & Decreasing> = internal.isDecreasing\n\n/**\n * Asserts that the curve is strictly monotonic in x on `[0, 1]`, returning\n * the same curve with the x-axis trait branded `Monotonic`.\n *\n * @param c - The rational cubic curve.\n * @returns The same curve, refined with the `Monotonic` brand on x.\n * @throws When the x projection is not strictly monotonic on `[0, 1]`.\n * @since 2.0.0\n */\nexport const asMonotonicX: <XT, YT>(\n c: RationalCubicCurve2d<XT, YT>,\n) => RationalCubicCurve2d<XT & Monotonic, YT> = internal.asMonotonicX\n\n/**\n * Asserts that the curve is strictly increasing in x on `[0, 1]`.\n *\n * @since 2.0.0\n */\nexport const asIncreasingX: <XT, YT>(\n c: RationalCubicCurve2d<XT, YT>,\n) => RationalCubicCurve2d<XT & Increasing, YT> = internal.asIncreasingX\n\n/**\n * Asserts that the curve is strictly decreasing in x on `[0, 1]`.\n *\n * @since 2.0.0\n */\nexport const asDecreasingX: <XT, YT>(\n c: RationalCubicCurve2d<XT, YT>,\n) => RationalCubicCurve2d<XT & Decreasing, YT> = internal.asDecreasingX\n\n/**\n * Asserts that the curve is strictly monotonic in y on `[0, 1]`. y analog of\n * {@link asMonotonicX}.\n *\n * @since 2.0.0\n */\nexport const asMonotonicY: <XT, YT>(\n c: RationalCubicCurve2d<XT, YT>,\n) => RationalCubicCurve2d<XT, YT & Monotonic> = internal.asMonotonicY\n\n/**\n * Asserts that the curve is strictly increasing in y on `[0, 1]`.\n *\n * @since 2.0.0\n */\nexport const asIncreasingY: <XT, YT>(\n c: RationalCubicCurve2d<XT, YT>,\n) => RationalCubicCurve2d<XT, YT & Increasing> = internal.asIncreasingY\n\n/**\n * Asserts that the curve is strictly decreasing in y on `[0, 1]`.\n *\n * @since 2.0.0\n */\nexport const asDecreasingY: <XT, YT>(\n c: RationalCubicCurve2d<XT, YT>,\n) => RationalCubicCurve2d<XT, YT & Decreasing> = internal.asDecreasingY\n\n/**\n * Asserts that the curve is strictly monotonic in both axes on `[0, 1]`,\n * returning the same curve with both axes branded `Monotonic`.\n *\n * @param c - The rational cubic curve.\n * @returns The same curve, refined with the `Monotonic` brand on both axes.\n * @throws When either axis is not strictly monotonic on `[0, 1]`.\n * @since 2.0.0\n */\nexport const asMonotonic: <XT, YT>(\n c: RationalCubicCurve2d<XT, YT>,\n) => RationalCubicCurve2d<XT & Monotonic, YT & Monotonic> = internal.asMonotonic\n\n/**\n * Asserts that the curve is strictly increasing in both axes on `[0, 1]`,\n * returning the same curve with both axes branded `Increasing`.\n *\n * @since 2.0.0\n */\nexport const asIncreasing: <XT, YT>(\n c: RationalCubicCurve2d<XT, YT>,\n) => RationalCubicCurve2d<XT & Increasing, YT & Increasing> = internal.asIncreasing\n\n/**\n * Asserts that the curve is strictly decreasing in both axes on `[0, 1]`,\n * returning the same curve with both axes branded `Decreasing`.\n *\n * @since 2.0.0\n */\nexport const asDecreasing: <XT, YT>(\n c: RationalCubicCurve2d<XT, YT>,\n) => RationalCubicCurve2d<XT & Decreasing, YT & Decreasing> = internal.asDecreasing\n\nexport const transform: {\n /**\n * Applies an `Affine2d` transform to a `RationalCubicCurve2d`, returning a\n * new curve whose image is the affine image of the original. The denominator\n * polynomial is preserved; each numerator pulls in a translation term\n * weighted by the denominator so the projected curve matches `A · R(s) + t`\n * pointwise.\n *\n * @param c - The rational cubic curve.\n * @param a - The affine transform.\n * @returns The transformed rational cubic curve.\n * @since 2.0.0\n */\n (c: RationalCubicCurve2d, a: Affine2d): RationalCubicCurve2d\n /**\n * Applies an `Affine2d` transform to a `RationalCubicCurve2d`.\n *\n * @param a - The affine transform.\n * @returns A function that takes a `RationalCubicCurve2d` and returns the transformed curve.\n * @since 2.0.0\n */\n (a: Affine2d): (c: RationalCubicCurve2d) => RationalCubicCurve2d\n} = internal.transform\n\nexport const approximateAsCubicCurves: {\n /**\n * Approximates the rational cubic as a sequence of polynomial cubic curves\n * via recursive subdivision. At each level a candidate polynomial cubic is\n * built by projecting the segment's homogeneous Bézier control points to\n * 2D; if the symmetric Hausdorff distance between the rational segment and\n * its candidate exceeds `tolerance` (verified via a certified subdivision\n * bound, not a single-point sample), the segment is split at `t = 0.5` and\n * the procedure recurses on each half. Returns a non-empty array; for a\n * curve that is already polynomial (uniform weights) the result is a\n * single exact segment.\n *\n * The Hausdorff guarantee means: every point on the rational lies within\n * `tolerance` of some output segment, and every point on the output lies\n * within `tolerance` of the rational — a true two-sided bound on geometric\n * deviation, not just a parametric error at one sample.\n *\n * @param c - The rational cubic curve to approximate.\n * @param tolerance - Maximum allowed Hausdorff distance; must be positive.\n * @returns A sequence of polynomial cubic curves covering the input.\n * @since 2.0.0\n */\n (c: RationalCubicCurve2d, tolerance: number): ReadonlyArray<CubicCurve2d>\n /**\n * Approximates the rational cubic as a sequence of polynomial cubic curves.\n *\n * @param tolerance - Maximum allowed Hausdorff distance; must be positive.\n * @returns A function that takes a curve and returns its polynomial approximation.\n * @since 2.0.0\n */\n (tolerance: number): (c: RationalCubicCurve2d) => ReadonlyArray<CubicCurve2d>\n} = internal.approximateAsCubicCurves\n"],"mappings":"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"}
|