#ifndef CGAL_KERNEL_D_FUNCTION_OBJECTS_CARTESIAN_H #define CGAL_KERNEL_D_FUNCTION_OBJECTS_CARTESIAN_H #include #include #include #include #include #include #include #include #include #include namespace CGAL { namespace CartesianDKernelFunctors { template struct Orientation : private Store_kernel { CGAL_FUNCTOR_INIT_STORE(Orientation) typedef R_ R; typedef typename R_::FT FT; typedef typename R::Vector Vector; typedef typename R::Point Point; typedef typename R::Orientation result_type; typedef typename R::LA::template Matrix::type Matrix; template result_type operator()(Iter f, Iter const& e, Vector_tag)const{ typename R::template Functor::type c(this->kernel()); Matrix m(R().dimension(),R().dimension()); for(int i=0;f!=e;++f,++i) { for(int j=0;j result_type operator()(Iter f, Iter const& e, Point_tag)const{ typename R::template Functor::type c(this->kernel()); Matrix m(R().dimension(),R().dimension()); Point const& p0=*f++; for(int i=0;f!=e;++f,++i) { for(int j=0;j result_type operator()(Iter const&f, Iter const& e)const{ typename std::iterator_traits::difference_type d=std::distance(f,e); int dim=R().dimension(); if(d==dim) return operator()(f,e,Vector_tag()); CGAL_assertion(d==dim+1); return operator()(f,e,Point_tag()); } //TODO: version that takes objects directly instead of iterators }; template struct Construct_opposite_vector : private Store_kernel { CGAL_FUNCTOR_INIT_STORE(Construct_opposite_vector) typedef R_ R; typedef typename R_::FT FT; typedef typename R::Vector Vector; typedef typename R::template Functor::type CV; typedef typename R::template Functor::type CI; typedef Vector result_type; typedef Vector argument_type; result_type operator()(Vector const&v)const{ CI ci(this->kernel()); return CV(this->kernel())(make_transforming_iterator(ci(v,Begin_tag()),std::negate()),make_transforming_iterator(ci(v,End_tag()),std::negate())); } }; template struct Construct_sum_of_vectors : private Store_kernel { CGAL_FUNCTOR_INIT_STORE(Construct_sum_of_vectors) typedef R_ R; typedef typename R_::FT FT; typedef typename R::Vector Vector; typedef typename R::template Functor::type CV; typedef typename R::template Functor::type CI; typedef Vector result_type; typedef Vector first_argument_type; typedef Vector second_argument_type; result_type operator()(Vector const&a, Vector const&b)const{ CI ci(this->kernel()); return CV(this->kernel())(make_transforming_pair_iterator(ci(a,Begin_tag()),ci(b,Begin_tag()),std::plus()),make_transforming_pair_iterator(ci(a,End_tag()),ci(b,End_tag()),std::plus())); } }; template struct Construct_difference_of_vectors : private Store_kernel { CGAL_FUNCTOR_INIT_STORE(Construct_difference_of_vectors) typedef R_ R; typedef typename R_::FT FT; typedef typename R::Vector Vector; typedef typename R::template Functor::type CV; typedef typename R::template Functor::type CI; typedef Vector result_type; typedef Vector first_argument_type; typedef Vector second_argument_type; result_type operator()(Vector const&a, Vector const&b)const{ CI ci(this->kernel()); return CV(this->kernel())(make_transforming_pair_iterator(ci(a,Begin_tag()),ci(b,Begin_tag()),std::minus()),make_transforming_pair_iterator(ci(a,End_tag()),ci(b,End_tag()),std::minus())); } }; template struct Construct_midpoint : private Store_kernel { CGAL_FUNCTOR_INIT_STORE(Construct_midpoint) typedef R_ R; typedef typename R_::FT FT; typedef typename R::Point Point; typedef typename R::template Functor::type CP; typedef typename R::template Functor::type CI; typedef Point result_type; typedef Point first_argument_type; typedef Point second_argument_type; struct Average : std::binary_function { FT operator()(FT const&a, FT const&b)const{ return (a+b)/2; } }; result_type operator()(Point const&a, Point const&b)const{ CI ci(this->kernel()); //Divide half(2); //return CP(this->kernel())(make_transforming_iterator(make_transforming_pair_iterator(ci.begin(a),ci.begin(b),std::plus()),half),make_transforming_iterator(make_transforming_pair_iterator(ci.end(a),ci.end(b),std::plus()),half)); return CP(this->kernel())(make_transforming_pair_iterator(ci(a,Begin_tag()),ci(b,Begin_tag()),Average()),make_transforming_pair_iterator(ci(a,End_tag()),ci(b,End_tag()),Average())); } }; template struct Compute_squared_length : private Store_kernel { CGAL_FUNCTOR_INIT_STORE(Compute_squared_length) typedef R_ R; typedef typename R_::FT FT; typedef typename R::Vector Vector; typedef typename R::template Functor::type CI; typedef FT result_type; typedef Vector argument_type; result_type operator()(Vector const&a)const{ CI ci(this->kernel()); typename Algebraic_structure_traits::Square f; // TODO: avoid this FT(0)+... return std::accumulate(make_transforming_iterator(ci(a,Begin_tag()),f),make_transforming_iterator(ci(a,End_tag()),f),FT(0)); } }; template struct Compute_squared_distance : private Store_kernel { CGAL_FUNCTOR_INIT_STORE(Compute_squared_distance) typedef R_ R; typedef typename R_::FT FT; typedef typename R::Point Point; typedef typename R::template Functor::type CI; typedef FT result_type; typedef Point first_argument_type; typedef Point second_argument_type; struct Sq_diff : std::binary_function { FT operator()(FT const&a, FT const&b)const{ return CGAL::square(a-b); } }; result_type operator()(Point const&a, Point const&b)const{ CI ci(this->kernel()); Sq_diff f; // TODO: avoid this FT(0)+... return std::accumulate(make_transforming_pair_iterator(ci(a,Begin_tag()),ci(b,Begin_tag()),f),make_transforming_pair_iterator(ci(a,End_tag()),ci(b,End_tag()),f),FT(0)); } }; template struct Less_cartesian_coordinate : private Store_kernel { CGAL_FUNCTOR_INIT_STORE(Less_cartesian_coordinate) typedef R_ R; typedef typename R_::FT FT; typedef typename R::Comparison_result result_type; typedef typename R::template Functor::type Cc; // TODO: This is_exact thing should be reengineered. // the goal is to have a way to tell: don't filter this typedef typename CGAL::Is_exact::type Is_exact; template result_type operator()(V const&a, V const&b, I i)const{ Cc c(this->kernel()); return c(a,i) struct Construct_segment { CGAL_FUNCTOR_INIT_IGNORE(Construct_segment) typedef R_ R; typedef typename R_::Point Point; typedef typename R_::Segment Segment; typedef Segment result_type; #ifdef CGAL_CXX0X template result_type operator()(U&&...u)const{ // should use Construct_point ? return result_type(std::forward(u)...); } #else result_type operator()(Point const&a, Point const&b)const{ return result_type(a,b); } #endif }; // This should be part of Construct_point, according to Kernel_23 conventions template struct Construct_segment_extremity { CGAL_FUNCTOR_INIT_IGNORE(Construct_segment_extremity) typedef R_ R; typedef typename R_::Point Point; typedef typename R_::Segment Segment; typedef Point result_type; result_type operator()(Segment const&s, int i)const{ if(i==0) return s.source(); CGAL_assertion(i==1); return s.target(); } #ifdef CGAL_CXX0X result_type operator()(Segment &&s, int i)const{ if(i==0) return std::move(s).source(); CGAL_assertion(i==1); return std::move(s).target(); } #endif }; } } #endif // CGAL_KERNEL_D_FUNCTION_OBJECTS_CARTESIAN_H