mirror of
https://github.com/xibyte/jsketcher
synced 2025-12-06 08:25:19 +01:00
58 lines
No EOL
1.3 KiB
JavaScript
58 lines
No EOL
1.3 KiB
JavaScript
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;
|
|
} |