mirror of https://github.com/CGAL/cgal
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.
This commit is contained in:
parent
8b77c7139e
commit
b95c60fc9f
|
|
@ -64,26 +64,38 @@ squared_distance_to_triangle(const typename K::Point_3& pt,
|
|||
const Vector_3 oe3 = vector(t0, t2);
|
||||
const Vector_3 normal = wcross(e1, oe3, k);
|
||||
|
||||
if(normal != NULL_VECTOR &&
|
||||
on_left_of_triangle_edge(pt, normal, t0, t1, k) &&
|
||||
on_left_of_triangle_edge(pt, normal, t1, t2, k) &&
|
||||
on_left_of_triangle_edge(pt, normal, t2, t0, k))
|
||||
{
|
||||
// the projection of pt is inside the triangle
|
||||
inside = true;
|
||||
return squared_distance_to_plane(normal, vector(t0, pt), k);
|
||||
}
|
||||
else
|
||||
if(normal == NULL_VECTOR)
|
||||
{
|
||||
// The case normal == NULL_VECTOR covers the case when the triangle
|
||||
// is colinear, or even more degenerate. In that case, we can
|
||||
// simply take also the distance to the three segments.
|
||||
//
|
||||
// Note that in the degenerate case, at most 2 edges cover the full triangle,
|
||||
// and only two distances could be used, but leaving 3 for the case of
|
||||
// inexact constructions as it might improve the accuracy.
|
||||
|
||||
typename K::FT d1 = internal::squared_distance(pt, segment(t2, t0), k);
|
||||
typename K::FT d2 = internal::squared_distance(pt, segment(t1, t2), k);
|
||||
typename K::FT d3 = internal::squared_distance(pt, segment(t0, t1), k);
|
||||
|
||||
return (std::min)( (std::min)(d1, d2), d3);
|
||||
}
|
||||
|
||||
const bool b01 = on_left_of_triangle_edge(pt, normal, t0, t1, k);
|
||||
if(!b01)
|
||||
return internal::squared_distance(pt, segment(t0, t1), k);
|
||||
|
||||
const bool b12 = on_left_of_triangle_edge(pt, normal, t1, t2, k);
|
||||
if(!b12)
|
||||
return internal::squared_distance(pt, segment(t1, t2), k);
|
||||
|
||||
const bool b20 = on_left_of_triangle_edge(pt, normal, t2, t0, k);
|
||||
if(!b20)
|
||||
return internal::squared_distance(pt, segment(t2, t0), k);
|
||||
|
||||
// The projection of pt is inside the triangle
|
||||
inside = true;
|
||||
return squared_distance_to_plane(normal, vector(t0, pt), k);
|
||||
}
|
||||
|
||||
template <class K>
|
||||
|
|
|
|||
Loading…
Reference in New Issue