Avoid some superfluous checks

This commit is contained in:
Mael Rouxel-Labbé 2022-02-28 11:29:54 +01:00
parent 192ae3fb83
commit 5aeb59215f
1 changed files with 123 additions and 23 deletions

View File

@ -66,19 +66,10 @@ squared_distance_to_triangle_RT(const typename K::Point_3& pt,
const Vector_3 oe3 = vector(t0, t2); const Vector_3 oe3 = vector(t0, t2);
const Vector_3 normal = wcross(e1, oe3, k); const Vector_3 normal = wcross(e1, oe3, k);
if(normal != NULL_VECTOR && 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 // The case normal==NULL_VECTOR covers the case when the triangle
inside = true; // is colinear, or even more degenerate. In that case, we can
squared_distance_to_plane_RT(normal, vector(t0, pt), num, den, k);
}
else
{
// The case normal == NULL_VECTOR covers the case when the triangle
// is collinear, or even more degenerate. In that case, we can
// simply take also the distance to the three segments. // simply take also the distance to the three segments.
squared_distance_RT(pt, segment(t2, t0), num, den, k); squared_distance_RT(pt, segment(t2, t0), num, den, k);
@ -98,6 +89,78 @@ squared_distance_to_triangle_RT(const typename K::Point_3& pt,
num = num2; num = num2;
den = den2; den = den2;
} }
return;
}
if(!on_left_of_triangle_edge(pt, normal, t0, t1, k))
{
if(!on_left_of_triangle_edge(pt, normal, t1, t2, k))
{
// can't be to the right of all three segments
squared_distance_RT(pt, segment(t0, t1), num, den, k);
typename K::RT num2, den2;
squared_distance_RT(pt, segment(t1, t2), num2, den2, k);
if(compare_quotients(num2,den2, num,den) == SMALLER)
{
num = num2;
den = den2;
}
}
else // on_left_of_triangle_edge(pt, normal, t1, t2, k)
{
if(!on_left_of_triangle_edge(pt, normal, t2, t0, k))
{
squared_distance_RT(pt, segment(t0, t1), num, den, k);
typename K::RT num2, den2;
squared_distance_RT(pt, segment(t2, t0), num2, den2, k);
if(compare_quotients(num2,den2, num,den) == SMALLER)
{
num = num2;
den = den2;
}
}
else // on_left_of_triangle_edge(pt, normal, t2, t0, k)
{
return squared_distance_RT(pt, segment(t0, t1), num, den, k);
}
}
}
else // on_left_of_triangle_edge(pt, normal, t0, t1, k)
{
if(!on_left_of_triangle_edge(pt, normal, t1, t2, k))
{
if(!on_left_of_triangle_edge(pt, normal, t2, t0, k))
{
squared_distance_RT(pt, segment(t1, t2), num, den, k);
typename K::RT num2, den2;
squared_distance_RT(pt, segment(t2, t0), num2, den2, k);
if(compare_quotients(num2,den2, num,den) == SMALLER)
{
num = num2;
den = den2;
}
}
else // on_left_of_triangle_edge(pt, normal, t2, t0, k)
{
return squared_distance_RT(pt, segment(t1, t2), num, den, k);
}
}
else // on_left_of_triangle_edge(pt, normal, t1, t2, k)
{
if(!on_left_of_triangle_edge(pt, normal, t2, t0, k))
{
return squared_distance_RT(pt, segment(t2, t0), num, den, k);
}
else // on_left_of_triangle_edge(pt, normal, t2, t0, k)
{
inside = true;
return squared_distance_to_plane_RT(normal, vector(t0, pt), num, den, k);
}
}
} }
} }
@ -140,19 +203,10 @@ squared_distance_to_triangle(const typename K::Point_3& pt,
const Vector_3 oe3 = vector(t0, t2); const Vector_3 oe3 = vector(t0, t2);
const Vector_3 normal = wcross(e1, oe3, k); const Vector_3 normal = wcross(e1, oe3, k);
if(normal != NULL_VECTOR && 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
{ {
// The case normal == NULL_VECTOR covers the case when the triangle // The case normal == NULL_VECTOR covers the case when the triangle
// is collinear, or even more degenerate. In that case, we can // is colinear, or even more degenerate. In that case, we can
// simply take also the distance to the three segments. // simply take also the distance to the three segments.
// //
// Note that in the degenerate case, at most 2 edges cover the full triangle, // Note that in the degenerate case, at most 2 edges cover the full triangle,
@ -164,6 +218,52 @@ squared_distance_to_triangle(const typename K::Point_3& pt,
return (std::min)((std::min)(d1, d2), d3); return (std::min)((std::min)(d1, d2), d3);
} }
if(!on_left_of_triangle_edge(pt, normal, t0, t1, k))
{
if(!on_left_of_triangle_edge(pt, normal, t1, t2, k))
{
// can't be to the right of all three segments
return (std::min)(sq_dist(pt, segment(t0, t1)), sq_dist(pt, segment(t1, t2)));
}
else // on_left_of_triangle_edge(pt, normal, t1, t2, k)
{
if(!on_left_of_triangle_edge(pt, normal, t2, t0, k))
{
return (std::min)(sq_dist(pt, segment(t0, t1)), sq_dist(pt, segment(t2, t0)));
}
else // on_left_of_triangle_edge(pt, normal, t2, t0, k)
{
return sq_dist(pt, segment(t0, t1));
}
}
}
else // on_left_of_triangle_edge(pt, normal, t0, t1, k)
{
if(!on_left_of_triangle_edge(pt, normal, t1, t2, k))
{
if(!on_left_of_triangle_edge(pt, normal, t2, t0, k))
{
return (std::min)(sq_dist(pt, segment(t1, t2)), sq_dist(pt, segment(t2, t0)));
}
else // on_left_of_triangle_edge(pt, normal, t2, t0, k)
{
return sq_dist(pt, segment(t1, t2));
}
}
else // on_left_of_triangle_edge(pt, normal, t1, t2, k)
{
if(!on_left_of_triangle_edge(pt, normal, t2, t0, k))
{
return sq_dist(pt, segment(t2, t0));
}
else // on_left_of_triangle_edge(pt, normal, t2, t0, k)
{
inside = true;
return squared_distance_to_plane(normal, vector(t0, pt), k);
}
}
}
} }
template <class K> template <class K>