mirror of https://github.com/CGAL/cgal
Merge pull request #2774 from MaelRL/T3-Fix_is_Gabriel-GF
T3/P3T3: Fix Is_Gabriel(Vertex_handle) for regular triangulations
This commit is contained in:
commit
15069c1a4e
|
|
@ -34,12 +34,7 @@ public:
|
|||
/// @{
|
||||
|
||||
/*!
|
||||
A predicate object that must provide the function operators
|
||||
|
||||
`Oriented_side operator()(Point_3 p, Point_3 q, Point_3 r, Point_3 s, Point_3 t)`,
|
||||
|
||||
which determines on which side of the oriented sphere circumscribing
|
||||
`p, q, r, s` the point `t` lies and
|
||||
A predicate object that must provide the function operator
|
||||
|
||||
`Oriented_side operator()(Point_3 p, Point_3 q, Point_3 r, Point_3 s, Point_3 t, Periodic_3_offset_3 o_p, Periodic_3_offset_3 o_q, Periodic_3_offset_3 o_r, Periodic_3_offset_3 o_s, Periodic_3_offset_3 o_t)`,
|
||||
|
||||
|
|
@ -51,12 +46,7 @@ which determines on which side of the oriented sphere circumscribing
|
|||
typedef unspecified_type Side_of_oriented_sphere_3;
|
||||
|
||||
/*!
|
||||
A predicate object that must provide the function operators
|
||||
|
||||
`Comparison_result operator()(Point_3 p, Point_3 q, Point_3 r)`,
|
||||
|
||||
which compares the distance between `p` and `q` to the distance
|
||||
between `p` and `r` and
|
||||
A predicate object that must provide the function operator
|
||||
|
||||
`Comparison_result operator()(Point_3 p, Point_3 q, Point_3 r, Periodic_3_offset_3 o_p, Periodic_3_offset_3 o_q, Periodic_3_offset_3 o_r)`,
|
||||
|
||||
|
|
@ -73,13 +63,7 @@ typedef unspecified_type Compare_distance_3;
|
|||
/// @{
|
||||
|
||||
/*!
|
||||
A predicate object that must provide the function operators
|
||||
|
||||
`Orientation operator()(Point_3 p, Point_3 q, Point_3 r)`,
|
||||
|
||||
which returns `COLLINEAR`, if the points are collinear; otherwise
|
||||
it must return a consistent orientation for any three points chosen in
|
||||
a same plane and
|
||||
A predicate object that must provide the function operator
|
||||
|
||||
`Orientation operator()(Point_3 p, Point_3 q, Point_3 r Periodic_3_offset_3 o_p, Periodic_3_offset_3 o_q, Periodic_3_offset_3 o_r)`,
|
||||
|
||||
|
|
@ -91,12 +75,7 @@ three point-offset pairs chosen in a same plane.
|
|||
typedef unspecified_type Coplanar_orientation_3;
|
||||
|
||||
/*!
|
||||
A predicate object that must provide the function operators
|
||||
|
||||
`Bounded_side operator()(Point_3 p, Point_3 q, Point_3 r, Point_3 s)`,
|
||||
|
||||
which determines the bounded side of the circle defined by `p, q`,
|
||||
and `r` on which the point `s` lies and
|
||||
A predicate object that must provide the function operator
|
||||
|
||||
`Bounded_side operator()(Point_3 p, Point_3 q, Point_3 r, Point_3 s, Periodic_3_offset_3 o_p, Periodic_3_offset_3 o_q, Periodic_3_offset_3 o_r, Periodic_3_offset_3 o_s)`,
|
||||
|
||||
|
|
@ -115,42 +94,19 @@ typedef unspecified_type Coplanar_side_of_bounded_circle_3;
|
|||
/// @{
|
||||
|
||||
/*!
|
||||
A predicate object that must provide the function operators
|
||||
|
||||
`Bounded_side operator()(Point_3 p, Point_3 q, Point_3 t)`,
|
||||
|
||||
which returns the position of the point `t` relative to the sphere
|
||||
that has `pq` as its diameter,
|
||||
A predicate object that must provide the function operator
|
||||
|
||||
`Bounded_side operator()(Point_3 p, Point_3 q, Point_3 t, Periodic_3_offset_3 o_p, Periodic_3_offset_3 o_q, Periodic_3_offset_3 o_t)`,
|
||||
|
||||
which returns the position of the point-offset pair `(t,o_t)`
|
||||
relative to the sphere that has `(p,o_p)(q,o_q)` as its diameter,
|
||||
|
||||
`Bounded_side operator()(Point_3 p, Point_3 q, Point_3 r, Point_3 t)`,
|
||||
|
||||
which returns the position of the point `t` relative to the sphere
|
||||
passing through `p, q`, and `r` and whose center is in the
|
||||
plane defined by these three points,
|
||||
|
||||
`Bounded_side operator()(Point_3 p, Point_3 q, Point_3 r, Point_3 t, Periodic_3_offset_3 o_p, Periodic_3_offset_3 o_q, Periodic_3_offset_3 o_r, Periodic_3_offset_3 o_q)`,
|
||||
|
||||
which returns the position of the point-offset pair `(t,o_t)`
|
||||
relative to the sphere passing through `(p,o_p), (q,o_q)`, and
|
||||
`(r,o_r)` and whose center is in the plane defined by these three
|
||||
point-offset pairs,
|
||||
|
||||
`Bounded_side operator()(Point_3 p, Point_3 q, Point_3 r, Point_3 s, Point_3 t)`,
|
||||
|
||||
which returns the relative position of point `t` to the sphere
|
||||
defined by `p, q, r`, and `s`; the order of the points `p, q, r`, and `s` does not matter, and
|
||||
|
||||
`Bounded_side operator()(Point_3 p, Point_3 q, Point_3 r, Point_3 s, Point_3 t, Periodic_3_offset_3 o_p, Periodic_3_offset_3 o_q, Periodic_3_offset_3 o_r, Periodic_3_offset_3 o_s, Periodic_3_offset_3 o_q)`,
|
||||
|
||||
which returns the relative position of the point-offset pair
|
||||
`(t,o_t)` to the sphere defined by `(p,o_p), (q,o_q), (r,o_r)`, and `(s,o_s)`; the order of the point-offset pairs
|
||||
`(p,o_p), (q,o_q), (r,o_r)`, and `(s,o_s)` does not matter.
|
||||
\pre `p, q, r`, and `s` are not coplanar, `(p,o_p), (q,o_q), (r,o_r)`, and `(s,o_s)` are not coplanar, `p`, `q`, `r`, `s`, `t` lie inside the domain.
|
||||
point-offset pairs.
|
||||
*/
|
||||
typedef unspecified_type Side_of_bounded_sphere_3;
|
||||
|
||||
|
|
@ -162,11 +118,7 @@ typedef unspecified_type Side_of_bounded_sphere_3;
|
|||
/// @{
|
||||
|
||||
/*!
|
||||
A constructor object that must provide the function operators
|
||||
|
||||
`Point_3 operator()(Point_3 p, Point_3 q, Point_3 r, Point_3 s)`,
|
||||
|
||||
which constructs the circumcenter of four points and
|
||||
A constructor object that must provide the function operator
|
||||
|
||||
`Point_3 operator()(Point_3 p, Point_3 q, Point_3 r, Point_3 s, Periodic_3_offset_3 o_p, Periodic_3_offset_3 o_q, Periodic_3_offset_3 o_r, Periodic_3_offset_3 o_s)`,
|
||||
|
||||
|
|
|
|||
|
|
@ -34,58 +34,41 @@ public:
|
|||
/// @{
|
||||
|
||||
/*!
|
||||
A predicate object that must provide the function operators:
|
||||
|
||||
`Oriented_side operator()(Weighted_point_3 p, Weighted_point_3 q, Weighted_point_3 r, Weighted_point_3 s, Weighted_point_3 t)`,
|
||||
|
||||
which determines the position of `t` with respect to the power sphere of `p, q, r, s`.
|
||||
A predicate object that must provide the function operators
|
||||
|
||||
`Oriented_side operator()(Weighted_point_3 p, Weighted_point_3 q, Weighted_point_3 r, Weighted_point_3 s, Weighted_point_3 t,
|
||||
Periodic_3_offset_3 o_p, Periodic_3_offset_3 o_q, Periodic_3_offset_3 o_r, Periodic_3_offset_3 o_s, Periodic_3_offset_3 o_t)`,
|
||||
|
||||
which is the same for the point-offset pair `(t,o_t)` with respect to the power sphere of the point-offset pairs
|
||||
`(p,o_p), (q,o_q), (r,o_r), (s,o_s)`.
|
||||
which determines the position of the point-offset pair `(t,o_t)` with respect
|
||||
to the power sphere of the point-offset pairs `(p,o_p), (q,o_q), (r,o_r), (s,o_s)`.
|
||||
\pre `p`, `q`, `r`, `s`, `t` lie inside the domain and `p, q, r, s` are not coplanar.
|
||||
|
||||
<HR WIDTH=50%>
|
||||
|
||||
When vertex removal is used, the predicate must in addition provide the following function operators:
|
||||
When vertex removal is used, the predicate must in addition provide the function operators
|
||||
|
||||
`Oriented_side operator()( Weighted_point_3 p, Weighted_point_3 q, Weighted_point_3 r, Weighted_point_3 t)`,
|
||||
`Oriented_side operator()(Weighted_point_3 p, Weighted_point_3 q, Weighted_point_3 r, Weighted_point_3 t,
|
||||
Periodic_3_offset_3 o_p, Periodic_3_offset_3 o_q, Periodic_3_offset_3 o_r, Periodic_3_offset_3 o_t)`,
|
||||
|
||||
which has a definition similar to the previous method, for coplanar points,
|
||||
with the power circle of `p,q,r`.
|
||||
\pre `p`, `q`, `r`, `t` lie inside the domain, `p, q, r` are not collinear,
|
||||
and `(p,o_p), (q,o_q), (r,o_r), (t,o_t)` are coplanar.
|
||||
|
||||
`Oriented_side operator()( Weighted_point_3 p, Weighted_point_3 q, Weighted_point_3 r, Weighted_point_3 t,
|
||||
Periodic_3_offset_3 o_p, Periodic_3_offset_3 o_q, Periodic_3_offset_3 o_r, Periodic_3_offset_3 o_t)`,
|
||||
`Oriented_side operator()(Weighted_point_3 p, Weighted_point_3 q, Weighted_point_3 t,
|
||||
Periodic_3_offset_3 o_p, Periodic_3_offset_3 o_q, Periodic_3_offset_3 o_t)`,
|
||||
|
||||
which is the same for point-offset pairs.
|
||||
which is the same for collinear points, and the power segment of `(p,o_p)` and `(q,o_q)`,
|
||||
|
||||
\pre `p`, `q`, `r`, `t` lie inside the domain, `p, q, r` are not collinear, and `p, q, r, t` are coplanar.
|
||||
\pre `p`, `q`, `t` lie inside the domain, `p` and `q` have different Bare_points, and
|
||||
`(p,o_p), (q,o_q), (t,o_t)` are collinear.
|
||||
|
||||
`Oriented_side operator()(Weighted_point_3 p, Weighted_point_3 q,
|
||||
Periodic_3_offset_3 o_p, Periodic_3_offset_3 o_q)`,
|
||||
|
||||
`Oriented_side operator()( Weighted_point_3 p, Weighted_point_3 q, Weighted_point_3 t)`,
|
||||
|
||||
which is the same for collinear points, and the power segment of `p` and `q`,
|
||||
|
||||
`Oriented_side operator()( Weighted_point_3 p, Weighted_point_3 q, Weighted_point_3 t,
|
||||
Periodic_3_offset_3 o_p, Periodic_3_offset_3 o_q, Periodic_3_offset_3 o_t)`,
|
||||
|
||||
which is the same for point-offset pairs.
|
||||
|
||||
\pre `p`, `q`, `t` lie inside the domain, `p` and `q` have different Bare_points, and `p, q, t` are collinear.
|
||||
|
||||
|
||||
`Oriented_side operator()( Weighted_point_3 p, Weighted_point_3 q)`,
|
||||
|
||||
which is the same for equal points, that is when `p` and `q`
|
||||
which is the same for equal points, that is when `(p,o_p)` and `(q,o_q)`
|
||||
have equal coordinates, then it returns the comparison of the weights.
|
||||
|
||||
`Oriented_side operator()( Weighted_point_3 p, Weighted_point_3 q,
|
||||
Periodic_3_offset_3 o_p, Periodic_3_offset_3 o_q)`,
|
||||
|
||||
which is the same for point-offset pairs.
|
||||
|
||||
\pre `p` and `q` lie inside the domain and have equal Bare_points.
|
||||
|
||||
*/
|
||||
|
|
@ -118,15 +101,11 @@ typedef unspecified_type Compare_weighted_squared_radius_3;
|
|||
A predicate object, model of `ComparePowerDistance_3`, that must provide
|
||||
the function operator
|
||||
|
||||
`Comparison_result operator()(Point_3 p, Weighted_point_3 q, Weighted_point_3 r)`,
|
||||
|
||||
which compares the power distance between `p` and `q` to the power distance
|
||||
between `p` and `r` and
|
||||
|
||||
`Comparison_result operator()(Point_3 p, Weighted_point_3 q, Weighted_point_3 r,
|
||||
Periodic_3_offset_3 o_p, Periodic_3_offset_3 o_q, Periodic_3_offset_3 o_r)`,
|
||||
Periodic_3_offset_3 o_p, Periodic_3_offset_3 o_q, Periodic_3_offset_3 o_r)`,
|
||||
|
||||
which is the same for point-offset pairs.
|
||||
which compares the power distance between `(p,o_p)` and `(q,o_q)` to the power distance
|
||||
between `(p,o_p)` and `(r,o_r)`.
|
||||
|
||||
\note This predicate is required if a call to `nearest_power_vertex()` or
|
||||
`nearest_power_vertex_in_cell()` is issued.*/
|
||||
|
|
@ -157,23 +136,51 @@ typedef unspecified_type Coplanar_orientation_3;
|
|||
|
||||
/// @}
|
||||
|
||||
/// \name
|
||||
/// When `is_Gabriel` functions are used, the traits class must
|
||||
/// in addition provide the following predicate object:
|
||||
/// @{
|
||||
|
||||
/*!
|
||||
A predicate object that must provide the function operator
|
||||
|
||||
`Bounded_side operator()(Weighted_point_3 p, Weighted_point_3 t,
|
||||
Periodic_3_offset_3 o_p, Periodic_3_offset_3 o_t)`,
|
||||
|
||||
which returns the sign of the power test of `(t,o_t)` with respect to the smallest
|
||||
sphere orthogonal to `(p,o_p)` (which is the sphere with center `(p,o_p)` and squared
|
||||
radius `-w_p` with `w_p` the weight of `p`),
|
||||
|
||||
`Bounded_side operator()(Weighted_point_3 p, Weighted_point_3 q, Weighted_point_3 t,
|
||||
Periodic_3_offset_3 o_p, Periodic_3_offset_3 o_q, Periodic_3_offset_3 o_t)`,
|
||||
|
||||
which returns the sign of the power test of `(t,o_t)` with respect to the smallest
|
||||
sphere orthogonal to `(p,o_p)` and `(q,o_q)`,
|
||||
|
||||
`Bounded_side operator()(Weighted_point_3 p, Weighted_point_3 q, Weighted_point_3 r, Weighted_point_3 t,
|
||||
Periodic_3_offset_3 o_p, Periodic_3_offset_3 o_q, Periodic_3_offset_3 o_r, Periodic_3_offset_3 o_q)`,
|
||||
|
||||
which returns the sign of the power test of `(t,o_t)` with respect to the smallest
|
||||
sphere orthogonal to `(p,o_p)`, `(q,o_q)`, and `(r,o_r)`.
|
||||
*/
|
||||
typedef unspecified_type Power_side_of_bounded_power_sphere_3;
|
||||
|
||||
/// @}
|
||||
|
||||
/// \name
|
||||
/// When the dual operations are used, the traits
|
||||
/// class must in addition provide the following constructor object:
|
||||
/// @{
|
||||
|
||||
/*!
|
||||
A constructor object that must provide the function operators:
|
||||
|
||||
`Weighted_point_3 operator()(Weighted_point_3 p, Weighted_point_3 q, Weighted_point_3 r, Weighted_point_3 s)`,
|
||||
|
||||
which constructs the weighted circumcenter of four points and
|
||||
A constructor object that must provide the function operator
|
||||
|
||||
`Weighted_point_3 operator()(Weighted_point_3 p, Weighted_point_3 q, Weighted_point_3 r, Weighted_point_3 s,
|
||||
Periodic_3_offset_3 o_p, Periodic_3_offset_3 o_q, Periodic_3_offset_3 o_r, Periodic_3_offset_3 o_s)`,
|
||||
|
||||
which constructs the weighted circumcenter of four point-offset pairs.
|
||||
\pre `p`, `q`, `r` and `s` as well as `(p,o_p)`, `(q,o_q)`, `(r,o_r)` and `(s,o_s)` must be non coplanar. `p`, `q`, `r`, `s` lie inside the domain.
|
||||
\pre `p`, `q`, `r`, `s` lie inside the domain. `p`, `q`, `r` and `s`,
|
||||
as well as `(p,o_p)`, `(q,o_q)`, `(r,o_r)` and `(s,o_s)` must be non coplanar.
|
||||
*/
|
||||
typedef unspecified_type Construct_weighted_circumcenter_3;
|
||||
|
||||
|
|
|
|||
|
|
@ -80,11 +80,7 @@ of `Kernel::Tetrahedron_3`.
|
|||
typedef unspecified_type Tetrahedron_3;
|
||||
|
||||
/*!
|
||||
A predicate object that must provide the function operators
|
||||
|
||||
`Comparison_result operator()(Point_3 p, Point_3 q)`,
|
||||
|
||||
which returns `EQUAL` if the two points are equal and
|
||||
A predicate object that must provide the function operator
|
||||
|
||||
`Comparison_result operator()(Point_3 p, Point_3 q, Periodic_3_offset_3 o_p, Periodic_3_offset_3 o_q)`,
|
||||
|
||||
|
|
@ -96,14 +92,7 @@ in a same line.
|
|||
typedef unspecified_type Compare_xyz_3;
|
||||
|
||||
/*!
|
||||
A predicate object that must provide the function operators
|
||||
|
||||
`Orientation operator()(Point_3 p, Point_3 q, Point_3 r, Point_3 s)`,
|
||||
|
||||
which returns `POSITIVE`, if `s` lies on the positive side of
|
||||
the oriented plane `h` defined by `p`, `q`, and `r`,
|
||||
returns `NEGATIVE` if `s` lies on the negative side of
|
||||
`h`, and returns `COPLANAR` if `s` lies on `h` and
|
||||
A predicate object that must provide the function operator
|
||||
|
||||
`Orientation operator()(Point_3 p, Point_3 q, Point_3 r, Point_3 s, Periodic_3_offset_3 o_p, Periodic_3_offset_3 o_q, Periodic_3_offset_3 o_r, Periodic_3_offset_3 o_s)`,
|
||||
|
||||
|
|
@ -134,11 +123,7 @@ which constructs a point from a point-offset pair.
|
|||
typedef unspecified_type Construct_point_3;
|
||||
|
||||
/*!
|
||||
A constructor object that must provide the function operators
|
||||
|
||||
`Segment_3 operator()(Point_3 p, Point_3 q)`,
|
||||
|
||||
which constructs a segment from two points and
|
||||
A constructor object that must provide the function operator
|
||||
|
||||
`Segment_3 operator()(Point_3 p, Point_3 q, Periodic_3_offset_3 o_p, Periodic_3_offset_3 o_q)`,
|
||||
|
||||
|
|
@ -148,11 +133,7 @@ which constructs a segment from two point-offset pairs.
|
|||
typedef unspecified_type Construct_segment_3;
|
||||
|
||||
/*!
|
||||
A constructor object that must provide the function operators
|
||||
|
||||
`Triangle_3 operator()(Point_3 p, Point_3 q, Point_3 r )`,
|
||||
|
||||
which constructs a triangle from three points and
|
||||
A constructor object that must provide the function operator
|
||||
|
||||
`Triangle_3 operator()(Point_3 p, Point_3 q, Point_3 r, Periodic_3_offset_3 o_q, Periodic_3_offset_3 o_q, Periodic_3_offset_3 o_r)`,
|
||||
|
||||
|
|
@ -162,11 +143,7 @@ which constructs a triangle from three point-offset pairs.
|
|||
typedef unspecified_type Construct_triangle_3;
|
||||
|
||||
/*!
|
||||
A constructor object that must provide the function operators
|
||||
|
||||
`Tetrahedron_3 operator()(Point_3 p, Point_3 q, Point_3 r, Point_3 s)`,
|
||||
|
||||
which constructs a tetrahedron from four points and
|
||||
A constructor object that must provide the function operator
|
||||
|
||||
`Tetrahedron_3 operator()(Point_3 p, Point_3 q, Point_3 r, Point_3 s, Periodic_3_offset_3 o_q, Periodic_3_offset_3 o_q, Periodic_3_offset_3 o_r, Periodic_3_offset_3 o_s)`,
|
||||
|
||||
|
|
|
|||
|
|
@ -733,37 +733,96 @@ public:
|
|||
|
||||
Vertex_handle nearest_power_vertex(const Bare_point& p, Cell_handle start) const
|
||||
{
|
||||
CGAL_triangulation_precondition(p.x() < domain().xmax());
|
||||
CGAL_triangulation_precondition(p.y() < domain().ymax());
|
||||
CGAL_triangulation_precondition(p.z() < domain().zmax());
|
||||
CGAL_triangulation_precondition(p.x() >= domain().xmin());
|
||||
CGAL_triangulation_precondition(p.y() >= domain().ymin());
|
||||
CGAL_triangulation_precondition(p.z() >= domain().zmin());
|
||||
|
||||
if(number_of_vertices() == 0)
|
||||
return Vertex_handle();
|
||||
|
||||
typename Gt::Construct_weighted_point_3 p2wp =
|
||||
geom_traits().construct_weighted_point_3_object();
|
||||
|
||||
Locate_type lt;
|
||||
int li, lj;
|
||||
Offset query_offset;
|
||||
Cell_handle c = locate(p2wp(p), query_offset, lt, li, lj, start);
|
||||
|
||||
typename Gt::Construct_weighted_point_3 p2wp =
|
||||
geom_traits().construct_weighted_point_3_object();
|
||||
Cell_handle c = locate(p2wp(p), lt, li, lj, start);
|
||||
if(lt == Tr_Base::VERTEX)
|
||||
return c->vertex(li);
|
||||
const Conflict_tester tester(p2wp(p), this);
|
||||
Offset o = combine_offsets(Offset(), get_location_offset(tester, c));
|
||||
#ifdef CGAL_PERIODIC_DEBUG_NEAREST_POWER_VERTEX
|
||||
std::cout << "nearest power vertex: " << p << std::endl;
|
||||
std::cout << "vertices: " << number_of_vertices() << std::endl;
|
||||
std::cout << "stored vertices: " << this->number_of_stored_vertices() << std::endl;
|
||||
std::cout << "Locate: " << p << std::endl;
|
||||
std::cout << "Cell: " << &*c << std::endl;
|
||||
std::cout << this->point(c, 0) << std::endl;
|
||||
std::cout << this->point(c, 1) << std::endl;
|
||||
std::cout << this->point(c, 2) << std::endl;
|
||||
std::cout << this->point(c, 3) << std::endl;
|
||||
std::cout << "offset query: " << query_offset << std::endl;
|
||||
std::cout << "bounded side : " << geom_traits().bounded_side_3_object()(
|
||||
Tetrahedron(this->point(c, 0).point(), this->point(c, 1).point(),
|
||||
this->point(c, 2).point(), this->point(c, 3).point()), p) << std::endl;
|
||||
std::cout << "power side: " << geom_traits().power_side_of_bounded_power_sphere_3_object()(
|
||||
this->point(c, 0), this->point(c, 1),
|
||||
this->point(c, 2), this->point(c, 3), p2wp(p)) << std::endl;
|
||||
std::cout << "power distance: " << geom_traits().compute_power_distance_to_power_sphere_3_object()(
|
||||
this->point(c, 0), this->point(c, 1),
|
||||
this->point(c, 2), this->point(c, 3), p2wp(p)) << std::endl;
|
||||
#endif
|
||||
|
||||
// - start with the closest vertex from the located cell.
|
||||
// - repeatedly take the nearest of its incident vertices if any
|
||||
// - if not, we're done.
|
||||
Vertex_handle nearest = nearest_vertex_in_cell(c, p, o);
|
||||
|
||||
// Take the opposite because periodic_locate() returns the offset such that
|
||||
// cell + offset contains 'p' but here we need to move 'p'
|
||||
query_offset = this->combine_offsets(Offset(), -query_offset);
|
||||
|
||||
Vertex_handle nearest = nearest_vertex_in_cell(c, p, query_offset);
|
||||
Offset offset_of_nearest = get_min_dist_offset(p, query_offset, nearest);
|
||||
|
||||
#ifdef CGAL_PERIODIC_DEBUG_NEAREST_POWER_VERTEX
|
||||
std::cout << "nearest vertex in cell : " << &*nearest << " : " << nearest->point() << std::endl;
|
||||
std::cout << "offset_of_nearest: " << offset_of_nearest << std::endl;
|
||||
#endif
|
||||
|
||||
std::vector<Vertex_handle> vs;
|
||||
vs.reserve(32);
|
||||
while(true)
|
||||
{
|
||||
Vertex_handle tmp = nearest;
|
||||
Offset tmp_off = get_min_dist_offset(p, o, tmp);
|
||||
#ifdef CGAL_PERIODIC_DEBUG_NEAREST_POWER_VERTEX
|
||||
std::cout << "tmp set to : " << &*nearest << " : " << nearest->point()
|
||||
<< " || offset: " << nearest->offset() << std::endl;
|
||||
#endif
|
||||
|
||||
adjacent_vertices(nearest, std::back_inserter(vs));
|
||||
for(typename std::vector<Vertex_handle>::const_iterator vsit = vs.begin(); vsit != vs.end(); ++vsit)
|
||||
tmp = (compare_distance(p, tmp->point(), (*vsit)->point(),
|
||||
o, tmp_off, get_min_dist_offset(p, o, *vsit))
|
||||
== SMALLER) ? tmp : *vsit;
|
||||
for(typename std::vector<Vertex_handle>::const_iterator vsit = vs.begin();
|
||||
vsit != vs.end(); ++vsit)
|
||||
{
|
||||
// Can happen in 27-sheeted triangulations composed of few points
|
||||
if((*vsit)->point() == nearest->point())
|
||||
continue;
|
||||
|
||||
const Offset min_dist_offset = get_min_dist_offset(p, query_offset, *vsit);
|
||||
if(compare_distance(p, (*vsit)->point(), tmp->point(),
|
||||
query_offset, min_dist_offset, offset_of_nearest) == SMALLER)
|
||||
{
|
||||
tmp = *vsit;
|
||||
offset_of_nearest = min_dist_offset;
|
||||
#ifdef CGAL_PERIODIC_DEBUG_NEAREST_POWER_VERTEX
|
||||
std::cout << " Closer adjacent vertex: " << &*tmp << " : " << tmp->point()
|
||||
<< " || offset " << offset_of_nearest << std::endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if(tmp == nearest)
|
||||
break;
|
||||
|
||||
vs.clear();
|
||||
nearest = tmp;
|
||||
}
|
||||
|
|
@ -834,7 +893,7 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
bool is_Gabriel(const Facet& f)const
|
||||
bool is_Gabriel(const Facet& f) const
|
||||
{
|
||||
return is_Gabriel(f.first, f.second);
|
||||
}
|
||||
|
|
@ -846,8 +905,20 @@ public:
|
|||
|
||||
bool is_Gabriel(Vertex_handle v) const
|
||||
{
|
||||
return nearest_power_vertex(
|
||||
geom_traits().construct_point_3_object()(v->point()), v->cell()) == v;
|
||||
typename Geom_traits::Power_side_of_bounded_power_sphere_3
|
||||
side_of_bounded_orthogonal_sphere =
|
||||
geom_traits().power_side_of_bounded_power_sphere_3_object();
|
||||
|
||||
const Bare_point& bp = geom_traits().construct_point_3_object()(v->point());
|
||||
|
||||
Vertex_handle nearest_v = nearest_power_vertex(bp, v->cell());
|
||||
|
||||
// Need to find the offset such that power distance v->point()
|
||||
// to nearest_v->point() is minimum
|
||||
Offset nearest_v_off = get_min_dist_offset_general(bp, nearest_v);
|
||||
|
||||
return (side_of_bounded_orthogonal_sphere(
|
||||
v->point(), nearest_v->point(), Offset(), nearest_v_off) != CGAL::ON_BOUNDED_SIDE);
|
||||
}
|
||||
|
||||
Offset get_min_dist_offset(const Bare_point& p, const Offset & o,
|
||||
|
|
@ -878,6 +949,36 @@ public:
|
|||
return combine_offsets(mdo,min_off);
|
||||
}
|
||||
|
||||
// In this version, `p` must be in the domain, and we check all possible
|
||||
// offsets to find the minimum
|
||||
Offset get_min_dist_offset_general(const Bare_point& p, const Vertex_handle vh) const
|
||||
{
|
||||
CGAL_triangulation_precondition(p.x() < domain().xmax());
|
||||
CGAL_triangulation_precondition(p.y() < domain().ymax());
|
||||
CGAL_triangulation_precondition(p.z() < domain().zmax());
|
||||
CGAL_triangulation_precondition(p.x() >= domain().xmin());
|
||||
CGAL_triangulation_precondition(p.y() >= domain().ymin());
|
||||
CGAL_triangulation_precondition(p.z() >= domain().zmin());
|
||||
|
||||
Offset min_off = Offset(0,0,0);
|
||||
|
||||
for(int i=-1; i<=1; ++i) {
|
||||
for(int j=-1; j<=1; ++j) {
|
||||
for(int k=-1; k<=1; ++k)
|
||||
{
|
||||
if(i==0 && j==0 && k==0)
|
||||
continue;
|
||||
|
||||
Offset loc_off(i, j, k);
|
||||
if(compare_distance(p, vh->point(), vh->point(), Offset(), min_off, loc_off) == LARGER)
|
||||
min_off = loc_off;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return min_off;
|
||||
}
|
||||
|
||||
Vertex_handle nearest_vertex_in_cell(const Cell_handle& c, const Bare_point& p,
|
||||
const Offset & o) const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ public:
|
|||
typedef typename P3RT3::Facet Facet;
|
||||
typedef typename P3RT3::Cell Cell;
|
||||
typedef typename P3RT3::Vertex_iterator Vertex_iterator;
|
||||
typedef typename P3RT3::Unique_vertex_iterator Unique_vertex_iterator;
|
||||
typedef typename P3RT3::Cell_iterator Cell_iterator;
|
||||
typedef typename P3RT3::Segment Segment;
|
||||
typedef typename P3RT3::Triangle Triangle;
|
||||
|
|
@ -77,6 +78,100 @@ public:
|
|||
assert(p3rt3.is_valid());
|
||||
}
|
||||
|
||||
static void test_is_gabriel()
|
||||
{
|
||||
std::cout << "--- test is_gabriel" << std::endl;
|
||||
|
||||
P3RT3 p3rt3;
|
||||
|
||||
typename P3RT3::Geom_traits::Power_side_of_bounded_power_sphere_3
|
||||
side_of_bounded_power_sphere =
|
||||
p3rt3.geom_traits().power_side_of_bounded_power_sphere_3_object();
|
||||
|
||||
Weighted_point_3 t(Point_3(0.5,0.5,0.45), 0.01);
|
||||
Weighted_point_3 s(Point_3(0.5,0.5,0.49), 0.006);
|
||||
Weighted_point_3 q(Point_3(0.5,0.5,0.5), 0.015);
|
||||
Weighted_point_3 p(Point_3(0.95,0.95,0.96), 0.001);
|
||||
Weighted_point_3 r(Point_3(0.01,0.008,0.01), 0.002);
|
||||
p3rt3.insert(p);
|
||||
p3rt3.insert(q);
|
||||
p3rt3.insert(r);
|
||||
p3rt3.insert(s);
|
||||
p3rt3.insert(t);
|
||||
|
||||
assert(p3rt3.is_valid());
|
||||
|
||||
std::cout << "p3rt3.number_of_vertices() " << p3rt3.number_of_vertices() << std::endl;
|
||||
assert(p3rt3.number_of_vertices() == 4);
|
||||
assert(std::distance(p3rt3.unique_vertices_begin(), p3rt3.unique_vertices_end()) == 4);
|
||||
assert(p3rt3.number_of_stored_vertices() == 108);
|
||||
|
||||
for(Unique_vertex_iterator iter = p3rt3.unique_vertices_begin(), end_iter = p3rt3.unique_vertices_end(); iter != end_iter; ++iter)
|
||||
{
|
||||
Vertex_handle vh((Vertex_iterator(iter)));
|
||||
std::cout << p3rt3.is_Gabriel(vh) << std::endl;
|
||||
if(p3rt3.is_Gabriel(vh))
|
||||
{
|
||||
for(Unique_vertex_iterator iter2 = p3rt3.unique_vertices_begin(), end_iter2 = p3rt3.unique_vertices_end(); iter2 != end_iter2; ++iter2)
|
||||
{
|
||||
Vertex_handle vh2((Vertex_iterator(iter2)));
|
||||
|
||||
if(vh2->point() == vh->point())
|
||||
{
|
||||
assert(p3rt3.is_Gabriel(vh2)); // consistency check
|
||||
}
|
||||
else
|
||||
{
|
||||
// Check that w/e the offset, the power distance is positive
|
||||
for(int i = -1; i < 2; ++i) {
|
||||
for(int j = -1; j < 2; ++j) {
|
||||
for(int k = -1; k < 2; ++k)
|
||||
{
|
||||
const Offset off(i, j, k);
|
||||
// std::cout << "power distance: " << p3rt3.geom_traits().compute_power_product_3_object()(
|
||||
// Weighted_point_3(vh->point().point(), vh->point().weight()),
|
||||
// p3rt3.geom_traits().construct_weighted_point_3_object()(vh2->point(), off)) << std::endl;
|
||||
if(!(side_of_bounded_power_sphere(vh->point(), vh2->point(),
|
||||
Offset(), off) != CGAL::ON_BOUNDED_SIDE))
|
||||
{
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bool found = false;
|
||||
for(Vertex_iterator iter2 = p3rt3.vertices_begin(), end_iter2 = p3rt3.vertices_end(); iter2 != end_iter2; ++iter2)
|
||||
{
|
||||
Vertex_handle vh2 = iter2;
|
||||
if(vh2->point() == vh->point())
|
||||
{
|
||||
assert(!p3rt3.is_Gabriel(vh2)); // consistency check
|
||||
}
|
||||
else
|
||||
{
|
||||
for(int i = -1; i < 2; ++i) {
|
||||
for(int j = -1; j < 2; ++j) {
|
||||
for(int k = -1; k < 2; ++k)
|
||||
{
|
||||
const Offset off = vh->offset() + Offset(i, j, k);
|
||||
if(!(side_of_bounded_power_sphere(vh->point(), vh2->point(),
|
||||
vh->offset(), off) != CGAL::ON_BOUNDED_SIDE))
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // iter2
|
||||
assert(found); // must have found a point that is in the smallest orthogonal power sphere
|
||||
} // is_gabriel(vh)
|
||||
}
|
||||
}
|
||||
|
||||
static void test_insert_1 ()
|
||||
{
|
||||
std::cout << "--- test_insert_1" << std::endl;
|
||||
|
|
@ -721,6 +816,7 @@ public:
|
|||
|
||||
static void test ()
|
||||
{
|
||||
test_is_gabriel();
|
||||
test_find_conflicts();
|
||||
test_insert_range(800, 7);
|
||||
test_construction_and_insert_range(800, 7);
|
||||
|
|
@ -736,7 +832,6 @@ public:
|
|||
test_insert_two_points_with_the_same_position();
|
||||
test_remove();
|
||||
test_27_to_1_sheeted_covering();
|
||||
////// Iso_cuboid unitaire -> 0 <= weight < 0.015625
|
||||
test_insert_rnd_as_delaunay(100, 0.);
|
||||
test_insert_rnd_as_delaunay(100, 0.01);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,6 +81,29 @@ It is only needed when using the `Fast_location` policy or the
|
|||
typedef unspecified_type Compare_distance_3;
|
||||
|
||||
|
||||
/// @}
|
||||
|
||||
/// \name
|
||||
/// When `is_Gabriel` functions are used, the traits class must
|
||||
/// in addition provide the following predicate object:
|
||||
/// @{
|
||||
|
||||
/*!
|
||||
A predicate object that must provide the function operators
|
||||
|
||||
`Bounded_side operator()(Point_3 p, Point_3 q, Point_3 t)`,
|
||||
|
||||
which returns the position of the point `t` relative to the sphere
|
||||
that has `pq` as its diameter,
|
||||
|
||||
`Bounded_side operator()(Point_3 p, Point_3 q, Point_3 r, Point_3 t)`,
|
||||
|
||||
which returns the position of the point `t` relative to the sphere
|
||||
passing through `p, q`, and `r` and whose center is in the
|
||||
plane defined by these three points.
|
||||
*/
|
||||
typedef unspecified_type Side_of_bounded_sphere_3;
|
||||
|
||||
/// @}
|
||||
|
||||
/*! \name
|
||||
|
|
@ -166,8 +189,6 @@ When using the `Fast_location` policy or the `CGAL::Delaunay_triangulation_3::ne
|
|||
*/
|
||||
Compare_distance_3 compare_distance_3_object();
|
||||
|
||||
|
||||
|
||||
/// @}
|
||||
|
||||
/*! \name
|
||||
|
|
|
|||
|
|
@ -210,6 +210,34 @@ typedef unspecified_type Construct_ray_3;
|
|||
|
||||
/// @}
|
||||
|
||||
/// \name
|
||||
/// When `is_Gabriel` functions are used, the traits class must
|
||||
/// in addition provide the following predicate object:
|
||||
/// @{
|
||||
|
||||
/*!
|
||||
A predicate object that must provide the function operators
|
||||
|
||||
`Bounded_side operator()(Weighted_point_3 p, Weighted_point_3 t)`,
|
||||
|
||||
which returns the sign of the power test of `t` with respect to the smallest
|
||||
sphere orthogonal to `p` (which is the sphere with center `p` and squared
|
||||
radius `-w_p` with `w_p` the weight of `p`),
|
||||
|
||||
`Bounded_side operator()(Weighted_point_3 p, Weighted_point_3 q, Weighted_point_3 t)`,
|
||||
|
||||
which returns the sign of the power test of `t` with respect to the smallest
|
||||
sphere orthogonal to `p` and `q`,
|
||||
|
||||
`Bounded_side operator()(Weighted_point_3 p, Weighted_point_3 q, Weighted_point_3 r, Weighted_point_3 t)`,
|
||||
|
||||
which returns the sign of the power test of `t` with respect to the smallest
|
||||
sphere orthogonal to `p`, `q`, and `r`.
|
||||
*/
|
||||
typedef unspecified_type Power_side_of_bounded_power_sphere_3;
|
||||
|
||||
/// @}
|
||||
|
||||
/// \name Operations
|
||||
/// @{
|
||||
|
||||
|
|
|
|||
|
|
@ -2180,8 +2180,16 @@ namespace CGAL {
|
|||
Regular_triangulation_3<Gt,Tds,Lds>::
|
||||
is_Gabriel(Vertex_handle v) const
|
||||
{
|
||||
return nearest_power_vertex(
|
||||
geom_traits().construct_point_3_object()(v->point()), v->cell()) == v;
|
||||
typename Geom_traits::Power_side_of_bounded_power_sphere_3
|
||||
side_of_bounded_orthogonal_sphere =
|
||||
geom_traits().power_side_of_bounded_power_sphere_3_object();
|
||||
|
||||
Vertex_handle nearest_v =
|
||||
nearest_power_vertex(geom_traits().construct_point_3_object()(v->point()),
|
||||
v->cell());
|
||||
|
||||
return (side_of_bounded_orthogonal_sphere(v->point(), nearest_v->point())
|
||||
!= CGAL::ON_BOUNDED_SIDE);
|
||||
}
|
||||
|
||||
// Returns
|
||||
|
|
|
|||
Loading…
Reference in New Issue