pub fn face_contains<S: Scalar>(
model: &Model<S>,
face_id: FaceId,
u: S,
v: S,
max_nodes: usize,
epsilon: S,
seed: u64,
) -> GeopResult<PointClassification>Expand description
Classify (u, v) against face_id’s trimmed boundary (outer loop minus
holes): PointClassification::OnVertex / PointClassification::OnCoedge
if the query point itself coincides with a vertex or lies on a coedge’s
pcurve, else PointClassification::Inside/PointClassification::Outside
via ray casting in parameter space.
The ray direction is drawn from a seeded PRNG (see Rng) and retried
(up to a bounded number of attempts) until every crossing it finds lands
strictly inside a coedge’s pcurve, away from any vertex — vertex grazes
are ambiguous to count (shared by two coedges) so they’re avoided rather
than specially classified. Once such a direction is found, the parity
(even/odd) of its crossing count determines inside/outside; this needs no
normal or winding-direction information, so it works regardless of a
face’s loop orientation.
max_nodes bounds both the curve_could_contain BFS subdivision search
(on-vertex/on-coedge tests) and the curve_curve_intersect DFS search
(edge-interior hits). seed seeds the direction PRNG.