Replace code with calls to kernel functions and functors

This commit is contained in:
Efi Fogel 2002-08-21 10:32:18 +00:00
parent 9d8bb64c44
commit d04d80491c
4 changed files with 403 additions and 841 deletions

View File

@ -8,12 +8,11 @@
//
// ----------------------------------------------------------------------
//
// release : $CGAL_Revision: CGAL-2.4-I-55 $
// release_date : $CGAL_Date: 2002/02/15 $
// release :
// release_date : 1999, October 13
//
// file : include/CGAL/Planar_map_2/Planar_map_misc.h
// package : Planar_map (5.84)
// maintainer : Eyal Flato <flato@math.tau.ac.il>
// package : pm (4.08)
// source :
// revision :
// revision_date :
@ -28,9 +27,7 @@
#ifndef CGAL_PLANAR_MAP_MISC_H
#define CGAL_PLANAR_MAP_MISC_H
#ifndef CGAL_POLYHEDRON_ITERATOR_3_H
#include <CGAL/Polyhedron_iterator_3.h>
#endif
CGAL_BEGIN_NAMESPACE
@ -49,63 +46,32 @@ public:
// typedef typename I::Info_edge Info_edge;
// typedef typename I::Info_face Info_face;
typedef PlanarMapTraits_2 Base;
typedef typename Base::X_curve X_curve;
typedef typename Base::Point Point;
typedef Point Point_2;
//typedef typename PlanarMapTraits_2::Point_2 Point; // for backward compat.
Planar_map_traits_wrap() : Base()
{
}
typedef PlanarMapTraits_2 Base;
typedef typename Base::X_curve_2 X_curve_2;
typedef typename Base::Point_2 Point_2;
typedef typename Base::Direction_2 Direction_2;
Planar_map_traits_wrap(const Base& i) : Base(i)
{
}
// Creators:
// ---------
Planar_map_traits_wrap() : Base() {}
Planar_map_traits_wrap(const Base & i) : Base(i) {}
// Predicates:
// -----------
bool point_is_same_x(const Point_2 & p1, const Point_2 & p2) const
{ return (compare_x(p1, p2) == EQUAL); }
bool point_is_left( const Point_2 & p1, const Point_2 & p2 ) const
{
return (compare_x(p1, p2) == SMALLER);
}
bool point_is_lower(const Point_2 & p1, const Point_2 & p2) const
{ return (compare_y(p1, p2) == SMALLER); }
bool point_is_right( const Point_2 & p1, const Point_2 & p2 ) const
{
return (compare_x(p1, p2) == LARGER);
}
bool point_is_higher(const Point_2 & p1, const Point_2 & p2) const
{ return (compare_y(p1, p2) == LARGER); }
bool point_is_same_x( const Point_2 & p1, const Point_2 & p2 ) const
{
return (compare_x(p1, p2) == EQUAL);
}
bool point_is_lower( const Point_2 & p1, const Point_2 & p2 ) const
{
return (compare_y(p1, p2) == SMALLER);
}
bool point_is_higher( const Point_2 & p1, const Point_2 & p2 ) const
{
return (compare_y(p1, p2) == LARGER);
}
bool point_is_same_y( const Point_2 & p1, const Point_2 & p2 ) const
{
return (compare_y(p1, p2) == EQUAL);
}
bool point_is_same( const Point_2 & p1, const Point_2 & p2 ) const
{
#ifdef PM_MISC_USE_ISSAME
return is_same(p1, p2);
#else
return ( (compare_y(p1, p2) == EQUAL) &&
(compare_x(p1, p2) == EQUAL) );
#endif
}
bool point_is_left_low( const Point_2 & p1,
const Point_2 & p2 ) const
bool point_is_same_y(const Point_2 & p1, const Point_2 & p2) const
{ return (compare_y(p1, p2) == EQUAL); }
bool point_is_left_low(const Point_2 & p1, const Point_2 & p2) const
{
Comparison_result k = compare_x(p1, p2);
if (k == SMALLER)
@ -114,52 +80,57 @@ public:
return true;
return false;
}
bool point_is_right_top( const Point_2 & p1,
const Point_2 & p2 ) const
{
return point_is_left_low(p2,p1);
}
const Point_2& point_leftmost(const Point_2 &p1, const Point_2 &p2) const
bool point_is_right_top(const Point_2 & p1, const Point_2 & p2) const
{ return point_is_left_low(p2,p1); }
const Point_2 & point_leftmost(const Point_2 & p1, const Point_2 & p2) const
{ return (point_is_left(p1, p2) ? p1 : p2); }
const Point_2& point_rightmost(const Point_2 &p1, const Point_2 &p2) const
const Point_2 & point_rightmost(const Point_2 & p1, const Point_2 & p2) const
{ return (point_is_right(p1, p2) ? p1 : p2); }
const Point_2& point_lowest(const Point_2 &p1, const Point_2 &p2) const
const Point_2 & point_lowest(const Point_2 & p1, const Point_2 & p2) const
{ return (point_is_lower(p1, p2) ? p1 : p2); }
const Point_2& point_highest(const Point_2 &p1, const Point_2 &p2) const
const Point_2 & point_highest(const Point_2 & p1, const Point_2 & p2) const
{ return (point_is_higher(p1, p2) ? p1 : p2); }
const Point_2& point_leftlow_most(const Point_2 &p1, const Point_2 &p2) const
const Point_2 & point_leftlow_most(const Point_2 & p1, const Point_2 & p2)
const
{ return (point_is_left_low(p1, p2) ? p1 : p2); }
const Point_2& point_righttop_most(const Point_2 &p1, const Point_2 &p2)const
const Point_2 & point_righttop_most(const Point_2 & p1, const Point_2 & p2)
const
{ return (point_is_right_top(p1, p2) ? p1 : p2); }
Point_2 curve_leftmost(const X_curve& cv) const
{
return point_leftmost(curve_source(cv),curve_target(cv));
}
Point_2 curve_rightmost(const X_curve& cv) const
{
return point_rightmost(curve_source(cv),curve_target(cv));
}
Point_2 curve_lowest(const X_curve& cv) const
{
return point_lowest(curve_source(cv),curve_target(cv));
}
Point_2 curve_highest(const X_curve& cv) const
{
return point_highest(curve_source(cv),curve_target(cv));
}
Point_2 curve_leftlow_most(const X_curve& cv) const
Point_2 curve_leftmost(const X_curve_2 & cv) const
{ return point_leftmost(curve_source(cv),curve_target(cv)); }
Point_2 curve_rightmost(const X_curve_2 & cv) const
{ return point_rightmost(curve_source(cv),curve_target(cv)); }
Point_2 curve_lowest(const X_curve_2 & cv) const
{ return point_lowest(curve_source(cv),curve_target(cv)); }
Point_2 curve_highest(const X_curve_2 & cv) const
{ return point_highest(curve_source(cv),curve_target(cv)); }
Point_2 curve_leftlow_most(const X_curve_2 & cv) const
{
if (!curve_is_vertical(cv)) return curve_leftmost(cv);
return curve_lowest(cv);
}
Point_2 curve_righttop_most(const X_curve& cv) const
Point_2 curve_righttop_most(const X_curve_2 & cv) const
{
if (!curve_is_vertical(cv)) return curve_rightmost(cv);
return curve_highest(cv);
}
bool curve_merge_condition(const X_curve& whole,
const X_curve& part1,
const X_curve& part2) const
bool curve_merge_condition(const X_curve_2 & whole,
const X_curve_2 & part1,
const X_curve_2 & part2) const
{
return
point_is_same(curve_leftlow_most(whole),curve_leftlow_most(part1))&&
@ -169,153 +140,144 @@ public:
point_is_same(curve_righttop_most(part2),curve_leftlow_most(part1))&&
point_is_same(curve_righttop_most(whole),curve_righttop_most(part1));
}
inline bool curve_is_degenerate(const X_curve& cv) const
{
return point_is_same(curve_source(cv),curve_target(cv));
}
inline bool curve_is_degenerate(const X_curve_2 & cv) const
{ return point_is_same(curve_source(cv),curve_target(cv)); }
public:
/* precondition:
cv1,cv2 are adjacent to q
postcondition:
returns which of cv1,cv2 is first in clockwise sweep around q
starting from bottom direction.
*/
/*! curve_compare_at_x_from_bottom()
*
* \precondition cv1,cv2 are adjacent to q
* \postcondition returns which of cv1,cv2 is first in clockwise sweep
* around q starting from bottom direction.
*/
Comparison_result
curve_compare_at_x_from_bottom(const X_curve &cv1,
const X_curve &cv2,
const Point_2& q) const
{
if (!curve_is_vertical(cv1))
if (!curve_is_vertical(cv2))
if (point_is_same(curve_rightmost(cv1),q))
// cv1 extends leftwards from q
{
if (point_is_same(curve_rightmost(cv2),q))
// cv2 extends leftwards from q
{
return curve_compare_at_x_left(cv1,cv2,q);
}
else // cv2 extends rightwards from q
{
return SMALLER;
}
}
else // cv1 extends rightwards from q
{
if (point_is_same(curve_leftmost(cv2),q))
// cv2 extends rightwards from q
{
return curve_compare_at_x_right(cv2,cv1,q);
}
else // cv2 extends leftwards from q
{
return LARGER;
}
}
else // cv2 is vertical, cv1 is not vertical
curve_compare_at_x_from_bottom(const X_curve_2 & cv1,
const X_curve_2 & cv2,
const Point_2 & q) const
{
if (!curve_is_vertical(cv1)) {
if (!curve_is_vertical(cv2)) {
if (point_is_same(curve_rightmost(cv1),q))
{
// cv1 extends leftwards from q
if (point_is_same(curve_rightmost(cv2),q))
{
if (point_is_same(curve_rightmost(cv1),q) &&
point_is_same(curve_lowest(cv2), q))
return SMALLER;
else
return LARGER;
// cv2 extends leftwards from q
return curve_compare_at_x_left(cv1,cv2,q);
}
else // cv1 is vertical
{
if (point_is_same(curve_highest(cv1),q))
if (!curve_is_vertical(cv2) || point_is_same(curve_lowest(cv2),q))
return SMALLER;
else
return EQUAL; // both curves extend downwards
else // cv1 extends from q upwards
if (point_is_same(curve_righttop_most(cv2),q))
return LARGER;
else if (!curve_is_vertical(cv2)) // extends rightwards
return SMALLER;
else // cv2 extends upwards
return EQUAL;
}
else // cv2 extends rightwards from q
{
return SMALLER;
}
}
else // cv1 extends rightwards from q
{
if (point_is_same(curve_leftmost(cv2),q))
{
// cv2 extends rightwards from q
return curve_compare_at_x_right(cv2,cv1,q);
}
else // cv2 extends leftwards from q
{
return LARGER;
}
}
} else {
// cv2 is vertical, cv1 is not vertical
if (point_is_same(curve_rightmost(cv1),q) &&
point_is_same(curve_lowest(cv2), q))
return SMALLER;
else
return LARGER;
}
} else {
// cv1 is vertical
if (point_is_same(curve_highest(cv1),q))
if (!curve_is_vertical(cv2) || point_is_same(curve_lowest(cv2),q))
return SMALLER;
else
return EQUAL; // both curves extend downwards
else // cv1 extends from q upwards
if (point_is_same(curve_righttop_most(cv2),q))
return LARGER;
else if (!curve_is_vertical(cv2)) // extends rightwards
return SMALLER;
else // cv2 extends upwards
return EQUAL;
}
}
/*! curve_compare_at_x_from_top()
*/
Comparison_result
curve_compare_at_x_from_top(const X_curve &cv1,
const X_curve &cv2,
const Point_2& q)
curve_compare_at_x_from_top(const X_curve_2 & cv1,
const X_curve_2 & cv2,
const Point_2 & q)
const
{
if (!curve_is_vertical(cv1))
if (!curve_is_vertical(cv2))
if (point_is_same(curve_rightmost(cv1),q))
// cv1 extends leftwards from q
{
if (point_is_same(curve_rightmost(cv2),q))
// cv2 extends leftwards from q
{
return curve_compare_at_x_left(cv1,cv2,q);
}
else // cv2 extends rightwards from q
{
return LARGER;
}
}
else // cv1 extends rightwards from q
{
if (point_is_same(curve_leftmost(cv2),q))
// cv2 extends rightwards from q
{
return curve_compare_at_x_right(cv2,cv1,q);
}
else // cv2 extends leftwards from q
{
return SMALLER;
}
}
else // cv2 is vertical, cv1 is not vertical
{
if (!curve_is_vertical(cv1))
if (!curve_is_vertical(cv2))
if (point_is_same(curve_rightmost(cv1),q))
{
// cv1 extends leftwards from q
if (point_is_same(curve_rightmost(cv2),q))
{
if (point_is_same(curve_leftmost(cv1),q) &&
point_is_same(curve_highest(cv2), q))
return SMALLER;
else
return LARGER;
// cv2 extends leftwards from q
return curve_compare_at_x_left(cv1,cv2,q);
}
else // cv1 is vertical
{
if (point_is_same(curve_lowest(cv1),q))
if (!curve_is_vertical(cv2) || point_is_same(curve_highest(cv2),q))
return SMALLER;
else
return EQUAL; // both curves extend upwards
else // cv1 extends from q downwards
if (point_is_same(curve_leftlow_most(cv2),q))
return LARGER;
else if (!curve_is_vertical(cv2)) // extends leftwards
return SMALLER;
else // cv2 extends downwards
return EQUAL;
}
else // cv2 extends rightwards from q
{
return LARGER;
}
}
else // cv1 extends rightwards from q
{
if (point_is_same(curve_leftmost(cv2),q))
{
// cv2 extends rightwards from q
return curve_compare_at_x_right(cv2,cv1,q);
}
else // cv2 extends leftwards from q
{
return SMALLER;
}
}
else // cv2 is vertical, cv1 is not vertical
{
if (point_is_same(curve_leftmost(cv1),q) &&
point_is_same(curve_highest(cv2), q))
return SMALLER;
else
return LARGER;
}
else // cv1 is vertical
{
if (point_is_same(curve_lowest(cv1),q))
if (!curve_is_vertical(cv2) || point_is_same(curve_highest(cv2),q))
return SMALLER;
else
return EQUAL; // both curves extend upwards
else // cv1 extends from q downwards
if (point_is_same(curve_leftlow_most(cv2),q))
return LARGER;
else if (!curve_is_vertical(cv2)) // extends leftwards
return SMALLER;
else // cv2 extends downwards
return EQUAL;
}
bool curve_is_unbounded(const X_curve& cv) const
}
/*! curve_is_unbounded()
*/
bool curve_is_unbounded(const X_curve_2 & cv) const
{
return
curve_is_source_unbounded(cv)||
curve_is_target_unbounded(cv);
}
Comparison_result
compare_xy(const Point &p, const Point &q)
{
Comparison_result c = compare_x(p,q);
return (c != EQUAL) ? c : compare_y(p,q);
}
};
CGAL_END_NAMESPACE
#endif //CGAL_PLANAR_MAP_MISC_H
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
*
* Planar_map_misc.h - End of File
\*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
#endif

View File

@ -11,7 +11,7 @@
// release :
// release_date : 1999, October 13
//
// file : include/CGAL/Planar_map_2/Planar_map_misc_slim.h
// file : include/CGAL/Planar_map_2/Planar_map_misc.h
// package : pm (4.08)
// source :
// revision :
@ -98,6 +98,10 @@ public:
const X_curve &first,
const X_curve &second,
const Point_2 &point) const
{
return counterclockwise_in_between_2_object()(cv, first, second, point);
}
/*
{
Direction_2 d = construct_direction_2_object()(cv, point);
Direction_2 d1 = construct_direction_2_object()(first , point);
@ -112,6 +116,7 @@ public:
return counterclockwise_in_between_2_object()(d, d1, d2);
}
*/
// Compares the x value of two points
Comparison_result compare_x(const Point_2 &p1, const Point_2 &p2) const
@ -227,7 +232,7 @@ public:
{ return (point_is_higher(p1, p2) ? p1 : p2); }
const Point_2& point_leftlow_most(const Point_2 &p1, const Point_2 &p2) const
{ return (point_is_left_low(p1, p2) ? p1 : p2); }
const Point_2& point_righttop_most(const Point_2 &p1, const Point_2 &p2)const
const Point_2& point_righttop_most(const Point_2 &p1, const Point_2 &p2) const
{ return (point_is_right_top(p1, p2) ? p1 : p2); }
Point_2 curve_leftmost(const X_curve& cv) const
{

View File

@ -1,139 +1,43 @@
// ======================================================================
//
// Copyright (c) 2001 The CGAL Consortium
//
// This software and related documentation is part of an INTERNAL release
// of the Computational Geometry Algorithms Library (CGAL). It is not
// intended for general use.
//
// ----------------------------------------------------------------------
//
// release : $CGAL_Revision: CGAL-2.4-I-40 $
// release_date : $CGAL_Date: 2001/12/28 $
//
// file : include/CGAL/Pm_segment_slim_traits.h
// package : Planar_map (5.80)
// maintainer : Eyal Flato <flato@math.tau.ac.il>
// author(s) : Oren Nechushtan <theoren@math.tau.ac.il>
// Iddo Hanniel <hanniel@math.tau.ac.il>
// Shai Hirsch <shaihi@post.tau.ac.il>
// Efi Fogel <efifogel@post.tau.ac.il>
//
// coordinator : Tel-Aviv University (Dan Halperin halperin<@math.tau.ac.il>)
//
// ======================================================================
#ifndef CGAL_PM_SEGMENT_TRAITS_H
#define CGAL_PM_SEGMENT_TRAITS_H
// Status on Dec. 4th, 2001
// Class was converted to use as much of the kernel as currently possible
#include <CGAL/Planar_map/Pm_segment_utilities_2.h>
CGAL_BEGIN_NAMESPACE
template <class Kernel_, class X_curve_>
struct Construct_direction_at_endpoint_2 :
public Kernel_::Construct_direction_2
{
typedef Kernel_ Kernel;
typedef X_curve_ X_curve;
typedef typename Kernel::Construct_direction_2 Base;
typedef typename Kernel::Direction_2 Direction_2;
typedef typename Kernel::Point_2 Point_2;
Direction_2 operator()(const X_curve & cv, const Point_2 &) const
{
return Base::operator()(cv);
}
};
// Compares the y value of two curves at an x value of the input point
template <class Kernel_, class X_curve_>
struct Compare_y_at_x_for_segments_2 :
public Kernel_::Compare_y_at_x_2
{
typedef Kernel_ Kernel;
typedef X_curve_ X_curve;
typedef typename Kernel::Compare_y_at_x_2 Base;
typedef typename Kernel::Point_2 Point_2;
typedef typename Kernel::Construct_line_2 Construct_line_2;
Comparison_result
operator()( const Point_2 & q, const X_curve &cv1, const X_curve &cv2) const
{
typename Kernel::Line_2 l1 = construct_line(cv1);
typename Kernel::Line_2 l2 = construct_line(cv2);
return Base::operator()(q, l1, l2);
}
Comparison_result
operator()( const Point_2 & q, const X_curve &cv) const
{
/*
if ( is_vertical_2_object()(cv) )
{
const Point & src = construct_vertex_2_object()(cv, 0);
const Point & trg = construct_vertex_2_object()(cv, 1);
}
*/
typename Kernel::Line_2 l = construct_line(cv);
return Base::operator()(q, l);
}
Construct_line_2 construct_line;
};
/*
template <class Kernel>
inline
Pm_segment_traits<Kernel>::
Construct_direction_2
Pm_segment_traits<Kernel>::
construct_direction_2_object() const
{
return Construct_direction_2();
}
*/
template <class Kernel_>
class Pm_segment_traits : public Kernel_
{
public:
typedef Kernel_ Kernel;
typedef Kernel_ Kernel;
// traits objects
typedef typename Kernel::Point_2 Point_2;
typedef Point_2 Point; // for backward compatability
typedef typename Kernel::Direction_2 Direction_2;
typedef typename Kernel::Segment_2 X_curve;
// Things I get from the kernel
// ----------------------------
//
// Future interface:
//
typedef typename Kernel::Is_vertical_2 Is_vertical_2;
typedef typename Kernel::Counterclockwise_in_between_2
Counterclockwise_in_between_2;
typedef typename Kernel::Equal_2 Equal_2;
typedef typename Kernel::Has_on_2 Has_on_2;
typedef typename Kernel::Compare_x_2 Compare_x_2;
typedef typename Kernel::Compare_y_2 Compare_y_2;
typedef typename Kernel::Construct_vertex_2 Construct_vertex_2;
typedef typename Kernel::Construct_opposite_direction_2
Construct_opposite_direction_2;
typedef Construct_direction_at_endpoint_2<Kernel, X_curve>
typedef CGAL::Construct_direction_at_endpoint_2<Kernel, X_curve>
Construct_direction_2;
typedef Compare_y_at_x_for_segments_2<Kernel, X_curve>
typedef CGAL::Compare_y_at_x_for_segments_2<Kernel, X_curve>
Compare_y_at_x_2;
typedef CGAL::Counterclockwise_in_between_for_segments_2<Kernel, X_curve>
Counterclockwise_in_between_2;
inline Construct_direction_2 construct_direction_2_object() const
{ return Construct_direction_2(); }
@ -141,6 +45,9 @@ public:
inline Compare_y_at_x_2 compare_y_at_x_2_object() const
{ return Compare_y_at_x_2(); }
inline Counterclockwise_in_between_2 counterclockwise_in_between_2_object() const
{ return Counterclockwise_in_between_2(); }
// Implementation
//
// typedef typename Kernel::Less_x_2 Less_x_2;
@ -162,14 +69,11 @@ public:
} Curve_point_status;
private:
Kernel m_kernel;
public:
// Creation
Pm_segment_traits() {}
Pm_segment_traits(const Kernel& kernel) : m_kernel(kernel) {}
// SHAI: What about kernels with state?
// Compare the y value of two curves in an epsilon environment to
// the left of the x value of the input point
@ -178,14 +82,14 @@ public:
const Point_2 &q) const
{
// If one of the curves is vertical then return EQUAL.
if ( is_vertical_2_object()(cv1) || (is_vertical_2_object()(cv2)) )
if ( is_vertical_2_object()(cv1) ||
(is_vertical_2_object()(cv2)) )
return EQUAL;
// If one of the curves is not defined at q then return EQUAL.
if ( ! is_left(leftmost(cv1.source(), cv1.target()), q) ) return EQUAL;
if ( ! is_left(leftmost(cv2.source(), cv2.target()), q) ) return EQUAL;
Comparison_result r = compare_y_at_x_2_object()(q, cv1, cv2);
if ( r != EQUAL )
return r; // since the curve is continous
@ -202,7 +106,8 @@ public:
const Point_2 & q) const
{
// If one of the curves is vertical then return EQUAL.
if ( is_vertical_2_object()(cv1) || (is_vertical_2_object()(cv2)) )
if ( is_vertical_2_object()(cv1) ||
(is_vertical_2_object()(cv2)) )
return EQUAL;
// If one of the curves is not defined at q then return EQUAL.
if ( ! is_right(rightmost(cv1.source(), cv1.target()), q) ) return EQUAL;
@ -217,47 +122,7 @@ public:
// compare their derivatives
return compare_slope_2_object()(cv1, cv2);
}
protected:
// constructs the opposite segment (with the source and target
// exchanged)
// Used internally and in the Arrangement, so shouldn't be part of
// this interface
X_curve curve_flip(const X_curve &cv) const
{
return m_kernel.construct_opposite_segment_2_object()(cv);
}
// These stuff need to be cached
bool is_left(const Point_2 &p1, const Point_2 &p2) const
{ return m_kernel.less_x_2_object()(p1, p2); }
bool is_right(const Point_2 &p1, const Point_2 &p2) const
{ return m_kernel.less_x_2_object()(p2, p1); }
bool is_same_x(const Point_2 &p1, const Point_2 &p2) const
{ return m_kernel.equal_x_object()(p1, p2); }
bool is_lower(const Point_2 &p1, const Point_2 &p2) const
{ return m_kernel.less_y_2_object()(p1, p2); }
bool is_higher(const Point_2 &p1, const Point_2 &p2) const
{ return m_kernel.less_y_2_object()(p2, p1); }
bool is_same_y(const Point_2 &p1, const Point_2 &p2) const
{ return m_kernel.equal_y_object()(p1, p2); }
bool is_same(const Point_2 &p1, const Point_2 &p2) const
{
return (compare_x(p1, p2) == EQUAL) &&
(compare_y(p1, p2) == EQUAL);
}
const Point_2& leftmost(const Point_2 &p1, const Point_2 &p2) const
{ return (is_left(p1, p2) ? p1 : p2); }
const Point_2& rightmost(const Point_2 &p1, const Point_2 &p2) const
{ return (is_right(p1, p2) ? p1 : p2); }
const Point_2& lowest(const Point_2 &p1, const Point_2 &p2) const
{ return (is_lower(p1, p2) ? p1 : p2); }
const Point_2& highest(const Point_2 &p1, const Point_2 &p2) const
{ return (is_higher(p1, p2) ? p1 : p2); }
};
CGAL_END_NAMESPACE

View File

@ -1,516 +1,246 @@
// ======================================================================
//
// Copyright (c) 1997 The CGAL Consortium
//
// This software and related documentation is part of an INTERNAL release
// of the Computational Geometry Algorithms Library (CGAL). It is not
// intended for general use.
//
// ----------------------------------------------------------------------
//
// release : $CGAL_Revision: CGAL-2.3-I-26 $
// release_date : $CGAL_Date: 2001/01/05 $
//
// file : include/CGAL/Pm_segment_traits_2.h
// package : pm (5.43)
// maintainer : Eyal Flato <flato@math.tau.ac.il>
// source :
// revision :
// revision_date :
// author(s) : Iddo Hanniel <hanniel@math.tau.ac.il>
// Eyal Flato
// Oren Nechushtan <theoren@math.tau.ac.il>
// Shai Hirsch <shaihi@post.tau.ac.il>
// Efi Fogel <efifogel@post.tau.ac.il>
//
// coordinator : Tel-Aviv University (Dan Halperin <halperin@math.tau.ac.il>)
//
// Chapter :
// ======================================================================
#ifndef CGAL_PM_SEGMENT_TRAITS_2_H
#define CGAL_PM_SEGMENT_TRAITS_2_H
#ifndef CGAL_POINT_2_H
#include <CGAL/Point_2.h>
#endif
#ifndef CGAL_SEGMENT_2_H
#include <CGAL/Segment_2.h>
#endif
#include <CGAL/Planar_map_2/Pm_segment_utilities_2.h>
// #include <CGAL/Planar_map_2/Pm_point_utilities_2.h>
CGAL_BEGIN_NAMESPACE
template <class R>
class Pm_segment_traits_2
template <class Kernel_>
class Pm_segment_traits_2 : public Kernel_
{
public:
typedef Kernel_ Kernel;
typedef typename R::Segment_2 X_curve_2;
typedef typename R::Point_2 Point_2;
typedef typename R::Vector_2 Vector_2;
// Traits objects
typedef typename Kernel::Point_2 Point_2;
typedef typename Kernel::Segment_2 X_curve_2;
// Obsolete, for backward compatibility
typedef X_curve_2 X_curve;
typedef Point_2 Point;
typedef Vector_2 Vector;
// Backward compatability
typedef Point_2 Point;
typedef X_curve_2 X_curve;
// Currently, I leave this in the traits
// Maybe we can change the usage inside Planar_map_2
typedef enum
{
UNDER_CURVE = -1,
ABOVE_CURVE = 1,
ON_CURVE = 2,
CURVE_NOT_IN_RANGE = 0
UNDER_CURVE = -1,
CURVE_NOT_IN_RANGE = 0,
ABOVE_CURVE = 1,
ON_CURVE = 2
} Curve_point_status;
protected:
private:
// Functors:
typedef typename Kernel::Is_vertical_2 Is_vertical_2;
typedef typename Kernel::Construct_vertex_2 Construct_vertex_2;
typedef typename Kernel::Less_x_2 Less_x_2;
typedef CGAL::Counterclockwise_in_between_for_segments_2<Kernel, X_curve>
Counterclockwise_in_between_2;
// This is an implementation type
typedef enum
{
CURVE_VERTICAL_UP = 0,
CURVE_VERTICAL_DOWN = 2,
CURVE_LEFT = 3,
CURVE_RIGHT = 1
} Curve_status;
inline Counterclockwise_in_between_2 counterclockwise_in_between_2_object()
const
{ return Counterclockwise_in_between_2(); }
public:
// Creation
Pm_segment_traits_2() {}
Point_2 curve_source(const X_curve_2 & cv) const
{
return cv.source();
}
Point_2 curve_target(const X_curve_2 & cv) const
{
return cv.target();
}
// Operations
// ----------
/*! compare_x() compares the x-coordinates of two given points
* \param p1 the first point
* \param p2 the second point
* \return LARGER if x(p1) > x(p2), SMALLER if x(p1) < x(p2), or else EQUAL
*
* \todo replace indirect use compare_x() with compare_x_2()
*/
Comparison_result compare_x(const Point_2 & p1, const Point_2 & p2) const
{ return compare_x_2_object()(p1, p2); }
/*! compare_y() compares the y-coordinates of two given points
* \param p1 the first point
* \param p2 the second point
* \return LARGER if y(p1) > y(p2), SMALLER if y(p1) < y(p2), or else EQUAL
*
* \todo replace indirect use compare_y() with compare_y_2()
*/
Comparison_result compare_y(const Point_2 & p1, const Point_2 & p2) const
{ return compare_y_2_object()(p1, p2); }
/*! curve_is_vertical()
* \param cv the curve
* \return true iff the curve is vertical
*
* \todo replace indirect use curve_is_vertical() with is_vertical_2()
*/
bool curve_is_vertical(const X_curve_2 & cv) const
{
return is_same_x(cv.source(), cv.target());
}
{ return is_vertical_2_object()(cv); }
/*! curve_is_in_x_range()
* \param cv the curve
* \param q the point
* \return true if q is in the x range of cv
*
* \todo Intorduce Is_in_x_range_2() or perhaps Is_in_x_closed_range_2()
* in kernel. Currently, this is implemented using existing traits (kernel)
* functions (curve_source(), curve_target()) that return the source and
* target points by value, which is not as efficient as possible.
*/
bool curve_is_in_x_range(const X_curve_2 & cv, const Point_2 & q) const
{
return !( is_right(q, rightmost(cv.source(), cv.target())) ||
is_left(q, leftmost(cv.source(), cv.target())) );
}
bool curve_is_in_y_range(const X_curve_2 &cv, const Point_2 & q) const
{
bool r = !( is_lower(q, lowest(cv.source(), cv.target())) ||
is_higher(q, highest(cv.source(), cv.target())) );
return r;
}
Curve_point_status
curve_get_point_status(const X_curve_2 &cv, const Point_2 & p) const
{
if (!curve_is_in_x_range(cv, p))
return CURVE_NOT_IN_RANGE;
if (!curve_is_vertical(cv))
{
int res = compare_y(p, curve_calc_point(cv, p));
if (res == SMALLER) return UNDER_CURVE;
if (res == LARGER) return ABOVE_CURVE;
//if (res == EQUAL)
return ON_CURVE;
}
else
{
if (is_lower(p,lowest(curve_source(cv),curve_target(cv))))
return UNDER_CURVE;
if (is_higher(p,highest(curve_source(cv),curve_target(cv))))
return ABOVE_CURVE;
// if (curve_is_in_y_range(cv,p))
return ON_CURVE;
}
Construct_vertex_2 construct_vertex = construct_vertex_2_object();
const Point_2 & source = construct_vertex(cv, 0);
const Point_2 & target = construct_vertex(cv, 1);
Less_x_2 less_x = less_x_2_object();
return !((less_x(source, q) && less_x(target, q)) ||
(less_x(q, source) && less_x(q, target)));
}
Comparison_result
curve_compare_at_x(const X_curve_2 & cv1,
const X_curve_2 & cv2,
const Point_2 & q) const
/*! curve_compare_at_x() compares the y-coordinate of two given curves at
* the x-coordinate of a given point
* \param cv1 the first curve
* \param cv2 the second curve
* \param q the point
* \return EQUAL if at least one of cv1 and cv2 is not defined at q's
* x-coordinate x(q). Otherwise, LARGER if cv1(x(q)) > cv2(x(q)), SMALLER if
* cv1(x(q)) < cv2(x(q), or else EQUAL.
* \todo replace indirect use curve_compare_at_x() with compare_y_at_x_2()
*/
Comparison_result curve_compare_at_x(const X_curve_2 & cv1,
const X_curve_2 & cv2,
const Point_2 & q) const
{ return compare_y_at_x_2_object()(q, cv1, cv2); }
/*! curve_compare_at_x_left() compares the y value of two curves in an
* epsilon environment to the left of the x value of the input point
*/
Comparison_result curve_compare_at_x_left(const X_curve & cv1,
const X_curve & cv2,
const Point_2 & q) const
{
//CGAL_assertion (curve_is_in_x_range(cv1, q));
//CGAL_assertion (curve_is_in_x_range(cv2, q));
if ((!curve_is_in_x_range(cv1, q)) || (!curve_is_in_x_range(cv2, q)))
return EQUAL;
X_curve_2 cv1_ = cv1;
X_curve_2 cv2_ = cv2;
if (compare_lexicographically_xy(cv1.source(), cv1.target()) == LARGER)
cv1_ = curve_flip(cv1);
if (compare_lexicographically_xy(cv2.source(), cv2.target()) == LARGER)
cv2_ = curve_flip(cv2);
Point_2 p1 = curve_calc_point(cv1_, q);
Point_2 p2 = curve_calc_point(cv2_, q);
if (curve_is_vertical(cv1_))
{
if (curve_is_vertical(cv2_))
{
// both cv1 and cv2 are vertical
if ( is_lower(cv1_.target(), cv2_.source()) )
return SMALLER;
if ( is_higher(cv1_.source(), cv2_.target()) )
return LARGER;
return SMALLER;
}
// cv1 is vertical and cv2 not
if ( is_lower(cv1_.target(), p2) )
return SMALLER;
if ( is_higher(cv1_.source(), p2) )
return LARGER;
return EQUAL;
}
if (curve_is_vertical(cv2_))
{
// cv2 is vertical and cv1- not
/* bug fix (Oren)
if (is_lower(cv2.target(), p1) )
return LARGER;
if ( is_higher(cv2.source(), p1) )
return SMALLER;
if ( is_higher(cv2.source(), p1) ) // bug fix (Oren)
The answer should be independent of the curve's orientation !!
// If one of the curves is vertical then return EQUAL.
Is_vertical_2 is_vertical = is_vertical_2_object();
if (is_vertical(cv1) || (is_vertical(cv2))) return EQUAL;
p1 x--x p1 x--x
| /\
| versus |
\/cv2 |cv2
x x
p p
*/
if (is_lower(cv2_.target(), p1) )
return LARGER;
if (is_higher(cv2_.source(), p1) )
return SMALLER;
return EQUAL;
}
// If one of the curves is not defined at q then return EQUAL.
Construct_vertex_2 construct_vertex = construct_vertex_2_object();
Less_x_2 less_x = less_x_2_object();
const Point_2 & source1 = construct_vertex(cv1, 0);
const Point_2 & target1 = construct_vertex(cv1, 1);
if (!(less_x(source1, q) || less_x(target1, q))) return EQUAL;
// both are not vertical
if (is_higher(p1, p2)) return LARGER;
if (is_lower(p1, p2)) return SMALLER;
return EQUAL;
}
Comparison_result
curve_compare_at_x_left(const X_curve_2 &cv1, const X_curve_2 &cv2,
const Point_2 &q) const
{
// cases in which the function isn't defined
//CGAL_assertion(!curve_is_vertical(cv1));
//CGAL_assertion(!curve_is_vertical(cv2));
//CGAL_assertion(is_left(leftmost(cv1.source(), cv1.target()), q));
//CGAL_assertion(is_left(leftmost(cv2.source(), cv2.target()), q));
const Point_2 & source2 = construct_vertex(cv2, 0);
const Point_2 & target2 = construct_vertex(cv2, 1);
if (!(less_x(source2, q) || less_x(target2, q))) return EQUAL;
if (curve_is_vertical(cv1) || (curve_is_vertical(cv2))) return EQUAL;
if (!is_left(leftmost(cv1.source(), cv1.target()), q)) return EQUAL;
if (!is_left(leftmost(cv2.source(), cv2.target()), q)) return EQUAL;
Comparison_result r = curve_compare_at_x(cv1, cv2, q);
if ( r != EQUAL)
return r; // since the curve is continous
// since the curve is continous
Comparison_result r = compare_y_at_x_2_object()(q, cv1, cv2);
if (r != EQUAL) return r;
// <cv2> and <cv1> meet at a point with the same x-coordinate as q
// compare their derivatives
return compare_value(curve_derivative(cv2), curve_derivative(cv1));
}
Comparison_result
curve_compare_at_x_right(const X_curve_2 &cv1, const X_curve_2 &cv2,
const Point_2 & q) const
return compare_slope_2_object()(cv2, cv1);
}
/*! curve_compare_at_x_right() compares the y value of two curves in an
* epsilon environment to the right of the x value of the input point
*/
Comparison_result curve_compare_at_x_right(const X_curve & cv1,
const X_curve & cv2,
const Point_2 & q) const
{
// cases in which the function isn't defined
//CGAL_assertion(!curve_is_vertical(cv1));
//CGAL_assertion(!curve_is_vertical(cv2));
//CGAL_assertion(is_right(rightmost(cv1.source(), cv1.target()), q));
//CGAL_assertion(is_right(rightmost(cv2.source(), cv2.target()), q));
if (curve_is_vertical(cv1) || (curve_is_vertical(cv2))) return EQUAL;
if (!is_right(rightmost(cv1.source(), cv1.target()), q)) return EQUAL;
if (!is_right(rightmost(cv2.source(), cv2.target()), q)) return EQUAL;
// If one of the curves is vertical then return EQUAL.
Is_vertical_2 is_vertical = is_vertical_2_object();
if (is_vertical(cv1) || (is_vertical(cv2))) return EQUAL;
// If one of the curves is not defined at q then return EQUAL.
Construct_vertex_2 construct_vertex = construct_vertex_2_object();
Less_x_2 less_x = less_x_2_object();
const Point_2 & source1 = construct_vertex(cv1, 0);
const Point_2 & target1 = construct_vertex(cv1, 1);
if (!(less_x(q, source1) || less_x(q, target1))) return EQUAL;
const Point_2 & source2 = construct_vertex(cv2, 0);
const Point_2 & target2 = construct_vertex(cv2, 1);
if (!(less_x(q, source2) || less_x(q, target2))) return EQUAL;
// since the curve is continous (?)
Comparison_result r = curve_compare_at_x(cv1, cv2, q);
if ( r != EQUAL)
return r; // since the curve is continous (?)
if (r != EQUAL) return r;
// <cv1> and <cv2> meet at a point with the same x-coordinate as q
// compare their derivatives
return compare_value(curve_derivative(cv1), curve_derivative(cv2));
return compare_slope_2_object()(cv1, cv2);
}
X_curve_2 curve_flip(const X_curve_2 &cv) const
{
return X_curve_2(cv.target(), cv.source());
}
bool curve_is_between_cw(const X_curve_2 &cv,
const X_curve_2 &first,
const X_curve_2 &second,
const Point_2 &point) const
// TRUE if cv is between first and second in cw direction
// precondition: this, first and second have a common endpoint
// precondition: first, second, this are pairwise interior disjoint
{
// CGAL_assertion(is_intersection_simple(first, second);
// CGAL_assertion(is_intersection_simple(first, *this);
// CGAL_assertion(is_intersection_simple(*this, second);
Curve_status cv0_status, cv1_status, cvx_status;
int cv0_cv1, cv0_cvx, cv1_cvx;
cv0_cv1 = cv0_cvx = cv1_cvx = -1;
Point_2 cp = point;
X_curve_2 cv0 = first;
X_curve_2 cv1 = second;
X_curve_2 cvx = cv;
if ( !is_same(cv0.source(),cp) ) cv0 = curve_flip(cv0);
if ( !is_same(cv1.source(),cp) ) cv1 = curve_flip(cv1);
if ( !is_same(cvx.source(),cp) ) cvx = curve_flip(cvx);
cv0_status = curve_get_status(cv0);
cv1_status = curve_get_status(cv1);
cvx_status = curve_get_status(cvx);
// the circle: 0
// ** | **
// * *
// 3 * * 1
// * *
// ** | **
// 2
if (cv0_status == cv1_status)
{
if (cv0_status == CURVE_RIGHT)
cv0_cv1 = curve_compare_at_x_right(cv0, cv1, cp);
if (cv0_status == CURVE_LEFT)
cv0_cv1 = curve_compare_at_x_left(cv0, cv1, cp);
}
if (cv0_status == cvx_status)
{
if (cv0_status == CURVE_RIGHT)
cv0_cvx = curve_compare_at_x_right(cv0, cvx, cp);
if (cv0_status == CURVE_LEFT)
cv0_cvx = curve_compare_at_x_left(cv0, cvx, cp);
}
if (cv1_status == cvx_status)
{
if (cv1_status == CURVE_RIGHT)
cv1_cvx = curve_compare_at_x_right(cv1, cvx, cp);
if (cv1_status == CURVE_LEFT)
cv1_cvx = curve_compare_at_x_left(cv1, cvx, cp);
}
if (cv0_status == cv1_status)
{
if (cv0_status == CURVE_LEFT)
{
if ( ((cv0_cv1==1) && (cvx_status==cv0_status) &&
((cv0_cvx==-1) || (cv1_cvx==1))) ||
((cv0_cv1==1) && (cvx_status!=cv0_status)) ||
((cv0_cv1==-1) && (cvx_status==cv0_status) &&
((cv0_cvx==-1) && (cv1_cvx==1))) )
return true;
}
if (cv0_status == CURVE_RIGHT)
{
if ( ((cv0_cv1==1) && (cvx_status==cv0_status) &&
((cv0_cvx==1) && (cv1_cvx==-1))) ||
((cv0_cv1==-1) && (cvx_status!=cv0_status)) ||
((cv0_cv1==-1) && (cvx_status==cv0_status) &&
((cv0_cvx==1) || (cv1_cvx==-1))) )
return true;
}
return false;
}
// else do the following
if (cv0_status == cvx_status)
{
if ( ((cv0_status == CURVE_LEFT) && (cv0_cvx==-1)) ||
((cv0_status == CURVE_RIGHT) && (cv0_cvx==1)) )
return true;
//Addition by iddo for enabeling addition of null segments - testing
if ( (cv0_status==CURVE_VERTICAL_DOWN)&&
((cv0.source()==cv0.target())||(cvx.source()==cvx.target())) )
return true; //a null segment (=point)
return false;
}
if (cv1_status == cvx_status)
{
if ( ((cv1_status == CURVE_LEFT) && (cv1_cvx==1)) ||
((cv1_status == CURVE_RIGHT) && (cv1_cvx==-1)) )
return true;
//Addition by iddo for enabeling addition of null segments - testing
if ( (cv1_status==CURVE_VERTICAL_DOWN)&&
((cv1.source()==cv1.target())||(cvx.source()==cvx.target())) )
return true; //a null segment (=point)
return false;
}
// cv1 and cv0 are on diffrent part of the circle - it is easy
if ( ((cv1_status - cv0_status + 4)%4) <
((cvx_status - cv0_status + 4)%4) )
return false;
else
// if there is an equality or inequality to the other side
// everything is ok
return true;
}
Comparison_result compare_x(const Point_2 &p1, const Point_2 &p2) const
{ return compare_value(p1.x(), p2.x()); }
Comparison_result compare_y(const Point_2 &p1, const Point_2 &p2) const
{ return compare_value(p1.y(), p2.y()); }
public:
Point_2 point_to_left(const Point_2& p) const {
return p+Vector_2(-1,0);}
Point_2 point_to_right(const Point_2& p) const {return p+Vector_2(1,0);}
bool curve_is_same(const X_curve_2 &cv1, const X_curve_2 &cv2) const
{
return is_same(curve_source(cv1),curve_source(cv2))&&
is_same(curve_target(cv1),curve_target(cv2));
}
bool is_point_on_curve(const X_curve_2 &cv, const Point_2& p) const //check
/*! Return the curve-point status of the input objects
* \todo Remove curve_get_point_status() from wrapper. Verify that
* curve_is_in_x_range() and compare_y_at_x_2() are required in the
* traits, and use directly.
*/
Curve_point_status
curve_get_point_status(const X_curve_2 & cv, const Point_2 & p) const
{
if (!curve_is_in_x_range(cv, p))
return false;
if (curve_is_vertical(cv))
{
if (curve_is_in_y_range(cv,p))
return true;
else
return false;
}
int res = compare_y(p, curve_calc_point(cv, p));
if (res == EQUAL)
return true;
return false;
}
private:
bool is_left(const Point_2 &p1, const Point_2 &p2) const
{ return (compare_x(p1, p2) == SMALLER); }
bool is_right(const Point_2 &p1, const Point_2 &p2) const
{ return (compare_x(p1, p2) == LARGER); }
bool is_same_x(const Point_2 &p1, const Point_2 &p2) const
{ return (compare_x(p1, p2) == EQUAL); }
bool is_lower(const Point_2 &p1, const Point_2 &p2) const
{ return (compare_y(p1, p2) == SMALLER); }
bool is_higher(const Point_2 &p1, const Point_2 &p2) const
{ return (compare_y(p1, p2) == LARGER); }
bool is_same_y(const Point_2 &p1, const Point_2 &p2) const
{ return (compare_y(p1, p2) == EQUAL); }
bool is_same(const Point_2 &p1, const Point_2 &p2) const
{
return (compare_x(p1, p2) == EQUAL) &&
(compare_y(p1, p2) == EQUAL);
}
const Point_2& leftmost(const Point_2 &p1, const Point_2 &p2) const
{ return (is_left(p1, p2) ? p1 : p2); }
const Point_2& rightmost(const Point_2 &p1, const Point_2 &p2) const
{ return (is_right(p1, p2) ? p1 : p2); }
const Point_2& lowest(const Point_2 &p1, const Point_2 &p2) const
{ return (is_lower(p1, p2) ? p1 : p2); }
const Point_2& highest(const Point_2 &p1, const Point_2 &p2) const
{ return (is_higher(p1, p2) ? p1 : p2); }
private:
Point_2 curve_calc_point(const X_curve_2 &cv, const Point_2 & q) const
{
// CGAL_assertion (!curve_is_in_s_range(cv, q));
if ( !curve_is_in_x_range(cv, q) )
return cv.source();
return CURVE_NOT_IN_RANGE;
if (curve_is_vertical(cv))
return cv.source();
Comparison_result res = compare_y_at_x_2_object()(p, cv);
//return Point_2(q.x(), cv.source().y() +
// (cv.target().y() - cv.source().y()) /
// (cv.target().x() - cv.source().x()) *
// (q.x() - cv.source().x()) );
if ( res == LARGER ) return ABOVE_CURVE;
else if ( res == SMALLER ) return UNDER_CURVE;
const Point_2 & a = cv.source();
const Point_2 & b = cv.target();
return Point_2((b.hx() * a.hw() - a.hx() * b.hw()) * q.hx() * a.hw(),
(b.hx() * a.hw() - a.hx() * b.hw()) * q.hw() * a.hy() +
(b.hy() * a.hw() - a.hy() * b.hw()) *
(q.hx() * a.hw() - a.hx() * q.hw()),
(b.hx() * a.hw() - a.hx() * b.hw()) * q.hw() * a.hw());
}
typename R::FT curve_derivative(const X_curve_2 &cv) const
{
CGAL_assertion(!curve_is_vertical(cv));
return ( (cv.target()).y() - cv.source().y()) /
(cv.target().x() - cv.source().x());
}
typename R::FT curve_b_const(const X_curve_2 &cv)const
{
CGAL_assertion (!curve_is_vertical(cv));
return ((cv.target().x() * cv.source().y() -
cv.target().y()*cv.source().x()) /
(cv.target().x() - cv.source().x()));
}
Comparison_result compare_value(const typename R::FT &v1,
const typename R::FT &v2) const
{
typename R::FT d = v1 - v2;
typename R::FT z(0);
if (d == z)
return EQUAL;
if (z < d)
return LARGER;
else
return SMALLER;
return ON_CURVE;
}
Curve_status curve_get_status(const X_curve_2 &cv) const
/*! \todo Degenerate cases may not work! Talk with Eyal to fix the actual
* code in Pmwx to use the same consisting definitions of
* curve_is_between_cw(), counterclockwise_in_between_2_object(), and
* the kernel function that is used to implement the later.
*/
bool curve_is_between_cw(const X_curve_2 & cv,
const X_curve_2 & first,
const X_curve_2 & second,
const Point_2 & point) const
{
if (curve_is_vertical(cv))
{
if ( is_higher(cv.target(), cv.source()) )
return CURVE_VERTICAL_UP;
else
return CURVE_VERTICAL_DOWN;
}
else
{
if ( is_right(cv.target(), cv.source()) )
return CURVE_RIGHT;
else
return CURVE_LEFT;
}
// Notice the change in order of first and second
return counterclockwise_in_between_2_object()(point, cv, second, first);
}
/*! \todo replace indirect use curve_is_same() with equal_2()
*/
bool curve_is_same(const X_curve_2 & cv1,const X_curve_2 & cv2) const
{ return equal_2_object()(cv1, cv2); }
/*! \todo replace indirect use point_is_same() with equal_2()
*/
bool point_is_same(const Point_2 & p1, const Point_2 & p2) const
{ return equal_2_object()(p1, p2); }
/*! \todo replace indirect use curve_source() with construct_vertex_2()
*/
Point_2 curve_source(const X_curve_2 & cv) const
{ return construct_vertex_2_object()(cv, 0); }
/*! \todo replace indirect use curve_source() with construct_vertex_2()
*/
Point_2 curve_target(const X_curve_2 & cv) const
{ return construct_vertex_2_object()(cv, 1); }
/*! \todo replace indirect use point_is_left() with less_x_2()
*/
bool point_is_left(const Point_2 & p1, const Point_2 & p2) const
{ return less_x_2_object()(p1, p2); }
/*! \todo replace indirect use point_is_right() with less_x_2()
*/
bool point_is_right(const Point_2 & p1, const Point_2 & p2) const
{ return less_x_2_object()(p2, p1); }
};
CGAL_END_NAMESPACE
#endif // CGAL_PM_SEGMENT_TRAITS_2_H
// EOF
#endif