Specialize the cw test to be more robust if the kernel is not exact

This commit is contained in:
Maxime Gimeno 2019-10-03 10:48:52 +02:00
parent ad3c3d16b7
commit 9ede1f3ee7
2 changed files with 39 additions and 17 deletions

View File

@ -30,6 +30,7 @@
#include <CGAL/Intersections_2/Line_2_Line_2.h>
#include <CGAL/Intersection_traits_2.h>
#include <CGAL/Algebraic_structure_traits.h>
namespace CGAL {
@ -281,13 +282,6 @@ Triangle_2_Triangle_2_pair<K>::vertex(int n) const
return cur->point;
}
//algorithm taken from here : https://stackoverflow.com/questions/1165647/how-to-determine-if-a-list-of-polygon-points-are-in-clockwise-order
template <typename K, typename ArrayOfPoints>
bool is_cw(const ArrayOfPoints& ps)
{
return !CGAL::left_turn(ps[0], ps[1], ps[2]);
}
template <class K>
typename K::Triangle_2
Triangle_2_Triangle_2_pair<K>::intersection_triangle() const
@ -296,16 +290,18 @@ Triangle_2_Triangle_2_pair<K>::intersection_triangle() const
if (!_known)
intersection_type();
CGAL_kernel_assertion(_result == TRIANGLE);
std::array<typename K::Point_2, 3> res;
res[0]=_pointlist.first->point;
res[1]=_pointlist.first->next->point;
res[2]=_pointlist.first->next->next->point;
if(!is_cw<K>(res))
if(CGAL::left_turn(_pointlist.first->point,
_pointlist.first->next->point,
_pointlist.first->next->next->point))
{
return Triangle_2(res[0], res[1], res[2]);
return Triangle_2(_pointlist.first->point,
_pointlist.first->next->point,
_pointlist.first->next->next->point);
}
else {
return Triangle_2(res[0], res[2], res[1]);
return Triangle_2(_pointlist.first->point,
_pointlist.first->next->next->point,
_pointlist.first->next->point);
}
}
@ -332,6 +328,30 @@ Triangle_2_Triangle_2_pair<K>::intersection_point() const
}
//algorithm taken from here : https://stackoverflow.com/questions/1165647/how-to-determine-if-a-list-of-polygon-points-are-in-clockwise-order
template <typename K, typename ArrayOfPoints, typename Exact>
struct Is_cw{
bool operator()(const ArrayOfPoints& ps)
{
typename K::FT res(0);
std::size_t length = ps.size();
for(std::size_t i = 0; i<length; ++i)
{
res += (ps[(i+1)%length].x() - ps[i].x())*(ps[(i+1)%length].y()+ps[i].y());
}
return res > 0;
}
};
template <typename K, typename ArrayOfPoints>
struct Is_cw<K, ArrayOfPoints,Tag_true>{
bool operator()(const ArrayOfPoints& ps)
{
return !CGAL::left_turn(ps[0], ps[1], ps[2]);
}
};
template <class K>
typename CGAL::Intersection_traits
@ -358,7 +378,7 @@ intersection(const typename K::Triangle_2 &tr1,
for (int i =0; i < ispair.vertex_count(); i++) {
points[i] = ispair.vertex(i);
}
if(is_cw<K>(points))
if(Is_cw<K, Container, typename Algebraic_structure_traits<typename K::FT>::Is_exact>()(points))
{
std::size_t length = points.size();

View File

@ -98,7 +98,8 @@ struct Test
{
if (p.size() != q.size())
return false;
if (CGAL::Intersections::internal::is_cw<K>(p))
if (CGAL::Intersections::internal::Is_cw<K, Pol,
typename CGAL::Algebraic_structure_traits<typename K::FT>::Is_exact>()(p))
return false;
for(typename Pol::const_iterator itp = p.begin(), itq = q.begin(); itp != p.end(); ++itp, ++itq)
if (!approx_equal(*itp, *itq))
@ -111,7 +112,8 @@ struct Test
{
std::vector<P> vec(3);
for(int i=0; i<3; ++i){vec[i]=p[i];}
if (CGAL::Intersections::internal::is_cw<K>(vec))
if (CGAL::Intersections::internal::Is_cw<K, std::vector<P>,
typename CGAL::Algebraic_structure_traits<typename K::FT>::Is_exact>(vec))
return false;
return p == q;
}