// Copyright (c) 1999,2002,2005 // Utrecht University (The Netherlands), // ETH Zurich (Switzerland), // INRIA Sophia-Antipolis (France), // Max-Planck-Institute Saarbruecken (Germany) // and Tel-Aviv University (Israel). All rights reserved. // // This file is part of CGAL (www.cgal.org) // // $URL: https://github.com/CGAL/cgal/blob/v5.1/Kernel_23/include/CGAL/Kernel/function_objects.h $ // $Id: function_objects.h 4476663 2020-04-08T16:14:44+02:00 Sébastien Loriot // SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial // // // Author(s) : Stefan Schirra, Sylvain Pion, // Camille Wormser, Stephane Tayeb, Pierre Alliez #ifndef CGAL_KERNEL_FUNCTION_OBJECTS_H #define CGAL_KERNEL_FUNCTION_OBJECTS_H #include #include #include #include #include #include #include #include #include #include // for Compute_dihedral_angle namespace CGAL { namespace CommonKernelFunctors { template class Are_ordered_along_line_2 { typedef typename K::Point_2 Point_2; typedef typename K::Collinear_2 Collinear_2; typedef typename K::Collinear_are_ordered_along_line_2 Collinear_are_ordered_along_line_2; Collinear_2 c; Collinear_are_ordered_along_line_2 cao; public: typedef typename K::Boolean result_type; Are_ordered_along_line_2() {} Are_ordered_along_line_2(const Collinear_2& c_, const Collinear_are_ordered_along_line_2& cao_) : c(c_), cao(cao_) {} result_type operator()(const Point_2& p, const Point_2& q, const Point_2& r) const { return c(p, q, r) && cao(p, q, r); } }; template class Are_ordered_along_line_3 { typedef typename K::Point_3 Point_3; typedef typename K::Collinear_3 Collinear_3; typedef typename K::Collinear_are_ordered_along_line_3 Collinear_are_ordered_along_line_3; Collinear_3 c; Collinear_are_ordered_along_line_3 cao; public: typedef typename K::Boolean result_type; Are_ordered_along_line_3() {} Are_ordered_along_line_3(const Collinear_3& c_, const Collinear_are_ordered_along_line_3& cao_) : c(c_), cao(cao_) {} result_type operator()(const Point_3& p, const Point_3& q, const Point_3& r) const { return c(p, q, r) && cao(p, q, r); } }; template class Are_strictly_ordered_along_line_2 { typedef typename K::Point_2 Point_2; typedef typename K::Collinear_2 Collinear_2; typedef typename K::Collinear_are_strictly_ordered_along_line_2 Collinear_are_strictly_ordered_along_line_2; Collinear_2 c; Collinear_are_strictly_ordered_along_line_2 cao; public: typedef typename K::Boolean result_type; Are_strictly_ordered_along_line_2() {} Are_strictly_ordered_along_line_2( const Collinear_2& c_, const Collinear_are_strictly_ordered_along_line_2& cao_) : c(c_), cao(cao_) {} result_type operator()(const Point_2& p, const Point_2& q, const Point_2& r) const { return c(p, q, r) && cao(p, q, r); } }; template class Are_strictly_ordered_along_line_3 { typedef typename K::Point_3 Point_3; typedef typename K::Collinear_3 Collinear_3; typedef typename K::Collinear_are_strictly_ordered_along_line_3 Collinear_are_strictly_ordered_along_line_3; Collinear_3 c; Collinear_are_strictly_ordered_along_line_3 cao; public: typedef typename K::Boolean result_type; Are_strictly_ordered_along_line_3() {} Are_strictly_ordered_along_line_3( const Collinear_3& c_, const Collinear_are_strictly_ordered_along_line_3& cao_) : c(c_), cao(cao_) {} result_type operator()(const Point_3& p, const Point_3& q, const Point_3& r) const { return c(p, q, r) && cao(p, q, r); } }; template class Assign_2 { typedef typename K::Object_2 Object_2; public: //typedef typename K::Boolean result_type; typedef bool result_type; template result_type operator()(T& t, const Object_2& o) const { return assign(t, o); } }; template class Assign_3 { typedef typename K::Object_3 Object_3; public: //typedef typename K::Boolean result_type; typedef bool result_type; template result_type operator()(T& t, const Object_3& o) const { return assign(t, o); } }; template class Compare_dihedral_angle_3 { typedef typename K::Point_3 Point_3; typedef typename K::Vector_3 Vector_3; typedef typename K::FT FT; public: 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& d1, const Point_3& a2, const Point_3& b2, const Point_3& c2, const Point_3& d2) const { const Vector_3 ab1 = b1 - a1; const Vector_3 ac1 = c1 - a1; const Vector_3 ad1 = d1 - a1; const Vector_3 ab2 = b2 - a2; const Vector_3 ac2 = c2 - a2; const Vector_3 ad2 = d2 - a2; return this->operator()(ab1, ac1, ad1, ab2, ac2, ad2); } result_type operator()(const Point_3& a1, const Point_3& b1, const Point_3& c1, const Point_3& d1, const FT& cosine) const { const Vector_3 ab1 = b1 - a1; const Vector_3 ac1 = c1 - a1; const Vector_3 ad1 = d1 - a1; return this->operator()(ab1, ac1, ad1, cosine); } result_type operator()(const Vector_3& ab1, const Vector_3& ac1, const Vector_3& ad1, const FT& cosine) const { typedef typename K::FT FT; typedef typename K::Construct_cross_product_vector_3 Cross_product; Cross_product xproduct = K().construct_cross_product_vector_3_object(); const Vector_3 abac1 = xproduct(ab1, ac1); const Vector_3 abad1 = xproduct(ab1, ad1); const FT sc_prod_1 = abac1 * abad1; CGAL_kernel_assertion_msg( abac1 != NULL_VECTOR, "ab1 and ac1 are collinear" ); CGAL_kernel_assertion_msg( abad1 != NULL_VECTOR, "ab1 and ad1 are collinear" ); if(sc_prod_1 >= 0 ) { if(cosine >= 0) { // the two cosine are >= 0, square(cosine) is decreasing on [0,pi/2] return CGAL::compare(CGAL::square(cosine)* abac1.squared_length()*abad1.squared_length(), CGAL::square(sc_prod_1)); } else { return SMALLER; } } else { if(cosine < 0) { // the two cosine are < 0, square(cosine) is increasing on [pi/2,pi] return CGAL::compare(CGAL::square(sc_prod_1), CGAL::square(cosine)* abac1.squared_length()*abad1.squared_length()); } else return LARGER; } } result_type operator()(const Vector_3& ab1, const Vector_3& ac1, const Vector_3& ad1, const Vector_3& ab2, const Vector_3& ac2, const Vector_3& ad2) const { typedef typename K::FT FT; typedef typename K::Construct_cross_product_vector_3 Cross_product; Cross_product xproduct = K().construct_cross_product_vector_3_object(); const Vector_3 abac1 = xproduct(ab1, ac1); const Vector_3 abad1 = xproduct(ab1, ad1); const FT sc_prod_1 = abac1 * abad1; const Vector_3 abac2 = xproduct(ab2, ac2); const Vector_3 abad2 = xproduct(ab2, ad2); const FT sc_prod_2 = abac2 * abad2; CGAL_kernel_assertion_msg( abac1 != NULL_VECTOR, "ab1 and ac1 are collinear" ); CGAL_kernel_assertion_msg( abad1 != NULL_VECTOR, "ab1 and ad1 are collinear" ); CGAL_kernel_assertion_msg( abac2 != NULL_VECTOR, "ab2 and ac2 are collinear" ); CGAL_kernel_assertion_msg( abad2 != NULL_VECTOR, "ab2 and ad2 are collinear" ); if(sc_prod_1 >= 0 ) { if(sc_prod_2 >= 0) { // the two cosine are >= 0, cosine is decreasing on [0,1] return CGAL::compare(CGAL::square(sc_prod_2)* abac1.squared_length()*abad1.squared_length(), CGAL::square(sc_prod_1)* abac2.squared_length()*abad2.squared_length()); } else { return SMALLER; } } else { if(sc_prod_2 < 0) { // the two cosine are < 0, cosine is increasing on [-1,0] return CGAL::compare(CGAL::square(sc_prod_1)* abac2.squared_length()*abad2.squared_length(), CGAL::square(sc_prod_2)* abac1.squared_length()*abad1.squared_length()); } else return LARGER; } } }; template < typename K > class Compare_power_distance_3 { public: typedef typename K::Weighted_point_3 Weighted_point_3; typedef typename K::Point_3 Point_3; typedef typename K::Comparison_result Comparison_result; typedef Comparison_result result_type; Comparison_result operator()(const Point_3 & p, const Weighted_point_3 & q, const Weighted_point_3 & r) const { return compare_power_distanceC3(p.x(), p.y(), p.z(), q.x(), q.y(), q.z(), q.weight(), r.x(), r.y(), r.z(), r.weight()); } }; template < typename K > class Construct_weighted_circumcenter_3 { public: typedef typename K::Weighted_point_3 Weighted_point_3; typedef typename K::Point_3 Point_3; typedef typename K::FT FT; typedef Point_3 result_type; Point_3 operator()(const Weighted_point_3 & p, const Weighted_point_3 & q, const Weighted_point_3 & r, const Weighted_point_3 & s) const { FT x, y, z; weighted_circumcenterC3(p.x(), p.y(), p.z(), p.weight(), q.x(), q.y(), q.z(), q.weight(), r.x(), r.y(), r.z(), r.weight(), s.x(), s.y(), s.z(), s.weight(), x,y,z); return Point_3(x,y,z); } Point_3 operator()(const Weighted_point_3 & p, const Weighted_point_3 & q, const Weighted_point_3 & r) const { FT x, y, z; weighted_circumcenterC3(p.x(), p.y(), p.z(), p.weight(), q.x(), q.y(), q.z(), q.weight(), r.x(), r.y(), r.z(), r.weight(), x,y,z); return Point_3(x,y,z); } Point_3 operator()(const Weighted_point_3 & p, const Weighted_point_3 & q) const { FT x, y, z; weighted_circumcenterC3(p.x(), p.y(), p.z(), p.weight(), q.x(), q.y(), q.z(), q.weight(), x,y,z); return Point_3(x,y,z); } }; template < class K > class Power_side_of_bounded_power_circle_2 { public: typedef typename K::Weighted_point_2 Weighted_point_2; typedef Bounded_side result_type; Bounded_side operator()(const Weighted_point_2& p, const Weighted_point_2& q, const Weighted_point_2& r, const Weighted_point_2& t) const { K traits; typename K::Orientation_2 orientation = traits.orientation_2_object(); typename K::Construct_point_2 wp2p = traits.construct_point_2_object(); typename K::Power_side_of_oriented_power_circle_2 power_test = traits.power_side_of_oriented_power_circle_2_object(); typename K::Orientation o = orientation(wp2p(p),wp2p(q),wp2p(r)); typename K::Oriented_side os = power_test(p,q,r,t); CGAL_assertion(o != COPLANAR); return enum_cast(o * os); } Bounded_side operator()(const Weighted_point_2& p, const Weighted_point_2& q, const Weighted_point_2& t) const { return power_side_of_bounded_power_circleC2(p.x(), p.y(), p.weight(), q.x(), q.y(), q.weight(), t.x(), t.y(), t.weight()); } Bounded_side operator()(const Weighted_point_2& p, const Weighted_point_2& t) const { return enum_cast( - CGAL_NTS sign( CGAL_NTS square(p.x() - t.x()) + CGAL_NTS square(p.y() - t.y()) + p.weight() - t.weight()) ); } }; // operator () // return the sign of the power test of last weighted point // with respect to the smallest sphere orthogonal to the others template< typename K > class Power_side_of_bounded_power_sphere_3 { public: typedef typename K::Weighted_point_3 Weighted_point_3; typedef typename K::Sign Sign; typedef Bounded_side result_type; Bounded_side operator()(const Weighted_point_3 & p, const Weighted_point_3 & q, const Weighted_point_3 & r, const Weighted_point_3 & s, const Weighted_point_3 & t) const { K traits; typename K::Orientation_3 orientation = traits.orientation_3_object(); typename K::Construct_point_3 wp2p = traits.construct_point_3_object(); typename K::Power_side_of_oriented_power_sphere_3 power_test = traits.power_side_of_oriented_power_sphere_3_object(); typename K::Orientation o = orientation(wp2p(p),wp2p(q),wp2p(r),wp2p(s)); typename K::Oriented_side os = power_test(p,q,r,s,t); // Power_side_of_oriented_power_sphere_3 // returns in fact minus the 5x5 determinant of lifted (p,q,r,s,t) CGAL_assertion(o != COPLANAR); return enum_cast(o * os); } Bounded_side operator()(const Weighted_point_3 & p, const Weighted_point_3 & q, const Weighted_point_3 & r, const Weighted_point_3 & s) const { return power_side_of_bounded_power_sphereC3( p.x(), p.y(), p.z(), p.weight(), q.x(), q.y(), q.z(), q.weight(), r.x(), r.y(), r.z(), r.weight(), s.x(), s.y(), s.z(), s.weight()); } Bounded_side operator()(const Weighted_point_3 & p, const Weighted_point_3 & q, const Weighted_point_3 & r) const { return power_side_of_bounded_power_sphereC3( p.x(), p.y(), p.z(), p.weight(), q.x(), q.y(), q.z(), q.weight(), r.x(), r.y(), r.z(), r.weight()); } Bounded_side operator()(const Weighted_point_3 & p, const Weighted_point_3 & q) const { return enum_cast( - CGAL_NTS sign( CGAL_NTS square(p.x()-q.x()) + CGAL_NTS square(p.y()-q.y()) + CGAL_NTS square(p.z()-q.z()) + p.weight() - q.weight())); } }; template < typename K > class Power_side_of_oriented_power_sphere_3 { public: typedef typename K::Weighted_point_3 Weighted_point_3; typedef typename K::Oriented_side Oriented_side; typedef Oriented_side result_type; Oriented_side operator()(const Weighted_point_3 & p, const Weighted_point_3 & q, const Weighted_point_3 & r, const Weighted_point_3 & s, const Weighted_point_3 & t) const { return power_side_of_oriented_power_sphereC3(p.x(), p.y(), p.z(), p.weight(), q.x(), q.y(), q.z(), q.weight(), r.x(), r.y(), r.z(), r.weight(), s.x(), s.y(), s.z(), s.weight(), t.x(), t.y(), t.z(), t.weight()); } // The methods below are currently undocumented because the definition of // orientation is unclear for 3, 2, and 1 point configurations in a 3D space. // One should be (very) careful with the order of vertices when using them, // as swapping points will change the result and one must therefore have a // precise idea of what is the positive orientation in the full space. // For example, these functions are (currently) used safely in the regular // triangulations classes because we always call them on vertices of // triangulation cells, which are always positively oriented. Oriented_side operator()(const Weighted_point_3 & p, const Weighted_point_3 & q, const Weighted_point_3 & r, const Weighted_point_3 & s) const { //CGAL_kernel_precondition( coplanar(p, q, r, s) ); //CGAL_kernel_precondition( !collinear(p, q, r) ); return power_side_of_oriented_power_sphereC3(p.x(), p.y(), p.z(), p.weight(), q.x(), q.y(), q.z(), q.weight(), r.x(), r.y(), r.z(), r.weight(), s.x(), s.y(), s.z(), s.weight()); } Oriented_side operator()(const Weighted_point_3 & p, const Weighted_point_3 & q, const Weighted_point_3 & r) const { //CGAL_kernel_precondition( collinear(p, q, r) ); //CGAL_kernel_precondition( p.point() != q.point() ); return power_side_of_oriented_power_sphereC3(p.x(), p.y(), p.z(), p.weight(), q.x(), q.y(), q.z(), q.weight(), r.x(), r.y(), r.z(), r.weight()); } Oriented_side operator()(const Weighted_point_3 & p, const Weighted_point_3 & q) const { //CGAL_kernel_precondition( p.point() == r.point() ); return power_side_of_oriented_power_sphereC3(p.weight(),q.weight()); } }; template < typename K > class Compute_weight_2 { public: typedef typename K::Weighted_point_2 Weighted_point_2; typedef typename K::FT Weight; typedef const Weight& result_type; const Weight& operator()(const Weighted_point_2 & p) const { return p.rep().weight(); } }; template < typename K > class Compute_weight_3 { public: typedef typename K::Weighted_point_3 Weighted_point_3; typedef typename K::FT Weight; typedef const Weight& result_type; const Weight& operator()(const Weighted_point_3 & p) const { return p.rep().weight(); } }; template < typename K > class Compute_power_product_2 { public: typedef typename K::Weighted_point_2 Weighted_point_2; typedef typename K::FT FT; typedef FT result_type; FT operator()(const Weighted_point_2 & p, const Weighted_point_2 & q) const { return power_productC2(p.x(), p.y(), p.weight(), q.x(), q.y(), q.weight()); } }; template < typename K > class Compute_power_product_3 { public: typedef typename K::Weighted_point_3 Weighted_point_3; typedef typename K::FT FT; typedef FT result_type; FT operator()(const Weighted_point_3 & p, const Weighted_point_3 & q) const { return power_productC3(p.x(), p.y(), p.z(), p.weight(), q.x(), q.y(), q.z(), q.weight()); } }; template < typename K > class Compute_squared_radius_smallest_orthogonal_circle_2 { public: typedef typename K::Weighted_point_2 Weighted_point_2; typedef typename K::FT FT; typedef FT result_type; FT operator()(const Weighted_point_2& p, const Weighted_point_2& q, const Weighted_point_2& r) const { return squared_radius_orthogonal_circleC2(p.x(), p.y(), p.weight(), q.x(), q.y(), q.weight(), r.x(), r.y(), r.weight()); } FT operator()(const Weighted_point_2& p, const Weighted_point_2& q) const { return squared_radius_smallest_orthogonal_circleC2(p.x(), p.y(), p.weight(), q.x(), q.y(), q.weight()); } FT operator()(const Weighted_point_2& p) const { return - p.weight(); } }; template < typename K > class Compute_squared_radius_smallest_orthogonal_sphere_3 { public: typedef typename K::Weighted_point_3 Weighted_point_3; typedef typename K::FT FT; typedef FT result_type; FT operator()(const Weighted_point_3 & p, const Weighted_point_3 & q, const Weighted_point_3 & r, const Weighted_point_3 & s) const { return squared_radius_orthogonal_sphereC3(p.x(), p.y(), p.z(), p.weight(), q.x(), q.y(), q.z(), q.weight(), r.x(), r.y(), r.z(), r.weight(), s.x(), s.y(), s.z(), s.weight()); } FT operator()(const Weighted_point_3 & p, const Weighted_point_3 & q, const Weighted_point_3 & r) const { return squared_radius_smallest_orthogonal_sphereC3(p.x(), p.y(), p.z(), p.weight(), q.x(), q.y(), q.z(), q.weight(), r.x(), r.y(), r.z(), r.weight()); } FT operator()(const Weighted_point_3 & p, const Weighted_point_3 & q) const { return squared_radius_smallest_orthogonal_sphereC3(p.x(), p.y(), p.z(), p.weight(), q.x(), q.y(), q.z(), q.weight()); } FT operator()(const Weighted_point_3 & p) const { return - p.weight(); } }; // Compute the square radius of the sphere centered in t // and orthogonal to the sphere orthogonal to p,q,r,s template< typename K> class Compute_power_distance_to_power_sphere_3 { public: typedef typename K::Weighted_point_3 Weighted_point_3; typedef typename K::FT FT; typedef FT result_type; result_type operator()(const Weighted_point_3 & p, const Weighted_point_3 & q, const Weighted_point_3 & r, const Weighted_point_3 & s, const Weighted_point_3 & t) const { return power_distance_to_power_sphereC3 (p.x(),p.y(),p.z(),FT(p.weight()), q.x(),q.y(),q.z(),FT(q.weight()), r.x(),r.y(),r.z(),FT(r.weight()), s.x(),s.y(),s.z(),FT(s.weight()), t.x(),t.y(),t.z(),FT(t.weight())); } }; template class Compare_weighted_squared_radius_3 { public: typedef typename K::Weighted_point_3 Weighted_point_3; typedef typename K::Comparison_result Comparison_result; typedef typename K::FT FT; typedef Comparison_result result_type; result_type operator()(const Weighted_point_3 & p, const Weighted_point_3 & q, const Weighted_point_3 & r, const Weighted_point_3 & s, const FT& w) const { return CGAL::compare(squared_radius_orthogonal_sphereC3( p.x(),p.y(),p.z(),p.weight(), q.x(),q.y(),q.z(),q.weight(), r.x(),r.y(),r.z(),r.weight(), s.x(),s.y(),s.z(),s.weight()), w); } result_type operator()(const Weighted_point_3 & p, const Weighted_point_3 & q, const Weighted_point_3 & r, const FT& w) const { return CGAL::compare(squared_radius_smallest_orthogonal_sphereC3( p.x(),p.y(),p.z(),p.weight(), q.x(),q.y(),q.z(),q.weight(), r.x(),r.y(),r.z(),r.weight()), w); } result_type operator()(const Weighted_point_3 & p, const Weighted_point_3 & q, const FT& w) const { return CGAL::compare(squared_radius_smallest_orthogonal_sphereC3( p.x(),p.y(),p.z(),p.weight(), q.x(),q.y(),q.z(),q.weight()), w); } result_type operator()(const Weighted_point_3 & p, const FT& w) const { return CGAL::compare(-p.weight(), w); } }; template class Compare_slope_3 { typedef typename K::FT FT; typedef typename K::Point_3 Point_3; public: typedef typename K::Comparison_result result_type; result_type operator()(const Point_3& p, const Point_3& q, const Point_3& r, const Point_3& s) const { Comparison_result sign_pq = CGAL::compare(q.z(),p.z()); Comparison_result sign_rs = CGAL::compare(s.z(),r.z()); if(sign_pq != sign_rs){ return CGAL::compare(static_cast(sign_pq), static_cast(sign_rs)); } if((sign_pq == EQUAL) && (sign_rs == EQUAL)){ return EQUAL; } CGAL_assertion( (sign_pq == sign_rs) && (sign_pq != EQUAL) ); Comparison_result res = CGAL::compare(square(p.z() - q.z()) * (square(r.x()-s.x())+square(r.y()-s.y())), square(r.z() - s.z()) * (square(p.x()-q.x())+square(p.y()-q.y()))); return (sign_pq == SMALLER) ? opposite(res) : res; } }; template class Compare_squared_distance_2 { typedef typename K::FT FT; public: typedef typename K::Comparison_result result_type; template result_type operator()(const T1& p, const T2& q, const FT& d2) const { return CGAL::compare(squared_distance(p, q), d2); } template result_type operator()(const T1& p, const T2& q, const T3& r, const T4& s) const { return CGAL::compare(squared_distance(p, q), squared_distance(r, s)); } }; template class Compare_squared_distance_3 { typedef typename K::FT FT; public: typedef typename K::Comparison_result result_type; template result_type operator()(const T1& p, const T2& q, const FT& d2) const { return CGAL::compare(squared_distance(p, q), d2); } template result_type operator()(const T1& p, const T2& q, const T3& r, const T4& s) const { return CGAL::compare(squared_distance(p, q), squared_distance(r, s)); } }; template class Compute_approximate_angle_3 { typedef typename K::Point_3 Point_3; typedef typename K::Vector_3 Vector_3; public: typedef typename K::FT result_type; result_type operator()(const Vector_3& u, const Vector_3& v) const { K k; typename K::Compute_scalar_product_3 scalar_product = k.compute_scalar_product_3_object(); double product = CGAL::sqrt(to_double(scalar_product(u,u)) * to_double(scalar_product(v,v))); if(product == 0) return 0; // cosine double dot = to_double(scalar_product(u,v)); double cosine = dot / product; if(cosine > 1.){ cosine = 1.; } if(cosine < -1.){ cosine = -1.; } return std::acos(cosine) * 180./CGAL_PI; } result_type operator()(const Point_3& p, const Point_3& q, const Point_3& r) const { K k; typename K::Construct_vector_3 vector = k.construct_vector_3_object(); Vector_3 u = vector(q,p); Vector_3 v = vector(q,r); return this->operator()(u,v); } }; template class Compute_approximate_dihedral_angle_3 { typedef typename K::Point_3 Point_3; public: typedef typename K::FT result_type; result_type operator()(const Point_3& a, const Point_3& b, const Point_3& c, const Point_3& d) const { K k; typename K::Construct_vector_3 vector = k.construct_vector_3_object(); typename K::Construct_cross_product_vector_3 cross_product = k.construct_cross_product_vector_3_object(); typename K::Compute_squared_distance_3 sq_distance = k.compute_squared_distance_3_object(); typename K::Compute_scalar_product_3 scalar_product = k.compute_scalar_product_3_object(); typedef typename K::Vector_3 Vector_3; typedef typename K::FT FT; const Vector_3 ab = vector(a,b); const Vector_3 ac = vector(a,c); const Vector_3 ad = vector(a,d); const Vector_3 abad = cross_product(ab,ad); const double x = CGAL::to_double(scalar_product(cross_product(ab,ac), abad)); const double l_ab = CGAL::sqrt(CGAL::to_double(sq_distance(a,b))); const double y = l_ab * CGAL::to_double(scalar_product(ac,abad)); return FT(std::atan2(y, x) * 180 / CGAL_PI ); } }; template class Compute_area_3 { typedef typename K::FT FT; typedef typename K::Point_3 Point_3; typedef typename K::Triangle_3 Triangle_3; public: typedef FT result_type; FT operator()( const Triangle_3& t ) const { return CGAL_NTS sqrt(K().compute_squared_area_3_object()(t)); } FT operator()( const Point_3& p, const Point_3& q, const Point_3& r ) const { return CGAL_NTS sqrt(K().compute_squared_area_3_object()(p, q, r)); } }; template class Compute_squared_distance_2 { typedef typename K::FT FT; public: typedef FT result_type; // There are 25 combinaisons, we use a template. template FT operator()( const T1& t1, const T2& t2) const { return internal::squared_distance(t1, t2, K()); } }; template class Compute_squared_distance_3 { typedef typename K::FT FT; typedef typename K::Point_3 Point_3; public: typedef FT result_type; // There are 25 combinaisons, we use a template. template FT operator()( const T1& t1, const T2& t2) const { return internal::squared_distance(t1, t2, K()); } FT operator()( const Point_3& pt1, const Point_3& pt2) const { typedef typename K::Vector_3 Vector_3; Vector_3 vec = pt2 - pt1; return vec*vec; } }; template class Compute_squared_length_2 { typedef typename K::FT FT; typedef typename K::Segment_2 Segment_2; typedef typename K::Vector_2 Vector_2; public: typedef FT result_type; FT operator()( const Vector_2& v) const { return CGAL_NTS square(K().compute_x_2_object()(v)) + CGAL_NTS square(K().compute_y_2_object()(v));} FT operator()( const Segment_2& s) const { return K().compute_squared_distance_2_object()(s.source(), s.target()); } }; template class Compute_squared_length_3 { typedef typename K::FT FT; typedef typename K::Segment_3 Segment_3; typedef typename K::Vector_3 Vector_3; public: typedef FT result_type; FT operator()( const Vector_3& v) const { return v.rep().squared_length(); } FT operator()( const Segment_3& s) const { return s.squared_length(); } }; template class Compute_a_2 { typedef typename K::RT RT; typedef typename K::Line_2 Line_2; public: typedef RT result_type; RT operator()(const Line_2& l) const { return l.rep().a(); } }; template class Compute_a_3 { typedef typename K::RT RT; typedef typename K::Plane_3 Plane_3; public: typedef RT result_type; RT operator()(const Plane_3& l) const { return l.rep().a(); } }; template class Compute_b_2 { typedef typename K::RT RT; typedef typename K::Line_2 Line_2; public: typedef RT result_type; RT operator()(const Line_2& l) const { return l.rep().b(); } }; template class Compute_b_3 { typedef typename K::RT RT; typedef typename K::Plane_3 Plane_3; public: typedef RT result_type; RT operator()(const Plane_3& l) const { return l.rep().b(); } }; template class Compute_c_2 { typedef typename K::RT RT; typedef typename K::Line_2 Line_2; public: typedef RT result_type; RT operator()(const Line_2& l) const { return l.rep().c(); } }; template class Compute_c_3 { typedef typename K::RT RT; typedef typename K::Plane_3 Plane_3; public: typedef RT result_type; RT operator()(const Plane_3& l) const { return l.rep().c(); } }; template class Compute_d_3 { typedef typename K::RT RT; typedef typename K::Plane_3 Plane_3; public: typedef RT result_type; RT operator()(const Plane_3& l) const { return l.rep().d(); } }; template class Compute_x_at_y_2 { typedef typename K::FT FT; typedef typename K::Point_2 Point_2; typedef typename K::Line_2 Line_2; public: typedef FT result_type; FT operator()(const Line_2& l, const FT& y) const { CGAL_kernel_precondition( ! l.is_degenerate() ); return (FT(-l.b())*y - FT(l.c()) )/FT(l.a()); } }; template class Compute_y_at_x_2 { typedef typename K::FT FT; typedef typename K::Point_2 Point_2; typedef typename K::Line_2 Line_2; public: typedef FT result_type; FT operator()(const Line_2& l, const FT& x) const { CGAL_kernel_precondition_msg( ! l.is_vertical(), "Compute_y_at_x(FT x) is undefined for vertical line"); return (FT(-l.a())*x - FT(l.c()) )/FT(l.b()); } }; template class Compute_xmin_2 { typedef typename K::FT FT; typedef typename K::Iso_rectangle_2 Iso_rectangle_2; typedef FT Cartesian_coordinate_type; //typedef typename K::Cartesian_coordinate_type Cartesian_coordinate_type; public: typedef FT result_type; Cartesian_coordinate_type operator()(const Iso_rectangle_2& r) const { return (r.min)().x(); } }; template class Compute_xmin_3 { typedef typename K::FT FT; typedef typename K::Iso_cuboid_3 Iso_cuboid_3; typedef FT Cartesian_coordinate_type; //typedef typename K::Cartesian_coordinate_type Cartesian_coordinate_type; public: typedef FT result_type; Cartesian_coordinate_type operator()(const Iso_cuboid_3& r) const { return (r.min)().x(); } }; template class Compute_xmax_2 { typedef typename K::FT FT; typedef typename K::Iso_rectangle_2 Iso_rectangle_2; typedef FT Cartesian_coordinate_type; //typedef typename K::Cartesian_coordinate_type Cartesian_coordinate_type; public: typedef FT result_type; Cartesian_coordinate_type operator()(const Iso_rectangle_2& r) const { return (r.max)().x(); } }; template class Compute_xmax_3 { typedef typename K::FT FT; typedef typename K::Iso_cuboid_3 Iso_cuboid_3; typedef FT Cartesian_coordinate_type; //typedef typename K::Cartesian_coordinate_type Cartesian_coordinate_type; public: typedef FT result_type; Cartesian_coordinate_type operator()(const Iso_cuboid_3& r) const { return (r.max)().x(); } }; template class Compute_ymin_2 { typedef typename K::FT FT; typedef typename K::Iso_rectangle_2 Iso_rectangle_2; typedef FT Cartesian_coordinate_type; //typedef typename K::Cartesian_coordinate_type Cartesian_coordinate_type; public: typedef FT result_type; Cartesian_coordinate_type operator()(const Iso_rectangle_2& r) const { return (r.min)().y(); } }; template class Compute_ymin_3 { typedef typename K::FT FT; typedef typename K::Iso_cuboid_3 Iso_cuboid_3; typedef FT Cartesian_coordinate_type; //typedef typename K::Cartesian_coordinate_type Cartesian_coordinate_type; public: typedef FT result_type; Cartesian_coordinate_type operator()(const Iso_cuboid_3& r) const { return (r.min)().y(); } }; template class Compute_ymax_2 { typedef typename K::FT FT; typedef typename K::Iso_rectangle_2 Iso_rectangle_2; typedef FT Cartesian_coordinate_type; //typedef typename K::Cartesian_coordinate_type Cartesian_coordinate_type; public: typedef FT result_type; Cartesian_coordinate_type operator()(const Iso_rectangle_2& r) const { return (r.max)().y(); } }; template class Compute_ymax_3 { typedef typename K::FT FT; typedef typename K::Iso_cuboid_3 Iso_cuboid_3; typedef FT Cartesian_coordinate_type; //typedef typename K::Cartesian_coordinate_type Cartesian_coordinate_type; public: typedef FT result_type; Cartesian_coordinate_type operator()(const Iso_cuboid_3& r) const { return (r.max)().y(); } }; template class Compute_zmin_3 { typedef typename K::FT FT; typedef typename K::Iso_cuboid_3 Iso_cuboid_3; typedef FT Cartesian_coordinate_type; //typedef typename K::Cartesian_coordinate_type Cartesian_coordinate_type; public: typedef FT result_type; Cartesian_coordinate_type operator()(const Iso_cuboid_3& r) const { return (r.min)().z(); } }; template class Compute_zmax_3 { typedef typename K::FT FT; typedef typename K::Iso_cuboid_3 Iso_cuboid_3; typedef FT Cartesian_coordinate_type; //typedef typename K::Cartesian_coordinate_type Cartesian_coordinate_type; public: typedef FT result_type; Cartesian_coordinate_type operator()(const Iso_cuboid_3& r) const { return (r.max)().z(); } }; template class Compute_L_infinity_distance_2 { typedef typename K::FT FT; typedef typename K::Point_2 Point_2; public: typedef FT result_type; result_type operator()(const Point_2& p, const Point_2& q) const { return (std::max)( CGAL::abs( K().compute_x_2_object()(p) - K().compute_x_2_object()(q)), CGAL::abs( K().compute_y_2_object()(p) - K().compute_y_2_object()(q)) ); } }; template class Compute_L_infinity_distance_3 { typedef typename K::FT FT; typedef typename K::Point_3 Point_3; public: typedef FT result_type; result_type operator()(const Point_3& p, const Point_3& q) const { return (std::max)( CGAL::abs( K().compute_x_3_object()(p) - K().compute_x_3_object()(q)), (std::max)(CGAL::abs( K().compute_y_3_object()(p) - K().compute_y_3_object()(q)), CGAL::abs( K().compute_z_3_object()(p) - K().compute_z_3_object()(q)))); } }; template class Construct_center_2 { typedef typename K::Point_2 Point_2; typedef typename K::Circle_2 Circle_2; public: typedef const Point_2& result_type; result_type operator()(const Circle_2& c) const { return c.rep().center(); } }; template class Construct_center_3 { typedef typename K::Point_3 Point_3; typedef typename K::Sphere_3 Sphere_3; typedef typename K::Circle_3 Circle_3; public: typedef const Point_3& result_type; result_type operator()(const Sphere_3& s) const { return s.rep().center(); } result_type operator()(const Circle_3& c) const { return c.rep().center(); } }; template class Construct_circle_2 { typedef typename K::FT FT; typedef typename K::Point_2 Point_2; typedef typename K::Circle_2 Circle_2; typedef typename Circle_2::Rep Rep; public: typedef Circle_2 result_type; Rep // Circle_2 operator()( Return_base_tag, const Point_2& center, const FT& squared_radius, Orientation orientation = COUNTERCLOCKWISE) const { return Rep(center, squared_radius, orientation); } Rep // Circle_2 operator()( Return_base_tag, const Point_2& p, const Point_2& q, const Point_2& r) const { typename K::Orientation_2 orientation; typename K::Compute_squared_distance_2 squared_distance; typename K::Construct_circumcenter_2 circumcenter; typename K::Orientation orient = orientation(p, q, r); CGAL_kernel_precondition( orient != COLLINEAR); Point_2 center = circumcenter(p, q, r); return Rep(center, squared_distance(p, center), orient); } Rep // Circle_2 operator()( Return_base_tag, const Point_2& p, const Point_2& q, Orientation orientation = COUNTERCLOCKWISE) const { CGAL_kernel_precondition( orientation != COLLINEAR); typename K::Compute_squared_distance_2 squared_distance; typename K::Construct_midpoint_2 midpoint; if (p != q) { Point_2 center = midpoint(p, q); return Rep(center, squared_distance(p, center), orientation); } else return Rep(p, FT(0), orientation); } Rep // Circle_2 operator()( Return_base_tag, const Point_2& p, const Point_2& q, const FT& bulge) const { typename K::Compute_squared_distance_2 squared_distance; const FT sqr_bulge = CGAL::square(bulge); const FT common = (FT(1) - sqr_bulge) / (FT(4)*bulge); const FT x_coord = (p.x() + q.x())/FT(2) + common*(p.y() - q.y()); const FT y_coord = (p.y() + q.y())/FT(2) + common*(q.x() - p.x()); const FT sqr_rad = squared_distance(p, q) * (FT(1)/sqr_bulge + FT(2) + sqr_bulge) / FT(16); return Rep(Point_2(x_coord, y_coord), sqr_rad); } Rep // Circle_2 operator()( Return_base_tag, const Point_2& center, Orientation orientation = COUNTERCLOCKWISE) const { CGAL_kernel_precondition( orientation != COLLINEAR ); return Rep(center, FT(0), orientation); } Circle_2 operator()( const Point_2& center, const FT& squared_radius, Orientation orientation = COUNTERCLOCKWISE) const { return this->operator()(Return_base_tag(), center, squared_radius, orientation); } Circle_2 operator()( const Point_2& p, const Point_2& q, const Point_2& r) const { return this->operator()(Return_base_tag(), p, q, r); } Circle_2 operator()( const Point_2& p, const Point_2& q, Orientation orientation = COUNTERCLOCKWISE) const { return this->operator()(Return_base_tag(), p, q, orientation); } Circle_2 operator()( const Point_2& p, const Point_2& q, const FT& bulge) const { return this->operator()(Return_base_tag(), p, q, bulge); } Circle_2 operator()( const Point_2& center, Orientation orientation = COUNTERCLOCKWISE) const { return this->operator()(Return_base_tag(), center, orientation); } }; template < typename K > class Construct_circle_3 { typedef typename K::FT FT; typedef typename K::Point_3 Point_3; typedef typename K::Plane_3 Plane_3; typedef typename K::Sphere_3 Sphere_3; typedef typename K::Circle_3 Circle_3; typedef typename K::Vector_3 Vector_3; typedef typename K::Direction_3 Direction_3; typedef typename Circle_3::Rep Rep; public: typedef Circle_3 result_type; Rep operator() (Return_base_tag, const Point_3& p, const FT& sr, const Plane_3& plane) const { return Rep(p, sr, plane); } Rep operator() (Return_base_tag, const Point_3& p, const FT& sr, const Vector_3& v) const { return Rep(p, sr, v); } Rep operator() (Return_base_tag, const Point_3& p, const FT& sr, const Direction_3& d) const { return Rep(p, sr, d); } Rep operator() (Return_base_tag, const Sphere_3& s1, const Sphere_3& s2) const { return Rep(s1, s2); } Rep operator() (Return_base_tag, const Plane_3& p, const Sphere_3& s) const { return Rep(p, s); } Rep operator() (Return_base_tag, const Plane_3& p, const Sphere_3& s, int a) const { return Rep(p, s, a); } Rep operator() (Return_base_tag, const Point_3& p1, const Point_3& p2, const Point_3& p3) const { return Rep(p1, p2, p3); } Circle_3 operator()(const Point_3& p, const FT& sr, const Plane_3& plane) const { return this->operator()(Return_base_tag(), p, sr, plane); } Circle_3 operator() (const Point_3& p, const FT& sr, const Vector_3& v) const { return this->operator()(Return_base_tag(), p, sr, v); } Circle_3 operator() (const Point_3& p, const FT& sr, const Direction_3& d) const { return this->operator()(Return_base_tag(), p, sr, d); } Circle_3 operator() (const Sphere_3& s1, const Sphere_3& s2) const { return this->operator()(Return_base_tag(), s1, s2); } Circle_3 operator() (const Plane_3& p, const Sphere_3& s) const { return this->operator()(Return_base_tag(), p, s); } Circle_3 operator() (const Sphere_3& s, const Plane_3& p) const { return this->operator()(Return_base_tag(), p, s); } Circle_3 operator() (const Plane_3& p, const Sphere_3& s, int a) const { return this->operator()(Return_base_tag(), p, s, a); } Circle_3 operator() (const Sphere_3& s, const Plane_3& p, int a) const { return this->operator()(Return_base_tag(), p, s, a); } Circle_3 operator()( const Point_3& p1, const Point_3& p2, const Point_3& p3) const { return this->operator()(Return_base_tag(), p1, p2, p3); } }; template class Construct_iso_cuboid_3 { typedef typename K::RT RT; typedef typename K::Point_3 Point_3; typedef typename K::Iso_cuboid_3 Iso_cuboid_3; typedef typename Iso_cuboid_3::Rep Rep; public: typedef Iso_cuboid_3 result_type; Rep // Iso_cuboid_3 operator()(Return_base_tag, const Point_3& p, const Point_3& q, int) const { return Rep(p, q, 0); } Rep // Iso_cuboid_3 operator()(Return_base_tag, const Point_3& p, const Point_3& q) const { return Rep(p, q); } Rep // Iso_cuboid_3 operator()(Return_base_tag, const Point_3 &left, const Point_3 &right, const Point_3 &bottom, const Point_3 &top, const Point_3 &far_, const Point_3 &close) const { return Rep(left, right, bottom, top, far_, close); } Rep // Iso_cuboid_3 operator()(Return_base_tag, const RT& min_hx, const RT& min_hy, const RT& min_hz, const RT& max_hx, const RT& max_hy, const RT& max_hz, const RT& hw) const { return Rep(min_hx, min_hy, min_hz, max_hx, max_hy, max_hz, hw); } Rep // Iso_cuboid_3 operator()(Return_base_tag, const RT& min_hx, const RT& min_hy, const RT& min_hz, const RT& max_hx, const RT& max_hy, const RT& max_hz) const { return Rep(min_hx, min_hy, min_hz, max_hx, max_hy, max_hz); } Iso_cuboid_3 operator()(const Point_3& p, const Point_3& q, int) const { return this->operator()(Return_base_tag(), p, q, 0); } Iso_cuboid_3 operator()(const Point_3& p, const Point_3& q) const { return this->operator()(Return_base_tag(), p, q); } Iso_cuboid_3 operator()(const Point_3 &left, const Point_3 &right, const Point_3 &bottom, const Point_3 &top, const Point_3 &far_, const Point_3 &close) const { return this->operator()(Return_base_tag(), left, right, bottom, top, far_, close); } Iso_cuboid_3 operator()(const RT& min_hx, const RT& min_hy, const RT& min_hz, const RT& max_hx, const RT& max_hy, const RT& max_hz, const RT& hw) const { return this->operator()(Return_base_tag(), min_hx, min_hy, min_hz, max_hx, max_hy, max_hz, hw); } Iso_cuboid_3 operator()(const RT& min_hx, const RT& min_hy, const RT& min_hz, const RT& max_hx, const RT& max_hy, const RT& max_hz) const { return this->operator()(Return_base_tag(), min_hx, min_hy, min_hz, max_hx, max_hy, max_hz); } }; template class Construct_line_line_intersection_point_3 { typedef typename K::Line_3 Line; typedef typename K::Point_3 Point; typename K::Construct_line_3 construct_line; public: typedef Point result_type; Point operator()(const Point& l11, const Point& l12, const Point& l21, const Point& l22) const { Line l1 = construct_line(l11, l12); Line l2 = construct_line(l21, l22); typename cpp11::result_of::type res = typename K::Intersect_3()(l1,l2); CGAL_assertion(res!=boost::none); const Point* e_pt = boost::get(&(*res)); CGAL_assertion(e_pt!=nullptr); return *e_pt; } }; template class Construct_max_vertex_2 { typedef typename K::Point_2 Point_2; typedef typename K::Segment_2 Segment_2; typedef typename K::Iso_rectangle_2 Iso_rectangle_2; public: typedef const Point_2& result_type; result_type operator()(const Iso_rectangle_2& r) const { return (r.rep().max)(); } result_type operator()(const Segment_2& s) const { return (s.max)(); } }; template class Construct_min_vertex_2 { typedef typename K::Point_2 Point_2; typedef typename K::Segment_2 Segment_2; typedef typename K::Iso_rectangle_2 Iso_rectangle_2; public: typedef const Point_2& result_type; result_type operator()(const Iso_rectangle_2& r) const { return (r.rep().min)(); } result_type operator()(const Segment_2& s) const { return (s.min)(); } }; template class Construct_max_vertex_3 { typedef typename K::Point_3 Point_3; typedef typename K::Segment_3 Segment_3; typedef typename K::Iso_cuboid_3 Iso_cuboid_3; public: typedef const Point_3& result_type; result_type operator()(const Iso_cuboid_3& r) const { return (r.rep().max)(); } result_type operator()(const Segment_3& s) const { return (s.rep().max)(); } }; template class Construct_min_vertex_3 { typedef typename K::Point_3 Point_3; typedef typename K::Segment_3 Segment_3; typedef typename K::Iso_cuboid_3 Iso_cuboid_3; public: typedef const Point_3& result_type; result_type operator()(const Iso_cuboid_3& r) const { return (r.rep().min)(); } result_type operator()(const Segment_3& s) const { return (s.rep().min)(); } }; template class Construct_normal_3 { typedef typename K::Point_3 Point_3; typedef typename K::Vector_3 Vector_3; public: typedef Vector_3 result_type; Vector_3 operator()(const Point_3& p,const Point_3& q, const Point_3& r) const { CGAL_kernel_precondition(! K().collinear_3_object()(p,q,r) ); Vector_3 res = CGAL::cross_product(q-p, r-p); return res; } }; template class Construct_object_2 { typedef typename K::Object_2 Object_2; public: typedef Object_2 result_type; template Object_2 operator()( const Cls& c) const { return make_object(c); } }; template class Construct_object_3 { typedef typename K::Object_3 Object_3; public: typedef Object_3 result_type; template Object_3 operator()( const Cls& c) const { return make_object(c); } }; template class Construct_opposite_circle_2 { typedef typename K::Circle_2 Circle_2; public: typedef Circle_2 result_type; Circle_2 operator()( const Circle_2& c) const { return c.opposite(); } }; template class Construct_opposite_direction_2 { typedef typename K::Direction_2 Direction_2; typedef typename Direction_2::Rep Rep; public: typedef Direction_2 result_type; Direction_2 operator()( const Direction_2& d) const { return Rep(-d.dx(), -d.dy()); } }; template class Construct_opposite_direction_3 { typedef typename K::Direction_3 Direction_3; typedef typename Direction_3::Rep Rep; public: typedef Direction_3 result_type; Direction_3 operator()( const Direction_3& d) const { return Rep(-d.dx(), -d.dy(), -d.dz()); } }; template class Construct_opposite_line_2 { typedef typename K::Line_2 Line_2; public: typedef Line_2 result_type; Line_2 operator()( const Line_2& l) const { return Line_2( -l.a(), -l.b(), -l.c()); } }; template class Construct_opposite_line_3 { typedef typename K::Line_3 Line_3; public: typedef Line_3 result_type; Line_3 operator()( const Line_3& l) const { return l.rep().opposite(); } }; template class Construct_opposite_plane_3 { typedef typename K::Plane_3 Plane_3; public: typedef Plane_3 result_type; Plane_3 operator()( const Plane_3& p) const { return p.rep().opposite(); } }; template class Construct_opposite_ray_2 { typedef typename K::Ray_2 Ray_2; public: typedef Ray_2 result_type; Ray_2 operator()( const Ray_2& r) const { return r.opposite(); } }; template class Construct_opposite_ray_3 { typedef typename K::Ray_3 Ray_3; public: typedef Ray_3 result_type; Ray_3 operator()( const Ray_3& r) const { return r.opposite(); } }; template class Construct_opposite_segment_2 { typedef typename K::Segment_2 Segment_2; public: typedef Segment_2 result_type; Segment_2 operator()( const Segment_2& s) const { return Segment_2(s.target(), s.source()); } }; template class Construct_opposite_segment_3 { typedef typename K::Segment_3 Segment_3; public: typedef Segment_3 result_type; Segment_3 operator()( const Segment_3& s) const { return s.rep().opposite(); } }; template class Construct_opposite_sphere_3 { typedef typename K::Sphere_3 Sphere_3; public: typedef Sphere_3 result_type; Sphere_3 operator()( const Sphere_3& s) const { return s.rep().opposite(); } }; template class Construct_opposite_triangle_2 { typedef typename K::Triangle_2 Triangle_2; public: typedef Triangle_2 result_type; Triangle_2 operator()( const Triangle_2& t) const { return Triangle_2(t.vertex(0), t.vertex(2), t.vertex(1));} }; template class Construct_perpendicular_line_3 { typedef typename K::Line_3 Line_3; typedef typename K::Point_3 Point_3; typedef typename K::Plane_3 Plane_3; public: typedef Line_3 result_type; Line_3 operator()( const Plane_3& pl, const Point_3& p) const { return pl.rep().perpendicular_line(p); } }; template class Construct_perpendicular_plane_3 { typedef typename K::Line_3 Line_3; typedef typename K::Point_3 Point_3; typedef typename K::Plane_3 Plane_3; public: typedef Plane_3 result_type; Plane_3 operator()( const Line_3& l, const Point_3& p) const { return l.rep().perpendicular_plane(p); } }; template class Construct_plane_3 { typedef typename K::RT RT; typedef typename K::Point_3 Point_3; typedef typename K::Vector_3 Vector_3; typedef typename K::Direction_3 Direction_3; typedef typename K::Line_3 Line_3; typedef typename K::Ray_3 Ray_3; typedef typename K::Segment_3 Segment_3; typedef typename K::Plane_3 Plane_3; typedef typename K::Circle_3 Circle_3; typedef typename Plane_3::Rep Rep; public: typedef Plane_3 result_type; Rep // Plane_3 operator()(Return_base_tag, const RT& a, const RT& b, const RT& c, const RT& d) const { return Rep(a, b, c, d); } Rep // Plane_3 operator()(Return_base_tag, const Point_3& p, const Point_3& q, const Point_3& r) const { return Rep(p, q, r); } Rep // Plane_3 operator()(Return_base_tag, const Point_3& p, const Direction_3& d) const { return Rep(p, d); } Rep // Plane_3 operator()(Return_base_tag, const Point_3& p, const Vector_3& v) const { return Rep(p, v); } Rep // Plane_3 operator()(Return_base_tag, const Line_3& l, const Point_3& p) const { return Rep(l, p); } Rep // Plane_3 operator()(Return_base_tag, const Ray_3& r, const Point_3& p) const { return Rep(r, p); } Rep // Plane_3 operator()(Return_base_tag, const Segment_3& s, const Point_3& p) const { return Rep(s, p); } Rep // Plane_3 operator()(Return_base_tag, const Circle_3 & c) const { return c.rep().supporting_plane(); } Plane_3 operator()(const RT& a, const RT& b, const RT& c, const RT& d) const { return this->operator()(Return_base_tag(), a, b, c, d); } Plane_3 operator()(const Point_3& p, const Point_3& q, const Point_3& r) const { return this->operator()(Return_base_tag(), p, q, r); } Plane_3 operator()(const Point_3& p, const Direction_3& d) const { return this->operator()(Return_base_tag(), p, d); } Plane_3 operator()(const Point_3& p, const Vector_3& v) const { return this->operator()(Return_base_tag(), p, v); } Plane_3 operator()(const Line_3& l, const Point_3& p) const { return this->operator()(Return_base_tag(), l, p); } Plane_3 operator()(const Ray_3& r, const Point_3& p) const { return this->operator()(Return_base_tag(), r, p); } Plane_3 operator()(const Segment_3& s, const Point_3& p) const { return this->operator()(Return_base_tag(), s, p); } Plane_3 operator()(const Circle_3 & c) const { return this->operator()(Return_base_tag(), c); } }; template class Construct_plane_line_intersection_point_3 { typedef typename K::Plane_3 Plane; typedef typename K::Line_3 Line; typedef typename K::Point_3 Point; typename K::Construct_plane_3 construct_plane; typename K::Construct_line_3 construct_line; public: typedef Point result_type; Point operator()(const Point& p1, const Point& p2, const Point& p3, const Point& l1, const Point& l2) const { Plane plane = construct_plane(p1, p2, p3); Line line = construct_line( l1, l2 ); typename cpp11::result_of::type res = typename K::Intersect_3()(plane,line); CGAL_assertion(res!=boost::none); const Point* e_pt = boost::get(&(*res)); CGAL_assertion(e_pt!=nullptr); return *e_pt; } Point operator()(const Plane& plane, const Point& l1, const Point& l2) const { Line line = construct_line( l1, l2 ); typename cpp11::result_of::type res = typename K::Intersect_3()(plane,line); CGAL_assertion(res!=boost::none); const Point* e_pt = boost::get(&(*res)); CGAL_assertion(e_pt!=nullptr); return *e_pt; } }; template class Construct_point_on_2 { typedef typename K::FT FT; typedef typename K::Point_2 Point_2; typedef typename K::Segment_2 Segment_2; typedef typename K::Line_2 Line_2; typedef typename K::Ray_2 Ray_2; public: typedef Point_2 result_type; Point_2 operator()( const Line_2& l, const FT i) const { return l.point(i); } Point_2 operator()( const Segment_2& s, int i) const { return s.point(i); } Point_2 operator()( const Ray_2& r, const FT i) const { return r.point(i); } }; template class Construct_point_on_3 { typedef typename K::FT FT; typedef typename K::Point_3 Point_3; typedef typename K::Segment_3 Segment_3; typedef typename K::Line_3 Line_3; typedef typename K::Ray_3 Ray_3; typedef typename K::Plane_3 Plane_3; public: typedef Point_3 result_type; Point_3 operator()( const Line_3& l, const FT i) const { return l.rep().point(i); } Point_3 operator()( const Segment_3& s, int i) const { return s.point(i); } Point_3 operator()( const Ray_3& r, const FT i) const { return r.rep().point(i); } Point_3 operator()( const Plane_3& p) const { return p.rep().point(); } }; template class Construct_projected_xy_point_2 { typedef typename K::Point_2 Point_2; typedef typename K::Point_3 Point_3; typedef typename K::Plane_3 Plane_3; public: typedef Point_2 result_type; Point_2 operator()( const Plane_3& h, const Point_3& p) const { return h.rep().to_2d(p); } }; template class Construct_ray_2 { typedef typename K::Point_2 Point_2; typedef typename K::Vector_2 Vector_2; typedef typename K::Direction_2 Direction_2; typedef typename K::Line_2 Line_2; typedef typename K::Ray_2 Ray_2; typedef typename Ray_2::Rep Rep; public: typedef Ray_2 result_type; Rep // Ray_2 operator()(Return_base_tag, const Point_2& p, const Point_2& q) const { return Rep(p, q); } Rep // Ray_2 operator()(Return_base_tag, const Point_2& p, const Vector_2& v) const { return Rep(p, K().construct_translated_point_2_object()(p, v)); } Rep // Ray_2 operator()(Return_base_tag, const Point_2& p, const Direction_2& d) const { return Rep(p, K().construct_translated_point_2_object()(p, d.to_vector())); } Rep // Ray_2 operator()(Return_base_tag, const Point_2& p, const Line_2& l) const { return Rep(p, K().construct_translated_point_2_object()(p, l.to_vector())); } Ray_2 operator()(const Point_2& p, const Point_2& q) const { return this->operator()(Return_base_tag(), p, q); } Ray_2 operator()(const Point_2& p, const Vector_2& v) const { return this->operator()(Return_base_tag(), p, v); } Ray_2 operator()(const Point_2& p, const Direction_2& d) const { return this->operator()(Return_base_tag(), p, d); } Ray_2 operator()(const Point_2& p, const Line_2& l) const { return this->operator()(Return_base_tag(), p, l); } }; template class Construct_ray_3 { typedef typename K::Point_3 Point_3; typedef typename K::Vector_3 Vector_3; typedef typename K::Direction_3 Direction_3; typedef typename K::Line_3 Line_3; typedef typename K::Ray_3 Ray_3; typedef typename Ray_3::Rep Rep; public: typedef Ray_3 result_type; Rep // Ray_3 operator()(Return_base_tag, const Point_3& p, const Point_3& q) const { return Rep(p, q); } Rep // Ray_3 operator()(Return_base_tag, const Point_3& p, const Vector_3& v) const { return Rep(p, v); } Rep // Ray_3 operator()(Return_base_tag, const Point_3& p, const Direction_3& d) const { return Rep(p, d); } Rep // Ray_3 operator()(Return_base_tag, const Point_3& p, const Line_3& l) const { return Rep(p, l); } Ray_3 operator()(const Point_3& p, const Point_3& q) const { return this->operator()(Return_base_tag(), p, q); } Ray_3 operator()(const Point_3& p, const Vector_3& v) const { return this->operator()(Return_base_tag(), p, v); } Ray_3 operator()(const Point_3& p, const Direction_3& d) const { return this->operator()(Return_base_tag(), p, d); } Ray_3 operator()(const Point_3& p, const Line_3& l) const { return this->operator()(Return_base_tag(), p, l); } }; template class Construct_segment_2 { typedef typename K::Segment_2 Segment_2; typedef typename Segment_2::Rep Rep; typedef typename K::Point_2 Point_2; public: typedef Segment_2 result_type; Rep // Segment_2 operator()(Return_base_tag, const Point_2& p, const Point_2& q) const { return Rep(p, q); } Segment_2 operator()( const Point_2& p, const Point_2& q) const { return this->operator()(Return_base_tag(), p, q); } }; template class Construct_segment_3 { typedef typename K::Segment_3 Segment_3; typedef typename K::Point_3 Point_3; typedef typename Segment_3::Rep Rep; public: typedef Segment_3 result_type; Rep // Segment_3 operator()(Return_base_tag, const Point_3& p, const Point_3& q) const { return Rep(p, q); } Segment_3 operator()( const Point_3& p, const Point_3& q) const { return this->operator()(Return_base_tag(), p, q); } }; template class Construct_source_2 { typedef typename K::Segment_2 Segment_2; typedef typename K::Ray_2 Ray_2; typedef typename K::Point_2 Point_2; public: typedef const Point_2& result_type; result_type operator()(const Segment_2& s) const { return s.rep().source(); } result_type operator()(const Ray_2& r) const { return r.rep().source(); } }; template class Construct_source_3 { typedef typename K::Segment_3 Segment_3; typedef typename K::Ray_3 Ray_3; typedef typename K::Point_3 Point_3; public: typedef const Point_3& result_type; result_type operator()(const Segment_3& s) const { return s.rep().source(); } result_type operator()(const Ray_3& r) const { return r.rep().source(); } }; template class Construct_target_2 { typedef typename K::Segment_2 Segment_2; typedef typename K::Point_2 Point_2; public: typedef const Point_2& result_type; result_type operator()(const Segment_2& s) const { return s.rep().target(); } }; template class Construct_target_3 { typedef typename K::Segment_3 Segment_3; typedef typename K::Point_3 Point_3; public: typedef const Point_3& result_type; result_type operator()(const Segment_3& s) const { return s.rep().target(); } }; template class Construct_second_point_2 { typedef typename K::Ray_2 Ray_2; typedef typename K::Point_2 Point_2; public: typedef const Point_2& result_type; result_type operator()(const Ray_2& r) const { return r.rep().second_point(); } }; template class Construct_second_point_3 { typedef typename K::Ray_3 Ray_3; typedef typename K::Point_3 Point_3; public: typedef Point_3 result_type; result_type // const result_type& // Homogeneous... operator()(const Ray_3& r) const { return r.rep().second_point(); } }; template class Construct_sphere_3 { typedef typename K::FT FT; typedef typename K::Point_3 Point_3; typedef typename K::Sphere_3 Sphere_3; typedef typename K::Circle_3 Circle_3; typedef typename Sphere_3::Rep Rep; public: typedef Sphere_3 result_type; Rep // Sphere_3 operator()(Return_base_tag, const Point_3& center, const FT& squared_radius, Orientation orientation = COUNTERCLOCKWISE) const { return Rep(center, squared_radius, orientation); } Rep // Sphere_3 operator()(Return_base_tag, const Point_3& p, const Point_3& q, const Point_3& r, const Point_3& s) const { return Rep(p, q, r, s); } Rep // Sphere_3 operator()(Return_base_tag, const Point_3& p, const Point_3& q, const Point_3& r, Orientation orientation = COUNTERCLOCKWISE) const { return Rep(p, q, r, orientation); } Rep // Sphere_3 operator()(Return_base_tag, const Point_3& p, const Point_3& q, Orientation orientation = COUNTERCLOCKWISE) const { return Rep(p, q, orientation); } Rep // Sphere_3 operator()(Return_base_tag, const Point_3& center, Orientation orientation = COUNTERCLOCKWISE) const { return Rep(center, orientation); } Rep operator() (Return_base_tag, const Circle_3 & c) const { return c.rep().diametral_sphere(); } Sphere_3 operator()( const Point_3& center, const FT& squared_radius, Orientation orientation = COUNTERCLOCKWISE) const { return this->operator()(Return_base_tag(), center, squared_radius, orientation); } Sphere_3 operator()( const Point_3& p, const Point_3& q, const Point_3& r, const Point_3& s) const { return this->operator()(Return_base_tag(), p, q, r, s); } Sphere_3 operator()( const Point_3& p, const Point_3& q, const Point_3& r, Orientation orientation = COUNTERCLOCKWISE) const { return this->operator()(Return_base_tag(), p, q, r, orientation); } Sphere_3 operator()( const Point_3& p, const Point_3& q, Orientation orientation = COUNTERCLOCKWISE) const { return this->operator()(Return_base_tag(), p, q, orientation); } Sphere_3 operator()( const Point_3& center, Orientation orientation = COUNTERCLOCKWISE) const { return this->operator()(Return_base_tag(), center, orientation); } Sphere_3 operator() (const Circle_3 & c) const { return this->operator()(Return_base_tag(), c); } }; template class Construct_supporting_plane_3 { typedef typename K::Triangle_3 Triangle_3; typedef typename K::Plane_3 Plane_3; public: typedef Plane_3 result_type; Plane_3 operator()( const Triangle_3& t) const { return t.rep().supporting_plane(); } }; template class Construct_tetrahedron_3 { typedef typename K::Tetrahedron_3 Tetrahedron_3; typedef typename K::Point_3 Point_3; typedef typename Tetrahedron_3::Rep Rep; public: typedef Tetrahedron_3 result_type; Rep // Tetrahedron_3 operator()(Return_base_tag, const Point_3& p, const Point_3& q, const Point_3& r, const Point_3& s) const { return Rep(p, q, r, s); } Tetrahedron_3 operator()( const Point_3& p, const Point_3& q, const Point_3& r, const Point_3& s) const { return this->operator()(Return_base_tag(), p, q, r, s); } }; template class Construct_triangle_2 { typedef typename K::Triangle_2 Triangle_2; typedef typename Triangle_2::Rep Rep; typedef typename K::Point_2 Point_2; public: typedef Triangle_2 result_type; Rep // Triangle_2 operator()(Return_base_tag, const Point_2& p, const Point_2& q, const Point_2& r) const { return Rep(p, q, r); } Triangle_2 operator()( const Point_2& p, const Point_2& q, const Point_2& r) const { return this->operator()(Return_base_tag(), p, q, r); } }; template class Construct_triangle_3 { typedef typename K::Triangle_3 Triangle_3; typedef typename K::Point_3 Point_3; typedef typename Triangle_3::Rep Rep; public: typedef Triangle_3 result_type; Rep // Triangle_3 operator()(Return_base_tag, const Point_3& p, const Point_3& q, const Point_3& r) const { return Rep(p, q, r); } Triangle_3 operator()( const Point_3& p, const Point_3& q, const Point_3& r) const { return this->operator()(Return_base_tag(), p, q, r); } }; template class Construct_unit_normal_3 { typedef typename K::Point_3 Point_3; typedef typename K::Vector_3 Vector_3; public: typedef Vector_3 result_type; Vector_3 operator()(const Point_3& p,const Point_3& q, const Point_3& r) const { CGAL_kernel_precondition(! K().collinear_3_object()(p,q,r) ); Vector_3 res = CGAL::cross_product(q-p, r-p); res = res / CGAL::sqrt(res.squared_length()); return res; } }; template class Construct_vertex_3 { typedef typename K::Point_3 Point_3; typedef typename K::Segment_3 Segment_3; typedef typename K::Iso_cuboid_3 Iso_cuboid_3; typedef typename K::Triangle_3 Triangle_3; typedef typename K::Tetrahedron_3 Tetrahedron_3; public: template struct result { typedef const Point_3& type; }; template struct result { typedef Point_3 type; }; const Point_3& operator()( const Segment_3& s, int i) const { return s.rep().vertex(i); } const Point_3& operator()( const Triangle_3& t, int i) const { return t.rep().vertex(i); } Point_3 operator()( const Iso_cuboid_3& r, int i) const { return r.rep().vertex(i); } const Point_3& operator()( const Tetrahedron_3& t, int i) const { return t.rep().vertex(i); } }; template class Construct_cartesian_const_iterator_2 { typedef typename K::Point_2 Point_2; typedef typename K::Vector_2 Vector_2; typedef typename K::Cartesian_const_iterator_2 Cartesian_const_iterator_2; public: typedef Cartesian_const_iterator_2 result_type; Cartesian_const_iterator_2 operator()( const Point_2& p) const { return p.rep().cartesian_begin(); } Cartesian_const_iterator_2 operator()( const Point_2& p, int) const { return p.rep().cartesian_end(); } Cartesian_const_iterator_2 operator()( const Vector_2& v) const { return v.rep().cartesian_begin(); } Cartesian_const_iterator_2 operator()( const Vector_2& v, int) const { return v.rep().cartesian_end(); } }; template class Construct_cartesian_const_iterator_3 { typedef typename K::Point_3 Point_3; typedef typename K::Vector_3 Vector_3; typedef typename K::Cartesian_const_iterator_3 Cartesian_const_iterator_3; public: typedef Cartesian_const_iterator_3 result_type; Cartesian_const_iterator_3 operator()( const Point_3& p) const { return p.rep().cartesian_begin(); } Cartesian_const_iterator_3 operator()( const Point_3& p, int) const { return p.rep().cartesian_end(); } Cartesian_const_iterator_3 operator()( const Vector_3& v) const { return v.rep().cartesian_begin(); } Cartesian_const_iterator_3 operator()( const Vector_3& v, int) const { return v.rep().cartesian_end(); } }; template class Construct_projected_point_3 { bool is_inside_triangle_3_aux(const typename K::Vector_3& w, const typename K::Point_3& p1, const typename K::Point_3& p2, const typename K::Point_3& q, typename K::Point_3& result, bool& outside, const K& k) { typedef typename K::Vector_3 Vector_3; typedef typename K::FT FT; typename K::Construct_vector_3 vector = k.construct_vector_3_object(); typename K::Construct_projected_point_3 projection = k.construct_projected_point_3_object(); typename K::Construct_line_3 line = k.construct_line_3_object(); typename K::Compute_scalar_product_3 scalar_product = k.compute_scalar_product_3_object(); typename K::Construct_cross_product_vector_3 cross_product = k.construct_cross_product_vector_3_object(); const Vector_3 v = cross_product(vector(p1,p2), vector(p1,q)); if ( scalar_product(v,w) < FT(0)) { if ( scalar_product(vector(p1,q), vector(p1,p2)) >= FT(0) && scalar_product(vector(p2,q), vector(p2,p1)) >= FT(0) ) { result = projection(line(p1, p2), q); return true; } outside = true; } return false; } /** * Returns the nearest point of p1,p2,p3 from origin * @param origin the origin point * @param p1 the first point * @param p2 the second point * @param p3 the third point * @param k the kernel * @return the nearest point from origin */ typename K::Point_3 nearest_point_3(const typename K::Point_3& origin, const typename K::Point_3& p1, const typename K::Point_3& p2, const typename K::Point_3& p3, const K& k) { typedef typename K::FT FT; typename K::Compute_squared_distance_3 sq_distance = k.compute_squared_distance_3_object(); const FT dist_origin_p1 = sq_distance(origin,p1); const FT dist_origin_p2 = sq_distance(origin,p2); const FT dist_origin_p3 = sq_distance(origin,p3); if ( dist_origin_p2 >= dist_origin_p1 && dist_origin_p3 >= dist_origin_p1 ) { return p1; } if ( dist_origin_p3 >= dist_origin_p2 ) { return p2; } return p3; } /** * @brief returns true if p is inside triangle t. If p is not inside t, * result is the nearest point of t from p. WARNING: it is assumed that * t and p are on the same plane. * @param p the reference point * @param t the triangle * @param result if p is not inside t, the nearest point of t from p * @param k the kernel * @return true if p is inside t */ bool is_inside_triangle_3(const typename K::Point_3& p, const typename K::Triangle_3& t, typename K::Point_3& result, const K& k) { typedef typename K::Point_3 Point_3; typedef typename K::Vector_3 Vector_3; typename K::Construct_vector_3 vector = k.construct_vector_3_object(); typename K::Construct_vertex_3 vertex_on = k.construct_vertex_3_object(); typename K::Construct_cross_product_vector_3 cross_product = k.construct_cross_product_vector_3_object(); const Point_3& t0 = vertex_on(t,0); const Point_3& t1 = vertex_on(t,1); const Point_3& t2 = vertex_on(t,2); Vector_3 w = cross_product(vector(t0,t1), vector(t1,t2)); bool outside = false; if ( is_inside_triangle_3_aux(w, t0, t1, p, result, outside, k) || is_inside_triangle_3_aux(w, t1, t2, p, result, outside, k) || is_inside_triangle_3_aux(w, t2, t0, p, result, outside, k) ) { return false; } if ( outside ) { result = nearest_point_3(p,t0,t1,t2,k); return false; } else { return true; } } /** * @brief returns true if p is inside segment s. If p is not inside s, * result is the nearest point of s from p. WARNING: it is assumed that * t and p are on the same line. * @param query the query point * @param s the segment * @param closest_point_on_segment if query is not inside s, the nearest point of s from p * @param k the kernel * @return true if p is inside s */ bool is_inside_segment_3(const typename K::Point_3& query, const typename K::Segment_3 & s, typename K::Point_3& closest_point_on_segment, const K& k) { typename K::Construct_vector_3 vector = k.construct_vector_3_object(); typename K::Construct_vertex_3 vertex_on = k.construct_vertex_3_object(); typename K::Compute_scalar_product_3 scalar_product = k.compute_scalar_product_3_object(); typedef typename K::FT FT; typedef typename K::Point_3 Point; const Point& a = vertex_on(s, 0); const Point& b = vertex_on(s, 1); if( scalar_product(vector(a,b), vector(a, query)) < FT(0) ) { closest_point_on_segment = a; return false; } if( scalar_product(vector(b,a), vector(b, query)) < FT(0) ) { closest_point_on_segment = b; return false; } // query is on segment return true; } public: typename K::Point_3 operator()(const typename K::Point_3& origin, const typename K::Triangle_3& triangle, const K& k) { typedef typename K::Point_3 Point_3; typename K::Construct_supporting_plane_3 supporting_plane = k.construct_supporting_plane_3_object(); typename K::Construct_projected_point_3 projection = k.construct_projected_point_3_object(); typename K::Is_degenerate_3 is_degenerate = k.is_degenerate_3_object(); const typename K::Plane_3 plane = supporting_plane(triangle); if(is_degenerate(plane)) { // If the plane is degenerate, then the triangle is degenerate, and // one tries to find to which segment it is equivalent. typename K::Construct_vertex_3 vertex = k.construct_vertex_3_object(); typename K::Construct_vector_3 vector = k.construct_vector_3_object(); typename K::Compute_x_3 x = k.compute_x_3_object(); typename K::Compute_y_3 y = k.compute_y_3_object(); typename K::Compute_z_3 z = k.compute_z_3_object(); typedef typename K::FT FT; typedef typename K::Vector_3 Vector_3; const Point_3& a = vertex(triangle, 0); const Point_3& b = vertex(triangle, 1); const Point_3& c = vertex(triangle, 2); const Vector_3 ab = vector(a, b); const Vector_3 ac = vector(a, c); const Vector_3 bc = vector(b, c); const FT linf_ab = (std::max)((std::max)(x(ab), y(ab)), z(ab)); const FT linf_ac = (std::max)((std::max)(x(ac), y(ac)), z(ac)); const FT linf_bc = (std::max)((std::max)(x(bc), y(bc)), z(bc)); typename K::Construct_segment_3 seg = k.construct_segment_3_object(); if(linf_ab > linf_ac) { if(linf_ab > linf_bc) { // ab is the maximal segment return this->operator()(origin, seg(a, b), k); } else { // ab > ac, bc >= ab, use bc return this->operator()(origin, seg(b, c), k); } } else { // ab <= ac if(linf_ac > linf_bc) { // ac is the maximal segment return this->operator()(origin, seg(a, c), k); } else { // ab <= ac, ac <= bc, use bc return this->operator()(origin, seg(b, c), k); } } } // degenerate plane // Project origin on triangle supporting plane const Point_3 proj = projection(plane, origin); Point_3 moved_point; bool inside = is_inside_triangle_3(proj,triangle,moved_point,k); // If proj is inside triangle, return it if ( inside ) { return proj; } // Else return the constructed point return moved_point; } typename K::Point_3 operator()(const typename K::Point_3& query, const typename K::Segment_3& segment, const K& k) { typename K::Is_degenerate_3 is_degenerate = k.is_degenerate_3_object(); typename K::Construct_vertex_3 vertex = k.construct_vertex_3_object(); if(is_degenerate(segment)) return vertex(segment, 0); if(segment.to_vector() * (query-segment.source()) <= 0) return segment.source(); if(segment.to_vector() * (query-segment.target()) >= 0) return segment.target(); // If proj is inside segment, returns it return k.construct_projected_point_3_object()(segment.supporting_line(), query); } typename K::Point_3 operator()(const typename K::Point_3& query, const typename K::Ray_3& ray, const K& k) { if ( ray.to_vector() * (query-ray.source()) <= 0) return ray.source(); else { return k.construct_projected_point_3_object()(ray.supporting_line(), query); } } // code for operator for plane and point is defined in // CGAL/Cartesian/function_objects.h and CGAL/Homogeneous/function_objects.h }; template class Coplanar_3 { typedef typename K::Point_3 Point_3; typedef typename K::Orientation_3 Orientation_3; Orientation_3 o; public: typedef typename K::Boolean result_type; Coplanar_3() {} Coplanar_3(const Orientation_3& o_) : o(o_) {} result_type operator()( const Point_3& p, const Point_3& q, const Point_3& r, const Point_3& s) const { return o(p, q, r, s) == COPLANAR; } }; template class Counterclockwise_in_between_2 { typedef typename K::Direction_2 Direction_2; public: typedef typename K::Boolean result_type; result_type operator()( const Direction_2& p, const Direction_2& q, const Direction_2& r) const { if ( q < p) return ( p < r )||( r <= q ); else return ( p < r )&&( r <= q ); } }; template class Do_intersect_2 { public: typedef typename K::Boolean result_type; // There are 36 combinaisons, so I use a template. template result_type operator()(const T1& t1, const T2& t2) const { return Intersections::internal::do_intersect(t1, t2, K()); } }; template class Do_intersect_3 { public: typedef typename K::Boolean result_type; // There are x combinaisons, so I use a template. template result_type operator()(const T1& t1, const T2& t2) const { return Intersections::internal::do_intersect(t1, t2, K()); } result_type operator()(const typename K::Plane_3& pl1, const typename K::Plane_3& pl2, const typename K::Plane_3& pl3) const { return Intersections::internal::do_intersect(pl1, pl2, pl3, K() ); } }; template class Equal_2 { typedef typename K::Point_2 Point_2; typedef typename K::Vector_2 Vector_2; typedef typename K::Direction_2 Direction_2; typedef typename K::Segment_2 Segment_2; typedef typename K::Ray_2 Ray_2; typedef typename K::Line_2 Line_2; typedef typename K::Triangle_2 Triangle_2; typedef typename K::Iso_rectangle_2 Iso_rectangle_2; typedef typename K::Circle_2 Circle_2; public: typedef typename K::Boolean result_type; result_type operator()(const Point_2 &p, const Point_2 &q) const { return p.rep() == q.rep(); } result_type operator()(const Vector_2 &v1, const Vector_2 &v2) const { return v1.rep() == v2.rep(); } result_type operator()(const Vector_2 &v, const Null_vector &n) const { return v.rep() == n; } result_type operator()(const Direction_2 &d1, const Direction_2 &d2) const { return d1.rep() == d2.rep(); } result_type operator()(const Segment_2 &s1, const Segment_2 &s2) const { return s1.source() == s2.source() && s1.target() == s2.target(); } result_type operator()(const Line_2 &l1, const Line_2 &l2) const { return l1.rep() == l2.rep(); } result_type operator()(const Ray_2& r1, const Ray_2& r2) const { return r1.source() == r2.source() && r1.direction() == r2.direction(); } result_type operator()(const Circle_2& c1, const Circle_2& c2) const { return c1.center() == c2.center() && c1.squared_radius() == c2.squared_radius() && c1.orientation() == c2.orientation(); } result_type operator()(const Triangle_2& t1, const Triangle_2& t2) const { int i; for(i=0; i<3; i++) if ( t1.vertex(0) == t2.vertex(i) ) break; return (i<3) && t1.vertex(1) == t2.vertex(i+1) && t1.vertex(2) == t2.vertex(i+2); } result_type operator()(const Iso_rectangle_2& i1, const Iso_rectangle_2& i2) const { return ((i1.min)() == (i2.min)()) && ((i1.max)() == (i2.max)()); } }; template class Equal_3 { typedef typename K::Point_3 Point_3; typedef typename K::Vector_3 Vector_3; typedef typename K::Direction_3 Direction_3; typedef typename K::Segment_3 Segment_3; typedef typename K::Line_3 Line_3; typedef typename K::Ray_3 Ray_3; typedef typename K::Triangle_3 Triangle_3; typedef typename K::Tetrahedron_3 Tetrahedron_3; typedef typename K::Sphere_3 Sphere_3; typedef typename K::Iso_cuboid_3 Iso_cuboid_3; typedef typename K::Plane_3 Plane_3; typedef typename K::Circle_3 Circle_3; public: typedef typename K::Boolean result_type; // Point_3 is special case since the global operator== would recurse. result_type operator()(const Point_3 &p, const Point_3 &q) const { return p.x() == q.x() && p.y() == q.y() && p.z() == q.z(); } result_type operator()(const Plane_3 &v1, const Plane_3 &v2) const { return v1.rep() == v2.rep(); } result_type operator()(const Iso_cuboid_3 &v1, const Iso_cuboid_3 &v2) const { return v1.rep() == v2.rep(); } result_type operator()(const Sphere_3 &v1, const Sphere_3 &v2) const { return v1.rep() == v2.rep(); } result_type operator()(const Tetrahedron_3 &v1, const Tetrahedron_3 &v2) const { return v1.rep() == v2.rep(); } result_type operator()(const Triangle_3 &v1, const Triangle_3 &v2) const { return v1.rep() == v2.rep(); } result_type operator()(const Ray_3 &v1, const Ray_3 &v2) const { return v1.rep() == v2.rep(); } result_type operator()(const Line_3 &v1, const Line_3 &v2) const { return v1.rep() == v2.rep(); } result_type operator()(const Direction_3 &v1, const Direction_3 &v2) const { return v1.rep() == v2.rep(); } result_type operator()(const Segment_3 &v1, const Segment_3 &v2) const { return v1.rep() == v2.rep(); } result_type operator()(const Vector_3 &v1, const Vector_3 &v2) const { return v1.rep() == v2.rep(); } result_type operator()(const Vector_3 &v, const Null_vector &n) const { return v.rep() == n; } result_type operator()(const Circle_3 &v1, const Circle_3 &v2) const { return v1.rep() == v2.rep(); } }; template class Has_on_boundary_2 { typedef typename K::Point_2 Point_2; typedef typename K::Iso_rectangle_2 Iso_rectangle_2; typedef typename K::Circle_2 Circle_2; typedef typename K::Triangle_2 Triangle_2; public: typedef typename K::Boolean result_type; result_type operator()( const Circle_2& c, const Point_2& p) const { return c.has_on_boundary(p); } result_type operator()( const Triangle_2& t, const Point_2& p) const { return t.has_on_boundary(p); } result_type operator()( const Iso_rectangle_2& r, const Point_2& p) const { return K().bounded_side_2_object()(r,p) == ON_BOUNDARY; } }; template class Has_on_boundary_3 { typedef typename K::Point_3 Point_3; typedef typename K::Iso_cuboid_3 Iso_cuboid_3; typedef typename K::Sphere_3 Sphere_3; typedef typename K::Tetrahedron_3 Tetrahedron_3; typedef typename K::Plane_3 Plane_3; public: typedef typename K::Boolean result_type; result_type operator()( const Sphere_3& s, const Point_3& p) const { return s.rep().has_on_boundary(p); } result_type operator()( const Tetrahedron_3& t, const Point_3& p) const { return t.rep().has_on_boundary(p); } result_type operator()( const Iso_cuboid_3& c, const Point_3& p) const { return c.rep().has_on_boundary(p); } }; template class Has_on_bounded_side_2 { typedef typename K::Point_2 Point_2; typedef typename K::Iso_rectangle_2 Iso_rectangle_2; typedef typename K::Circle_2 Circle_2; typedef typename K::Triangle_2 Triangle_2; public: typedef typename K::Boolean result_type; result_type operator()( const Circle_2& c, const Point_2& p) const { return c.has_on_bounded_side(p); } result_type operator()( const Triangle_2& t, const Point_2& p) const { return t.has_on_bounded_side(p); } result_type operator()( const Iso_rectangle_2& r, const Point_2& p) const { return K().bounded_side_2_object()(r,p) == ON_BOUNDED_SIDE; } }; template class Has_on_bounded_side_3 { typedef typename K::Point_3 Point_3; typedef typename K::Iso_cuboid_3 Iso_cuboid_3; typedef typename K::Sphere_3 Sphere_3; typedef typename K::Tetrahedron_3 Tetrahedron_3; typedef typename K::Circle_3 Circle_3; public: typedef typename K::Boolean result_type; result_type operator()( const Sphere_3& s, const Point_3& p) const { return s.has_on_bounded_side(p); } result_type operator()( const Tetrahedron_3& t, const Point_3& p) const { return t.rep().has_on_bounded_side(p); } result_type operator()( const Iso_cuboid_3& c, const Point_3& p) const { return c.rep().has_on_bounded_side(p); } result_type operator()(const Circle_3& c, const Point_3& p) const { CGAL_kernel_precondition( K().has_on_3_object()(c.supporting_plane(),p) ); return c.rep().has_on_bounded_side(p); } bool operator()(const Sphere_3& s1, const Sphere_3& s2, const Point_3& a, const Point_3& b) const { typedef typename K::Circle_3 Circle_3; typedef typename K::Point_3 Point_3; typedef typename K::Segment_3 Segment_3; typedef typename K::Plane_3 Plane_3; typedef typename K::Intersect_3 Intersect_3; const Has_on_bounded_side_3& has_on_bounded_side = *this; const bool a_in_s1 = has_on_bounded_side(s1, a); const bool a_in_s2 = has_on_bounded_side(s2, a); if(!(a_in_s1 || a_in_s2)) return false; const bool b_in_s1 = has_on_bounded_side(s1, b); const bool b_in_s2 = has_on_bounded_side(s2, b); if(!(b_in_s1 || b_in_s2)) return false; if(a_in_s1 && b_in_s1) return true; if(a_in_s2 && b_in_s2) return true; if(!K().do_intersect_3_object()(s1, s2)) return false; const Circle_3 circ(s1, s2); const Plane_3& plane = circ.supporting_plane(); typename CGAL::cpp11::result_of::type optional = K().intersect_3_object()(plane, Segment_3(a, b)); CGAL_kernel_assertion_msg(bool(optional) == true, "the segment does not intersect the supporting" " plane"); const Point_3* p = boost::get(&*optional); CGAL_kernel_assertion_msg(p != 0, "the segment intersection with the plane is " "not a point"); return squared_distance(circ.center(), *p) < circ.squared_radius(); } }; template class Has_on_negative_side_2 { typedef typename K::Point_2 Point_2; typedef typename K::Line_2 Line_2; typedef typename K::Circle_2 Circle_2; typedef typename K::Triangle_2 Triangle_2; public: typedef typename K::Boolean result_type; result_type operator()( const Circle_2& c, const Point_2& p) const { return c.has_on_negative_side(p); } result_type operator()( const Triangle_2& t, const Point_2& p) const { return t.has_on_negative_side(p); } result_type operator()( const Line_2& l, const Point_2& p) const { return l.has_on_negative_side(p); } }; template class Has_on_negative_side_3 { typedef typename K::Point_3 Point_3; typedef typename K::Plane_3 Plane_3; typedef typename K::Sphere_3 Sphere_3; typedef typename K::Tetrahedron_3 Tetrahedron_3; public: typedef typename K::Boolean result_type; result_type operator()( const Sphere_3& s, const Point_3& p) const { return s.has_on_negative_side(p); } result_type operator()( const Tetrahedron_3& t, const Point_3& p) const { return t.rep().has_on_negative_side(p); } result_type operator()( const Plane_3& pl, const Point_3& p) const { return pl.rep().has_on_negative_side(p); } }; template class Has_on_positive_side_2 { typedef typename K::Point_2 Point_2; typedef typename K::Line_2 Line_2; typedef typename K::Circle_2 Circle_2; typedef typename K::Triangle_2 Triangle_2; public: typedef typename K::Boolean result_type; result_type operator()( const Circle_2& c, const Point_2& p) const { return c.has_on_positive_side(p); } result_type operator()( const Triangle_2& t, const Point_2& p) const { return t.has_on_positive_side(p); } result_type operator()( const Line_2& l, const Point_2& p) const { return l.has_on_positive_side(p); } }; template class Has_on_positive_side_3 { typedef typename K::Point_3 Point_3; typedef typename K::Plane_3 Plane_3; typedef typename K::Sphere_3 Sphere_3; typedef typename K::Tetrahedron_3 Tetrahedron_3; public: typedef typename K::Boolean result_type; result_type operator()( const Sphere_3& s, const Point_3& p) const { return s.has_on_positive_side(p); } result_type operator()( const Tetrahedron_3& t, const Point_3& p) const { return t.rep().has_on_positive_side(p); } result_type operator()( const Plane_3& pl, const Point_3& p) const { return pl.rep().has_on_positive_side(p); } }; template class Has_on_unbounded_side_2 { typedef typename K::Point_2 Point_2; typedef typename K::Iso_rectangle_2 Iso_rectangle_2; typedef typename K::Circle_2 Circle_2; typedef typename K::Triangle_2 Triangle_2; public: typedef typename K::Boolean result_type; result_type operator()( const Circle_2& c, const Point_2& p) const { return c.has_on_unbounded_side(p); } result_type operator()( const Triangle_2& t, const Point_2& p) const { return t.has_on_unbounded_side(p); } result_type operator()( const Iso_rectangle_2& r, const Point_2& p) const { return K().bounded_side_2_object()(r,p)== ON_UNBOUNDED_SIDE; } }; template class Has_on_unbounded_side_3 { typedef typename K::Point_3 Point_3; typedef typename K::Iso_cuboid_3 Iso_cuboid_3; typedef typename K::Sphere_3 Sphere_3; typedef typename K::Circle_3 Circle_3; typedef typename K::Tetrahedron_3 Tetrahedron_3; public: typedef typename K::Boolean result_type; result_type operator()( const Sphere_3& s, const Point_3& p) const { return s.has_on_unbounded_side(p); } result_type operator()( const Tetrahedron_3& t, const Point_3& p) const { return t.rep().has_on_unbounded_side(p); } result_type operator()( const Iso_cuboid_3& c, const Point_3& p) const { return c.rep().has_on_unbounded_side(p); } result_type operator()(const Circle_3& c, const Point_3& p) const { CGAL_kernel_precondition( K().has_on_3_object()(c.supporting_plane(),p) ); return c.rep().has_on_unbounded_side(p); } }; template class Has_on_2 { typedef typename K::Point_2 Point_2; typedef typename K::Line_2 Line_2; typedef typename K::Ray_2 Ray_2; typedef typename K::Segment_2 Segment_2; public: typedef typename K::Boolean result_type; result_type operator()( const Line_2& l, const Point_2& p) const { return l.has_on(p); } result_type operator()( const Ray_2& r, const Point_2& p) const { return r.has_on(p); } result_type operator()( const Segment_2& s, const Point_2& p) const { return s.has_on(p); } }; template class Intersect_2 { public: template struct result; template struct result { typedef typename Intersection_traits::result_type type; }; // 25 possibilities, so I keep the template. template typename Intersection_traits::result_type operator()(const T1& t1, const T2& t2) const { return Intersections::internal::intersection(t1, t2, K()); } }; template class Intersect_3 { typedef typename K::Plane_3 Plane_3; public: template struct result; template struct result { typedef typename Intersection_traits::result_type type; }; template struct result { typedef boost::optional< boost::variant< typename K::Point_3, typename K::Line_3, typename K::Plane_3 > > type; }; // n possibilities, so I keep the template. template typename cpp11::result_of< Intersect_3(T1, T2) >::type operator()(const T1& t1, const T2& t2) const { return Intersections::internal::intersection(t1, t2, K() ); } typename boost::optional< boost::variant< typename K::Point_3, typename K::Line_3, typename K::Plane_3 > > operator()(const Plane_3& pl1, const Plane_3& pl2, const Plane_3& pl3)const { return Intersections::internal::intersection(pl1, pl2, pl3, K() ); } }; template class Is_degenerate_2 { typedef typename K::Circle_2 Circle_2; typedef typename K::Iso_rectangle_2 Iso_rectangle_2; typedef typename K::Line_2 Line_2; typedef typename K::Ray_2 Ray_2; typedef typename K::Segment_2 Segment_2; typedef typename K::Triangle_2 Triangle_2; typedef typename K::Circle_3 Circle_3; public: typedef typename K::Boolean result_type; result_type operator()( const Circle_2& c) const { return c.is_degenerate(); } result_type operator()( const Iso_rectangle_2& r) const { return (r.xmin() == r.xmax()) || (r.ymin() == r.ymax()); } result_type operator()( const Line_2& l) const { return CGAL_NTS is_zero(l.a()) && CGAL_NTS is_zero(l.b()); } result_type operator()( const Ray_2& r) const { return r.rep().is_degenerate(); } result_type operator()( const Segment_2& s) const { return s.source() == s.target(); } result_type operator()( const Triangle_2& t) const { return t.is_degenerate(); } result_type operator()( const Circle_3& c) const { return c.rep().is_degenerate(); } }; template class Is_degenerate_3 { typedef typename K::Iso_cuboid_3 Iso_cuboid_3; typedef typename K::Line_3 Line_3; typedef typename K::Circle_3 Circle_3; typedef typename K::Plane_3 Plane_3; typedef typename K::Ray_3 Ray_3; typedef typename K::Segment_3 Segment_3; typedef typename K::Sphere_3 Sphere_3; typedef typename K::Triangle_3 Triangle_3; typedef typename K::Tetrahedron_3 Tetrahedron_3; public: typedef typename K::Boolean result_type; result_type operator()( const Iso_cuboid_3& c) const { return c.rep().is_degenerate(); } result_type operator()( const Line_3& l) const { return l.rep().is_degenerate(); } result_type operator()( const Plane_3& pl) const { return pl.rep().is_degenerate(); } result_type operator()( const Ray_3& r) const { return r.rep().is_degenerate(); } result_type operator()( const Segment_3& s) const { return s.rep().is_degenerate(); } result_type operator()( const Sphere_3& s) const { return s.rep().is_degenerate(); } result_type operator()( const Triangle_3& t) const { return t.rep().is_degenerate(); } result_type operator()( const Tetrahedron_3& t) const { return t.rep().is_degenerate(); } result_type operator()( const Circle_3& t) const { return t.rep().is_degenerate(); } }; template class Is_horizontal_2 { typedef typename K::Line_2 Line_2; typedef typename K::Segment_2 Segment_2; typedef typename K::Ray_2 Ray_2; public: typedef typename K::Boolean result_type; result_type operator()( const Line_2& l) const { return CGAL_NTS is_zero(l.a()); } result_type operator()( const Segment_2& s) const { return s.is_horizontal(); } result_type operator()( const Ray_2& r) const { return r.is_horizontal(); } }; template class Is_vertical_2 { typedef typename K::Line_2 Line_2; typedef typename K::Segment_2 Segment_2; typedef typename K::Ray_2 Ray_2; public: typedef typename K::Boolean result_type; result_type operator()( const Line_2& l) const { return CGAL_NTS is_zero(l.b()); } result_type operator()( const Segment_2& s) const { return s.is_vertical(); } result_type operator()( const Ray_2& r) const { return r.is_vertical(); } }; template class Left_turn_2 { typedef typename K::Point_2 Point_2; typedef typename K::Orientation_2 Orientation_2; Orientation_2 o; public: typedef typename K::Boolean result_type; Left_turn_2() {} Left_turn_2(const Orientation_2& o_) : o(o_) {} result_type operator()(const Point_2& p, const Point_2& q, const Point_2& r) const { return o(p, q, r) == LEFT_TURN; } }; template class Less_rotate_ccw_2 { typedef typename K::Point_2 Point_2; typedef typename K::Orientation_2 Orientation_2; typedef typename K::Collinear_are_ordered_along_line_2 Collinear_are_ordered_along_line_2; Orientation_2 o; Collinear_are_ordered_along_line_2 co; public: typedef typename K::Boolean result_type; Less_rotate_ccw_2() {} Less_rotate_ccw_2(const Orientation_2& o_, const Collinear_are_ordered_along_line_2& co_) : o(o_), co(co_) {} result_type operator()(const Point_2& r, const Point_2& p, const Point_2& q) const { typename K::Orientation ori = o(r, p, q); if ( ori == LEFT_TURN ) return true; else if ( ori == RIGHT_TURN ) return false; else { if (p == r) return false; if (q == r) return true; if (p == q) return false; return co( r, q, p); } } }; template class Oriented_side_3 { typedef typename K::Point_3 Point_3; typedef typename K::Tetrahedron_3 Tetrahedron_3; typedef typename K::Plane_3 Plane_3; typedef typename K::Sphere_3 Sphere_3; public: typedef typename K::Oriented_side result_type; result_type operator()( const Sphere_3& s, const Point_3& p) const { return s.rep().oriented_side(p); } result_type operator()( const Plane_3& pl, const Point_3& p) const { return pl.rep().oriented_side(p); } result_type operator()( const Tetrahedron_3& t, const Point_3& p) const { return t.rep().oriented_side(p); } }; template < typename K > class Construct_weighted_circumcenter_2 { public: typedef typename K::Weighted_point_2 Weighted_point_2; typedef typename K::Point_2 Point_2; typedef typename K::FT FT; typedef Point_2 result_type; result_type operator() (const Weighted_point_2 & p, const Weighted_point_2 & q, const Weighted_point_2 & r) const { CGAL_kernel_precondition( ! collinear(p.point(), q.point(), r.point()) ); FT x,y; weighted_circumcenterC2(p.x(),p.y(),p.weight(), q.x(),q.y(),q.weight(), r.x(),r.y(),r.weight(),x,y); return Point_2(x,y); } }; } // namespace CommonKernelFunctors } //namespace CGAL #endif // CGAL_KERNEL_FUNCTION_OBJECTS_H