mirror of https://github.com/CGAL/cgal
Curved_kernel -> Circular_kernel_2 [adapt]
This commit is contained in:
parent
49f94977ef
commit
c7c4a3dd17
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
Loading…
Reference in New Issue