jsketcher/modules/geom/intersection/surfaceSurface.js
Val Erastov (xibyte) e11c1f7f4a geom module
2020-07-19 22:37:24 -07:00

78 lines
No EOL
2.4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import {NUMERICAL_SOLVE_TOL, TOLERANCE, TOLERANCE_01, TOLERANCE_SQ} from '../tolerance';
import {curveDomain, curvePoint, meshesIntersect, surfaceMaxDegree} from '../impl/nurbs-ext';
import {IntersectionCurve} from '../curves/intersectionCurve';
import * as vec from 'math/vec';
export function surfaceIntersect(surfaceA, surfaceB) {
const tessA = verb.eval.Tess.rationalSurfaceAdaptive(surfaceA);
const tessB = verb.eval.Tess.rationalSurfaceAdaptive(surfaceB);
function fixTessNaNPoitns(s, tess) {
for (let i = 0; i < tess.points.length; i++) {
let pt = tess.points[i];
if (Number.isNaN(pt[0]) || Number.isNaN(pt[1]) || Number.isNaN(pt[2])) {
let [u, v] = tess.uvs[i];
tess.points[i] = verb.eval.Eval.rationalSurfacePoint(s, u, v);
}
}
}
fixTessNaNPoitns(surfaceA, tessA);
fixTessNaNPoitns(surfaceB, tessB);
const resApprox = meshesIntersect(tessA, tessB, TOLERANCE, TOLERANCE_SQ, TOLERANCE_01);
const exactPls = resApprox.map(pl => pl.map(inter =>
verb.eval.Intersect.surfacesAtPointWithEstimate(surfaceA, surfaceB, inter.uv0, inter.uv1, NUMERICAL_SOLVE_TOL)
));
let curves = [];
for (let pl of exactPls) {
let points = pl.map(ip => ip.point);
points = removeSuperfluousPoints(points, 30*30); //5*5
// points.forEach(__DEBUG__.AddPoint3);
curves.push(new IntersectionCurve(points, surfaceA, surfaceB))
}
return curves;
}
//it's DouglasPeucker and it's not well suited here
function removeSuperfluousPoints(points, tolSq) {
let out = [];
let stack = [[0, points.length - 1]];
out.push(points[0]);
while (stack.length !== 0) {
let stackItem = stack.pop();
if (!Array.isArray(stackItem)) {
out.push(points[stackItem]);
continue;
}
let [from, to] = stackItem;
let maxDistSq = tolSq;
let hero = -1;
let v = vec._normalize(vec.sub(points[to], points[from]));
for (let i = from + 1; i < to; i ++) {
let proj = vec.dot(v, vec.sub(points[i], points[from]));
let vA = vec.add(points[from], vec.mul(v, proj));
let vX = vec.sub(points[i], vA);
let perpDistSq = vec.lengthSq(vX);
if (perpDistSq > maxDistSq) {
hero = i;
maxDistSq = perpDistSq;
}
}
if (hero !== -1) {
if (to - hero > 1) {
stack.push([hero, to]);
}
stack.push(hero);
if (hero - from > 1) {
stack.push([from, hero]);
}
}
}
out.push(points[points.length - 1]);
return out;
}