From a7d67459b97bbe48d49eb863e1b3f5c25c829be3 Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Mon, 31 Mar 2014 00:14:30 +0200 Subject: [PATCH] Construct_flat_orientation orients positively. That's a bit inconvenient and not necessary at all for Triangulation, and it exposes a bug there where dark and light triangulations have inconsistent orientations. --- .../include/CGAL/NewKernel_d/Coaffine.h | 23 +++-- NewKernel_d/test/NewKernel_d/Epick_d.cpp | 87 ++++++++++++++++++- 2 files changed, 101 insertions(+), 9 deletions(-) diff --git a/NewKernel_d/include/CGAL/NewKernel_d/Coaffine.h b/NewKernel_d/include/CGAL/NewKernel_d/Coaffine.h index bc72e7e856f..0b02cd201c9 100644 --- a/NewKernel_d/include/CGAL/NewKernel_d/Coaffine.h +++ b/NewKernel_d/include/CGAL/NewKernel_d/Coaffine.h @@ -11,6 +11,7 @@ namespace CartesianDKernelFunctors { struct Flat_orientation { std::vector proj; std::vector rest; + bool reverse; }; // For debugging purposes @@ -23,6 +24,7 @@ inline std::ostream& operator<< (std::ostream& o, Flat_orientation const& f) { for(std::vector::const_iterator i=f.rest.begin(); i!=f.rest.end(); ++i) o << *i << ' '; + o << "\nInv: " << f.reverse; return o << '\n'; } @@ -53,9 +55,11 @@ template struct Construct_flat_orientation : private Store_kernel typedef Flat_orientation result_type; // This implementation is going to suck. Maybe we should push the - // functionality into LA. + // functionality into LA. And we should check (in debug mode) that + // the points are affinely independent. template result_type operator()(Iter f, Iter e)const{ + Iter f_save = f; PD pd (this->kernel()); CCC ccc (this->kernel()); int dim = pd(*f); @@ -89,6 +93,9 @@ template struct Construct_flat_orientation : private Store_kernel } } std::sort(proj.begin(),proj.end()); + typename Get_functor::type ifo(this->kernel()); + o.reverse = false; + o.reverse = ifo(o, f_save, e) != CGAL::POSITIVE; return o; } }; @@ -186,8 +193,10 @@ template struct In_flat_orientation : private Store_kernel { if(*it != d) m(i,1+*it)=1; } - return LA::sign_of_determinant(CGAL_MOVE(m)); - } + result_type ret = LA::sign_of_determinant(CGAL_MOVE(m)); + if(o.reverse) ret=-ret; + return ret; + } }; template struct In_flat_side_of_oriented_sphere : private Store_kernel { @@ -233,8 +242,10 @@ template struct In_flat_side_of_oriented_sphere : private Store_kernel m(d+1,d+1)+=CGAL_NTS square(m(d+1,j+1)); } - return -LA::sign_of_determinant(CGAL_MOVE(m)); - } + result_type ret = -LA::sign_of_determinant(CGAL_MOVE(m)); + if(o.reverse) ret=-ret; + return ret; + } }; @@ -242,7 +253,7 @@ template struct In_flat_side_of_oriented_sphere : private Store_kernel CGAL_KD_DEFAULT_TYPE(Flat_orientation_tag,(CGAL::CartesianDKernelFunctors::Flat_orientation),(),()); CGAL_KD_DEFAULT_FUNCTOR(In_flat_orientation_tag,(CartesianDKernelFunctors::In_flat_orientation),(Point_tag),(Compute_point_cartesian_coordinate_tag,Point_dimension_tag)); CGAL_KD_DEFAULT_FUNCTOR(In_flat_side_of_oriented_sphere_tag,(CartesianDKernelFunctors::In_flat_side_of_oriented_sphere),(Point_tag),(Compute_point_cartesian_coordinate_tag,Point_dimension_tag)); -CGAL_KD_DEFAULT_FUNCTOR(Construct_flat_orientation_tag,(CartesianDKernelFunctors::Construct_flat_orientation),(Point_tag),(Compute_point_cartesian_coordinate_tag,Point_dimension_tag)); +CGAL_KD_DEFAULT_FUNCTOR(Construct_flat_orientation_tag,(CartesianDKernelFunctors::Construct_flat_orientation),(Point_tag),(Compute_point_cartesian_coordinate_tag,Point_dimension_tag,In_flat_orientation_tag)); CGAL_KD_DEFAULT_FUNCTOR(Contained_in_affine_hull_tag,(CartesianDKernelFunctors::Contained_in_affine_hull),(Point_tag),(Compute_point_cartesian_coordinate_tag,Point_dimension_tag)); } #endif diff --git a/NewKernel_d/test/NewKernel_d/Epick_d.cpp b/NewKernel_d/test/NewKernel_d/Epick_d.cpp index 734d873a374..d7139f2622c 100644 --- a/NewKernel_d/test/NewKernel_d/Epick_d.cpp +++ b/NewKernel_d/test/NewKernel_d/Epick_d.cpp @@ -177,9 +177,21 @@ void test2(){ std::cout << *i << ' '; std::cout << '\n'; P tab[]={a,b,c,d}; - std::cout << po (&tab[0],tab+3) << ' '; - std::cout << sos(&tab[0],tab+4) << ' '; - std::cout << sbs(&tab[0],tab+4) << std::endl; + assert(po (&tab[0],tab+3) == CGAL::CLOCKWISE); + std::cout << sos(tab+1,tab+4,a) << ' '; + std::cout << sbs(tab+1,tab+4,a) << std::endl; + P tabp[]={P(0,0),P(1,0),P(0,1)}; + P tabn[]={P(0,0),P(0,1),P(1,0)}; + assert(po(tabp+0,tabp+3)==CGAL::POSITIVE); + assert(po(tabn+0,tabn+3)==CGAL::NEGATIVE); + assert(sos(tabp+0,tabp+3,P(3,3))==CGAL::ON_NEGATIVE_SIDE); + assert(sos(tabn+0,tabn+3,P(3,3))==CGAL::ON_POSITIVE_SIDE); + assert(sbs(tabp+0,tabp+3,P(3,3))==CGAL::ON_UNBOUNDED_SIDE); + assert(sbs(tabn+0,tabn+3,P(3,3))==CGAL::ON_UNBOUNDED_SIDE); + assert(sos(tabp+0,tabp+3,P(.5,.5))==CGAL::ON_POSITIVE_SIDE); + assert(sos(tabn+0,tabn+3,P(.5,.5))==CGAL::ON_NEGATIVE_SIDE); + assert(sbs(tabp+0,tabp+3,P(.5,.5))==CGAL::ON_BOUNDED_SIDE); + assert(sbs(tabn+0,tabn+3,P(.5,.5))==CGAL::ON_BOUNDED_SIDE); P x1=cp(0,1); P x2=cp(-1,-1); P x3=cp(1,-1); @@ -205,6 +217,36 @@ void test2(){ FO fo=cfo(tab2+1,tab2+3); assert(ifo(fo,tab2+1,tab2+3)==CGAL::POSITIVE); assert(ifsos(fo,tab2+1,tab2+3,x5)==CGAL::ON_POSITIVE_SIDE); + P tab_h[]={P(0,42),P(1,42),P(4,42),P(2,42),P(3,42)}; + FO fo_hp = cfo (tab_h+0, tab_h+2); + FO fo_hn = cfo (tab_h+2, tab_h+4); + assert(ifo(fo_hp, tab_h+1, tab_h+3)==CGAL::POSITIVE); + assert(ifo(fo_hn, tab_h+1, tab_h+3)==CGAL::NEGATIVE); + assert(ifo(fo_hn, tab_h+2, tab_h+4)==CGAL::POSITIVE); + assert(ifo(fo_hp, tab_h+2, tab_h+4)==CGAL::NEGATIVE); + assert(ifsos(fo_hp, tab_h+1, tab_h+3, tab_h[3])==CGAL::ON_POSITIVE_SIDE); + assert(ifsos(fo_hn, tab_h+1, tab_h+3, tab_h[3])==CGAL::ON_NEGATIVE_SIDE); + assert(ifsos(fo_hp, tab_h+0, tab_h+2, tab_h[2])==CGAL::ON_NEGATIVE_SIDE); + assert(ifsos(fo_hn, tab_h+0, tab_h+2, tab_h[2])==CGAL::ON_POSITIVE_SIDE); + assert(ifsos(fo_hp, tab_h+2, tab_h+4, tab_h[1])==CGAL::ON_POSITIVE_SIDE); + assert(ifsos(fo_hn, tab_h+2, tab_h+4, tab_h[1])==CGAL::ON_NEGATIVE_SIDE); + assert(ifsos(fo_hp, tab_h+2, tab_h+4, tab_h[4])==CGAL::ON_NEGATIVE_SIDE); + assert(ifsos(fo_hn, tab_h+2, tab_h+4, tab_h[4])==CGAL::ON_POSITIVE_SIDE); + P tab_v[]={P(42,0),P(42,1),P(42,4),P(42,2),P(42,3)}; + FO fo_vp = cfo (tab_v+0, tab_v+2); + FO fo_vn = cfo (tab_v+2, tab_v+4); + assert(ifo(fo_vp, tab_v+1, tab_v+3)==CGAL::POSITIVE); + assert(ifo(fo_vn, tab_v+1, tab_v+3)==CGAL::NEGATIVE); + assert(ifo(fo_vn, tab_v+2, tab_v+4)==CGAL::POSITIVE); + assert(ifo(fo_vp, tab_v+2, tab_v+4)==CGAL::NEGATIVE); + assert(ifsos(fo_vp, tab_v+1, tab_v+3, tab_v[3])==CGAL::ON_POSITIVE_SIDE); + assert(ifsos(fo_vn, tab_v+1, tab_v+3, tab_v[3])==CGAL::ON_NEGATIVE_SIDE); + assert(ifsos(fo_vp, tab_v+0, tab_v+2, tab_v[2])==CGAL::ON_NEGATIVE_SIDE); + assert(ifsos(fo_vn, tab_v+0, tab_v+2, tab_v[2])==CGAL::ON_POSITIVE_SIDE); + assert(ifsos(fo_vp, tab_v+2, tab_v+4, tab_v[1])==CGAL::ON_POSITIVE_SIDE); + assert(ifsos(fo_vn, tab_v+2, tab_v+4, tab_v[1])==CGAL::ON_NEGATIVE_SIDE); + assert(ifsos(fo_vp, tab_v+2, tab_v+4, tab_v[4])==CGAL::ON_NEGATIVE_SIDE); + assert(ifsos(fo_vn, tab_v+2, tab_v+4, tab_v[4])==CGAL::ON_POSITIVE_SIDE); #endif P z0=cp( 0+2,5-3); P z1=cp(-5+2,0-3); @@ -354,6 +396,45 @@ void test3(){ FO fo4=cfo(tab2+0,tab2+3); assert(ifo(fo4,tab2+0,tab2+3)==CGAL::POSITIVE); assert(ifsos(fo4,tab2+0,tab2+3,x6)==CGAL::ON_POSITIVE_SIDE); + P tx[]={cp(1,1,42),cp(3,1,42),cp(1,3,42),cp(3,3,42),cp(2,2,42),cp(4,5,42)}; + FO foxp=cfo(tx+0,tx+3); + FO foxn=cfo(tx+1,tx+4); + assert(ifo(foxp, tx+0, tx+3) == CGAL::POSITIVE); + assert(ifo(foxn, tx+0, tx+3) == CGAL::NEGATIVE); + assert(ifo(foxp, tx+1, tx+4) == CGAL::NEGATIVE); + assert(ifo(foxn, tx+1, tx+4) == CGAL::POSITIVE); + assert(ifsos(foxp, tx+0, tx+3, tx[3]) == CGAL::ON_ORIENTED_BOUNDARY); + assert(ifsos(foxn, tx+0, tx+3, tx[3]) == CGAL::ON_ORIENTED_BOUNDARY); + assert(ifsos(foxp, tx+0, tx+3, tx[4]) == CGAL::ON_POSITIVE_SIDE); + assert(ifsos(foxn, tx+0, tx+3, tx[4]) == CGAL::ON_NEGATIVE_SIDE); + assert(ifsos(foxp, tx+0, tx+3, tx[5]) == CGAL::ON_NEGATIVE_SIDE); + assert(ifsos(foxn, tx+0, tx+3, tx[5]) == CGAL::ON_POSITIVE_SIDE); + P ty[]={cp(1,42,1),cp(3,42,1),cp(1,42,3),cp(3,42,3),cp(2,42,2),cp(4,42,5)}; + FO foyp=cfo(ty+0,ty+3); + FO foyn=cfo(ty+1,ty+4); + assert(ifo(foyp, ty+0, ty+3) == CGAL::POSITIVE); + assert(ifo(foyn, ty+0, ty+3) == CGAL::NEGATIVE); + assert(ifo(foyp, ty+1, ty+4) == CGAL::NEGATIVE); + assert(ifo(foyn, ty+1, ty+4) == CGAL::POSITIVE); + assert(ifsos(foyp, ty+0, ty+3, ty[3]) == CGAL::ON_ORIENTED_BOUNDARY); + assert(ifsos(foyn, ty+0, ty+3, ty[3]) == CGAL::ON_ORIENTED_BOUNDARY); + assert(ifsos(foyp, ty+0, ty+3, ty[4]) == CGAL::ON_POSITIVE_SIDE); + assert(ifsos(foyn, ty+0, ty+3, ty[4]) == CGAL::ON_NEGATIVE_SIDE); + assert(ifsos(foyp, ty+0, ty+3, ty[5]) == CGAL::ON_NEGATIVE_SIDE); + assert(ifsos(foyn, ty+0, ty+3, ty[5]) == CGAL::ON_POSITIVE_SIDE); + P tz[]={cp(1,1,42),cp(3,1,42),cp(1,3,42),cp(3,3,42),cp(2,2,42),cp(4,5,42)}; + FO fozp=cfo(tz+0,tz+3); + FO fozn=cfo(tz+1,tz+4); + assert(ifo(fozp, tz+0, tz+3) == CGAL::POSITIVE); + assert(ifo(fozn, tz+0, tz+3) == CGAL::NEGATIVE); + assert(ifo(fozp, tz+1, tz+4) == CGAL::NEGATIVE); + assert(ifo(fozn, tz+1, tz+4) == CGAL::POSITIVE); + assert(ifsos(fozp, tz+0, tz+3, tz[3]) == CGAL::ON_ORIENTED_BOUNDARY); + assert(ifsos(fozn, tz+0, tz+3, tz[3]) == CGAL::ON_ORIENTED_BOUNDARY); + assert(ifsos(fozp, tz+0, tz+3, tz[4]) == CGAL::ON_POSITIVE_SIDE); + assert(ifsos(fozn, tz+0, tz+3, tz[4]) == CGAL::ON_NEGATIVE_SIDE); + assert(ifsos(fozp, tz+0, tz+3, tz[5]) == CGAL::ON_NEGATIVE_SIDE); + assert(ifsos(fozn, tz+0, tz+3, tz[5]) == CGAL::ON_POSITIVE_SIDE); } template struct CGAL::Epick_d >; template struct CGAL::Epick_d >;