Added power_side_of_bounded_power_circle_2 to the 2D kernel predicates

A partial implementation was deleted from the Alpha_shapes_2 package without
moving the functions to the kernel...
This implementation adds the missing overloads (4, 3, and 2 points)

Test + doc included
This commit is contained in:
Mael Rouxel-Labbé 2017-04-21 11:33:45 +02:00
parent a751464ab6
commit bb086ff739
11 changed files with 223 additions and 1 deletions

View File

@ -647,6 +647,24 @@ compare_power_distanceC2(const FT& px, const FT& py, const FT& pwt,
return CGAL_NTS compare(d1, d2);
}
template <class FT>
CGAL_KERNEL_MEDIUM_INLINE
Bounded_side
power_side_of_bounded_power_circleC2(const FT &px, const FT &py, const FT &pw,
const FT &qx, const FT &qy, const FT &qw,
const FT &tx, const FT &ty, const FT &tw)
{
FT dpx = px - qx;
FT dpy = py - qy;
FT dtx = tx - qx;
FT dty = ty - qy;
FT dpz = CGAL_NTS square(dpx) + CGAL_NTS square(dpy);
return enum_cast<Bounded_side>
(CGAL_NTS sign(-(CGAL_NTS square(dtx) + CGAL_NTS square(dty)-tw+qw)*dpz
+(dpz-pw+qw)*(dpx*dtx+dpy*dty)));
}
template <class FT>
Oriented_side
power_side_of_oriented_power_circleC2(const FT &px, const FT &py, const FT &pwt,

View File

@ -9121,7 +9121,71 @@ public:
}; /* end Kernel::OrientedSide_3 */
/*!
\ingroup PkgKernel23ConceptsFunctionObjects
\cgalConcept
\cgalRefines `AdaptableFunctor` (with four arguments)
\sa `CGAL::Weighted_point_2<Kernel>`
\sa `ComputePowerProduct_3` for the definition of orthogonality for power distances.
\sa `PowerSideOfOrientedPowerCircle_2`
*/
class PowerSideOfBoundedPowerCircle_2
{
public:
/// \name Operations
/// A model of this concept must provide:
/// @{
/*!
Let \f$ {z(p,q,r)}^{(w)}\f$ be the power circle of the weighted points
\f$ (p,q,r)\f$. This method returns:
- `ON_BOUNDARY` if `t` is orthogonal to \f$ {z(p,q,r)}^{(w)}\f$,
- `ON_UNBOUNDED_SIDE` if `t` lies outside the bounded circle of
center \f$ z(p,q,r)\f$ and radius \f$ \sqrt{ w_{z(p,q,r)}^2 + w_t^2 }\f$
(which is equivalent to \f$ \Pi({t}^{(w)},{z(p,q,r)}^{(w)}) > 0\f$),
- `ON_BOUNDED_SIDE` if `t` lies inside this bounded circle.
The order of the points `p`, `q`, and `r` does not matter.
\pre `p`, `q`, and `r` are not collinear.
If all the points have a weight equal to 0, then
`power_side_of_bounded_power_circle_2(p,q,r,t)` ==
`side_of_bounded_circle(p,q,r,t)`.
*/
CGAL::Bounded_side
operator()(const Kernel::Weighted_point_2 & p,
const Kernel::Weighted_point_2 & q,
const Kernel::Weighted_point_2 & r,
const Kernel::Weighted_point_2 & t);
/*!
returns the sign of the power test of `t` with respect
to the smallest circle orthogonal to `p` and `q`.
\pre `p` and `q` have different bare points.
*/
CGAL::Bounded_side
operator()(const Kernel::Weighted_point_2 & p,
const Kernel::Weighted_point_2 & q,
const Kernel::Weighted_point_2 & t);
/*!
returns the sign of the power test of `t` with respect
to the smallest circle orthogonal to `p`.
*/
CGAL::Bounded_side
operator()(const Kernel::Weighted_point_2 & p,
const Kernel::Weighted_point_2 & t);
/// @}
}; /* end Kernel::PowerSideOfBoundedPowerCircle_2 */
/*!
\ingroup PkgKernel23ConceptsFunctionObjects
@ -9212,7 +9276,7 @@ public:
\sa `CGAL::Weighted_point_2<Kernel>`
\sa `ComputePowerProduct_2` for the definition of power distance.
\sa `PowerSideOfBoundedPowerCircle_2`
*/
class PowerSideOfOrientedPowerCircle_2
{

View File

@ -793,7 +793,9 @@ A type representing weighted points in two dimensions.
\sa `ComputeSquaredRadiusSmallestOrthogonalCircle_2`
\sa `ConstructRadicalAxis_2`
\sa `ConstructWeightedCircumcenter_2`
\sa `PowerSideOfBoundedPowerCircle_2`
\sa `PowerSideOfOrientedPowerCircle_2`
*/
class WeightedPoint_2 {
public:

View File

@ -692,6 +692,11 @@ public:
*/
typedef unspecified_type Power_side_of_oriented_power_circle_2;
/*!
a model of `Kernel::PowerSideOfBoundedPowerCircle_2`
*/
typedef unspecified_type Power_side_of_bounded_power_circle_2;
/*!
a model of `Kernel::IsHorizontal_2`
*/

View File

@ -485,6 +485,7 @@
- `Kernel::Orientation_3`
- `Kernel::OrientedSide_2`
- `Kernel::OrientedSide_3`
- `Kernel::PowerSideOfBoundedPowerCircle_2`
- `Kernel::PowerSideOfBoundedPowerSphere_3`
- `Kernel::PowerSideOfOrientedPowerCircle_2`
- `Kernel::PowerSideOfOrientedPowerSphere_3`

View File

@ -368,6 +368,48 @@ namespace CommonKernelFunctors {
}
};
template < class K >
class Power_side_of_bounded_power_circle_2
{
public:
typedef typename K::Weighted_point_2 Weighted_point_2;
typedef Bounded_side result_type;
Bounded_side operator()(const Weighted_point_2& p,
const Weighted_point_2& q,
const Weighted_point_2& r,
const Weighted_point_2& t) const
{
K traits;
typename K::Orientation_2 orientation = traits.orientation_2_object();
typename K::Power_side_of_oriented_power_circle_2 power_test =
traits.power_side_of_oriented_power_circle_2_object();
typename K::Orientation o = orientation(p,q,r);
typename K::Oriented_side os = power_test(p,q,r,t);
CGAL_assertion(o != COPLANAR);
return enum_cast<Bounded_side>(o * os);
}
Bounded_side operator()(const Weighted_point_2& p,
const Weighted_point_2& q,
const Weighted_point_2& t) const
{
return power_side_of_bounded_power_circleC2(p.x(), p.y(), p.weight(),
q.x(), q.y(), q.weight(),
t.x(), t.y(), t.weight());
}
Bounded_side operator()(const Weighted_point_2& p,
const Weighted_point_2& t) const
{
return enum_cast<Bounded_side>(
- CGAL_NTS sign( CGAL_NTS square(p.x() - t.x()) +
CGAL_NTS square(p.y() - t.y()) +
p.weight() - t.weight()) );
}
};
// operator ()
// return the sign of the power test of last weighted point
// with respect to the smallest sphere orthogonal to the others

View File

@ -949,6 +949,36 @@ orientation(const Vector_2<K> &u, const Vector_2<K> &v)
// parallel() functions are in global_functions.h
template <class K >
inline
typename K::Bounded_side
power_side_of_bounded_power_circle(const Weighted_point_2<K> &p,
const Weighted_point_2<K> &q)
{
return internal::power_side_of_bounded_power_circle(p, q, K());
}
template <class K >
inline
typename K::Bounded_side
power_side_of_bounded_power_circle(const Weighted_point_2<K> &p,
const Weighted_point_2<K> &q,
const Weighted_point_2<K> &r)
{
return internal::power_side_of_bounded_power_circle(p, q, r, K());
}
template <class K >
inline
typename K::Bounded_side
power_side_of_bounded_power_circle(const Weighted_point_2<K> &p,
const Weighted_point_2<K> &q,
const Weighted_point_2<K> &r,
const Weighted_point_2<K> &s)
{
return internal::power_side_of_bounded_power_circle(p, q, r, s, K());
}
template <typename K>
inline
typename K::Orientation

View File

@ -862,6 +862,36 @@ parallel(const typename K::Segment_2 &s1,
return k.are_parallel_2_object()(s1, s2);
}
template <class K >
inline
typename K::Bounded_side
power_side_of_bounded_power_circle(const typename K::Weighted_point_2 &p,
const typename K::Weighted_point_2 &q, const K &k)
{
return k.power_side_of_bounded_power_circle_2_object()(p, q);
}
template <class K >
inline
typename K::Bounded_side
power_side_of_bounded_power_circle(const typename K::Weighted_point_2 &p,
const typename K::Weighted_point_2 &q,
const typename K::Weighted_point_2 &r, const K &k)
{
return k.power_side_of_bounded_power_circle_2_object()(p, q, r);
}
template <class K >
inline
typename K::Bounded_side
power_side_of_bounded_power_circle(const typename K::Weighted_point_2 &p,
const typename K::Weighted_point_2 &q,
const typename K::Weighted_point_2 &r,
const typename K::Weighted_point_2 &s, const K &k)
{
return k.power_side_of_bounded_power_circle_2_object()(p, q, r, s);
}
template <class K>
inline
typename K::Oriented_side

View File

@ -588,6 +588,8 @@ CGAL_Kernel_pred(Oriented_side_2,
oriented_side_2_object)
CGAL_Kernel_pred(Oriented_side_3,
oriented_side_3_object)
CGAL_Kernel_pred(Power_side_of_bounded_power_circle_2,
power_side_of_bounded_power_circle_2_object)
CGAL_Kernel_pred(Power_side_of_bounded_power_sphere_3,
power_side_of_bounded_power_sphere_3_object)
CGAL_Kernel_pred_RT(Power_side_of_oriented_power_circle_2,

View File

@ -118,6 +118,29 @@ _test_fct_weighted_point_2(const R& )
std::cout << ".";
assert( CGAL::power_side_of_bounded_power_circle(wp5_b, wp7_b) == CGAL::ON_UNBOUNDED_SIDE );
assert( CGAL::power_side_of_bounded_power_circle(wp1_b, wp1_b) == CGAL::ON_BOUNDARY );
assert( CGAL::power_side_of_bounded_power_circle(wp6_b, wp6) == CGAL::ON_BOUNDED_SIDE );
assert( CGAL::power_side_of_bounded_power_circle(wp1_b, wp3_b, wp6_b) == CGAL::ON_UNBOUNDED_SIDE );
assert( CGAL::power_side_of_bounded_power_circle(wp3_b, wp1_b, wp6_b) == CGAL::ON_UNBOUNDED_SIDE );
assert( CGAL::power_side_of_bounded_power_circle(wp3_b, wp6_b, wp1_b) == CGAL::ON_BOUNDARY );
assert( CGAL::power_side_of_bounded_power_circle(wp6_b, wp3_b, wp8_b) == CGAL::ON_BOUNDED_SIDE );
assert( CGAL::power_side_of_bounded_power_circle(wp3_b, wp6_b, wp8_b) == CGAL::ON_BOUNDED_SIDE );
assert( CGAL::power_side_of_bounded_power_circle(wp2, wp3, wp4, wp5)
== CGAL::side_of_bounded_circle(p2, p3, p4, p5) );
assert( CGAL::power_side_of_bounded_power_circle(wp2, wp3, wp4, wp4)
== CGAL::side_of_bounded_circle(p2, p3, p4, p4) );
assert( CGAL::power_side_of_bounded_power_circle(wp6_b, wp3_b, wp1_b, wp10_b) == CGAL::ON_UNBOUNDED_SIDE );
assert( CGAL::power_side_of_bounded_power_circle(wp1_b, wp6_b, wp3_b, wp10_b) == CGAL::ON_UNBOUNDED_SIDE );
assert( CGAL::power_side_of_bounded_power_circle(wp6_b, wp3_b, wp1_b, wp6_b) == CGAL::ON_BOUNDARY );
assert( CGAL::power_side_of_bounded_power_circle(wp6_b, wp3_b, wp1_b, wp8_b) == CGAL::ON_BOUNDED_SIDE );
assert( CGAL::power_side_of_bounded_power_circle(wp3_b, wp1_b, wp6_b, wp8_b) == CGAL::ON_BOUNDED_SIDE );
std::cout << ".";
assert( CGAL::squared_radius_smallest_orthogonal_circle(wp1) == RT(0) );
assert( CGAL::squared_radius_smallest_orthogonal_circle(wp1_b) == -wp1_b.weight() );

View File

@ -554,6 +554,11 @@ test_new_2(const R& rep)
Bounded_side tmp42 = side_of_bounded_circle(p2,p3,p4,p5);
tmp42 = side_of_bounded_circle(p2,p3,p5);
typename R::Power_side_of_bounded_power_circle_2 power_side_of_bounded_power_circle
= rep.power_side_of_bounded_power_circle_2_object();
tmp42 = power_side_of_bounded_power_circle(wp4,wp5);
tmp42 = power_side_of_bounded_power_circle(wp4,wp5,wp6);
tmp42 = power_side_of_bounded_power_circle(wp4,wp5,wp6,wp7);
typename R::Is_horizontal_2 is_horizontal
= rep.is_horizontal_2_object();