Curved_kernel -> Circular_kernel_2 [adapt]

This commit is contained in:
Pedro Machado Manhaes de Castro 2006-08-24 14:20:34 +00:00
parent 49f94977ef
commit c7c4a3dd17
13 changed files with 5137 additions and 0 deletions

View File

@ -0,0 +1,726 @@
// Copyright (c) 2003-2006 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you may redistribute it under
// the terms of the Q Public License version 1.0.
// See the file LICENSE.QPL distributed with CGAL.
//
// 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) : Monique Teillaud, Sylvain Pion
// Partially supported by the IST Programme of the EU as a Shared-cost
// RTD (FET Open) Project under Contract No IST-2000-26473
// (ECG - Effective Computational Geometry for Curves and Surfaces)
// and a STREP (FET Open) Project under Contract No IST-006413
// (ACS -- Algorithms for Complex Shapes)
#ifdef CGAL_INTERSECTION_MAP_FOR_XMONOTONIC_ARC_WITH_SAME_SUPPORTING_CIRCLE
#define CGAL_USEFUL_MAPS_FOR_THE_CIRCULAR_KERNEL
#endif
#ifdef CGAL_INTERSECTION_MAP_FOR_SUPPORTING_CIRCLES
#define CGAL_USEFUL_MAPS_FOR_THE_CIRCULAR_KERNEL
#endif
#ifndef CGAL_CIRCULAR_KERNEL_CIRCULAR_ARC_2_H
#define CGAL_CIRCULAR_KERNEL_CIRCULAR_ARC_2_H
#include <CGAL/global_functions_on_circular_arcs_2.h>
#include <CGAL/Circular_kernel_2/internal_functions_on_circular_arc_2.h> // temporarily
#ifdef CGAL_USEFUL_MAPS_FOR_THE_CIRCULAR_KERNEL
#include <CGAL/Circular_kernel_2/intersection_line_2_circle_2_map.h>
#endif
#include <CGAL/intersections.h>
namespace CGAL {
namespace CGALi {
template <class CK >
class Circular_arc_2
{
typedef typename CK::FT FT;
typedef typename CK::RT RT;
typedef typename CK::Point_2 Point_2;
typedef typename CK::Line_2 Line_2;
typedef typename CK::Circle_2 Circle_2;
typedef typename CK::Circular_arc_point_2 Circular_arc_point_2;
typedef typename CK::Root_of_2 Root_of_2;
typedef struct bit_field {
unsigned short int is_full:2;
unsigned short int is_x_monotonic:2;
unsigned short int is_y_monotonic:2;
unsigned short int two_end_points_on_upper_part:2;
unsigned short int two_end_points_on_left_part:2;
unsigned short int is_complementary_x_monotone:1;
unsigned short int is_complementary_y_monotone:1;
} bit_field;
#ifdef CGAL_USEFUL_MAPS_FOR_THE_CIRCULAR_KERNEL
public:
typedef CGALi::Intersection_line_2_circle_2_map Table;
#endif
private:
// set flags to 0
// when 1 bit -> 0 = false, 1 = true
// when 2 bits -> 0 = don_know, 1 = false
// 2 = true
void reset_flags() const {
flags.is_full = 0;
flags.is_x_monotonic = 0;
flags.is_y_monotonic = 0;
flags.two_end_points_on_upper_part = 0;
flags.two_end_points_on_left_part = 0;
flags.is_complementary_x_monotone = 0;
flags.is_complementary_y_monotone = 0;
}
public:
Circular_arc_2()
#ifdef CGAL_INTERSECTION_MAP_FOR_SUPPORTING_CIRCLES
: id_of_my_supporting_circle(0)
#endif
{
reset_flags(); // example
#ifdef CGAL_INTERSECTION_MAP_FOR_XMONOTONIC_ARC_WITH_SAME_SUPPORTING_CIRCLE
_get_id_number();
#endif
}
Circular_arc_2(const Circle_2 &c)
: _support(c)
#ifdef CGAL_INTERSECTION_MAP_FOR_SUPPORTING_CIRCLES
, id_of_my_supporting_circle(0)
#endif
{
reset_flags(); // example
#ifdef CGAL_INTERSECTION_MAP_FOR_XMONOTONIC_ARC_WITH_SAME_SUPPORTING_CIRCLE
_get_id_number();
#endif
flags.is_full = 2; // is_full = true
_begin = _end =
CircularFunctors::x_extremal_point<CK>(supporting_circle(),true);
}
Circular_arc_2(const Circle_2 &support,
const Line_2 &l1, bool b1,
const Line_2 &l2, bool b2)
{
Point_2 center1 (support.center().x() + l1.a()/2,
support.center().y() + l1.b()/2);
FT sqr1 = support.squared_radius() + l1.c()
- CGAL::square(support.center().x())
- CGAL::square(support.center().y())
+ CGAL::square(center1.x())
+ CGAL::square(center1.y());
Circle_2 c1 (center1, sqr1);
Point_2 center2 (support.center().x() + l2.a()/2,
support.center().y() + l2.b()/2);
FT sqr2 = support.squared_radius() + l2.c()
- CGAL::square(support.center().x())
- CGAL::square(support.center().y())
+ CGAL::square(center2.x())
+ CGAL::square(center2.y());
Circle_2 c2 (center2, sqr2);
*this = Circular_arc_2(support, c1, b1, c2, b2);
CGAL_kernel_assertion(do_intersect(support, c1));
CGAL_kernel_assertion(do_intersect(support, c2));
}
Circular_arc_2(const Circle_2 &c,
const Circle_2 &c1, const bool b_1,
const Circle_2 &c2, const bool b_2)
: _support(c)
#ifdef CGAL_INTERSECTION_MAP_FOR_SUPPORTING_CIRCLES
, id_of_my_supporting_circle(0)
#endif
{
reset_flags();
#ifdef CGAL_INTERSECTION_MAP_FOR_XMONOTONIC_ARC_WITH_SAME_SUPPORTING_CIRCLE
_get_id_number();
#endif
if (c1 != c2) {
_begin = CGAL::circle_intersect<CK>(c, c1, b_1);
_end = CGAL::circle_intersect<CK>(c, c2, b_2);
}
else{
typedef std::vector<CGAL::Object > solutions_container;
solutions_container solutions;
CGAL::intersect_2<CK>( c, c1, std::back_inserter(solutions) );
typename solutions_container::iterator it = solutions.begin();
CGAL_kernel_precondition( it != solutions.end() );
// the circles intersect
const std::pair<typename CK::Circular_arc_point_2, unsigned> *result;
result = CGAL::object_cast<
std::pair<typename CK::Circular_arc_point_2, unsigned> > (&(*it));
if ( result->second == 2 ){ // double solution
_begin = result->first;
_end = result->first;
}
else{
if (b_1)
_begin = result->first;
if (b_2)
_end = result->first;
if (!(b_1 & b_2)) {
++it;
result = CGAL::object_cast<
std::pair<typename CK::Circular_arc_point_2, unsigned> >(&(*it));
if (!b_1)
_begin = result->first;
if (!b_2)
_end = result->first;
}
}
}
}
// IS THIS CONSTRUCTOR USED ?
// constructs a circular arc that is the arc included in A
// having same (b) endpoint as A (true == _begin, false == _end)
// but whose (!b) endpoint is the intersection of A with ccut given
// by b_cut
Circular_arc_2(const Circular_arc_2 &A, const bool b,
const Circle_2 &ccut, const bool b_cut)
: _support(A.supporting_circle())
#ifdef CGAL_INTERSECTION_MAP_FOR_SUPPORTING_CIRCLES
, id_of_my_supporting_circle(0)
#endif
{
reset_flags();
#ifdef CGAL_INTERSECTION_MAP_FOR_XMONOTONIC_ARC_WITH_SAME_SUPPORTING_CIRCLE
_get_id_number();
#endif
CGAL_kernel_precondition(A.is_x_monotone());
CGAL_kernel_precondition(do_intersect(A.supporting_circle(), ccut));
Circular_arc_point_2 new_p =
CGAL::circle_intersect<CK>(A.supporting_circle(), ccut, b_cut);
// CGAL_kernel_assertion(point_in_range(A, new_p));
CGAL_kernel_assertion
(A.on_upper_part() == (CGAL::compare(new_p.y(), A.center().y()) >= 0));
if (b) {
_begin = A._begin;
_end = new_p;
}
else {
_begin = new_p;
_end = A._end;
}
}
// Constructs an arc supported by Circle_2(begin, middle, end),
// with _begin == begin, _end == end.
// (middle is not necessarily on the arc)
Circular_arc_2(const Point_2 &begin,
const Point_2 &middle,
const Point_2 &end)
: _begin(begin), _end(end)
#ifdef CGAL_INTERSECTION_MAP_FOR_SUPPORTING_CIRCLES
, id_of_my_supporting_circle(0)
#endif
{
reset_flags();
#ifdef CGAL_INTERSECTION_MAP_FOR_XMONOTONIC_ARC_WITH_SAME_SUPPORTING_CIRCLE
_get_id_number();
#endif
CGAL_kernel_precondition(!CGAL::collinear(begin, middle, end));
_support = Circle_2(begin, middle, end);
/*
* Circle_2 c = Circle_2(begin, middle, end);
* Line_2 l1 (begin, middle);
Line_2 l2 (middle, end);
*this = Circular_arc_2(c,
l1, compare_xy(begin, middle) < 0,
l2, compare_xy(end, middle) < 0);*/
//std::cout << source() << std::endl;
//std::cout << target() << std::endl;
}
Circular_arc_2(const Circle_2 &support,
const Circular_arc_point_2 &source,
const Circular_arc_point_2 &target)
: _begin(source), _end(target), _support(support)
#ifdef CGAL_INTERSECTION_MAP_FOR_SUPPORTING_CIRCLES
, id_of_my_supporting_circle(0)
#endif
{
reset_flags();
#ifdef CGAL_INTERSECTION_MAP_FOR_XMONOTONIC_ARC_WITH_SAME_SUPPORTING_CIRCLE
_get_id_number();
#endif
// We cannot enable these preconditions for now, since the
// Lazy_circular_kernel_2
// calls it on the Interval kernel without try/catch protection
// through the Circular_kernel_converter.
// CGAL_kernel_exactness_precondition(CK().has_on_2_object()(support, source));
// CGAL_kernel_exactness_precondition(CK().has_on_2_object()(support, target));
}
Circular_arc_2(const Point_2 &begin,
const Point_2 &end,
const FT &bulge)
: _begin(begin), _end(end)
#ifdef CGAL_INTERSECTION_MAP_FOR_SUPPORTING_CIRCLES
, id_of_my_supporting_circle(0)
#endif
{
reset_flags();
#ifdef CGAL_INTERSECTION_MAP_FOR_XMONOTONIC_ARC_WITH_SAME_SUPPORTING_CIRCLE
_get_id_number();
#endif
const FT sqr_bulge = CGAL::square(bulge);
const FT common = (FT(1) - sqr_bulge) / (FT(4)*bulge);
const FT x_coord = (begin.x() + end.x())/FT(2)
+ common*(begin.y() - end.y());
const FT y_coord = (begin.y() + end.y())/FT(2)
+ common*(end.x() - begin.x());
const FT sqr_rad = squared_distance(begin, end)
* (FT(1)/sqr_bulge + FT(2) + sqr_bulge) / FT(16);
_support = Circle_2(Point_2(x_coord, y_coord), sqr_rad);
}
private:
// The arc goes from _begin to _end in the positive order
// If _begin == _end, then it's the full circle
Circular_arc_point_2 _begin, _end;
Circle_2 _support;
mutable bit_field flags;
#ifdef CGAL_INTERSECTION_MAP_FOR_XMONOTONIC_ARC_WITH_SAME_SUPPORTING_CIRCLE
unsigned int my_id; // the id of the arc
// to optimize make_x_monotone and splits
// so we have not echec de filtre for intersection
static Table table;
#endif
public:
#ifdef CGAL_INTERSECTION_MAP_FOR_XMONOTONIC_ARC_WITH_SAME_SUPPORTING_CIRCLE
template < class T >
static bool find_intersection(const Circular_arc_2& c1,
const Circular_arc_2& c2,
T& res) {
return table.find<T>(c1.my_id, c2.my_id, res);
}
template < class T >
static void put_intersection(const Circular_arc_2& c1,
const Circular_arc_2& c2,
const T& res) {
table.put<T>(c1.my_id, c2.my_id, res);
}
#endif
#ifdef CGAL_INTERSECTION_MAP_FOR_SUPPORTING_CIRCLES
static Table circle_table;
mutable unsigned int id_of_my_supporting_circle;
template < class T >
static bool find_intersection_circle_circle(
const Circular_arc_2& c1,
const Circular_arc_2& c2,
T& res) {
if(c1.id_of_my_supporting_circle == 0) return false;
if(c2.id_of_my_supporting_circle == 0) return false;
return circle_table.find<T>(c1.id_of_my_supporting_circle,
c2.id_of_my_supporting_circle,
res);
}
template < class T >
static void put_intersection_circle_circle(const Circular_arc_2& c1,
const Circular_arc_2& c2,
const T& res) {
circle_table.put<T>(c1.circle_number(),
c2.circle_number(),
res);
}
#endif
// to remember if the arc was constructed from a full circle
const Circular_arc_point_2 & left() const
{
CGAL_kernel_precondition(is_x_monotone());
CGAL_kernel_precondition(on_upper_part() ? compare_xy(_end,_begin)<0
: compare_xy(_begin,_end)<0);
if (on_upper_part()) return _end;
return _begin;
}
const Circular_arc_point_2 & right() const
{
CGAL_kernel_precondition(is_x_monotone());
CGAL_kernel_precondition(on_upper_part() ? compare_xy(_end,_begin)<0
: compare_xy(_begin,_end)<0);
if (on_upper_part()) return _begin;
return _end;
}
const Circular_arc_point_2 & source() const
{
return _begin;
}
const Circular_arc_point_2 & target() const
{
return _end;
}
inline const bool is_full() const {
return flags.is_full == 2;
}
private:
#ifdef CGAL_INTERSECTION_MAP_FOR_XMONOTONIC_ARC_WITH_SAME_SUPPORTING_CIRCLE
void _get_id_number() {
my_id = table.get_new_id();
}
#endif
bool _is_x_monotone() const {
if (is_full()) return false;
int cmp_begin = CGAL::compare(_begin.y(), center().y());
int cmp_end = CGAL::compare(_end.y(), center().y());
// XXX : be careful, this may be surprising if the return value
// is not -1/1 but some random int...
if (cmp_begin == opposite(cmp_end) && cmp_begin != 0)
return false;
// Maybe the complementar is x_monotone
// but we have to go further to know
// see is_x_monotone()
flags.is_complementary_x_monotone = 1;
int cmp_x = compare_x(_begin, _end);
// Is the arc on the upper part ?
if (cmp_begin > 0 || cmp_end > 0)
return cmp_x > 0;
// Is the arc on the lower part ?
if (cmp_begin < 0 || cmp_end < 0)
return cmp_x < 0;
// There remains the case :
CGAL_kernel_assertion(cmp_begin == 0 && cmp_end == 0);
return cmp_x != 0; // full circle or half circle.
}
bool _is_y_monotone() const {
if (is_full()) return false;
int cmp_begin = CGAL::compare(_begin.x(), center().x());
int cmp_end = CGAL::compare(_end.x(), center().x());
// XXX : be careful, this may be surprising if the return value
// is not -1/1 but some random int...
if (cmp_begin == opposite(cmp_end) && cmp_begin != 0)
return false;
// Maybe the complementar is y_monotone
// but we have to go further to know
// see is_y_monotone()
flags.is_complementary_y_monotone = 1;
int cmp_y = compare_y(_begin, _end);
// Is the arc on the right part ?
if (cmp_begin > 0 || cmp_end > 0)
return cmp_y < 0;
// Is the arc on the left part ?
if (cmp_begin < 0 || cmp_end < 0)
return cmp_y > 0;
// There remains the case :
assert(cmp_begin == 0 && cmp_end == 0);
return cmp_y != 0; // full circle or half circle.
}
// if the 2 points are on x-extremals
// true if the arc is on upper-part
bool _two_end_points_on_upper_part() const {
int c1y = CGAL::compare(_begin.y(),
supporting_circle().center().y());
if(c1y > 0) return true;
if(c1y < 0) return false;
int c2y = CGAL::compare(_end.y(),
supporting_circle().center().y());
if(c2y > 0) return true;
if(c2y < 0) return false;
return compare_x(_begin, _end) > 0;
}
// if the 2 points are on y-extremals
// true if the arc is on left-part
bool _two_end_points_on_left_part() const
{
int c1x = CGAL::compare(_begin.x(),
supporting_circle().center().x());
if(c1x < 0) return true;
if(c1x > 0) return false;
int c2x = CGAL::compare(_end.x(),
supporting_circle().center().x());
if(c2x < 0) return true;
if(c2x > 0) return false;
return compare_y(_begin, _end) > 0;
}
public:
bool is_x_monotone() const {
if(flags.is_x_monotonic == 0) {
bool b = _is_x_monotone();
if(b) {
flags.is_x_monotonic = 2;
flags.is_complementary_x_monotone = 0;
} else flags.is_x_monotonic = 1;
return b;
} else {
return (flags.is_x_monotonic == 1) ? false : true;
}
}
// Returns true if the complementary arc is x_monotone()
// note: if semi-cercle -> false
bool is_complementary_x_monotone() const {
// is_x_monotone calculates also if
// the complementary is x-monotone if needed
is_x_monotone();
return (flags.is_complementary_x_monotone == 0) ? false : true;
}
bool is_y_monotone() const {
if(flags.is_y_monotonic == 0) {
bool b = _is_y_monotone();
if(b) {
flags.is_y_monotonic = 2;
flags.is_complementary_y_monotone = 0;
} else flags.is_y_monotonic = 1;
return b;
} else {
return (flags.is_y_monotonic == 1) ? false : true;
}
}
// Returns true if the complementary arc is y_monotone()
// note: if semi-cercle -> false
bool is_complementary_y_monotone() const {
// is_y_monotone calculates also if
// the complementary is y-monotone if needed
is_y_monotone();
return (flags.is_complementary_y_monotone == 0) ? false : true;
}
// check whether 2 endpoints are at upper or not from the center
bool two_end_points_on_upper_part() const {
if(flags.two_end_points_on_upper_part == 0) {
bool b = _two_end_points_on_upper_part();
if(b) flags.two_end_points_on_upper_part = 2;
else flags.two_end_points_on_upper_part = 1;
return b;
} else {
return (flags.two_end_points_on_upper_part == 1) ? false : true;
}
}
// check whether the arc is at upper or not from the center
bool on_upper_part() const {
CGAL_kernel_precondition(is_x_monotone());
return two_end_points_on_upper_part();
}
// Returns true if the complementary arc is on_upper_part()
bool complementary_on_upper_part() const {
if(is_x_monotone()) return false;
return two_end_points_on_upper_part();
}
// check whether the 2 endpoints are at left or right from the center
bool two_end_points_on_left_part() const {
if(flags.two_end_points_on_left_part == 0) {
bool b = _two_end_points_on_left_part();
if(b) flags.two_end_points_on_left_part = 2;
else flags.two_end_points_on_left_part = 1;
return b;
} else {
return (flags.two_end_points_on_left_part == 1) ? false : true;
}
}
// check whether the arc is at left or right from the center
bool on_left_part() const {
CGAL_kernel_precondition(is_y_monotone());
return two_end_points_on_left_part();
}
// Returns true if the complementary arc is on_left_part()
bool complementary_on_left_part() const {
if(is_y_monotone()) return false;
return two_end_points_on_left_part();
}
#ifdef CGAL_INTERSECTION_MAP_FOR_XMONOTONIC_ARC_WITH_SAME_SUPPORTING_CIRCLE
unsigned int number() const {
return my_id;
}
#endif
#ifdef CGAL_INTERSECTION_MAP_FOR_SUPPORTING_CIRCLES
unsigned int circle_number() const {
if(!id_of_my_supporting_circle)
id_of_my_supporting_circle = circle_table.get_new_id();
return id_of_my_supporting_circle;
}
void set_circle_number(unsigned int i) const {
id_of_my_supporting_circle = i;
}
#endif
const Circle_2 & supporting_circle() const
{
return _support;
}
const Point_2 & center() const
{
return supporting_circle().center();
}
const FT & squared_radius() const
{
return supporting_circle().squared_radius();
}
Bbox_2 bbox() const
{
return CGAL::CircularFunctors::circular_arc_bbox<CK>(*this);
}
// Dont use this function, it is only for internal use
void _setx_info(unsigned short int v_is_x_monotone,
unsigned short int v_two_end_points_on_upper_part,
unsigned short int v_is_complementary_x_monotone) const {
flags.is_x_monotonic = v_is_x_monotone;
flags.two_end_points_on_upper_part = v_two_end_points_on_upper_part;
flags.is_complementary_x_monotone = v_is_complementary_x_monotone;
}
};
#ifdef CGAL_INTERSECTION_MAP_FOR_XMONOTONIC_ARC_WITH_SAME_SUPPORTING_CIRCLE
template < typename CK >
CGALi::Intersection_line_2_circle_2_map Circular_arc_2< CK >::table =
CGALi::Intersection_line_2_circle_2_map();
#endif
#ifdef CGAL_INTERSECTION_MAP_FOR_SUPPORTING_CIRCLES
template < typename CK >
CGALi::Intersection_line_2_circle_2_map Circular_arc_2< CK >::circle_table =
CGALi::Intersection_line_2_circle_2_map();
#endif
template < typename CK >
std::ostream &
operator<<(std::ostream & os, const Circular_arc_2<CK> &a)
{
// The output format is :
// - supporting circle
// - circle c1
// - bool b1
// - circle c2
// - bool b2
return os << a.supporting_circle() << " "
<< a.source() << " "
<< a.target() << " ";
}
template < typename CK >
std::istream &
operator>>(std::istream & is, Circular_arc_2<CK> &a)
{
typename CK::Circle_2 s;
typename CK::Circular_arc_point_2 p1;
typename CK::Circular_arc_point_2 p2;
is >> s >> p1 >> p2 ;
if (is)
a = Circular_arc_2<CK>(s, p1, p2);
return is;
}
template < typename CK >
std::ostream &
print(std::ostream & os, const Circular_arc_2<CK> &a)
{
if(a.is_x_monotone()) {
return os << "Circular_arc_2( " << std::endl
<< "left : " << a.left() << " , " << std::endl
<< "right : " << a.right() << " , " << std::endl
<< "upper part : " << a.on_upper_part() << std::endl
<< " [[ approximate circle is (x,y,r) : "
<< CGAL::to_double(a.supporting_circle().center().x()) << ""
<< CGAL::to_double(a.supporting_circle().center().y()) << ""
<< std::sqrt(CGAL::to_double(a.supporting_circle().squared_radius()))
<< " ]])" << std::endl;
} else {
return os << "Circular_arc_2( " << std::endl
<< " [[ approximate circle is (x,y,r) : "
<< CGAL::to_double(a.supporting_circle().center().x()) << ""
<< CGAL::to_double(a.supporting_circle().center().y()) << ""
<< std::sqrt(CGAL::to_double(a.supporting_circle().squared_radius()))
<< " ]])" << std::endl;
}
}
} // namespace CGALi
} // namespace CGAL
#undef CGAL_USEFUL_MAPS_FOR_THE_CIRCULAR_KERNEL
#endif // CGAL_CIRCULAR_KERNEL_CIRCULAR_ARC_2_H

View File

@ -0,0 +1,95 @@
// Copyright (c) 2003-2006 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you may redistribute it under
// the terms of the Q Public License version 1.0.
// See the file LICENSE.QPL distributed with CGAL.
//
// 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) : Monique Teillaud, Sylvain Pion
// Partially supported by the IST Programme of the EU as a Shared-cost
// RTD (FET Open) Project under Contract No IST-2000-26473
// (ECG - Effective Computational Geometry for Curves and Surfaces)
// and a STREP (FET Open) Project under Contract No IST-006413
// (ACS -- Algorithms for Complex Shapes)
#ifndef CGAL_CIRCULAR_KERNEL_CIRCULAR_ARC_POINT_2_H
#define CGAL_CIRCULAR_KERNEL_CIRCULAR_ARC_POINT_2_H
#include <iostream>
#include <cassert>
#include <CGAL/Bbox_2.h>
#include <CGAL/Interval_nt.h>
#include <boost/type_traits/is_same.hpp>
#include <CGAL/global_functions_on_circle_2.h>
namespace CGAL {
namespace CGALi {
template <class CK >
class Circular_arc_point_2
{
typedef typename CK::FT FT;
typedef typename CK::Root_of_2 Root_of_2;
typedef typename CK::Point_2 Point_2;
public: // fixme ?
typedef typename CK::Root_for_circles_2_2 Root_for_circles_2_2;
typedef typename CK::template Handle<Root_for_circles_2_2>::type Base;
Circular_arc_point_2()
{}
Circular_arc_point_2(const Root_for_circles_2_2 & np)
: _p(np)
{}
Circular_arc_point_2(const Point_2 & p)
: _p(p.x(),p.y()/*,1,1,-p.x()-p.y()*/)
{}
const Root_of_2 & x() const
{ return get(_p).x(); }
const Root_of_2 & y() const
{ return get(_p).y(); }
CGAL::Bbox_2 bbox() const
{
return get(_p).bbox();
}
const Root_for_circles_2_2 & coordinates() const
{ return get(_p); }
bool equal_ref(const Circular_arc_point_2 &p) const
{
return CGAL::identical(_p, p._p);
}
private:
Base _p;
};
template < typename CK >
std::ostream &
print(std::ostream & os, const Circular_arc_point_2<CK> &p)
{
return os << "CirclArcEndPoint_2(" << std::endl
<< p.x() << ", " << p.y() << ')';
}
} // namespace CGALi
} // namespace CGAL
#endif // CGAL_CIRCULAR_KERNEL_CIRCULAR_ARC_POINT_2_H

View File

@ -0,0 +1,297 @@
// Copyright (c) 2003-2006 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you may redistribute it under
// the terms of the Q Public License version 1.0.
// See the file LICENSE.QPL distributed with CGAL.
//
// 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) : Monique Teillaud, Sylvain Pion
// Partially supported by the IST Programme of the EU as a Shared-cost
// RTD (FET Open) Project under Contract No IST-2000-26473
// (ECG - Effective Computational Geometry for Curves and Surfaces)
// and a STREP (FET Open) Project under Contract No IST-006413
// (ACS -- Algorithms for Complex Shapes)
#ifndef CGAL_CIRCULAR_KERNEL_LINE_ARC_2_H
#define CGAL_CIRCULAR_KERNEL_LINE_ARC_2_H
#include <CGAL/global_functions_on_line_2.h>
#include <CGAL/global_functions_on_circle_2.h>
#include <CGAL/global_functions_on_line_arcs_2.h>
#include <CGAL/intersections.h>
#include <CGAL/Algebraic_kernel/internal_functions_on_roots_and_polynomial_1_2_and_2_2.h>
#include <CGAL/Circular_kernel_2/internal_functions_on_line_2.h>
#include <CGAL/Circular_kernel_2/internal_functions_on_line_arc_2.h>
#include <CGAL/Bbox_2.h>
#include <CGAL/Circular_kernel_2/Circular_arc_2.h>
namespace CGAL {
namespace CGALi {
template <class CK >
class Line_arc_2
{
typedef typename CK::FT FT;
typedef typename CK::RT RT;
typedef typename CK::Point_2 Point_2;
typedef typename CK::Line_2 Line_2;
typedef typename CK::Circle_2 Circle_2;
typedef typename CK::Circular_arc_2 Circular_arc_2;
typedef typename CK::Circular_arc_point_2 Circular_arc_point_2;
typedef typename CK::Root_of_2 Root_of_2;
typedef typename CK::Segment_2 Segment_2;
typedef struct bit_field {
unsigned char begin_less_xy_than_end:2;
} bit_field;
private:
// set flags to 0
// when 1 bit -> 0 = false, 1 = true
// when 2 bits -> 0 = don_know, 1 = false
// 2 = true
void reset_flags() const {
flags.begin_less_xy_than_end = 0;
}
public:
//typedef typename CGAL::Simple_cartesian<Root_of_2>::Point_2
// Numeric_point_2;
typedef typename CK::Root_for_circles_2_2
Root_for_circles_2_2;
static
Circular_arc_point_2
intersect(const Line_2 & l, const Circle_2 & c, const bool b)
{
typedef std::vector<CGAL::Object >
solutions_container;
solutions_container solutions;
CGAL::LinearFunctors::intersect_2<CK>
( l, c, std::back_inserter(solutions) );
typename solutions_container::iterator it = solutions.begin();
CGAL_kernel_precondition( it != solutions.end() );
// the circles intersect
const std::pair<typename CK::Circular_arc_point_2, unsigned> *result;
result = CGAL::object_cast<
std::pair<typename CK::Circular_arc_point_2, unsigned> >(&(*it));
if ( result->second == 2 ) // double solution
return result->first;
if (b) return result->first;
++it;
result = CGAL::object_cast<
std::pair<typename CK::Circular_arc_point_2, unsigned> >(&(*it));
return result->first;
}
public:
Line_arc_2()
#ifdef CGAL_INTERSECTION_MAP_FOR_SUPPORTING_CIRCLES
: id_of_my_supporting_line(Circular_arc_2::circle_table.get_new_id())
#endif
{}
Line_arc_2(const Line_2 &support,
const Circle_2 &c1,const bool b1,
const Circle_2 &c2,const bool b2)
:_support(support)
#ifdef CGAL_INTERSECTION_MAP_FOR_SUPPORTING_CIRCLES
,id_of_my_supporting_line(Circular_arc_2::circle_table.get_new_id())
#endif
{
_begin = intersect(support, c1, b1);
_end = intersect(support, c2, b2);
reset_flags();
}
Line_arc_2(const Line_2 &support,
const Line_2 &l1,
const Line_2 &l2)
:_support(support)
#ifdef CGAL_INTERSECTION_MAP_FOR_SUPPORTING_CIRCLES
,id_of_my_supporting_line(Circular_arc_2::circle_table.get_new_id())
#endif
{
CGAL_kernel_precondition(do_intersect(support, l1));
CGAL_kernel_precondition(do_intersect(support, l2));
//typedef typename Root_of_2::RT RT_2;
//Voir pour mettre une assertion au assign
Object obj = intersection(support, l1);
const Point_2 *pt = CGAL::object_cast<Point_2>(&obj);
_begin = Circular_arc_point_2(*pt);
obj = intersection(support, l2);
const Point_2 *pt2 = CGAL::object_cast<Point_2>(&obj);
_end = Circular_arc_point_2(*pt2);
reset_flags();
}
Line_arc_2(const Line_2 &support,
const Circular_arc_point_2 &p1,
const Circular_arc_point_2 &p2)
:_support(support)
#ifdef CGAL_INTERSECTION_MAP_FOR_SUPPORTING_CIRCLES
,id_of_my_supporting_line(Circular_arc_2::circle_table.get_new_id())
#endif
{
//Verifier si p1 et p2 sont sur la line
_begin = p1;
_end = p2;
reset_flags();
}
Line_arc_2(const Segment_2 &s)
:_support(s.supporting_line())
#ifdef CGAL_INTERSECTION_MAP_FOR_SUPPORTING_CIRCLES
,id_of_my_supporting_line(Circular_arc_2::circle_table.get_new_id())
#endif
{
_begin = Circular_arc_point_2(s.source());
_end = Circular_arc_point_2(s.target());
reset_flags();
}
Line_arc_2(const Point_2 &p1,
const Point_2 &p2)
#ifdef CGAL_INTERSECTION_MAP_FOR_SUPPORTING_CIRCLES
: id_of_my_supporting_line(Circular_arc_2::circle_table.get_new_id())
#endif
{
_support = Line_2(p1, p2);
_begin = Circular_arc_point_2(p1);
_end = Circular_arc_point_2(p2);
reset_flags();
}
private:
Line_2 _support;
Circular_arc_point_2 _begin, _end;
mutable bit_field flags;
#ifdef CGAL_INTERSECTION_MAP_FOR_SUPPORTING_CIRCLES
mutable unsigned int id_of_my_supporting_line;
unsigned int line_number() const {
return id_of_my_supporting_line;
}
void set_line_number(unsigned int i) const {
id_of_my_supporting_line = i;
}
#endif
private: //(some useful functions)
bool begin_less_xy_than_end() const {
if(flags.begin_less_xy_than_end == 0) {
if(compare_xy(_begin, _end) < 0)
flags.begin_less_xy_than_end = 2;
else flags.begin_less_xy_than_end = 1;
} return flags.begin_less_xy_than_end == 2;
}
public :
#ifdef CGAL_INTERSECTION_MAP_FOR_SUPPORTING_CIRCLES
template < class T >
static bool find_intersection_circle_line(
const Circular_arc_2& c,
const Line_arc_2& l,
T& res) {
if(c.id_of_my_supporting_circle == 0) return false;
return Circular_arc_2::circle_table.template find<T>(c.id_of_my_supporting_circle,
l.id_of_my_supporting_line,
res);
}
template < class T >
static void put_intersection_circle_line(const Circular_arc_2& c,
const Line_arc_2& l,
const T& res) {
Circular_arc_2::circle_table.template put<T>(c.circle_number(),
l.line_number(),
res);
}
#endif
const Line_2 & supporting_line() const
{
return _support;
}
const Circular_arc_point_2 & left() const
{
return begin_less_xy_than_end() ? _begin : _end;
}
const Circular_arc_point_2 & right() const
{
return begin_less_xy_than_end() ? _end : _begin;
}
const Circular_arc_point_2 & source() const
{
return _begin;
}
const Circular_arc_point_2 & target() const
{
return _end;
}
bool is_vertical() const
{
return supporting_line().is_vertical();
}
CGAL::Bbox_2 bbox() const
{
return _begin.bbox() + _end.bbox();
}
};
/* template < typename CK > */
/* std::ostream & */
/* operator<<(std::ostream & os, const Line_arc_2<CK> &a) */
/* { */
/* return os << a.supporting_line() << " " */
/* << a.source() << " " */
/* << a.target() << " "; */
/* } */
/* template < typename CK > */
/* std::istream & */
/* operator>>(std::istream & is, Line_arc_2<CK> &a) */
/* { */
/* typename CK::Line_2 l; */
/* typename CK::Circular_arc_point_2 p1; */
/* typename CK::Circular_arc_point_2 p2; */
/* is >> l >> p1 >> p2 ; */
/* if (is) */
/* a = Line_arc_2<CK>(l, p1, p2); */
/* return is; */
/* } */
} // namespace CGALi
} // namespace CGAL
#endif // CGAL_CIRCULAR_KERNEL_LINE_ARC_2_H

View File

@ -0,0 +1,73 @@
// Copyright (c) 2003-2006 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you may redistribute it under
// the terms of the Q Public License version 1.0.
// See the file LICENSE.QPL distributed with CGAL.
//
// 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) : Monique Teillaud, Sylvain Pion
// Partially supported by the IST Programme of the EU as a Shared-cost
// RTD (FET Open) Project under Contract No IST-2000-26473
// (ECG - Effective Computational Geometry for Curves and Surfaces)
// and a STREP (FET Open) Project under Contract No IST-006413
// (ACS -- Algorithms for Complex Shapes)
#ifndef CGAL_CIRCULAR_KERNEL_FUNCTION_OBJECTS_ON_CIRCLE_2_H
#define CGAL_CIRCULAR_KERNEL_FUNCTION_OBJECTS_ON_CIRCLE_2_H
#include <CGAL/Circular_kernel_2/internal_functions_on_circle_2.h>
#include <CGAL/Circular_kernel_2/function_objects_on_line_2.h>
// to be removed when CGAL::Kernel has a Get_equation
namespace CGAL {
namespace CircularFunctors {
template < class CK >
class Construct_circle_2 : public CK::Linear_kernel::Construct_circle_2
{
public:
typedef typename CK::Circle_2 result_type;
typedef Arity_tag<1> Arity;
using CK::Linear_kernel::Construct_circle_2::operator();
result_type
operator() ( const typename CK::Polynomial_for_circles_2_2 &eq )
{
return construct_circle_2<CK>(eq);
}
};
template < class CK >
class Get_equation : public LinearFunctors::Get_equation<CK>
{
public:
typedef typename CK::Polynomial_for_circles_2_2 result_type;
typedef Arity_tag<1> Arity;
using LinearFunctors::Get_equation<CK>::operator();
result_type
operator() ( const typename CK::Circle_2 & c )
{
return CircularFunctors::get_equation<CK>(c);
}
};
} // namespace CircularFunctors
} // namespace CGAL
#endif // CGAL_CIRCULAR_KERNEL_FUNCTION_OBJECTS_ON_CIRCLE_2_H

View File

@ -0,0 +1,66 @@
// Copyright (c) 2003-2006 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you may redistribute it under
// the terms of the Q Public License version 1.0.
// See the file LICENSE.QPL distributed with CGAL.
//
// 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) : Monique Teillaud, Sylvain Pion
// Partially supported by the IST Programme of the EU as a Shared-cost
// RTD (FET Open) Project under Contract No IST-2000-26473
// (ECG - Effective Computational Geometry for Curves and Surfaces)
// and a STREP (FET Open) Project under Contract No IST-006413
// (ACS -- Algorithms for Complex Shapes)
#ifndef CGAL_CIRCULAR_KERNEL_FUNCTION_OBJECTS_ON_LINE_2_H
#define CGAL_CIRCULAR_KERNEL_FUNCTION_OBJECTS_ON_LINE_2_H
#include <CGAL/Circular_kernel_2/internal_functions_on_line_2.h>
namespace CGAL {
namespace LinearFunctors {
template < class CK >
class Construct_line_2 : public CK::Linear_kernel::Construct_line_2
{
public:
typedef typename CK::Line_2 result_type;
typedef Arity_tag<1> Arity;
result_type
operator() ( const typename CK::Polynomial_1_2 &eq )
{
return construct_line_2<CK>(eq);
}
};
template < class CK >
class Get_equation
{
public:
typedef typename CK::Polynomial_1_2 result_type;
typedef Arity_tag<1> Arity;
result_type
operator() ( const typename CK::Line_2 & l )
{
return LinearFunctors::get_equation<CK>(l);
}
};
} // namespace LinearFunctors
} // namespace CGAL
#endif // CGAL_CIRCULAR_KERNEL_FUNCTION_OBJECTS_ON_LINE_2_H

View File

@ -0,0 +1,61 @@
// Copyright (c) 2003-2006 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you may redistribute it under
// the terms of the Q Public License version 1.0.
// See the file LICENSE.QPL distributed with CGAL.
//
// 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) : Monique Teillaud, Sylvain Pion
// Partially supported by the IST Programme of the EU as a Shared-cost
// RTD (FET Open) Project under Contract No IST-2000-26473
// (ECG - Effective Computational Geometry for Curves and Surfaces)
// and a STREP (FET Open) Project under Contract No IST-006413
// (ACS -- Algorithms for Complex Shapes)
#ifndef CGAL_CIRCULAR_KERNEL_FUNCTIONS_ON_CIRCLE_2_H
#define CGAL_CIRCULAR_KERNEL_FUNCTIONS_ON_CIRCLE_2_H
namespace CGAL {
// Should we have an iterator based interface, or both ?
template <class CK>
typename CK::Circular_arc_point_2
x_extremal_point(const Circle_2<CK> & c, bool i)
{
return CircularFunctors::x_extremal_point<CK>(c,i);
}
template <class CK, class OutputIterator>
OutputIterator
x_extremal_points(const Circle_2<CK> & c, OutputIterator res)
{
return CircularFunctors::x_extremal_points<CK>(c,res);
}
template <class CK>
typename CK::Circular_arc_point_2
y_extremal_point(const Circle_2<CK> & c, bool i)
{
return CircularFunctors::y_extremal_point<CK>(c,i);
}
template <class CK, class OutputIterator>
OutputIterator
y_extremal_points(const Circle_2<CK> & c, OutputIterator res)
{
return CircularFunctors::y_extremal_points<CK>(c,res);
}
} // namespace CGAL
#endif // CGAL_CIRCULAR_KERNEL_FUNCTIONS_ON_CIRCLE_2_H

View File

@ -0,0 +1,102 @@
// Copyright (c) 2003-2006 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you may redistribute it under
// the terms of the Q Public License version 1.0.
// See the file LICENSE.QPL distributed with CGAL.
//
// 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) : Monique Teillaud, Sylvain Pion
// This file is intentionally not protected against re-inclusion.
// It's aimed at being included from within a kernel traits class, this
// way we share more code.
// It is the responsability of the including file to correctly set the 2
// macros CGAL_Circular_Kernel_pred and CGAL_Circular_Kernel_cons.
// And they are #undefed at the end of this file.
CGAL_Circular_Kernel_cons(Get_equation,
get_equation_object)
CGAL_Circular_Kernel_cons(Construct_circle_2,
construct_circle_2_object)
CGAL_Circular_Kernel_pred(Compare_x_2,
compare_x_2_object)
CGAL_Circular_Kernel_pred(Compare_y_2,
compare_y_2_object)
CGAL_Circular_Kernel_pred(Compare_xy_2,
compare_xy_2_object)
CGAL_Circular_Kernel_pred(Compare_y_at_x_2,
compare_y_at_x_2_object)
CGAL_Circular_Kernel_pred(Compare_y_to_right_2,
compare_y_to_right_2_object)
CGAL_Circular_Kernel_pred(Do_overlap_2,
do_overlap_2_object)
CGAL_Circular_Kernel_pred(Equal_2,
equal_2_object)
CGAL_Circular_Kernel_pred(In_x_range_2,
in_x_range_2_object)
CGAL_Circular_Kernel_cons(Make_x_monotone_2,
make_x_monotone_2_object)
CGAL_Circular_Kernel_cons(Make_xy_monotone_2,
make_xy_monotone_2_object)
CGAL_Circular_Kernel_cons(Advanced_make_x_monotone_2,
advanced_make_x_monotone_2_object)
CGAL_Circular_Kernel_cons(Advanced_make_xy_monotone_2,
advanced_make_xy_monotone_2_object)
CGAL_Circular_Kernel_cons(Intersect_2,
intersect_2_object)
CGAL_Circular_Kernel_cons(Split_2,
split_2_object)
CGAL_Circular_Kernel_cons(Construct_circular_arc_2,
construct_circular_arc_2_object)
CGAL_Circular_Kernel_cons(Construct_line_arc_2,
construct_line_arc_2_object)
CGAL_Circular_Kernel_cons(Construct_circular_arc_point_2,
construct_circular_arc_point_2_object)
CGAL_Circular_Kernel_cons(Compute_Circular_x_2,
compute_circular_x_2_object)
CGAL_Circular_Kernel_cons(Compute_Circular_y_2,
compute_circular_y_2_object)
CGAL_Circular_Kernel_cons(Construct_circular_min_vertex_2,
construct_circular_min_vertex_2_object)
CGAL_Circular_Kernel_cons(Construct_circular_max_vertex_2,
construct_circular_max_vertex_2_object)
CGAL_Circular_Kernel_cons(Construct_circular_source_vertex_2,
construct_circular_source_vertex_2_object)
CGAL_Circular_Kernel_cons(Construct_circular_target_vertex_2,
construct_circular_target_vertex_2_object)
CGAL_Circular_Kernel_pred(Is_x_monotone_2,
is_x_monotone_2_object)
CGAL_Circular_Kernel_pred(Is_y_monotone_2,
is_y_monotone_2_object)
CGAL_Circular_Kernel_pred(On_upper_part_2,
on_upper_part_2_object)
CGAL_Circular_Kernel_pred(Is_vertical_2,
is_vertical_2_object)
CGAL_Circular_Kernel_pred(Has_on_2,
has_on_2_object)
CGAL_Circular_Kernel_pred(Has_on_bounded_side_2, has_on_bounded_side_2_object)
CGAL_Circular_Kernel_pred(Has_on_unbounded_side_2, has_on_unbounded_side_2_object)
CGAL_Circular_Kernel_pred(Bounded_side_2, bounded_side_2_object)
CGAL_Circular_Kernel_cons(Construct_supporting_circle_2,
construct_supporting_circle_2_object)
CGAL_Circular_Kernel_cons(Construct_supporting_line_2,
construct_supporting_line_2_object)
CGAL_Circular_Kernel_cons(Construct_bbox_2,
construct_bbox_2_object)
#undef CGAL_Circular_Kernel_pred
#undef CGAL_Circular_Kernel_cons

View File

@ -0,0 +1,194 @@
// Copyright (c) 2003-2006 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you may redistribute it under
// the terms of the Q Public License version 1.0.
// See the file LICENSE.QPL distributed with CGAL.
//
// 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) : Monique Teillaud, Sylvain Pion
// Partially supported by the IST Programme of the EU as a Shared-cost
// RTD (FET Open) Project under Contract No IST-2000-26473
// (ECG - Effective Computational Geometry for Curves and Surfaces)
// and a STREP (FET Open) Project under Contract No IST-006413
// (ACS -- Algorithms for Complex Shapes)
#ifndef CGAL_CIRCULAR_KERNEL_INTERNAL_FUNCTIONS_ON_CIRCLE_2_H
#define CGAL_CIRCULAR_KERNEL_INTERNAL_FUNCTIONS_ON_CIRCLE_2_H
CGAL_BEGIN_NAMESPACE
// temporary function : where to put it, if we want to keep it ?
template< class CK>
typename CK::Circular_arc_point_2
circle_intersect( const typename CK::Circle_2 & c1,
const typename CK::Circle_2 & c2,
bool b )
{
typedef std::vector<CGAL::Object > solutions_container;
solutions_container solutions;
CGAL::intersect_2<CK>( c1, c2, std::back_inserter(solutions) );
typename solutions_container::iterator it = solutions.begin();
CGAL_kernel_precondition( it != solutions.end() );
// the circles intersect
const std::pair<typename CK::Circular_arc_point_2, unsigned> *result;
result = CGAL::object_cast<
std::pair<typename CK::Circular_arc_point_2, unsigned> > (&(*it));
if ( result->second == 2 ) // double solution
return result->first;
if (b)
return result->first;
++it;
result = CGAL::object_cast<
std::pair<typename CK::Circular_arc_point_2, unsigned> >(&(*it));
return result->first;
}
namespace CircularFunctors {
template < class CK >
typename CK::Polynomial_for_circles_2_2
get_equation( const typename CK::Circle_2 & c )
{
typedef typename CK::RT RT;
typedef typename CK::Algebraic_kernel AK;
return AK().construct_polynomial_for_circles_2_2_object()
( c.center().x(), c.center().y(), c.squared_radius() );
}
template < class CK >
typename CK::Circle_2
construct_circle_2( const typename CK::Polynomial_for_circles_2_2 &eq )
{
return typename
CK::Circle_2( typename CK::Point_2(eq.a(), eq.b()), eq.r_sq() );
}
template < class CK >
bool
has_on(const typename CK::Circle_2 &a,
const typename CK::Circular_arc_point_2 &p)
{
typedef typename CK::Algebraic_kernel AK;
typedef typename CK::Polynomial_for_circles_2_2 Polynomial_for_circles_2_2;
Polynomial_for_circles_2_2 equation = CircularFunctors::get_equation<CK>(a);
return (AK().sign_at_object()(equation,p.coordinates()) == ZERO);
}
template < class CK >
inline bool
non_oriented_equal(const typename CK::Circle_2 & c1,
const typename CK::Circle_2 & c2) {
if(identical(c1,c2)) return true;
return (c1.squared_radius() == c2.squared_radius()) &&
(c1.center() == c2.center());
}
template < class CK >
inline
typename CK::Linear_kernel::Bounded_side
bounded_side(const typename CK::Circle_2 &c,
const typename CK::Circular_arc_point_2 &p) {
typedef typename CK::AK AK;
typedef typename CK::Polynomial_for_circles_2_2 Equation;
Equation equation = get_equation<CK>(c);
Sign sign = AK().sign_at_object()(equation,p.rep().coordinates());
if(sign == NEGATIVE) return ON_BOUNDED_SIDE;
else if(sign == POSITIVE) return ON_UNBOUNDED_SIDE;
else return ON_BOUNDARY;
}
template< class CK, class OutputIterator>
OutputIterator
intersect_2( const typename CK::Circle_2 & c1,
const typename CK::Circle_2 & c2,
OutputIterator res )
{
typedef typename CK::Algebraic_kernel AK;
typedef typename CK::Polynomial_for_circles_2_2 Equation;
typedef typename CK::Root_for_circles_2_2 Root_for_circles_2_2;
Equation e1 = CircularFunctors::get_equation<CK>(c1);
Equation e2 = CircularFunctors::get_equation<CK>(c2);
if (e1 == e2) {
*res++ = make_object(e1);
return res;
}
typedef std::vector< std::pair < Root_for_circles_2_2, unsigned > >
solutions_container;
solutions_container solutions;
AK().solve_object()(e1, e2, std::back_inserter(solutions));
// to be optimized
typedef typename CK::Circular_arc_point_2 Circular_arc_point_2;
for ( typename solutions_container::iterator it = solutions.begin();
it != solutions.end(); ++it )
{
*res++ = make_object(std::make_pair(Circular_arc_point_2(it->first),
it->second ));
}
return res;
}
// Should we have an iterator based interface, or both ?
template <class CK>
typename CK::Circular_arc_point_2
x_extremal_point(const typename CK::Circle_2 & c, bool i)
{
typedef typename CK::Algebraic_kernel AK;
return AK().x_critical_points_object()(typename CK::Get_equation()(c),i);
}
template <class CK,class OutputIterator>
OutputIterator
x_extremal_points(const typename CK::Circle_2 & c, OutputIterator res)
{
typedef typename CK::Algebraic_kernel AK;
return AK().x_critical_points_object()(typename CK::Get_equation()(c),res);
}
template <class CK>
typename CK::Circular_arc_point_2
y_extremal_point(const typename CK::Circle_2 & c, bool i)
{
typedef typename CK::Algebraic_kernel AK;
return AK().y_critical_points_object()(typename CK::Get_equation()(c),i);
}
template <class CK,class OutputIterator>
OutputIterator
y_extremal_points(const typename CK::Circle_2 & c, OutputIterator res)
{
typedef typename CK::Algebraic_kernel AK;
return AK().y_critical_points_object()(typename CK::Get_equation()(c),res);
}
} // namespace CircularFunctors
CGAL_END_NAMESPACE
#endif // CGAL_CIRCULAR_KERNEL_INTERNAL_FUNCTIONS_ON_CIRCLE_2_H

View File

@ -0,0 +1,110 @@
// Copyright (c) 2003-2006 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you may redistribute it under
// the terms of the Q Public License version 1.0.
// See the file LICENSE.QPL distributed with CGAL.
//
// 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) : Monique Teillaud, Sylvain Pion
// Partially supported by the IST Programme of the EU as a Shared-cost
// RTD (FET Open) Project under Contract No IST-2000-26473
// (ECG - Effective Computational Geometry for Curves and Surfaces)
// and a STREP (FET Open) Project under Contract No IST-006413
// (ACS -- Algorithms for Complex Shapes)
#ifndef CGAL_CIRCULAR_KERNEL_FUNCTIONS_ON_LINE_2_H
#define CGAL_CIRCULAR_KERNEL_FUNCTIONS_ON_LINE_2_H
namespace CGAL {
namespace LinearFunctors {
template < class CK >
typename CK::Polynomial_1_2
get_equation( const typename CK::Line_2 & L )
{
typedef typename CK::RT RT;
return typename CK::Polynomial_1_2(L.a(),L.b(),L.c());
}
template < class CK >
typename CK::Line_2
construct_line_2 ( const typename CK::Polynomial_1_2 &eq )
{
return typename CK::Line_2(eq[2],eq[1],eq[0]);
}
template < class CK >
bool
has_on(const typename CK::Line_2 & l,
const typename CK::Circular_arc_point_2 &p)
{
typedef typename CK::Algebraic_kernel AK;
typedef typename CK::Polynomial_1_2 Polynomial_1_2;
Polynomial_1_2 equation = CGAL::LinearFunctors::get_equation<CK>(l);
return(AK().sign_at_object()(equation,p.coordinates())== ZERO);
}
template < class CK >
inline bool
non_oriented_equal(const typename CK::Line_2 & a1,
const typename CK::Line_2 & a2) {
if(identical(a1,a2)) return true;
const typename CK::RT &a1c = a1.a();
const typename CK::RT &b1c = a1.b();
const typename CK::RT &c1c = a1.c();
const typename CK::RT &a2c = a2.a();
const typename CK::RT &b2c = a2.b();
const typename CK::RT &c2c = a2.c();
return (a1c*b2c == a2c*b1c) &&
(a1c*c2c == a2c*c1c) &&
(b1c*c2c == b2c*c1c);
}
template< class CK, class OutputIterator>
OutputIterator
intersect_2( const typename CK::Line_2 & l,
const typename CK::Circle_2 & c,
OutputIterator res )
{
typedef typename CK::Algebraic_kernel AK;
typedef typename CK::Polynomial_1_2 Equation_line;
typedef typename CK::Polynomial_for_circles_2_2 Equation_circle;
typedef typename CK::Root_for_circles_2_2 Root_for_circles_2_2;
Equation_line e1 = CGAL::get_equation<CK>(l);
Equation_circle e2 = CGAL::get_equation<CK>(c);
typedef std::vector< std::pair < Root_for_circles_2_2, unsigned > >
solutions_container;
solutions_container solutions;
AK().solve_object()(e1, e2, std::back_inserter(solutions));
// to be optimized
typedef typename CK::Circular_arc_point_2 Circular_arc_point_2;
for ( typename solutions_container::iterator it = solutions.begin();
it != solutions.end(); ++it )
{
*res++ = make_object
(std::make_pair(Circular_arc_point_2(it->first), it->second ));
}
return res;
}
} // namespace LinearFunctors
} // namespace CGAL
#endif // CGAL_CIRCULAR_KERNEL_FUNCTIONS_ON_LINE_2_H

View File

@ -0,0 +1,518 @@
// Copyright (c) 2003-2006 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you may redistribute it under
// the terms of the Q Public License version 1.0.
// See the file LICENSE.QPL distributed with CGAL.
//
// 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) : Monique Teillaud, Sylvain Pion
// Partially supported by the IST Programme of the EU as a Shared-cost
// RTD (FET Open) Project under Contract No IST-2000-26473
// (ECG - Effective Computational Geometry for Curves and Surfaces)
// and a STREP (FET Open) Project under Contract No IST-006413
// (ACS -- Algorithms for Complex Shapes)
#ifndef CGAL_CIRCULAR_KERNEL_PREDICATES_ON_LINE_ARC_2_H
#define CGAL_CIRCULAR_KERNEL_PREDICATES_ON_LINE_ARC_2_H
#include <CGAL/Circular_kernel_2/internal_functions_on_line_2.h>
#include <CGAL/Circular_kernel_2/internal_functions_on_circular_arc_2.h>
namespace CGAL {
namespace CircularFunctors {
template < class CK >
bool
point_in_x_range(const typename CK::Line_arc_2 &A,
const typename CK::Circular_arc_point_2 &p)
{
// range includes endpoints here
return ( (CircularFunctors::compare_x<CK>(p, A.source()) != CircularFunctors::compare_x<CK>(p, A.target()))
|| (CircularFunctors::compare_x<CK>(p, A.source()) == CGAL::EQUAL) );
}
template < class CK >
bool
equal(const typename CK::Line_arc_2 &A1,
const typename CK::Line_arc_2 &A2)
{
if (!LinearFunctors::non_oriented_equal<CK>(
A1.supporting_line(),A2.supporting_line()))
return false;
return ( (equal<CK>(A1.source(), A2.source()) &&
equal<CK>(A1.target(), A2.target())) ||
(equal<CK>(A1.target(), A2.source()) &&
equal<CK>(A1.source(), A2.target())) );
}
template < class CK >
bool
do_overlap(const typename CK::Line_arc_2 &A1,
const typename CK::Line_arc_2 &A2)
{
if (!LinearFunctors::non_oriented_equal<CK>(
A1.supporting_line(),A2.supporting_line()))
return false;
return CircularFunctors::compare_xy<CK>(A1.right(), A2.left()) > 0
&& CircularFunctors::compare_xy<CK>(A1.left(), A2.right()) < 0;
}
template < class CK >
bool
has_on(const typename CK::Line_arc_2 &a,
const typename CK::Circular_arc_point_2 &p,
const bool has_on_supporting_line = false)
{
if(!has_on_supporting_line) {
if(!CGAL::LinearFunctors::has_on<CK>(a.supporting_line(),p))
return false;
}
return (CircularFunctors::compare_xy<CK>(p, a.source()) != CircularFunctors::compare_xy<CK>(p, a.target()));
}
template< class CK>
bool
is_vertical(const typename CK::Line_arc_2 &l)
{
return l.supporting_line().is_vertical();
}
template< class CK>
bool
is_x_monotone(const typename CK::Line_arc_2 &l)
{
return true;
}
template< class CK>
bool
is_y_monotone(const typename CK::Line_arc_2 &l)
{
return true;
}
template < class CK >
Comparison_result
compare_y_at_x(const typename CK::Circular_arc_point_2 &p,
const typename CK::Line_arc_2 &A1)
{
//CGAL_kernel_precondition (CircularFunctors::point_in_x_range<CK>(A1, p));
//vertical case
if (CircularFunctors::is_vertical<CK>(A1)) {
if (p.y() <= A1.right().y()) {
if(A1.left().y() <= p.y()) {
return CGAL::EQUAL;
}
return CGAL::SMALLER;
}
return CGAL::LARGER;
}
//general case
typedef typename CK::Polynomial_1_2 Polynomial_1_2;
typedef typename CK::Root_of_2 Root_of_2;
Polynomial_1_2 equation =
CGAL::LinearFunctors::get_equation<CK>(A1.supporting_line());
Root_of_2 y((-p.x()*equation.a() - equation.c())/equation.b());
if (y == p.y())
return CGAL::EQUAL;
else if (y < p.y())
return CGAL::LARGER;
else return CGAL::SMALLER;
}
template < class CK >
Comparison_result
compare_y_to_right(const typename CK::Line_arc_2 &A1,
const typename CK::Line_arc_2 &A2,
const typename CK::Circular_arc_point_2 &p)
{
if(A1.supporting_line().is_vertical()){
if(A2.supporting_line().is_vertical())
return CGAL::EQUAL;
return CGAL::LARGER;
}
if(A2.supporting_line().is_vertical())
return CGAL::SMALLER;
typedef typename CK::Circular_arc_point_2 Circular_arc_point_2;
typedef typename CK::Polynomial_1_2 Polynomial_1_2;
typedef typename CK::Root_of_2 Root_of_2;
Polynomial_1_2 equation;
if(A1.right().x() < A2.right().x()){
equation = CGAL::LinearFunctors::get_equation<CK>(A2.supporting_line());
Root_of_2 y((-A1.right().x()*equation.a() - equation.c())/equation.b());
Root_of_2 A1_right_y = A1.right().y();
if (y == A1_right_y)
return CGAL::EQUAL;
if (y < A1_right_y)
return CGAL::LARGER;
return CGAL::SMALLER;
}
else{
equation = CGAL::LinearFunctors::get_equation<CK>(A1.supporting_line());
Root_of_2 y((-A2.right().x()*equation.a() - equation.c())/equation.b());
Root_of_2 A2_right_y = A2.right().y();
if (y == A2_right_y)
return CGAL::EQUAL;
if (y < A2_right_y)
return CGAL::SMALLER;
return CGAL::LARGER;
}
}
template < class CK >
Comparison_result
compare_y_to_right(const typename CK::Line_arc_2 &A1,
const typename CK::Circular_arc_2 &A2,
const typename CK::Circular_arc_point_2 &p)
{
//CGAL_kernel_precondition (A2.is_x_monotone());
if(A1.supporting_line().is_vertical())
return CGAL::LARGER;
typedef typename CK::Polynomial_1_2 Polynomial_1_2;
typedef typename CK::Root_of_2 Root_of_2;
const typename CK::Circle_2 & C2 = A2.supporting_circle();
Root_of_2 b2_y = C2.center().y() - p.y();
int s_b2_y = CGAL::sign(b2_y);
if (s_b2_y == 0) {
// Vertical tangent for A1.
return A2.on_upper_part() ? CGAL::SMALLER : CGAL::LARGER;
}
typename CK::Root_of_2 b2_x = C2.center().x() - p.x();
Root_of_2 tangent_2_x;
Root_of_2 tangent_2_y;
if (b2_y < 0){
tangent_2_x = -b2_y;
tangent_2_y = b2_x;
}
else{
tangent_2_x = b2_y;
tangent_2_y = -b2_x;
}
Polynomial_1_2 equation =
CGAL::LinearFunctors::get_equation<CK>(A1.supporting_line());
typedef typename CK::FT FT;
FT tangent_1_x;
FT tangent_1_y;
if (equation.b() < 0){
tangent_1_x = -equation.b();
tangent_1_y = equation.a();
}
else{
tangent_1_x = equation.b();
tangent_1_y = -equation.a();
}
if (((tangent_1_x < 0) && (tangent_2_x > 0)) ||
((tangent_1_x > 0) && (tangent_2_x < 0))){
Root_of_2 prod_left = tangent_1_y * tangent_2_x;
Root_of_2 prod_right = tangent_2_y * tangent_1_x;
if (prod_left < prod_right)
return CGAL::LARGER;
if (prod_left == prod_right)
return A2.on_upper_part() ? CGAL::LARGER : CGAL::SMALLER;
return CGAL::SMALLER;
}
else{
Root_of_2 prod_left = tangent_1_y * tangent_2_x;
Root_of_2 prod_right = tangent_2_y * tangent_1_x;
if (prod_left < prod_right)
return CGAL::SMALLER;
if (prod_left == prod_right)
return A2.on_upper_part() ? CGAL::LARGER : CGAL::SMALLER;
return CGAL::LARGER;
}
}
template < class CK >
Comparison_result
compare_y_to_right(const typename CK::Circular_arc_2 &A1,
const typename CK::Line_arc_2 &A2,
const typename CK::Circular_arc_point_2 &p)
{
if (compare_y_to_right<CK>(A2, A1, p) == CGAL::LARGER)
return CGAL::SMALLER;
return CGAL::LARGER;
}
template < class CK >
void
split(const typename CK::Line_arc_2 &A,
const typename CK::Circular_arc_point_2 &p,
typename CK::Line_arc_2 &ca1,
typename CK::Line_arc_2 &ca2)
{
CGAL_kernel_precondition( has_on<CK>(A, p));
typedef typename CK::Line_arc_2 Line_arc_2;
ca1 = Line_arc_2( A.supporting_line(), A.source(), p);
ca2 = Line_arc_2( A.supporting_line(), p, A.target());
if ( CircularFunctors::compare_xy<CK>(ca1.left(), ca2.left()) != SMALLER )
{
std::swap(ca1,ca2);
}
return;
}
template< class CK, class OutputIterator>
OutputIterator
intersect_2( const typename CK::Line_arc_2 &a1,
const typename CK::Line_arc_2 &a2,
OutputIterator res )
{
typedef typename CK::Circular_arc_point_2 Circular_arc_point_2;
typedef typename CK::Line_arc_2 Line_arc_2;
typedef typename CK::Point_2 Point_2;
typedef typename CK::Root_of_2 Root_of_2;
typedef typename CK::Root_for_circles_2_2 Root_for_circles_2_2;
if(LinearFunctors::non_oriented_equal<CK>(
a1.supporting_line(),a2.supporting_line())) {
if(compare_xy(a1.left(),a2.left()) < 0) {
int comparison = compare_xy(a2.left(),a1.right());
if(comparison < 0){
if(compare_xy(a1.right(),a2.right()) <= 0){
*res++ = make_object
(Line_arc_2(a1.supporting_line(), a2.left(), a1.right() ));
}
else{
*res++ = make_object
(Line_arc_2(a1.supporting_line(), a2.left(), a2.right() ));
}
}
else if (comparison == 0){
*res++ =make_object
( std::make_pair(a2.left(),1u));
}
return res;
}
else{
int comparison = compare_xy(a1.left(),a2.right());
if(comparison < 0){
if(compare_xy(a1.right(),a2.right()) <= 0){
*res++ = make_object
(Line_arc_2(a1.supporting_line(), a1.left(), a1.right() ));
}
else{
*res++ = make_object
(Line_arc_2(a1.supporting_line(), a1.left(), a2.right() ));
}
}
else if (comparison == 0){
*res++ = make_object
( std::make_pair(a1.left(),1u));
}
return res;
}
}
Object obj = intersection(a1.supporting_line(), a2.supporting_line());
const Point_2 *pt = CGAL::object_cast<Point_2>(&obj);
if(pt == NULL) return res;
Circular_arc_point_2 intersect_point = Circular_arc_point_2(*pt);
// (Root_for_circles_2_2(Root_of_2(pt->x()),Root_of_2(pt->y())));
if ((CircularFunctors::compare_xy<CK>(intersect_point, a1.source()) !=
CircularFunctors::compare_xy<CK>(intersect_point, a1.target())) &&
(CircularFunctors::compare_xy<CK>(intersect_point, a2.source()) !=
CircularFunctors::compare_xy<CK>(intersect_point, a2.target())))
*res++ = make_object(std::make_pair(intersect_point, 1u));
return res;
}
template< class CK, class OutputIterator>
OutputIterator
intersect_2( const typename CK::Line_arc_2 &l,
const typename CK::Circle_2 &c,
OutputIterator res )
{
typedef std::vector<CGAL::Object> solutions_container;
solutions_container solutions;
CGAL::LinearFunctors::intersect_2<CK>
( l.supporting_line(), c, std::back_inserter(solutions) );
for (typename solutions_container::iterator it = solutions.begin();
it != solutions.end(); ++it) {
const std::pair<typename CK::Circular_arc_point_2, unsigned>
*result = CGAL::object_cast
<std::pair<typename CK::Circular_arc_point_2, unsigned> > (&(*it));
if ( has_on<CK>(l,result->first,true))
*res++ = *it;
}
return res;
}
/*template< class CK, class OutputIterator>
OutputIterator
intersect_2( const typename CK::Line_arc_2 &l,
const typename CK::Circle_2 &c,
OutputIterator res )
{
typedef std::vector<CGAL::Object> solutions_container;
solutions_container solutions;
CGAL::LinearFunctors::intersect_2<CK>
( l.supporting_line(), c, std::back_inserter(solutions) );
for (typename solutions_container::iterator it = solutions.begin();
it != solutions.end(); ++it) {
const std::pair<typename CK::Circular_arc_point_2, unsigned> *result;
result = CGAL::object_cast
<std::pair<typename CK::Circular_arc_point_2, unsigned> > (&(*it));
if ( has_on<CK>(l,result->first))
*res++ = *it;
}
return res;
}*/
template< class CK, class OutputIterator>
OutputIterator
intersect_2( const typename CK::Circle_2 &c,
const typename CK::Line_arc_2 &l,
OutputIterator res )
{
return intersect_2<CK>(l,c,res);
}
template< class CK, class OutputIterator>
OutputIterator
intersect_2( const typename CK::Line_arc_2 &l,
const typename CK::Circular_arc_2 &c,
OutputIterator res )
{
typedef typename CK::Circular_arc_2 Circular_arc_2;
typedef typename CK::Line_arc_2 Line_arc_2;
typedef std::vector<CGAL::Object > solutions_container;
solutions_container solutions;
#ifdef CGAL_INTERSECTION_MAP_FOR_SUPPORTING_CIRCLES
if(!Line_arc_2::template
find_intersection_circle_line< solutions_container >
(c,l,solutions)) {
#endif
CGAL::LinearFunctors::intersect_2<CK>
( l.supporting_line(), c.supporting_circle(),
std::back_inserter(solutions) );
#ifdef CGAL_INTERSECTION_MAP_FOR_SUPPORTING_CIRCLES
Line_arc_2::template
put_intersection_circle_line< std::vector < CGAL::Object > >
(c,l,solutions);
}
#endif
for (typename solutions_container::iterator it = solutions.begin();
it != solutions.end(); ++it) {
const std::pair<typename CK::Circular_arc_point_2, unsigned>
*result = CGAL::object_cast
<std::pair<typename CK::Circular_arc_point_2, unsigned> > (&(*it));
if (has_on<CK>(l,result->first,true) &&
has_on<CK>(c,result->first,true)) {
*res++ = *it;
}
}
return res;
}
/*template< class CK, class OutputIterator>
OutputIterator
intersect_2( const typename CK::Line_arc_2 &l,
const typename CK::Circular_arc_2 &c,
OutputIterator res )
{
typedef typename CK::Circular_arc_2 Circular_arc_2;
typedef std::vector<CGAL::Object > solutions_container;
solutions_container solutions;
CGAL::LinearFunctors::intersect_2<CK>
( l.supporting_line(), c.supporting_circle(),
std::back_inserter(solutions) );
solutions_container objects_monotone;
std::vector<const Circular_arc_2*> arcs_x_monotone;
make_x_monotone( c, std::back_inserter(objects_monotone));
for(typename solutions_container::iterator it2 = objects_monotone.begin();
it2 != objects_monotone.end(); ++it2){
arcs_x_monotone.push_back(CGAL::object_cast<Circular_arc_2>(&(*it2)));
}
for (typename solutions_container::iterator it = solutions.begin();
it != solutions.end(); ++it){
const std::pair<typename CK::Circular_arc_point_2, unsigned> *result;
result = CGAL::object_cast
<std::pair<typename CK::Circular_arc_point_2, unsigned> > (&(*it));
if ( has_on<CK>(l,result->first)) {
bool is_on_arc = false;
for(typename std::vector<const Circular_arc_2*>::iterator
it2 = arcs_x_monotone.begin();
it2 != arcs_x_monotone.end(); ++it2){
if(has_on<CK>(**it2, result->first)){
is_on_arc = true;
break;
}
}
if(is_on_arc)
*res++ = *it;
}
}
return res;
}*/
template< class CK, class OutputIterator>
OutputIterator
intersect_2( const typename CK::Circular_arc_2 &c,
const typename CK::Line_arc_2 &l,
OutputIterator res )
{
return intersect_2<CK>(l,c,res);
}
template < class CK, class OutputIterator >
OutputIterator
make_x_monotone( const typename CK::Line_arc_2 &A,
OutputIterator res )
{
*res++ = make_object(A);
return res;
}
} // namespace CircularFunctors
} // namespace CGAL
#endif // CGAL_CIRCULAR_KERNEL_PREDICATES_ON_LINE_ARC_2_H

View File

@ -0,0 +1,79 @@
// Copyright (c) 2003-2006 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you may redistribute it under
// the terms of the Q Public License version 1.0.
// See the file LICENSE.QPL distributed with CGAL.
//
// 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) : Monique Teillaud, Sylvain Pion, Pedro Machado
// Partially supported by the IST Programme of the EU as a Shared-cost
// RTD (FET Open) Project under Contract No IST-2000-26473
// (ECG - Effective Computational Geometry for Curves and Surfaces)
// and a STREP (FET Open) Project under Contract No IST-006413
// (ACS -- Algorithms for Complex Shapes)
#ifndef INTERSECTION_LINE_2_CIRCLE_2_MAP_H
#define INTERSECTION_LINE_2_CIRCLE_2_MAP_H
#include <map>
#include <vector>
#include <CGAL/Object.h>
namespace CGAL {
namespace CGALi {
class Intersection_line_2_circle_2_map {
typedef struct inter_map_pair {
int x, y;
inter_map_pair(int xx=0, int yy=0) : x(xx), y(yy) {}
inter_map_pair(const inter_map_pair &i) : x(i.x), y(i.y) {}
bool operator<(const inter_map_pair &i) const {
if(x < i.x) return true;
if(x > i.x) return false;
if(y < i.y) return true;
return false;
}
} inter_map_pair;
typedef std::map< inter_map_pair , CGAL::Object > Table;
private:
Table intersection_map;
unsigned int id_gen;
public:
Intersection_line_2_circle_2_map() : id_gen(0) { intersection_map.clear(); }
~Intersection_line_2_circle_2_map() { intersection_map.clear(); }
unsigned int get_new_id() {
return ++id_gen;
}
template < class T >
bool find(int id1, int id2, T& res) const {
Table::const_iterator p = intersection_map.find(
inter_map_pair(id1,id2));
if(p == intersection_map.end()) return false;
assign(res, p->second);
return true;
}
template < class T >
void put(const int id1, const int id2, const T& res) {
intersection_map[inter_map_pair(id1,id2)] = CGAL::make_object(res);
}
};
} // endof internal cgal namespace
} //endof cgal namespace
#endif // INTERSECTION_LINE_2_CIRCLE_2_MAP_H