mirror of
https://github.com/xibyte/jsketcher
synced 2025-12-15 21:05:22 +01:00
raycast for point inside face classification
This commit is contained in:
parent
fdfa0519df
commit
0b3939e977
1 changed files with 51 additions and 45 deletions
|
|
@ -2,8 +2,11 @@ import {TopoObject} from './topo-object'
|
|||
import {Loop} from './loop'
|
||||
import PIP from '../../3d/tess/pip';
|
||||
import {NurbsCurve} from "../geom/impl/nurbs";
|
||||
import {eqSqTol, veq} from "../geom/tolerance";
|
||||
import {isCurveEntersEdgeAtPoint, isCurveEntersEnclose} from "../operations/boolean";
|
||||
import {eqSqTol, veq, veqNeg} from "../geom/tolerance";
|
||||
import {
|
||||
ENCLOSE_CLASSIFICATION, isCurveEntersEdgeAtPoint, isCurveEntersEnclose, isInsideEnclose,
|
||||
isOnPositiveHalfPlaneFromVec
|
||||
} from "../operations/boolean";
|
||||
|
||||
export class Face extends TopoObject {
|
||||
|
||||
|
|
@ -50,22 +53,14 @@ export class Face extends TopoObject {
|
|||
}
|
||||
|
||||
rayCast(pt) {
|
||||
function vertexResult(vertex) {
|
||||
return {
|
||||
inside: true,
|
||||
strictInside: false,
|
||||
vertex
|
||||
}
|
||||
}
|
||||
let initVertex = this.getAnyVertex();
|
||||
if (veq(pt, initVertex.point)) {
|
||||
return vertexResult(initVertex);
|
||||
}
|
||||
let ray = NurbsCurve.createLinearNurbs(pt, initVertex.point);
|
||||
|
||||
for (let edge of this.edges) {
|
||||
if (veq(pt, edge.vertexA.point)) {
|
||||
return vertexResult(edge.vertexA);
|
||||
return {
|
||||
inside: true,
|
||||
strictInside: false,
|
||||
vertex: edge.vertexA
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -78,41 +73,52 @@ export class Face extends TopoObject {
|
|||
}
|
||||
}
|
||||
}
|
||||
let result = null;
|
||||
|
||||
for (let loop of this.loops) {
|
||||
for (let [a, b, v] of loop.encloses) {
|
||||
if (ray.passesThrough(v.point) || initVertex === v) {
|
||||
let dist = pt.distanceToSquared(v.point);
|
||||
if (result === null || dist < result.dist) {
|
||||
let inside = !isCurveEntersEnclose(ray, a, b, true);
|
||||
if (inside !== undefined) {
|
||||
result = {
|
||||
dist,
|
||||
inside,
|
||||
strictInside: inside,
|
||||
};
|
||||
}
|
||||
}
|
||||
function closestPointToEdge(edge) {
|
||||
return edge.edge.curve.point(edge.edge.curve.param(pt));
|
||||
}
|
||||
|
||||
let closest = null;
|
||||
for (let edge of this.edges) {
|
||||
let closestPoint = closestPointToEdge(edge);
|
||||
let dist = pt.distanceToSquared(closestPoint);
|
||||
if (closest === null || dist < closest.dist) {
|
||||
closest = {dist, pt: closestPoint, edge};
|
||||
}
|
||||
}
|
||||
let enclose = null;
|
||||
function findEnclosure(vertex) {
|
||||
for (let e of closest.edge.loop.encloses) {
|
||||
if (e[2] === vertex) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (veq(closest.pt, closest.edge.vertexA.point)) {
|
||||
enclose = findEnclosure(closest.edge.vertexA);
|
||||
} else if (veq(closest.pt, closest.edge.vertexB.point)) {
|
||||
enclose = findEnclosure(closest.edge.vertexB);
|
||||
}
|
||||
|
||||
for (let edge of this.edges) {
|
||||
let intersectionPoints = ray.intersectCurve(edge.edge.curve);
|
||||
for (let {p0: ip} of intersectionPoints) {
|
||||
let dist = pt.distanceToSquared(ip);
|
||||
if (result === null || (!eqSqTol(dist, result.dist) && dist < result.dist)) {
|
||||
let inside = !isCurveEntersEdgeAtPoint(ray, edge, ip);
|
||||
result = {
|
||||
dist,
|
||||
inside,
|
||||
strictInside: inside,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
let normal = this.surface.normal(closest.pt);
|
||||
let testee = (enclose ? enclose[2].point : closest.pt).minus(pt)._normalize();
|
||||
|
||||
// __DEBUG__.AddSegment(pt, enclose ? enclose[2].point : closest.pt);
|
||||
|
||||
let tangent;
|
||||
if (enclose !== null) {
|
||||
let [ea, eb] = enclose;
|
||||
tangent = ea.tangentAtEnd().plus(eb.tangentAtStart())._normalize();
|
||||
} else {
|
||||
tangent = closest.edge.tangent(closest.pt);
|
||||
}
|
||||
// __DEBUG__.AddNormal(closest.pt, tangent);
|
||||
|
||||
let inside = !isOnPositiveHalfPlaneFromVec(tangent, testee, normal);
|
||||
return {
|
||||
inside,
|
||||
strictInside: inside,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue