Merge pull request #8337 from MaelRL/Kernel_23-Compare_angles-GF

Add Compare_angle_3 overload and missing global functions / doc
This commit is contained in:
Sébastien Loriot 2024-07-23 17:20:26 +02:00
commit 4fbb66a40d
5 changed files with 111 additions and 18 deletions

View File

@ -764,6 +764,32 @@ public:
const K::Point_3& b,
const K::Point_3& c,
const K::FT& cosine);
/*!
compares the angles \f$ \theta_1\f$ and \f$ \theta_2\f$, where
\f$ \theta_1\f$ is the angle in \f$ [0, \pi]\f$ of the triangle
\f$ (a1, b1, c1)\f$ at the vertex `b1`, and \f$ \theta_2\f$
is the angle in \f$ [0, \pi]\f$ of the triangle \f$ (a2, b2, c2)\f$ at the vertex `b2`.
\pre `a1!=b1 && c1!=b1 && a2!=b2 && c2!=b2`.
*/
Comparison_result operator()(const K::Point_3& a1,
const K::Point_3& b1,
const K::Point_3& c1,
const K::Point_3& a2,
const K::Point_3& b2,
const K::Point_3& c2);
/*!
compares the angles \f$ \theta_1\f$ and \f$ \theta_2\f$, where
\f$ \theta_1\f$ is the angle in \f$ [0, \pi]\f$ between the vectors
\f$ u1\f$ and \f$ v1\f$, and \f$ \theta_2\f$ is the angle in \f$ [0, \pi]\f$
between the vectors \f$ u2\f$ and \f$ v2\f$.
\pre none of the vectors have zero length.
*/
Comparison_result operator()(const K::Vector_3& u1,
const K::Vector_3& v1,
const K::Vector_3& u2,
const K::Vector_3& v2);
};
/*!

View File

@ -206,16 +206,15 @@ namespace CommonKernelFunctors {
typedef typename K::Comparison_result result_type;
result_type
operator()(const Point_3& a1, const Point_3& b1, const Point_3& c1,
const Point_3& a2, const Point_3& b2, const Point_3& c2) const
operator()(const Vector_3& ba1, const Vector_3& bc1,
const Vector_3& ba2, const Vector_3& bc2) const
{
using FT = typename K::FT;
const Vector_3 ba1 = a1 - b1;
const Vector_3 bc1 = c1 - b1;
const Vector_3 ba2 = a2 - b2;
const Vector_3 bc2 = c2 - b2;
const FT sc_prod_1 = ba1 * bc1;
const FT sc_prod_2 = ba2 * bc2;
typename K::Compute_scalar_product_3 scalar_product = K().compute_scalar_product_3_object();
typename K::Compute_squared_length_3 sq_length = K().compute_squared_length_3_object();
const FT sc_prod_1 = scalar_product(ba1, bc1);
const FT sc_prod_2 = scalar_product(ba2, bc2);
// Reminder: cos(angle) = scalar_product(ba, bc) / (length(ba)*length(bc))
// cosine is decreasing on 0, pi
// thus angle1 < angle2 is equivalent to cos(angle1) > cos(angle2)
@ -223,26 +222,36 @@ namespace CommonKernelFunctors {
if(sc_prod_2 >= 0) {
// the two cosine are >= 0, we can compare the squares
// (square(x) is increasing when x>=0
return CGAL::compare(CGAL::square(sc_prod_2)*
ba1.squared_length()*bc1.squared_length(),
CGAL::square(sc_prod_1)*
ba2.squared_length()*bc2.squared_length());
return CGAL::compare(CGAL::square(sc_prod_2) * sq_length(ba1) * sq_length(bc1),
CGAL::square(sc_prod_1) * sq_length(ba2) * sq_length(bc2));
} else {
return SMALLER;
}
} else {
if(sc_prod_2 < 0) {
// the two cosine are < 0, square(x) is decreasing when x<0
return CGAL::compare(CGAL::square(sc_prod_1)*
ba2.squared_length()*bc2.squared_length(),
CGAL::square(sc_prod_2)*
ba1.squared_length()*bc1.squared_length());
return CGAL::compare(CGAL::square(sc_prod_1) * sq_length(ba2) * sq_length(bc2),
CGAL::square(sc_prod_2) * sq_length(ba1) * sq_length(bc1));
} else {
return LARGER;
}
}
}
result_type
operator()(const Point_3& a1, const Point_3& b1, const Point_3& c1,
const Point_3& a2, const Point_3& b2, const Point_3& c2) const
{
typename K::Construct_vector_3 vector = K().construct_vector_3_object();
const Vector_3 ba1 = vector(b1, a1);
const Vector_3 bc1 = vector(b1, c1);
const Vector_3 ba2 = vector(b2, a2);
const Vector_3 bc2 = vector(b2, c2);
return this->operator()(ba1, bc1, ba2, bc2);
}
result_type
operator()(const Point_3& a, const Point_3& b, const Point_3& c,
const FT& cosine) const

View File

@ -318,6 +318,24 @@ compare_angle(const Point_3<K>& a, const Point_3<K>& b, const Point_3<K>& c,
return internal::compare_angle(a, b, c, cosine, K());
}
template < class K >
inline
typename K::Comparison_result
compare_angle(const Point_3<K>& a1, const Point_3<K>& b1, const Point_3<K>& c1,
const Point_3<K>& a2, const Point_3<K>& b2, const Point_3<K>& c2)
{
return internal::compare_angle(a1, b1, c1, a2, b2, c2, K());
}
template < class K >
inline
typename K::Comparison_result
compare_angle(const Vector_3<K>& u1, const Vector_3<K>& v1,
const Vector_3<K>& u2, const Vector_3<K>& v2)
{
return internal::compare_angle(u1, v1, u2, v2, K());
}
template < class K >
inline
typename K::Comparison_result

View File

@ -333,6 +333,32 @@ compare_angle(const typename K::Point_3& a,
return k.compare_angle_3_object()(a, b, c, cosine);
}
template < class K >
inline
typename K::Comparison_result
compare_angle(const typename K::Point_3& a1,
const typename K::Point_3& b1,
const typename K::Point_3& c1,
const typename K::Point_3& a2,
const typename K::Point_3& b2,
const typename K::Point_3& c2,
const K& k)
{
return k.compare_angle_3_object()(a1, b1, c1, a2, b2, c2);
}
template < class K >
inline
typename K::Comparison_result
compare_angle(const typename K::Vector_3& u1,
const typename K::Vector_3& v1,
const typename K::Vector_3& u2,
const typename K::Vector_3& v2,
const K& k)
{
return k.compare_angle_3_object()(u1, v1, u2, v2);
}
template < class K >
inline
typename K::Comparison_result

View File

@ -14,8 +14,10 @@ template <class R>
bool
_test_compare_angle_3(const R& rep)
{
typedef typename R::Point_3 Point_3;
typedef typename R::FT FT;
typedef typename R::Point_3 Point_3;
typedef typename R::Vector_3 Vector_3;
typename R::Compare_angle_3 compare_angle
= rep.compare_angle_3_object();
@ -33,6 +35,18 @@ _test_compare_angle_3(const R& rep)
return false;
if ( CGAL::compare(abs(theta1), abs(theta2)) != compare_angle(a, b, c, FT(std::cos(angle2))) )
return false;
Point_3 d((int)(std::cos(angle2)*1000), (int)(std::sin(angle2)*1000), 0);
if ( CGAL::compare(abs(theta1), abs(theta2)) != CGAL::compare_angle(a, b, c, a, b, d ) )
return false;
if ( CGAL::compare(abs(theta1), abs(theta2)) != compare_angle(a, b, c, a, b, d ) )
return false;
Vector_3 u1(b, a), v1(b, c), v2(b, d);
if ( CGAL::compare(abs(theta1), abs(theta2)) != CGAL::compare_angle(u1, v1, u1, v2) )
return false;
if ( CGAL::compare(abs(theta1), abs(theta2)) != compare_angle(u1, v1, u1, v2) )
return false;
} // end loop on theta2
} // end loop and theta1
return true;