Skip to content

Commit b95c60f

Browse files
committed
Avoid needless orientation checks / distance computations
If we are right of the edge, the distance is minimum over the edge... ...and that's it. Computing the distance to a segment is about as expensive as the orientation check, so no point pinpointing to check if the min is at a vertex.
1 parent 8b77c71 commit b95c60f

File tree

1 file changed

+22
-10
lines changed

1 file changed

+22
-10
lines changed

Distance_3/include/CGAL/Distance_3/Point_3_Triangle_3.h

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -64,26 +64,38 @@ squared_distance_to_triangle(const typename K::Point_3& pt,
6464
const Vector_3 oe3 = vector(t0, t2);
6565
const Vector_3 normal = wcross(e1, oe3, k);
6666

67-
if(normal != NULL_VECTOR &&
68-
on_left_of_triangle_edge(pt, normal, t0, t1, k) &&
69-
on_left_of_triangle_edge(pt, normal, t1, t2, k) &&
70-
on_left_of_triangle_edge(pt, normal, t2, t0, k))
71-
{
72-
// the projection of pt is inside the triangle
73-
inside = true;
74-
return squared_distance_to_plane(normal, vector(t0, pt), k);
75-
}
76-
else
67+
if(normal == NULL_VECTOR)
7768
{
7869
// The case normal == NULL_VECTOR covers the case when the triangle
7970
// is colinear, or even more degenerate. In that case, we can
8071
// simply take also the distance to the three segments.
72+
//
73+
// Note that in the degenerate case, at most 2 edges cover the full triangle,
74+
// and only two distances could be used, but leaving 3 for the case of
75+
// inexact constructions as it might improve the accuracy.
76+
8177
typename K::FT d1 = internal::squared_distance(pt, segment(t2, t0), k);
8278
typename K::FT d2 = internal::squared_distance(pt, segment(t1, t2), k);
8379
typename K::FT d3 = internal::squared_distance(pt, segment(t0, t1), k);
8480

8581
return (std::min)( (std::min)(d1, d2), d3);
8682
}
83+
84+
const bool b01 = on_left_of_triangle_edge(pt, normal, t0, t1, k);
85+
if(!b01)
86+
return internal::squared_distance(pt, segment(t0, t1), k);
87+
88+
const bool b12 = on_left_of_triangle_edge(pt, normal, t1, t2, k);
89+
if(!b12)
90+
return internal::squared_distance(pt, segment(t1, t2), k);
91+
92+
const bool b20 = on_left_of_triangle_edge(pt, normal, t2, t0, k);
93+
if(!b20)
94+
return internal::squared_distance(pt, segment(t2, t0), k);
95+
96+
// The projection of pt is inside the triangle
97+
inside = true;
98+
return squared_distance_to_plane(normal, vector(t0, pt), k);
8799
}
88100

89101
template <class K>

0 commit comments

Comments
 (0)