mirror of https://github.com/CGAL/cgal
3086 lines
85 KiB
C++
3086 lines
85 KiB
C++
// 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); you can redistribute it and/or
|
|
// modify it under the terms of the GNU Lesser General Public License as
|
|
// published by the Free Software Foundation; either version 3 of the License,
|
|
// or (at your option) any later version.
|
|
//
|
|
// Licensees holding a valid commercial license may use this file in
|
|
// accordance with the commercial license agreement provided with the software.
|
|
//
|
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
//
|
|
// $URL$
|
|
// $Id$
|
|
//
|
|
//
|
|
// Author(s) : Stefan Schirra, Sylvain Pion,
|
|
// Camille Wormser, Stephane Tayeb, Pierre Alliez
|
|
|
|
|
|
|
|
#ifndef CGAL_KERNEL_FUNCTION_OBJECTS_H
|
|
#define CGAL_KERNEL_FUNCTION_OBJECTS_H
|
|
|
|
#include <CGAL/Origin.h>
|
|
#include <CGAL/Bbox_2.h>
|
|
#include <CGAL/Bbox_3.h>
|
|
#include <CGAL/squared_distance_2.h>
|
|
#include <CGAL/squared_distance_3.h>
|
|
#include <CGAL/intersection_2.h>
|
|
#include <CGAL/intersection_3.h>
|
|
#include <CGAL/Kernel/Return_base_tag.h>
|
|
#include <CGAL/Kernel/global_functions_3.h>
|
|
|
|
#include <cmath> // for Compute_dihedral_angle
|
|
|
|
namespace CGAL {
|
|
|
|
namespace CommonKernelFunctors {
|
|
|
|
template <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
class Assign_2
|
|
{
|
|
typedef typename K::Object_2 Object_2;
|
|
public:
|
|
//typedef typename K::Boolean result_type;
|
|
typedef bool result_type;
|
|
|
|
template <class T>
|
|
result_type
|
|
operator()(T& t, const Object_2& o) const
|
|
{ return assign(t, o); }
|
|
};
|
|
|
|
template <typename K>
|
|
class Assign_3
|
|
{
|
|
typedef typename K::Object_3 Object_3;
|
|
public:
|
|
//typedef typename K::Boolean result_type;
|
|
typedef bool result_type;
|
|
|
|
template <class T>
|
|
result_type
|
|
operator()(T& t, const Object_3& o) const
|
|
{ return assign(t, o); }
|
|
};
|
|
|
|
template <typename K>
|
|
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, cosine is decreasing on [0,1]
|
|
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, cosine is increasing on [-1,0]
|
|
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_squared_distance_2
|
|
{
|
|
typedef typename K::FT FT;
|
|
public:
|
|
typedef typename K::Comparison_result result_type;
|
|
|
|
template <class T1, class T2>
|
|
result_type
|
|
operator()(const T1& p, const T2& q, const FT& d2) const
|
|
{
|
|
return CGAL::compare(squared_distance(p, q), d2);
|
|
}
|
|
|
|
template <class T1, class T2, class T3, class T4>
|
|
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 <typename K>
|
|
class Compare_squared_distance_3
|
|
{
|
|
typedef typename K::FT FT;
|
|
public:
|
|
typedef typename K::Comparison_result result_type;
|
|
|
|
template <class T1, class T2>
|
|
result_type
|
|
operator()(const T1& p, const T2& q, const FT& d2) const
|
|
{
|
|
return CGAL::compare(squared_distance(p, q), d2);
|
|
}
|
|
|
|
template <class T1, class T2, class T3, class T4>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
class Compute_squared_distance_2
|
|
{
|
|
typedef typename K::FT FT;
|
|
public:
|
|
typedef FT result_type;
|
|
|
|
// There are 25 combinaisons, we use a template.
|
|
template <class T1, class T2>
|
|
FT
|
|
operator()( const T1& t1, const T2& t2) const
|
|
{ return internal::squared_distance(t1, t2, K()); }
|
|
};
|
|
|
|
template <typename K>
|
|
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 <class T1, class T2>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
class Construct_object_2
|
|
{
|
|
typedef typename K::Object_2 Object_2;
|
|
public:
|
|
typedef Object_2 result_type;
|
|
|
|
template <class Cls>
|
|
Object_2
|
|
operator()( const Cls& c) const
|
|
{ return make_object(c); }
|
|
};
|
|
|
|
template <typename K>
|
|
class Construct_object_3
|
|
{
|
|
typedef typename K::Object_3 Object_3;
|
|
public:
|
|
typedef Object_3 result_type;
|
|
|
|
template <class Cls>
|
|
Object_3
|
|
operator()( const Cls& c) const
|
|
{ return make_object(c); }
|
|
};
|
|
|
|
template <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
class Construct_point_on_2
|
|
{
|
|
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, int 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, int i) const
|
|
{ return r.point(i); }
|
|
};
|
|
|
|
template <typename K>
|
|
class Construct_point_on_3
|
|
{
|
|
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, int 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, int i) const
|
|
{ return r.rep().point(i); }
|
|
|
|
Point_3
|
|
operator()( const Plane_3& p) const
|
|
{ return p.rep().point(); }
|
|
};
|
|
|
|
template <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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<typename>
|
|
struct result {
|
|
typedef const Point_3& type;
|
|
};
|
|
|
|
template<typename T>
|
|
struct result<T(Iso_cuboid_3, int)> {
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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();
|
|
|
|
// Project origin on triangle supporting plane
|
|
const Point_3 proj = projection(supporting_plane(triangle), 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)
|
|
{
|
|
typedef typename K::Point_3 Point_3;
|
|
|
|
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();
|
|
typename K::Construct_vertex_3 vertex =
|
|
k.construct_vertex_3_object();
|
|
|
|
if(is_degenerate(segment))
|
|
return vertex(segment, 0);
|
|
|
|
// Project query on segment supporting line
|
|
const Point_3 proj = projection(segment.supporting_line(), query);
|
|
|
|
Point_3 closest_point_on_segment;
|
|
bool inside = is_inside_segment_3(proj,segment,closest_point_on_segment,k);
|
|
|
|
// If proj is inside segment, returns it
|
|
if ( inside )
|
|
return proj;
|
|
|
|
// Else returns the constructed point
|
|
return closest_point_on_segment;
|
|
}
|
|
|
|
// code for operator for plane and point is defined in
|
|
// CGAL/Cartesian/function_objects.h and CGAL/Homogeneous/function_objects.h
|
|
};
|
|
|
|
template <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
class Do_intersect_2
|
|
{
|
|
public:
|
|
typedef typename K::Boolean result_type;
|
|
|
|
// There are 36 combinaisons, so I use a template.
|
|
template <class T1, class T2>
|
|
result_type
|
|
operator()(const T1& t1, const T2& t2) const
|
|
{ return internal::do_intersect(t1, t2, K()); }
|
|
};
|
|
|
|
template <typename K>
|
|
class Do_intersect_3
|
|
{
|
|
public:
|
|
typedef typename K::Boolean result_type;
|
|
|
|
// There are x combinaisons, so I use a template.
|
|
template <class T1, class T2>
|
|
result_type
|
|
operator()(const T1& t1, const T2& t2) const
|
|
{ return 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 internal::do_intersect(pl1, pl2, pl3, K() ); }
|
|
|
|
};
|
|
|
|
template <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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);
|
|
}
|
|
};
|
|
|
|
template <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
class Intersect_2
|
|
{
|
|
public:
|
|
template<typename>
|
|
struct result;
|
|
|
|
template<typename F, typename A, typename B>
|
|
struct result<F(A,B)> {
|
|
typedef typename Intersection_traits<K, A, B>::result_type type;
|
|
};
|
|
|
|
// Solely to make the lazy kernel work
|
|
#if CGAL_INTERSECTION_VERSION < 2
|
|
typedef CGAL::Object result_type;
|
|
#endif
|
|
|
|
// 25 possibilities, so I keep the template.
|
|
template <class T1, class T2>
|
|
typename Intersection_traits<K, T1, T2>::result_type
|
|
operator()(const T1& t1, const T2& t2) const
|
|
{ return internal::intersection(t1, t2, K()); }
|
|
};
|
|
|
|
template <typename K>
|
|
class Intersect_3
|
|
{
|
|
typedef typename K::Plane_3 Plane_3;
|
|
public:
|
|
template<typename>
|
|
struct result;
|
|
|
|
template<typename F, typename A, typename B>
|
|
struct result<F(A, B)> {
|
|
typedef typename Intersection_traits<K, A, B>::result_type type;
|
|
};
|
|
|
|
template<typename F>
|
|
struct result<F(Plane_3, Plane_3, Plane_3)> {
|
|
typedef boost::optional<
|
|
boost::variant< typename K::Point_3,
|
|
typename K::Line_3,
|
|
typename K::Plane_3 > > type;
|
|
};
|
|
|
|
// Solely to make the lazy kernel work
|
|
#if CGAL_INTERSECTION_VERSION < 2
|
|
typedef CGAL::Object result_type;
|
|
#endif
|
|
|
|
// n possibilities, so I keep the template.
|
|
template <class T1, class T2>
|
|
typename cpp11::result_of< Intersect_3(T1, T2) >::type
|
|
operator()(const T1& t1, const T2& t2) const
|
|
{ return internal::intersection(t1, t2, K() ); }
|
|
|
|
#if CGAL_INTERSECTION_VERSION < 2
|
|
CGAL::Object
|
|
#else
|
|
typename boost::optional< boost::variant< typename K::Point_3, typename K::Line_3, typename K::Plane_3 > >
|
|
#endif
|
|
operator()(const Plane_3& pl1, const Plane_3& pl2, const Plane_3& pl3)const
|
|
{ return internal::intersection(pl1, pl2, pl3, K() ); }
|
|
};
|
|
|
|
template <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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 <typename K>
|
|
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); }
|
|
};
|
|
|
|
} // namespace CommonKernelFunctors
|
|
} //namespace CGAL
|
|
|
|
#endif // CGAL_KERNEL_FUNCTION_OBJECTS_H
|