import * as vec from "math/vec"; export default function curveTess(curve, min, max, tessTol, scale) { return curveTessParams(curve, min, max, tessTol, scale).map(u => curve.point(u)); } export function curveTessParams(curve, min, max, tessTol, scale) { const out = []; const knots = curve.knots(); const splits = [min]; for (const split of knots) { if (split > min && split < max) { splits.push(split); } } splits.push(max); function refine(u1, u2, step) { const uDist = u2 - u1; if (uDist < 1e-3) { return } if (step < uDist) { const mid = u1 + uDist * 0.5; refine(u1, mid, step); out.push(mid); refine(mid, u2, curveStep(curve, mid, tessTol, scale)); } } for (let i = 1; i < splits.length; ++i) { const u1 = splits[i - 1]; out.push(u1); refine(u1, splits[i], curveStep(curve, u1, tessTol, scale)); } out.push(max); return out; } export function curveStep(curve, u, tessTol, scale) { tessTol = tessTol || 1; scale = scale || 1; const ders = curve.eval(u, 2); const r1 = ders[1]; const r2 = ders[2]; const r1lsq = vec.lengthSq(r1); const r1l = Math.sqrt(r1lsq); const r = r1lsq * r1l / vec.length(vec.cross(r1, r2)); const tol = tessTol / scale; const step = 2 * Math.sqrt(tol*(2*r - tol)) / r1l; return step; }