mirror of https://github.com/CGAL/cgal
removed object Side_of_hyperbolic_triangle from traits; added object Side_of_oriented_hyperbolic_segment in traits; added function side_of_hyperbolic_triangle in triangulation class
This commit is contained in:
parent
8d441cebc1
commit
e133fcea32
|
|
@ -85,7 +85,7 @@ public:
|
|||
};
|
||||
|
||||
|
||||
typedef typename Geom_traits::Side_of_hyperbolic_triangle_2 Side_of_hyperbolic_triangle;
|
||||
typedef typename Geom_traits::Side_of_oriented_hyperbolic_segment_2 Side_of_oriented_hyperbolic_segment;
|
||||
typedef typename Geom_traits::Is_Delaunay_hyperbolic Is_Delaunay_hyperbolic;
|
||||
|
||||
Hyperbolic_Delaunay_triangulation_2(const Geom_traits& gt = Geom_traits())
|
||||
|
|
@ -205,6 +205,68 @@ public:
|
|||
|
||||
private:
|
||||
|
||||
Oriented_side side_of_hyperbolic_triangle(const Point p, const Point q, const Point r,
|
||||
const Point query, Locate_type <, int& li) const {
|
||||
|
||||
// The triangle (p,q,r) must be Delaunay hyperbolic
|
||||
CGAL_triangulation_precondition(Is_Delaunay_hyperbolic()(p, q, r));
|
||||
|
||||
// Point p is assumed to be at index 0, q at index 1 and r at index 2 in the face.
|
||||
li = -1;
|
||||
|
||||
if (query == p) {
|
||||
lt = VERTEX;
|
||||
li = 0;
|
||||
return ON_ORIENTED_BOUNDARY;
|
||||
}
|
||||
if (query == q) {
|
||||
lt == VERTEX;
|
||||
li = 1;
|
||||
return ON_ORIENTED_BOUNDARY;
|
||||
}
|
||||
if (query == r) {
|
||||
lt == VERTEX;
|
||||
li = 2;
|
||||
return ON_ORIENTED_BOUNDARY;
|
||||
}
|
||||
|
||||
|
||||
Oriented_side cp1 = Side_of_oriented_hyperbolic_segment()(p, q, query);
|
||||
if (cp1 == ON_ORIENTED_BOUNDARY) {
|
||||
lt = EDGE;
|
||||
li = 2;
|
||||
return ON_ORIENTED_BOUNDARY;
|
||||
}
|
||||
|
||||
Oriented_side cp2 = Side_of_oriented_hyperbolic_segment()(q, r, query);
|
||||
if (cp2 == ON_ORIENTED_BOUNDARY) {
|
||||
lt = EDGE;
|
||||
li = 0;
|
||||
return ON_ORIENTED_BOUNDARY;
|
||||
}
|
||||
|
||||
Oriented_side cp3 = Side_of_oriented_hyperbolic_segment()(r, p, query);
|
||||
if (cp3 == ON_ORIENTED_BOUNDARY) {
|
||||
lt = EDGE;
|
||||
li = 1;
|
||||
return ON_ORIENTED_BOUNDARY;
|
||||
}
|
||||
|
||||
|
||||
Oriented_side cs1 = Side_of_oriented_hyperbolic_segment()(p, q, r);
|
||||
Oriented_side cs2 = Side_of_oriented_hyperbolic_segment()(q, r, p);
|
||||
Oriented_side cs3 = Side_of_oriented_hyperbolic_segment()(r, p, q);
|
||||
|
||||
// Cannot be on the boundary here.
|
||||
lt = FACE;
|
||||
if (cs1 != cp1 || cs2 != cp2 || cs3 != cp3) {
|
||||
return ON_NEGATIVE_SIDE;
|
||||
} else {
|
||||
return ON_POSITIVE_SIDE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool has_infinite_vertex(Face_handle f) const
|
||||
{
|
||||
return Base::is_infinite(f);
|
||||
|
|
@ -675,12 +737,12 @@ public:
|
|||
Point q = fh->vertex(1)->point();
|
||||
Point r = fh->vertex(2)->point();
|
||||
if (Is_Delaunay_hyperbolic()(p, q, r)) {
|
||||
Bounded_side side = Side_of_hyperbolic_triangle()(p, q, r, query, li);
|
||||
if (side == ON_BOUNDARY) {
|
||||
Oriented_side side = side_of_hyperbolic_triangle(p, q, r, query, lt, li);
|
||||
if (side == ON_ORIENTED_BOUNDARY) {
|
||||
lt = EDGE;
|
||||
return fh;
|
||||
} else {
|
||||
if (side == ON_BOUNDED_SIDE) {
|
||||
if (side == ON_POSITIVE_SIDE) {
|
||||
lt = FACE;
|
||||
return fh;
|
||||
} else {
|
||||
|
|
@ -693,12 +755,12 @@ public:
|
|||
q = fh->mirror_vertex(li)->point();
|
||||
r = fh->vertex(cw(li))->point();
|
||||
if (Is_Delaunay_hyperbolic()(p, q, r)) {
|
||||
Bounded_side side = Side_of_hyperbolic_triangle()(p, q, r, query, li);
|
||||
if (side == ON_BOUNDARY) {
|
||||
Oriented_side side = side_of_hyperbolic_triangle(p, q, r, query, lt, li);
|
||||
if (side == ON_ORIENTED_BOUNDARY) {
|
||||
lt = EDGE;
|
||||
return fh;
|
||||
} else {
|
||||
if (side == ON_BOUNDED_SIDE) {
|
||||
if (side == ON_POSITIVE_SIDE) {
|
||||
lt = FACE;
|
||||
return fh;
|
||||
} else {
|
||||
|
|
@ -719,12 +781,12 @@ public:
|
|||
return Face_handle();
|
||||
}
|
||||
|
||||
Bounded_side side = Side_of_hyperbolic_triangle()(p, q, r, query, li);
|
||||
if (side == ON_BOUNDED_SIDE) {
|
||||
Oriented_side side = side_of_hyperbolic_triangle(p, q, r, query, lt, li);
|
||||
if (side == ON_POSITIVE_SIDE) {
|
||||
lt = FACE;
|
||||
return fh;
|
||||
} else {
|
||||
if (side == ON_BOUNDARY) {
|
||||
if (side == ON_ORIENTED_BOUNDARY) {
|
||||
lt = EDGE;
|
||||
return fh;
|
||||
} else {
|
||||
|
|
@ -732,11 +794,11 @@ public:
|
|||
for (int i = 0; i < 3; i++) {
|
||||
Face_handle nfh = fh->neighbor(i);
|
||||
if (Is_Delaunay_hyperbolic()(nfh->vertex(0)->point(),nfh->vertex(1)->point(),nfh->vertex(2)->point())) {
|
||||
Bounded_side nside = Side_of_hyperbolic_triangle()(nfh->vertex(0)->point(),nfh->vertex(1)->point(),nfh->vertex(2)->point(), query, li);
|
||||
if (nside == ON_BOUNDED_SIDE) {
|
||||
Oriented_side nside = side_of_hyperbolic_triangle(nfh->vertex(0)->point(),nfh->vertex(1)->point(),nfh->vertex(2)->point(), query, lt, li);
|
||||
if (nside == ON_POSITIVE_SIDE) {
|
||||
lt = FACE;
|
||||
return nfh;
|
||||
} else if (nside == ON_BOUNDARY) {
|
||||
} else if (nside == ON_ORIENTED_BOUNDARY) {
|
||||
lt = EDGE;
|
||||
return nfh;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -368,95 +368,62 @@ public:
|
|||
|
||||
|
||||
|
||||
class Side_of_hyperbolic_triangle_2 {
|
||||
public:
|
||||
Side_of_hyperbolic_triangle_2() {}
|
||||
|
||||
typedef Bounded_side result_type;
|
||||
|
||||
// Returns the relative position of point t to the hyperbolic triangle (p,q,r)
|
||||
Bounded_side operator()(Point_2 p, Point_2 q, Point_2 r, Point_2 t, int& li) const {
|
||||
|
||||
// The triangle (p,q,r) cannot be hyperbolic! This case should be handled at triangulation level
|
||||
CGAL_triangulation_precondition(Is_Delaunay_hyperbolic()(p, q, r));
|
||||
|
||||
// Point p is assumed to be at index 0, q at index 1 and r at index 2 in the face.
|
||||
li = -1;
|
||||
|
||||
Bounded_side cp1 = side_of_segment_2(t, p, q);
|
||||
if (cp1 == ON_BOUNDARY) {
|
||||
li = 2;
|
||||
return ON_BOUNDARY;
|
||||
}
|
||||
|
||||
Bounded_side cp2 = side_of_segment_2(t, q, r);
|
||||
if (cp2 == ON_BOUNDARY) {
|
||||
li = 0;
|
||||
return ON_BOUNDARY;
|
||||
}
|
||||
|
||||
Bounded_side cp3 = side_of_segment_2(t, r, p);
|
||||
if (cp3 == ON_BOUNDARY) {
|
||||
li = 1;
|
||||
return ON_BOUNDARY;
|
||||
}
|
||||
|
||||
|
||||
Bounded_side cs1 = side_of_segment_2(r, p, q);
|
||||
Bounded_side cs2 = side_of_segment_2(p, q, r);
|
||||
Bounded_side cs3 = side_of_segment_2(q, r, p);
|
||||
|
||||
// Cannot be on the boundary here.
|
||||
if (cs1 != cp1 || cs2 != cp2 || cs3 != cp3) {
|
||||
return ON_UNBOUNDED_SIDE;
|
||||
} else {
|
||||
return ON_BOUNDED_SIDE;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
class Side_of_oriented_hyperbolic_segment_2 {
|
||||
typedef typename R::Construct_weighted_circumcenter_2 Construct_weighted_circumcenter_2;
|
||||
typedef typename R::Weighted_point_2 Weighted_point_2;
|
||||
typedef typename R::Point_2 Bare_point;
|
||||
|
||||
Bounded_side side_of_segment_2(const Point_2 query, const Point_2 p, const Point_2 q) const {
|
||||
public:
|
||||
Side_of_oriented_hyperbolic_segment_2() {}
|
||||
|
||||
typedef Oriented_side result_type;
|
||||
|
||||
result_type operator()(Point_2 p, Point_2 q, Point_2 query) const {
|
||||
|
||||
// Check first if the points are collinear with the origin
|
||||
Circle_2 poincare(Point_2(FT(0),FT(0)), FT(1));
|
||||
Orientation ori = orientation(poincare.center(), p, q);
|
||||
Point_2 O(FT(0), FT(0));
|
||||
Orientation ori = orientation(p, q, O);
|
||||
if (ori == COLLINEAR) {
|
||||
Euclidean_line_2 seg(p, q);
|
||||
Orientation qori = orientation(query, p, q);
|
||||
Orientation qori = orientation(p, q, query);
|
||||
if (qori == COLLINEAR) {
|
||||
return ON_BOUNDARY;
|
||||
return ON_ORIENTED_BOUNDARY;
|
||||
} else {
|
||||
// It is sufficient that these are consistent.
|
||||
if (qori == LEFT_TURN) {
|
||||
return ON_BOUNDED_SIDE;
|
||||
return ON_POSITIVE_SIDE;
|
||||
} else {
|
||||
return ON_UNBOUNDED_SIDE;
|
||||
return ON_NEGATIVE_SIDE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Origin o;
|
||||
Weighted_point_2 wp(p);
|
||||
Weighted_point_2 wq(q);
|
||||
Weighted_point_2 wo(Point_2(o), FT(1)); // Poincaré circle
|
||||
Weighted_point_2 wo(O, FT(1)); // Poincaré circle
|
||||
|
||||
Bare_point center = Construct_weighted_circumcenter_2()(wp, wo, wq);
|
||||
FT sq_radius = Compute_squared_Euclidean_distance_2()(p, center);
|
||||
|
||||
Circle_2 circle(center, sq_radius);
|
||||
return circle.bounded_side(query);
|
||||
Bounded_side bs = circle.bounded_side(query);
|
||||
if (bs == ON_BOUNDARY) {
|
||||
return ON_ORIENTED_BOUNDARY;
|
||||
} else {
|
||||
if (bs == ON_BOUNDED_SIDE) {
|
||||
return ON_POSITIVE_SIDE;
|
||||
} else {
|
||||
return ON_NEGATIVE_SIDE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
Side_of_hyperbolic_triangle_2
|
||||
side_of_hyperbolic_triangle_2_object() {
|
||||
return Side_of_hyperbolic_triangle_2();
|
||||
Side_of_oriented_hyperbolic_segment_2
|
||||
side_of_oriented_hyperbolic_segment_2() {
|
||||
return Side_of_oriented_hyperbolic_segment_2();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -658,96 +658,62 @@ public:
|
|||
}
|
||||
|
||||
|
||||
|
||||
class Side_of_hyperbolic_triangle_2 {
|
||||
public:
|
||||
Side_of_hyperbolic_triangle_2() {}
|
||||
|
||||
typedef Bounded_side result_type;
|
||||
|
||||
// Returns the relative position of point t to the hyperbolic triangle (p,q,r)
|
||||
Bounded_side operator()(Point_2 p, Point_2 q, Point_2 r, Point_2 t, int& li) const {
|
||||
|
||||
// The triangle (p,q,r) cannot be hyperbolic! This case should be handled at triangulation level
|
||||
CGAL_triangulation_precondition(Is_Delaunay_hyperbolic()(p, q, r));
|
||||
|
||||
// Point p is assumed to be at index 0, q at index 1 and r at index 2 in the face.
|
||||
li = -1;
|
||||
|
||||
Bounded_side cp1 = side_of_segment_2(t, p, q);
|
||||
if (cp1 == ON_BOUNDARY) {
|
||||
li = 2;
|
||||
return ON_BOUNDARY;
|
||||
}
|
||||
|
||||
Bounded_side cp2 = side_of_segment_2(t, q, r);
|
||||
if (cp2 == ON_BOUNDARY) {
|
||||
li = 0;
|
||||
return ON_BOUNDARY;
|
||||
}
|
||||
|
||||
Bounded_side cp3 = side_of_segment_2(t, r, p);
|
||||
if (cp3 == ON_BOUNDARY) {
|
||||
li = 1;
|
||||
return ON_BOUNDARY;
|
||||
}
|
||||
|
||||
|
||||
Bounded_side cs1 = side_of_segment_2(r, p, q);
|
||||
Bounded_side cs2 = side_of_segment_2(p, q, r);
|
||||
Bounded_side cs3 = side_of_segment_2(q, r, p);
|
||||
|
||||
// Cannot be on the boundary here.
|
||||
if (cs1 != cp1 || cs2 != cp2 || cs3 != cp3) {
|
||||
return ON_UNBOUNDED_SIDE;
|
||||
} else {
|
||||
return ON_BOUNDED_SIDE;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
class Side_of_oriented_hyperbolic_segment_2 {
|
||||
typedef typename Kernel::Construct_weighted_circumcenter_2 Construct_weighted_circumcenter_2;
|
||||
typedef typename Kernel::Weighted_point_2 Weighted_point_2;
|
||||
typedef typename Kernel::Point_2 Bare_point;
|
||||
|
||||
Bounded_side side_of_segment_2(const Point_2 query, const Point_2 p, const Point_2 q) const {
|
||||
public:
|
||||
Side_of_oriented_hyperbolic_segment_2() {}
|
||||
|
||||
typedef Oriented_side result_type;
|
||||
|
||||
result_type operator()(Point_2 p, Point_2 q, Point_2 query) const {
|
||||
|
||||
// Check first if the points are collinear with the origin
|
||||
Circle_2 poincare(Point_2(FT(0),FT(0)), FT(1));
|
||||
Orientation ori = orientation(poincare.center(), p, q);
|
||||
Point_2 O(FT(0), FT(0));
|
||||
Orientation ori = orientation(p, q, O);
|
||||
if (ori == COLLINEAR) {
|
||||
Euclidean_line_2 seg(p, q);
|
||||
Orientation qori = orientation(query, p, q);
|
||||
Orientation qori = orientation(p, q, query);
|
||||
if (qori == COLLINEAR) {
|
||||
return ON_BOUNDARY;
|
||||
return ON_ORIENTED_BOUNDARY;
|
||||
} else {
|
||||
// It is sufficient that these are consistent.
|
||||
if (qori == LEFT_TURN) {
|
||||
return ON_BOUNDED_SIDE;
|
||||
return ON_POSITIVE_SIDE;
|
||||
} else {
|
||||
return ON_UNBOUNDED_SIDE;
|
||||
return ON_NEGATIVE_SIDE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Origin o;
|
||||
Weighted_point_2 wp(p);
|
||||
Weighted_point_2 wq(q);
|
||||
Weighted_point_2 wo(Point_2(o), FT(1)); // Poincaré circle
|
||||
Weighted_point_2 wo(O, FT(1)); // Poincaré circle
|
||||
|
||||
Bare_point center = Construct_weighted_circumcenter_2()(wp, wo, wq);
|
||||
FT sq_radius = Compute_squared_Euclidean_distance_2()(p, center);
|
||||
|
||||
Circle_2 circle(center, sq_radius);
|
||||
return circle.bounded_side(query);
|
||||
Bounded_side bs = circle.bounded_side(query);
|
||||
if (bs == ON_BOUNDARY) {
|
||||
return ON_ORIENTED_BOUNDARY;
|
||||
} else {
|
||||
if (bs == ON_BOUNDED_SIDE) {
|
||||
return ON_POSITIVE_SIDE;
|
||||
} else {
|
||||
return ON_NEGATIVE_SIDE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
Side_of_hyperbolic_triangle_2
|
||||
side_of_hyperbolic_triangle_2_object() {
|
||||
return Side_of_hyperbolic_triangle_2();
|
||||
Side_of_oriented_hyperbolic_segment_2
|
||||
side_of_oriented_hyperbolic_segment_2() {
|
||||
return Side_of_oriented_hyperbolic_segment_2();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue