Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix floating point accuracy issue in triangulation #81

Merged
merged 1 commit into from
Jan 25, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 30 additions & 7 deletions src/kernel/topology/faces.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,18 +108,41 @@ impl Face {
let outside = aabb.maxs * 2.;

triangles.retain(|triangle| {
for segment in triangle.edges() {
'outer: for segment in triangle.edges() {
let mut inverted_segment = segment;
inverted_segment.swap();

let triangle_segment_is_face_edge = face_as_polygon
.contains(&segment)
|| face_as_polygon.contains(&inverted_segment);

// If the segment is an edge of the face, we don't need
// to take a closer look.
if triangle_segment_is_face_edge {
continue;
//
// We can't use `contains` here, as that compares the
// segments directly, without taking floating point
// accuracy into account.
//
// This is not great. See this issue:
// https://github.com/hannobraun/Fornjot/issues/78
for s in &face_as_polygon {
// This epsilon value is small enough to not mistake
// different vertices as equal, for common use
// cases, while still being a few orders of
// magnitude larger than the differences between
// equal vertices that I've seen so far.
let eps = 1e-12;

let aa = (s.a - segment.a).magnitude();
let bb = (s.b - segment.b).magnitude();
let ab = (s.a - segment.b).magnitude();
let ba = (s.b - segment.a).magnitude();

let segment_is_face_edge = aa < eps && bb < eps;
let segment_is_inverted_face_edge =
ab < eps && ba < eps;

if segment_is_face_edge
|| segment_is_inverted_face_edge
{
continue 'outer;
}
}

// To determine if the edge is within the polygon, we
Expand Down