// Copyright (c) 2014 // INRIA Saclay-Ile de France (France) // // This file is part of CGAL (www.cgal.org); you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public License as // published by the Free Software Foundation; either version 3 of the License, // or (at your option) any later version. // // Licensees holding a valid commercial license may use this file in // accordance with the commercial license agreement provided with the software. // // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. // // $URL$ // $Id$ // // Author(s) : Marc Glisse #ifndef CGAL_KD_COAFFINE_H #define CGAL_KD_COAFFINE_H #include #include #include #include #include namespace CGAL { namespace CartesianDKernelFunctors { struct Flat_orientation { std::vector proj; std::vector rest; bool reverse; }; // For debugging purposes inline std::ostream& operator<< (std::ostream& o, Flat_orientation const& f) { o << "Proj: "; for(std::vector::const_iterator i=f.proj.begin(); i!=f.proj.end(); ++i) o << *i << ' '; o << "\nRest: "; for(std::vector::const_iterator i=f.rest.begin(); i!=f.rest.end(); ++i) o << *i << ' '; o << "\nInv: " << f.reverse; return o << '\n'; } namespace internal { namespace coaffine { template inline void debug_matrix(std::ostream& o, Mat const&mat) { for(int i=0;i struct Construct_flat_orientation : private Store_kernel { CGAL_FUNCTOR_INIT_STORE(Construct_flat_orientation) typedef R_ R; typedef typename Get_type::type FT; typedef typename Get_type::type Point; typedef typename Increment_dimension::type Dplusone; typedef typename R::LA::template Rebind_dimension::Other LA; typedef typename LA::Square_matrix Matrix; typedef typename Get_functor::type CCC; typedef typename Get_functor::type PD; typedef Flat_orientation result_type; // This implementation is going to suck. Maybe we should push the // 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); Matrix coord (dim+1, dim+1); // use distance(f,e)? This matrix doesn't need to be square. int col = 0; Flat_orientation o; std::vector& proj=o.proj; std::vector& rest=o.rest; rest.reserve(dim+1); for(int i=0; i::iterator it=rest.begin();;++it) { CGAL_assertion(it!=rest.end()); for(int i=0; i::type ifo(this->kernel()); o.reverse = false; o.reverse = ifo(o, f_save, e) != CGAL::POSITIVE; return o; } }; template struct Contained_in_affine_hull : private Store_kernel { CGAL_FUNCTOR_INIT_STORE(Contained_in_affine_hull) typedef R_ R; typedef typename Get_type::type FT; typedef typename Get_type::type Point; typedef typename Get_type::type result_type; typedef typename Get_functor::type CCC; typedef typename Get_functor::type PD; //typedef typename Increment_dimension::type D1; //typedef typename Increment_dimension::type D2; //typedef typename R::LA::template Rebind_dimension::Other LA; typedef typename Increment_dimension::type Dplusone; typedef typename R::LA::template Rebind_dimension::Other LA; typedef typename LA::Square_matrix Matrix; // mostly copied from Construct_flat_orientation. TODO: dedup this code or use LA. template result_type operator()(Iter f, Iter e, Point const&x) const { // FIXME: are the points in (f,e) required to be affinely independent? PD pd (this->kernel()); CCC ccc (this->kernel()); int dim=pd(*f); Matrix coord (dim+1, dim+1); // use distance int col = 0; std::vector proj; std::vector rest; rest.reserve(dim+1); for(int i=0; i::iterator it=rest.begin();it!=rest.end();++it) { for(int i=0; i::iterator it=rest.begin();it!=rest.end();++it) { for(int i=0; i struct In_flat_orientation : private Store_kernel { CGAL_FUNCTOR_INIT_STORE(In_flat_orientation) typedef R_ R; typedef typename Get_type::type FT; typedef typename Get_type::type Point; typedef typename Get_type::type result_type; typedef typename Increment_dimension::type D1; typedef typename Increment_dimension::type D2; typedef typename R::LA::template Rebind_dimension::Other LA; typedef typename LA::Square_matrix Matrix; template result_type operator()(Flat_orientation const&o, Iter f, Iter e) const { // TODO: work in the projection instead of the ambient space. typename Get_functor::type c(this->kernel()); typename Get_functor::type pd(this->kernel()); int d=pd(*f); Matrix m(d+1,d+1); int i=0; for(;f!=e;++f,++i) { Point const& p=*f; m(i,0)=1; for(int j=0;j::const_iterator it = o.rest.begin(); it != o.rest.end() /* i struct In_flat_side_of_oriented_sphere : private Store_kernel { CGAL_FUNCTOR_INIT_STORE(In_flat_side_of_oriented_sphere) typedef R_ R; typedef typename Get_type::type FT; typedef typename Get_type::type Point; typedef typename Get_type::type result_type; typedef typename Increment_dimension::type D1; typedef typename Increment_dimension::type D2; typedef typename R::LA::template Rebind_dimension::Other LA; typedef typename LA::Square_matrix Matrix; template result_type operator()(Flat_orientation const&o, Iter f, Iter e, Point const&x) const { // TODO: can't work in the projection, but we should at least remove the row of 1s. typename Get_functor::type c(this->kernel()); typename Get_functor::type pd(this->kernel()); int d=pd(*f); Matrix m(d+2,d+2); int i=0; for(;f!=e;++f,++i) { Point const& p=*f; m(i,0)=1; m(i,d+1)=0; for(int j=0;j::const_iterator it = o.rest.begin(); it != o.rest.end() /* i),(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,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