Uniformize notations across the package + re-introduce documentation

This commit is contained in:
Mael Rouxel-Labbé 2022-10-20 17:17:06 +02:00
parent 15de97faf1
commit 5f89766c5c
17 changed files with 990 additions and 549 deletions

View File

@ -101,7 +101,7 @@ a model of `AnalyticWeightTraits_3` for 3D points
\endverbatim
This weight is computed as
\f$w = \frac{d_2^a A_1 - d^a B + d_1^a A_2}{A_1 A_2}\f$
\f$w = \frac{d_2^a A_0 - d^a B + d_0^a A_2}{A_0 A_2}\f$
with notations shown in the figure below and \f$a\f$ any real number
being the power parameter.
@ -142,7 +142,7 @@ a model of `AnalyticWeightTraits_3` for 3D points
\endverbatim
This weight is computed as
\f$w = \frac{C}{A_1 A_2}\f$
\f$w = \frac{C}{A_0 A_2}\f$
with notations shown in the figure below.
Here, `q` is a query point and the points `p0`, `p1`, and `p2` are its neighbors.
@ -207,10 +207,10 @@ a model of `AnalyticWeightTraits_3` for 3D points
\endverbatim
This weight is computed as
\f$w = \pm 2 \sqrt{\frac{2 (d_1 d_2 - D)}{(d d_1 + D_1)(d d_2 + D_2)}}\f$
\f$w = \pm 2 \sqrt{\frac{2 (d_0 d_2 - D)}{(d d_0 + D_0)(d d_2 + D_2)}}\f$
with notations shown in the figure below and dot products
\f$D_1 = (p_0 - q) \cdot (p_1 - q)\f$,
\f$D_0 = (p_0 - q) \cdot (p_1 - q)\f$,
\f$D_2 = (p_1 - q) \cdot (p_2 - q)\f$, and
\f$D = (p_0 - q) \cdot (p_2 - q)\f$.
@ -247,11 +247,11 @@ a model of `AnalyticWeightTraits_3` for 3D points
This weight is computed as
\f$w = 2 \frac{t_1 + t_2}{d}\f$, where
\f$t_1 = \frac{2 A_1}{d d_1 + D_1}\f$ and
\f$t_1 = \frac{2 A_0}{d d_0 + D_0}\f$ and
\f$t_2 = \frac{2 A_2}{d d_2 + D_2}\f$
with notations shown in the figure below and dot products
\f$D_1 = (p_0 - q) \cdot (p_1 - q)\f$ and
\f$D_0 = (p_0 - q) \cdot (p_1 - q)\f$ and
\f$D_2 = (p_1 - q) \cdot (p_2 - q)\f$.
Here, `q` is a query point and the points `p0`, `p1`, and `p2` are its neighbors.
@ -283,7 +283,7 @@ a model of `AnalyticWeightTraits_3` for 3D points
\endverbatim
This weight is computed as
\f$w = \frac{d_2^2 A_1 - d^2 B + d_1^2 A_2}{A_1 A_2}\f$
\f$w = \frac{d_2^2 A_0 - d^2 B + d_0^2 A_2}{A_0 A_2}\f$
with notations shown in the figure below.
Here, `q` is a query point and the points `p0`, `p1`, and `p2` are its neighbors.

View File

@ -57,79 +57,103 @@ FT weight(const FT cot_gamma, const FT cot_beta, const FT r2)
\brief computes the half value of the authalic weight.
This function constructs the half of the authalic weight using the precomputed
This function computes the half of the authalic weight using the precomputed
cotangent and squared distance values. The returned value is
\f$\frac{2\textbf{cot}}{\textbf{d2}}\f$.
\f$\frac{2\textbf{cot}}{\textbf{sq_d}}\f$.
\tparam FT a model of `FieldNumberType`
\param cot the cotangent value
\param d2 the squared distance value
\param sq_d the squared distance value
\pre d2 != 0
\pre sq_d != 0
\sa `authalic_weight()`
*/
template<typename FT>
FT half_authalic_weight(const FT cot, const FT d2)
FT half_authalic_weight(const FT cot, const FT sq_d)
{
return authalic_ns::half_weight(cot, d2);
return authalic_ns::half_weight(cot, sq_d);
}
// 2D ==============================================================================================
/*!
\ingroup PkgWeightsRefAuthalicWeights
\brief computes the authalic weight in 2D at `q` using the points `p0`, `p1`, and `p2`.
\tparam GeomTraits a model of `AnalyticWeightTraits_2`
*/
template<typename GeomTraits>
typename GeomTraits::FT authalic_weight(const typename GeomTraits::Point_2& t,
const typename GeomTraits::Point_2& r,
const typename GeomTraits::Point_2& p,
typename GeomTraits::FT authalic_weight(const typename GeomTraits::Point_2& p0,
const typename GeomTraits::Point_2& p1,
const typename GeomTraits::Point_2& p2,
const typename GeomTraits::Point_2& q,
const GeomTraits& traits)
{
using FT = typename GeomTraits::FT;
const FT cot_gamma = cotangent_2(p0, p1, q, traits);
const FT cot_beta = cotangent_2(q, p1, p2, traits);
auto squared_distance_2 = traits.compute_squared_distance_2_object();
const FT sq_d = squared_distance_2(q, p1);
const FT cot_gamma = internal::cotangent_2(traits, t, r, q);
const FT cot_beta = internal::cotangent_2(traits, q, r, p);
const FT d2 = squared_distance_2(q, r);
return authalic_ns::weight(cot_gamma, cot_beta, d2);
return authalic_ns::weight(cot_gamma, cot_beta, sq_d);
}
template<typename GeomTraits>
typename GeomTraits::FT authalic_weight(const CGAL::Point_2<GeomTraits>& t,
const CGAL::Point_2<GeomTraits>& r,
const CGAL::Point_2<GeomTraits>& p,
const CGAL::Point_2<GeomTraits>& q)
/*!
\ingroup PkgWeightsRefAuthalicWeights
\brief computes the authalic weight in 2D at `q` using the points `p0`, `p1`, and `p2`.
\tparam Kernel a model of `Kernel`
*/
template<typename Kernel>
typename Kernel::FT authalic_weight(const CGAL::Point_2<Kernel>& p0,
const CGAL::Point_2<Kernel>& p1,
const CGAL::Point_2<Kernel>& p2,
const CGAL::Point_2<Kernel>& q)
{
const GeomTraits traits;
return authalic_weight(t, r, p, q, traits);
const Kernel traits;
return authalic_weight(p0, p1, p2, q, traits);
}
// 3D ==============================================================================================
/*!
\ingroup PkgWeightsRefAuthalicWeights
\brief computes the authalic weight in 3D at `q` using the points `p0`, `p1`, and `p2`.
\tparam GeomTraits a model of `AnalyticWeightTraits_3`
*/
template<typename GeomTraits>
typename GeomTraits::FT authalic_weight(const typename GeomTraits::Point_3& t,
const typename GeomTraits::Point_3& r,
const typename GeomTraits::Point_3& p,
typename GeomTraits::FT authalic_weight(const typename GeomTraits::Point_3& p0,
const typename GeomTraits::Point_3& p1,
const typename GeomTraits::Point_3& p2,
const typename GeomTraits::Point_3& q,
const GeomTraits& traits)
{
using FT = typename GeomTraits::FT;
const FT cot_gamma = cotangent_3(p0, p1, q, traits);
const FT cot_beta = cotangent_3(q, p1, p2, traits);
auto squared_distance_3 = traits.compute_squared_distance_3_object();
const FT sq_d = squared_distance_3(q, p1);
const FT cot_gamma = internal::cotangent_3(traits, t, r, q);
const FT cot_beta = internal::cotangent_3(traits, q, r, p);
const FT d2 = squared_distance_3(q, r);
return authalic_ns::weight(cot_gamma, cot_beta, d2);
return authalic_ns::weight(cot_gamma, cot_beta, sq_d);
}
template<typename GeomTraits>
typename GeomTraits::FT authalic_weight(const CGAL::Point_3<GeomTraits>& t,
const CGAL::Point_3<GeomTraits>& r,
const CGAL::Point_3<GeomTraits>& p,
const CGAL::Point_3<GeomTraits>& q)
/*!
\ingroup PkgWeightsRefAuthalicWeights
\brief computes the authalic weight in 3D at `q` using the points `p0`, `p1`, and `p2`.
\tparam Kernel a model of `Kernel`
*/
template<typename Kernel>
typename Kernel::FT authalic_weight(const CGAL::Point_3<Kernel>& p0,
const CGAL::Point_3<Kernel>& p1,
const CGAL::Point_3<Kernel>& p2,
const CGAL::Point_3<Kernel>& q)
{
const GeomTraits traits;
return authalic_weight(t, r, p, q, traits);
const Kernel traits;
return authalic_weight(p0, p1, p2, q, traits);
}
} // namespace Weights

View File

@ -22,6 +22,13 @@
namespace CGAL {
namespace Weights {
// 2D ==============================================================================================
/*!
\ingroup PkgWeightsRefBarycentricRegionWeights
\brief computes the area of the barycentric cell in 2D using the points `p`, `q`, and `r`.
\tparam GeomTraits a model of `AnalyticWeightTraits_2`
*/
template<typename GeomTraits>
typename GeomTraits::FT barycentric_area(const typename GeomTraits::Point_2& p,
const typename GeomTraits::Point_2& q,
@ -38,20 +45,32 @@ typename GeomTraits::FT barycentric_area(const typename GeomTraits::Point_2& p,
const Point_2 m1 = midpoint_2(q, r);
const Point_2 m2 = midpoint_2(q, p);
const FT A1 = internal::positive_area_2(traits, q, m1, center);
const FT A2 = internal::positive_area_2(traits, q, center, m2);
const FT A1 = internal::positive_area_2(q, m1, center, traits);
const FT A2 = internal::positive_area_2(q, center, m2, traits);
return A1 + A2;
}
template<typename GeomTraits>
typename GeomTraits::FT barycentric_area(const CGAL::Point_2<GeomTraits>& p,
const CGAL::Point_2<GeomTraits>& q,
const CGAL::Point_2<GeomTraits>& r)
/*!
\ingroup PkgWeightsRefBarycentricRegionWeights
\brief computes the area of the barycentric cell in 2D using the points `p`, `q`, and `r`.
\tparam Kernel a model of `Kernel`
*/
template<typename Kernel>
typename Kernel::FT barycentric_area(const CGAL::Point_2<Kernel>& p,
const CGAL::Point_2<Kernel>& q,
const CGAL::Point_2<Kernel>& r)
{
const GeomTraits traits;
const Kernel traits;
return barycentric_area(p, q, r, traits);
}
// 3D ==============================================================================================
/*!
\ingroup PkgWeightsRefBarycentricRegionWeights
\brief computes the area of the barycentric cell in 3D using the points `p`, `q`, and `r`.
\tparam GeomTraits a model of `AnalyticWeightTraits_3`
*/
template<typename GeomTraits>
typename GeomTraits::FT barycentric_area(const typename GeomTraits::Point_3& p,
const typename GeomTraits::Point_3& q,
@ -68,17 +87,22 @@ typename GeomTraits::FT barycentric_area(const typename GeomTraits::Point_3& p,
const Point_3 m1 = midpoint_3(q, r);
const Point_3 m2 = midpoint_3(q, p);
const FT A1 = internal::positive_area_3(traits, q, m1, center);
const FT A2 = internal::positive_area_3(traits, q, center, m2);
const FT A1 = internal::positive_area_3(q, m1, center, traits);
const FT A2 = internal::positive_area_3(q, center, m2, traits);
return A1 + A2;
}
template<typename GeomTraits>
typename GeomTraits::FT barycentric_area(const CGAL::Point_3<GeomTraits>& p,
const CGAL::Point_3<GeomTraits>& q,
const CGAL::Point_3<GeomTraits>& r)
/*!
\ingroup PkgWeightsRefBarycentricRegionWeights
\brief computes the area of the barycentric cell in 3D using the points `p`, `q`, and `r`.
\tparam Kernel a model of `Kernel`
*/
template<typename Kernel>
typename Kernel::FT barycentric_area(const CGAL::Point_3<Kernel>& p,
const CGAL::Point_3<Kernel>& q,
const CGAL::Point_3<Kernel>& r)
{
const GeomTraits traits;
const Kernel traits;
return barycentric_area(p, q, r, traits);
}

View File

@ -65,57 +65,82 @@ FT half_cotangent_weight(const FT cot)
return cotangent_ns::half_weight(cot);
}
/*!
\ingroup PkgWeightsRefCotangentWeights
\brief computes the cotangent weight in 2D at `q` using the points `p0`, `p1`, and `p2`.
\tparam GeomTraits a model of `AnalyticWeightTraits_2`
*/
template<typename GeomTraits>
typename GeomTraits::FT cotangent_weight(const typename GeomTraits::Point_2& t,
const typename GeomTraits::Point_2& r,
const typename GeomTraits::Point_2& p,
typename GeomTraits::FT cotangent_weight(const typename GeomTraits::Point_2& p0,
const typename GeomTraits::Point_2& p1,
const typename GeomTraits::Point_2& p2,
const typename GeomTraits::Point_2& q,
const GeomTraits& traits)
{
using FT = typename GeomTraits::FT;
const FT cot_beta = internal::cotangent_2(traits, q, t, r);
const FT cot_gamma = internal::cotangent_2(traits, r, p, q);
const FT cot_beta = cotangent_2(q, p0, p1, traits);
const FT cot_gamma = cotangent_2(p1, p2, q, traits);
return cotangent_ns::weight(cot_beta, cot_gamma);
}
template<typename GeomTraits>
typename GeomTraits::FT cotangent_weight(const CGAL::Point_2<GeomTraits>& t,
const CGAL::Point_2<GeomTraits>& r,
const CGAL::Point_2<GeomTraits>& p,
const CGAL::Point_2<GeomTraits>& q)
/*!
\ingroup PkgWeightsRefCotangentWeights
\brief computes the cotangent weight in 2D at `q` using the points `p0`, `p1`, and `p2`.
\tparam Kernel a model of `Kernel`
*/
template<typename Kernel>
typename Kernel::FT cotangent_weight(const CGAL::Point_2<Kernel>& p0,
const CGAL::Point_2<Kernel>& p1,
const CGAL::Point_2<Kernel>& p2,
const CGAL::Point_2<Kernel>& q)
{
GeomTraits traits;
return cotangent_weight(t, r, p, q, traits);
Kernel traits;
return cotangent_weight(p0, p1, p2, q, traits);
}
// 3D ==============================================================================================
/*!
\ingroup PkgWeightsRefCotangentWeights
\brief computes the cotangent weight in 3D at `q` using the points `p0`, `p1`, and `p2`.
\tparam GeomTraits a model of `AnalyticWeightTraits_3`
*/
template<typename GeomTraits>
typename GeomTraits::FT cotangent_weight(const typename GeomTraits::Point_3& t,
const typename GeomTraits::Point_3& r,
const typename GeomTraits::Point_3& p,
typename GeomTraits::FT cotangent_weight(const typename GeomTraits::Point_3& p0,
const typename GeomTraits::Point_3& p1,
const typename GeomTraits::Point_3& p2,
const typename GeomTraits::Point_3& q,
const GeomTraits& traits)
{
using FT = typename GeomTraits::FT;
const FT cot_beta = internal::cotangent_3(traits, q, t, r);
const FT cot_gamma = internal::cotangent_3(traits, r, p, q);
const FT cot_beta = cotangent_3(q, p0, p1, traits);
const FT cot_gamma = cotangent_3(p1, p2, q, traits);
return cotangent_ns::weight(cot_beta, cot_gamma);
}
template<typename GeomTraits>
typename GeomTraits::FT cotangent_weight(const CGAL::Point_3<GeomTraits>& t,
const CGAL::Point_3<GeomTraits>& r,
const CGAL::Point_3<GeomTraits>& p,
const CGAL::Point_3<GeomTraits>& q)
/*!
\ingroup PkgWeightsRefCotangentWeights
\brief computes the cotangent weight in 3D at `q` using the points `p0`, `p1`, and `p2`.
\tparam Kernel a model of `Kernel`
*/
template<typename Kernel>
typename Kernel::FT cotangent_weight(const CGAL::Point_3<Kernel>& p0,
const CGAL::Point_3<Kernel>& p1,
const CGAL::Point_3<Kernel>& p2,
const CGAL::Point_3<Kernel>& q)
{
GeomTraits traits;
return cotangent_weight(t, r, p, q, traits);
Kernel traits;
return cotangent_weight(p0, p1, p2, q, traits);
}
/// \cond SKIP_IN_MANUAL
// Undocumented cotangent weight class.
//
// Its constructor takes a polygon mesh and a vertex to point map
// and its operator() is defined based on the halfedge_descriptor only.
// This version is currently used in:
@ -219,6 +244,7 @@ public:
};
// Undocumented cotangent weight class.
//
// Its constructor takes a boolean flag to choose between default and clamped
// versions of the cotangent weights and its operator() is defined based on the
// halfedge_descriptor, polygon mesh, and vertex to point map.
@ -460,6 +486,8 @@ private:
}
};
/// \endcond
} // namespace Weights
} // namespace CGAL

View File

@ -31,82 +31,97 @@ namespace Weights {
namespace discrete_harmonic_ns {
template<typename FT>
FT weight(const FT d1, const FT d2, const FT d,
const FT A1, const FT A2, const FT B)
FT weight(const FT d0, const FT d2, const FT d,
const FT A0, const FT A2, const FT B)
{
FT w = FT(0);
CGAL_precondition(!is_zero(A1) && !is_zero(A2));
const FT prod = A1 * A2;
CGAL_precondition(!is_zero(A0) && !is_zero(A2));
const FT prod = A0 * A2;
if (!is_zero(prod))
w = (d2 * A1 - d * B + d1 * A2) / prod;
w = (d2 * A0 - d * B + d0 * A2) / prod;
return w;
}
} // namespace discrete_harmonic_ns
/// \endcond
// 2D ==============================================================================================
/*!
\ingroup PkgWeightsRefDiscreteHarmonicWeights
\brief computes the discrete harmonic weight in 2D at `q` using the points `p0`, `p1`, and `p2`.
\tparam GeomTraits a model of `AnalyticWeightTraits_2`
*/
template<typename GeomTraits>
typename GeomTraits::FT discrete_harmonic_weight(const typename GeomTraits::Point_2& t,
const typename GeomTraits::Point_2& r,
const typename GeomTraits::Point_2& p,
typename GeomTraits::FT discrete_harmonic_weight(const typename GeomTraits::Point_2& p0,
const typename GeomTraits::Point_2& p1,
const typename GeomTraits::Point_2& p2,
const typename GeomTraits::Point_2& q,
const GeomTraits& traits)
{
using FT = typename GeomTraits::FT;
auto squared_distance_2 = traits.compute_squared_distance_2_object();
auto area_2 = traits.compute_area_2_object();
const FT d1 = squared_distance_2(q, t);
const FT d2 = squared_distance_2(q, r);
const FT d3 = squared_distance_2(q, p);
const FT d0 = squared_distance_2(q, p0);
const FT d = squared_distance_2(q, p1);
const FT d2 = squared_distance_2(q, p2);
const FT A1 = internal::area_2(traits, r, q, t);
const FT A2 = internal::area_2(traits, p, q, r);
const FT B = internal::area_2(traits, p, q, t);
const FT A0 = area_2(p1, q, p0);
const FT A2 = area_2(p2, q, p1);
const FT B = area_2(p2, q, p0);
return discrete_harmonic_ns::weight(d1, d2, d3, A1, A2, B);
return discrete_harmonic_ns::weight(d0, d2, d, A0, A2, B);
}
template<typename GeomTraits>
typename GeomTraits::FT discrete_harmonic_weight(const CGAL::Point_2<GeomTraits>& t,
const CGAL::Point_2<GeomTraits>& r,
const CGAL::Point_2<GeomTraits>& p,
const CGAL::Point_2<GeomTraits>& q)
/*!
\ingroup PkgWeightsRefDiscreteHarmonicWeights
\brief computes the discrete harmonic weight in 2D at `q` using the points `p0`, `p1`, and `p2`.
\tparam Kernel a model of `Kernel`
*/
template<typename Kernel>
typename Kernel::FT discrete_harmonic_weight(const CGAL::Point_2<Kernel>& p0,
const CGAL::Point_2<Kernel>& p1,
const CGAL::Point_2<Kernel>& p2,
const CGAL::Point_2<Kernel>& q)
{
const GeomTraits traits;
return discrete_harmonic_weight(t, r, p, q, traits);
const Kernel traits;
return discrete_harmonic_weight(p0, p1, p2, q, traits);
}
namespace internal {
// 3D ==============================================================================================
/// \cond SKIP_IN_MANUAL
template<typename GeomTraits>
typename GeomTraits::FT discrete_harmonic_weight(const typename GeomTraits::Point_3& t,
const typename GeomTraits::Point_3& r,
const typename GeomTraits::Point_3& p,
typename GeomTraits::FT discrete_harmonic_weight(const typename GeomTraits::Point_3& p0,
const typename GeomTraits::Point_3& p1,
const typename GeomTraits::Point_3& p2,
const typename GeomTraits::Point_3& q,
const GeomTraits& traits)
{
using Point_2 = typename GeomTraits::Point_2;
Point_2 tf, rf, pf, qf;
internal::flatten(traits,
t, r, p, q,
tf, rf, pf, qf);
return CGAL::Weights::discrete_harmonic_weight(tf, rf, pf, qf, traits);
Point_2 p0f, p1f, p2f, qf;
internal::flatten(p0, p1, p2, q,
p0f, p1f, p2f, qf,
traits);
return discrete_harmonic_weight(p0f, p1f, p2f, qf, traits);
}
template<typename GeomTraits>
typename GeomTraits::FT discrete_harmonic_weight(const CGAL::Point_3<GeomTraits>& t,
const CGAL::Point_3<GeomTraits>& r,
const CGAL::Point_3<GeomTraits>& p,
const CGAL::Point_3<GeomTraits>& q)
template<typename Kernel>
typename Kernel::FT discrete_harmonic_weight(const CGAL::Point_3<Kernel>& p0,
const CGAL::Point_3<Kernel>& p1,
const CGAL::Point_3<Kernel>& p2,
const CGAL::Point_3<Kernel>& q)
{
const GeomTraits traits;
return discrete_harmonic_weight(t, r, p, q, traits);
const Kernel traits;
return discrete_harmonic_weight(p0, p1, p2, q, traits);
}
} // namespace internal
/// \endcond
/*!
@ -341,9 +356,9 @@ private:
\return an output iterator to the element in the destination range, one past the last weight stored
\pre polygon.size() >= 3
\pre polygon is simple
\pre polygon is strictly convex
\pre `polygon.size() >= 3`
\pre `polygon` is simple
\pre `polygon` is strictly convex
*/
template<typename PointRange,
typename OutIterator,
@ -358,7 +373,6 @@ OutIterator discrete_harmonic_weights_2(const PointRange& polygon,
}
/// \cond SKIP_IN_MANUAL
template<typename PointRange,
typename OutIterator>
OutIterator discrete_harmonic_weights_2(const PointRange& polygon,

View File

@ -38,29 +38,53 @@ FT weight(const FT d)
} // namespace inverse_distance_ns
/// \endcond
/*!
\ingroup PkgWeightsRefInverseDistanceWeights
\brief computes the inverse distance weight in 2D using the points `p` and `q`.
\tparam GeomTraits a model of `AnalyticWeightTraits_2`
*/
template<typename GeomTraits>
typename GeomTraits::FT inverse_distance_weight(const typename GeomTraits::Point_2&,
const typename GeomTraits::Point_2& r,
const typename GeomTraits::Point_2& p,
const typename GeomTraits::Point_2&,
const typename GeomTraits::Point_2& q,
const GeomTraits& traits)
{
using FT = typename GeomTraits::FT;
const FT d = internal::distance_2(traits, q, r);
const FT d = internal::distance_2(p, q, traits);
return inverse_distance_ns::weight(d);
}
template<typename GeomTraits>
typename GeomTraits::FT inverse_distance_weight(const CGAL::Point_2<GeomTraits>& t,
const CGAL::Point_2<GeomTraits>& r,
const CGAL::Point_2<GeomTraits>& p,
const CGAL::Point_2<GeomTraits>& q)
/*!
\ingroup PkgWeightsRefInverseDistanceWeights
\brief computes the inverse distance weight in 2D using the points `p` and `q`.
\tparam Kernel a model of `Kernel`
*/
template<typename Kernel>
#ifdef DOXYGEN_RUNNING
typename Kernel::FT inverse_distance_weight(const CGAL::Point_2<Kernel>&,
const CGAL::Point_2<Kernel>& p,
const CGAL::Point_2<Kernel>&,
const CGAL::Point_2<Kernel>& q)
#else
typename Kernel::FT inverse_distance_weight(const CGAL::Point_2<Kernel>& stub_l,
const CGAL::Point_2<Kernel>& p,
const CGAL::Point_2<Kernel>& stub_r,
const CGAL::Point_2<Kernel>& q)
#endif
{
const GeomTraits traits;
return inverse_distance_weight(t, r, p, q, traits);
const Kernel traits;
return inverse_distance_weight(stub_l, p, stub_r, q, traits);
}
/*!
\ingroup PkgWeightsRefInverseDistanceWeights
\brief computes the inverse distance weight in 2D using the points `p` and `q`.
\tparam GeomTraits a model of `AnalyticWeightTraits_2`
*/
template<typename GeomTraits>
typename GeomTraits::FT inverse_distance_weight(const typename GeomTraits::Point_2& p,
const typename GeomTraits::Point_2& q,
@ -70,37 +94,66 @@ typename GeomTraits::FT inverse_distance_weight(const typename GeomTraits::Point
return inverse_distance_weight(stub, p, stub, q, traits);
}
template<typename GeomTraits>
typename GeomTraits::FT inverse_distance_weight(const CGAL::Point_2<GeomTraits>& p,
const CGAL::Point_2<GeomTraits>& q)
/*!
\ingroup PkgWeightsRefInverseDistanceWeights
\brief computes the inverse distance weight in 2D using the points `p` and `q`.
\tparam Kernel a model of `Kernel`
*/
template<typename Kernel>
typename Kernel::FT inverse_distance_weight(const CGAL::Point_2<Kernel>& p,
const CGAL::Point_2<Kernel>& q)
{
CGAL::Point_2<GeomTraits> stub;
CGAL::Point_2<Kernel> stub;
return inverse_distance_weight(stub, p, stub, q);
}
// 3D ==============================================================================================
/*!
\ingroup PkgWeightsRefInverseDistanceWeights
\brief computes the inverse distance weight in 3D using the points `p` and `q`.
\tparam GeomTraits a model of `AnalyticWeightTraits_3`
*/
template<typename GeomTraits>
typename GeomTraits::FT inverse_distance_weight(const typename GeomTraits::Point_3&,
const typename GeomTraits::Point_3& r,
const typename GeomTraits::Point_3& p,
const typename GeomTraits::Point_3&,
const typename GeomTraits::Point_3& q,
const GeomTraits& traits)
{
using FT = typename GeomTraits::FT;
const FT d = internal::distance_3(traits, q, r);
const FT d = internal::distance_3(p, q, traits);
return inverse_distance_ns::weight(d);
}
template<typename GeomTraits>
typename GeomTraits::FT inverse_distance_weight(const CGAL::Point_3<GeomTraits>& t,
const CGAL::Point_3<GeomTraits>& r,
const CGAL::Point_3<GeomTraits>& p,
const CGAL::Point_3<GeomTraits>& q)
/*!
\ingroup PkgWeightsRefInverseDistanceWeights
\brief computes the inverse distance weight in 3D using the points `p` and `q`.
\tparam Kernel a model of `Kernel`
*/
template<typename Kernel>
#ifdef DOXYGEN_RUNNING
typename Kernel::FT inverse_distance_weight(const CGAL::Point_3<Kernel>&,
const CGAL::Point_3<Kernel>& p,
const CGAL::Point_3<Kernel>&,
const CGAL::Point_3<Kernel>& q)
#else
typename Kernel::FT inverse_distance_weight(const CGAL::Point_3<Kernel>& stub_l,
const CGAL::Point_3<Kernel>& p,
const CGAL::Point_3<Kernel>& stub_r,
const CGAL::Point_3<Kernel>& q)
#endif
{
const GeomTraits traits;
return inverse_distance_weight(t, r, p, q, traits);
const Kernel traits;
return inverse_distance_weight(stub_l, p, stub_r, q, traits);
}
/*!
\ingroup PkgWeightsRefInverseDistanceWeights
\brief computes the inverse distance weight in 3D using the points `p` and `q`.
\tparam GeomTraits a model of `AnalyticWeightTraits_3`
*/
template<typename GeomTraits>
typename GeomTraits::FT inverse_distance_weight(const typename GeomTraits::Point_3& p,
const typename GeomTraits::Point_3& q,
@ -110,16 +163,19 @@ typename GeomTraits::FT inverse_distance_weight(const typename GeomTraits::Point
return inverse_distance_weight(stub, p, stub, q, traits);
}
template<typename GeomTraits>
typename GeomTraits::FT inverse_distance_weight(const CGAL::Point_3<GeomTraits>& p,
const CGAL::Point_3<GeomTraits>& q)
/*!
\ingroup PkgWeightsRefInverseDistanceWeights
\brief computes the inverse distance weight in 3D using the points `p` and `q`.
\tparam Kernel a model of `Kernel`
*/
template<typename Kernel>
typename Kernel::FT inverse_distance_weight(const CGAL::Point_3<Kernel>& p,
const CGAL::Point_3<Kernel>& q)
{
CGAL::Point_3<GeomTraits> stub;
CGAL::Point_3<Kernel> stub;
return inverse_distance_weight(stub, p, stub, q);
}
/// \endcond
} // namespace Weights
} // namespace CGAL

View File

@ -32,12 +32,12 @@ namespace Weights {
namespace mean_value_ns {
template<typename FT>
FT sign_of_weight(const FT A1, const FT A2, const FT B)
FT sign_of_weight(const FT A0, const FT A2, const FT B)
{
if (A1 > FT(0) && A2 > FT(0) && B <= FT(0))
if (A0 > FT(0) && A2 > FT(0) && B <= FT(0))
return +FT(1);
if (A1 < FT(0) && A2 < FT(0) && B >= FT(0))
if (A0 < FT(0) && A2 < FT(0) && B >= FT(0))
return -FT(1);
if (B > FT(0))
@ -50,112 +50,127 @@ FT sign_of_weight(const FT A1, const FT A2, const FT B)
}
template<typename GeomTraits>
typename GeomTraits::FT weight(const GeomTraits& traits,
const typename GeomTraits::FT r1,
const typename GeomTraits::FT r2,
const typename GeomTraits::FT r3,
const typename GeomTraits::FT D1,
typename GeomTraits::FT weight(const typename GeomTraits::FT d0,
const typename GeomTraits::FT d2,
const typename GeomTraits::FT d,
const typename GeomTraits::FT D0,
const typename GeomTraits::FT D2,
const typename GeomTraits::FT D,
const typename GeomTraits::FT sign)
const typename GeomTraits::FT sign,
const GeomTraits& traits)
{
using FT = typename GeomTraits::FT;
using Get_sqrt = internal::Get_sqrt<GeomTraits>;
auto sqrt = Get_sqrt::sqrt_object(traits);
const FT P1 = r1 * r2 + D1;
const FT P2 = r2 * r3 + D2;
const FT P1 = d * d0 + D0;
const FT P2 = d * d2 + D2;
FT w = FT(0);
CGAL_precondition(!is_zero(P1) && !is_zero(P2));
const FT prod = P1 * P2;
if (!is_zero(prod))
{
const FT inv = FT(1) / prod;
w = FT(2) * (r1 * r3 - D) * inv;
w = FT(2) * (d0 * d2 - D) / prod;
CGAL_assertion(w >= FT(0));
w = sqrt(w);
}
w *= FT(2); w *= sign;
w *= sign * FT(2);
return w;
}
} // namespace mean_value_ns
/// \endcond
// 2D ==============================================================================================
/*!
\ingroup PkgWeightsRefMeanValueWeights
\brief computes the mean value weight in 2D at `q` using the points `p0`, `p1`, and `p2`.
\tparam GeomTraits a model of `AnalyticWeightTraits_2`
*/
template<typename GeomTraits>
typename GeomTraits::FT mean_value_weight(const typename GeomTraits::Point_2& t,
const typename GeomTraits::Point_2& r,
const typename GeomTraits::Point_2& p,
typename GeomTraits::FT mean_value_weight(const typename GeomTraits::Point_2& p0,
const typename GeomTraits::Point_2& p1,
const typename GeomTraits::Point_2& p2,
const typename GeomTraits::Point_2& q,
const GeomTraits& traits)
{
using FT = typename GeomTraits::FT;
using Vector_2 = typename GeomTraits::Vector_2;
auto vector_2 = traits.construct_vector_2_object();
auto dot_product_2 = traits.compute_scalar_product_2_object();
auto construct_vector_2 = traits.construct_vector_2_object();
auto area_2 = traits.compute_area_2_object();
const Vector_2 v1 = construct_vector_2(q, t);
const Vector_2 v2 = construct_vector_2(q, r);
const Vector_2 v3 = construct_vector_2(q, p);
const Vector_2 v1 = vector_2(q, p0);
const Vector_2 v = vector_2(q, p1);
const Vector_2 v2 = vector_2(q, p2);
const FT l1 = internal::length_2(traits, v1);
const FT l2 = internal::length_2(traits, v2);
const FT l3 = internal::length_2(traits, v3);
const FT d0 = internal::length_2(v1, traits);
const FT d = internal::length_2(v, traits);
const FT d2 = internal::length_2(v2, traits);
const FT D1 = dot_product_2(v1, v2);
const FT D2 = dot_product_2(v2, v3);
const FT D = dot_product_2(v1, v3);
const FT D0 = dot_product_2(v1, v);
const FT D2 = dot_product_2(v, v2);
const FT D = dot_product_2(v1, v2);
const FT A1 = internal::area_2(traits, r, q, t);
const FT A2 = internal::area_2(traits, p, q, r);
const FT B = internal::area_2(traits, p, q, t);
const FT A0 = area_2(p1, q, p0);
const FT A2 = area_2(p2, q, p1);
const FT B = area_2(p2, q, p0);
const FT sign = mean_value_ns::sign_of_weight(A1, A2, B);
return mean_value_ns::weight(traits, l1, l2, l3, D1, D2, D, sign);
const FT sign = mean_value_ns::sign_of_weight(A0, A2, B);
return mean_value_ns::weight(d0, d2, d, D0, D2, D, sign, traits);
}
template<typename GeomTraits>
typename GeomTraits::FT mean_value_weight(const CGAL::Point_2<GeomTraits>& t,
const CGAL::Point_2<GeomTraits>& r,
const CGAL::Point_2<GeomTraits>& p,
const CGAL::Point_2<GeomTraits>& q)
/*!
\ingroup PkgWeightsRefMeanValueWeights
\brief computes the mean value weight in 2D at `q` using the points `p0`, `p1`, and `p2`.
\tparam Kernel a model of `Kernel`
*/
template<typename Kernel>
typename Kernel::FT mean_value_weight(const CGAL::Point_2<Kernel>& p0,
const CGAL::Point_2<Kernel>& p1,
const CGAL::Point_2<Kernel>& p2,
const CGAL::Point_2<Kernel>& q)
{
const GeomTraits traits;
return mean_value_weight(t, r, p, q, traits);
const Kernel traits;
return mean_value_weight(p0, p1, p2, q, traits);
}
namespace internal {
// 3D ==============================================================================================
/// \cond SKIP_IN_MANUAL
template<typename GeomTraits>
typename GeomTraits::FT mean_value_weight(const typename GeomTraits::Point_3& t,
const typename GeomTraits::Point_3& r,
const typename GeomTraits::Point_3& p,
typename GeomTraits::FT mean_value_weight(const typename GeomTraits::Point_3& p0,
const typename GeomTraits::Point_3& p1,
const typename GeomTraits::Point_3& p2,
const typename GeomTraits::Point_3& q,
const GeomTraits& traits)
{
using Point_2 = typename GeomTraits::Point_2;
Point_2 tf, rf, pf, qf;
internal::flatten(traits,
t, r, p, q,
tf, rf, pf, qf);
return CGAL::Weights::mean_value_weight(tf, rf, pf, qf, traits);
Point_2 p0f, p1f, p2f, qf;
internal::flatten(p0, p1, p2, q,
p0f, p1f, p2f, qf,
traits);
return CGAL::Weights::mean_value_weight(p0f, p1f, p2f, qf, traits);
}
template<typename GeomTraits>
typename GeomTraits::FT mean_value_weight(const CGAL::Point_3<GeomTraits>& t,
const CGAL::Point_3<GeomTraits>& r,
const CGAL::Point_3<GeomTraits>& p,
const CGAL::Point_3<GeomTraits>& q)
template<typename Kernel>
typename Kernel::FT mean_value_weight(const CGAL::Point_3<Kernel>& p0,
const CGAL::Point_3<Kernel>& p1,
const CGAL::Point_3<Kernel>& p2,
const CGAL::Point_3<Kernel>& q)
{
const GeomTraits traits;
return mean_value_weight(t, r, p, q, traits);
const Kernel traits;
return mean_value_weight(p0, p1, p2, q, traits);
}
} // namespace internal
/// \endcond
/*!
@ -163,13 +178,12 @@ typename GeomTraits::FT mean_value_weight(const CGAL::Point_3<GeomTraits>& t,
\brief 2D mean value weights for polygons.
This class implements 2D mean value weights ( \cite cgal:bc:hf-mvcapp-06,
\cite cgal:bc:fhk-gcbcocp-06, \cite cgal:f-mvc-03 ) which can be computed
at any point inside and outside a simple polygon.
This class implements 2D mean value weights (\cite cgal:bc:fhk-gcbcocp-06, \cite cgal:f-mvc-03,
\cite cgal:bc:hf-mvcapp-06) which can be computed at any point inside and outside a simple polygon.
Mean value weights are well-defined inside and outside a simple polygon and are
non-negative in the kernel of a star-shaped polygon. These weights are computed
analytically using the formulation from the `tangent_weight()`.
analytically using the formulation from `tangent_weight()`.
\tparam VertexRange a model of `ConstRange` whose iterator type is `RandomAccessIterator`
\tparam GeomTraits a model of `AnalyticWeightTraits_2`
@ -188,6 +202,7 @@ public:
/// @{
/// \cond SKIP_IN_MANUAL
using Vertex_range = VertexRange;
using Geom_traits = GeomTraits;
using Point_map = PointMap;
@ -199,6 +214,7 @@ public:
using Scalar_product_2 = typename GeomTraits::Compute_scalar_product_2;
using Get_sqrt = internal::Get_sqrt<GeomTraits>;
using Sqrt = typename Get_sqrt::Sqrt;
/// \endcond
/// Number type.
@ -274,6 +290,7 @@ public:
/// @}
/// \cond SKIP_IN_MANUAL
template<typename OutIterator>
OutIterator operator()(const Point_2& query,
OutIterator weights,
@ -414,11 +431,10 @@ private:
\param traits a traits class with geometric objects, predicates, and constructions;
this parameter can be omitted if the traits class can be deduced from the point type
\return an output iterator to the element in the destination range,
one past the last weight stored
\return an output iterator to the element in the destination range, one past the last weight stored
\pre polygon.size() >= 3
\pre polygon is simple
\pre `polygon.size() >= 3`
\pre `polygon` is simple
*/
template<typename PointRange,
typename OutIterator,

View File

@ -22,7 +22,13 @@
namespace CGAL {
namespace Weights {
/// \cond SKIP_IN_MANUAL
// 2D ==============================================================================================
/*!
\ingroup PkgWeightsRefMixedVoronoiRegionWeights
\brief computes the area of the mixed Voronoi cell in 2D using the points `p`, `q`, and `r`.
\tparam GeomTraits a model of `AnalyticWeightTraits_2`
*/
template<typename GeomTraits>
typename GeomTraits::FT mixed_voronoi_area(const typename GeomTraits::Point_2& p,
const typename GeomTraits::Point_2& q,
@ -49,11 +55,17 @@ typename GeomTraits::FT mixed_voronoi_area(const typename GeomTraits::Point_2& p
const Point_2 m1 = midpoint_2(q, r);
const Point_2 m2 = midpoint_2(q, p);
const FT A1 = internal::positive_area_2(traits, q, m1, center);
const FT A2 = internal::positive_area_2(traits, q, center, m2);
const FT A1 = internal::positive_area_2(q, m1, center, traits);
const FT A2 = internal::positive_area_2(q, center, m2, traits);
return A1 + A2;
}
/*!
\ingroup PkgWeightsRefMixedVoronoiRegionWeights
\brief computes the area of the mixed Voronoi cell in 2D using the points `p`, `q`, and `r`.
\tparam Kernel a model of `Kernel`
*/
template<typename GeomTraits>
typename GeomTraits::FT mixed_voronoi_area(const CGAL::Point_2<GeomTraits>& p,
const CGAL::Point_2<GeomTraits>& q,
@ -63,6 +75,13 @@ typename GeomTraits::FT mixed_voronoi_area(const CGAL::Point_2<GeomTraits>& p,
return mixed_voronoi_area(p, q, r, traits);
}
// 3D ==============================================================================================
/*!
\ingroup PkgWeightsRefMixedVoronoiRegionWeights
\brief computes the area of the mixed Voronoi cell in 3D using the points `p`, `q`, and `r`.
\tparam GeomTraits a model of `AnalyticWeightTraits_3`
*/
template<typename GeomTraits>
typename GeomTraits::FT mixed_voronoi_area(const typename GeomTraits::Point_3& p,
const typename GeomTraits::Point_3& q,
@ -89,22 +108,26 @@ typename GeomTraits::FT mixed_voronoi_area(const typename GeomTraits::Point_3& p
const Point_3 m1 = midpoint_3(q, r);
const Point_3 m2 = midpoint_3(q, p);
const FT A1 = internal::positive_area_3(traits, q, m1, center);
const FT A2 = internal::positive_area_3(traits, q, center, m2);
const FT A1 = internal::positive_area_3(q, m1, center, traits);
const FT A2 = internal::positive_area_3(q, center, m2, traits);
return A1 + A2;
}
template<typename GeomTraits>
typename GeomTraits::FT mixed_voronoi_area(const CGAL::Point_3<GeomTraits>& p,
const CGAL::Point_3<GeomTraits>& q,
const CGAL::Point_3<GeomTraits>& r)
/*!
\ingroup PkgWeightsRefMixedVoronoiRegionWeights
\brief computes the area of the mixed Voronoi cell in 3D using the points `p`, `q`, and `r`.
\tparam Kernel a model of `Kernel`
*/
template<typename Kernel>
typename Kernel::FT mixed_voronoi_area(const CGAL::Point_3<Kernel>& p,
const CGAL::Point_3<Kernel>& q,
const CGAL::Point_3<Kernel>& r)
{
const GeomTraits traits;
const Kernel traits;
return mixed_voronoi_area(p, q, r, traits);
}
/// \endcond
} // namespace Weights
} // namespace CGAL

View File

@ -26,13 +26,9 @@ namespace Weights {
namespace shepard_ns {
template<typename GeomTraits>
typename GeomTraits::FT weight(const GeomTraits& traits,
const typename GeomTraits::FT d,
const typename GeomTraits::FT p)
template<typename FT>
FT weight(const FT d, const FT p)
{
using FT = typename GeomTraits::FT;
FT w = FT(0);
CGAL_precondition(is_positive(d));
if(is_positive(d))
@ -43,31 +39,57 @@ typename GeomTraits::FT weight(const GeomTraits& traits,
} // namespace shepard_ns
/// \endcond
// 2D ==============================================================================================
/*!
\ingroup PkgWeightsRefShepardWeights
\brief computes the Shepard weight in 2D using the points `p` and `q` and the power parameter `a`.
\tparam GeomTraits a model of `AnalyticWeightTraits_2`
*/
template<typename GeomTraits>
typename GeomTraits::FT shepard_weight(const typename GeomTraits::Point_2&,
const typename GeomTraits::Point_2& r,
const typename GeomTraits::Point_2& p,
const typename GeomTraits::Point_2&,
const typename GeomTraits::Point_2& q,
const typename GeomTraits::FT a,
const GeomTraits& traits)
{
using FT = typename GeomTraits::FT;
const FT d = internal::distance_2(traits, q, r);
return shepard_ns::weight(traits, d, a);
const FT d = internal::distance_2(p, q, traits);
return shepard_ns::weight(d, a);
}
template<typename GeomTraits>
typename GeomTraits::FT shepard_weight(const CGAL::Point_2<GeomTraits>& t,
const CGAL::Point_2<GeomTraits>& r,
const CGAL::Point_2<GeomTraits>& p,
const CGAL::Point_2<GeomTraits>& q,
const typename GeomTraits::FT a = typename GeomTraits::FT(1))
/*!
\ingroup PkgWeightsRefShepardWeights
\brief computes the Shepard weight in 2D using the points `p` and `q`, and the power parameter `a`
\tparam Kernel a model of `Kernel`
*/
template<typename Kernel>
#ifdef DOXYGEN_RUNNING
typename Kernel::FT shepard_weight(const CGAL::Point_2<Kernel>&,
const CGAL::Point_2<Kernel>& p^,
const CGAL::Point_2<Kernel>&,
const CGAL::Point_2<Kernel>& q,
const typename Kernel::FT a = {1})
#else
typename Kernel::FT shepard_weight(const CGAL::Point_2<Kernel>& stub_l,
const CGAL::Point_2<Kernel>& p,
const CGAL::Point_2<Kernel>& stub_r,
const CGAL::Point_2<Kernel>& q,
const typename Kernel::FT a = {1})
#endif
{
const GeomTraits traits;
return shepard_weight(t, r, p, q, a, traits);
const Kernel traits;
return shepard_weight(stub_l, p, stub_r, q, a, traits);
}
/*!
\ingroup PkgWeightsRefShepardWeights
\brief computes the Shepard weight in 2D using the points `p` and `q` and the power parameter `a`.
\tparam GeomTraits a model of `AnalyticWeightTraits_2`
*/
template<typename GeomTraits>
typename GeomTraits::FT shepard_weight(const typename GeomTraits::Point_2& p,
const typename GeomTraits::Point_2& q,
@ -78,39 +100,69 @@ typename GeomTraits::FT shepard_weight(const typename GeomTraits::Point_2& p,
return shepard_weight(stub, p, stub, q, a, traits);
}
template<typename GeomTraits>
typename GeomTraits::FT shepard_weight(const CGAL::Point_2<GeomTraits>& p,
const CGAL::Point_2<GeomTraits>& q,
const typename GeomTraits::FT a = typename GeomTraits::FT(1))
/*!
\ingroup PkgWeightsRefShepardWeights
\brief computes the Shepard weight in 2D using the points `p` and `q`, and the power parameter `a`.
\tparam Kernel a model of `Kernel`
*/
template<typename Kernel>
typename Kernel::FT shepard_weight(const CGAL::Point_2<Kernel>& p,
const CGAL::Point_2<Kernel>& q,
const typename Kernel::FT a = {1})
{
CGAL::Point_2<GeomTraits> stub;
CGAL::Point_2<Kernel> stub;
return shepard_weight(stub, p, stub, q, a);
}
// 3D ==============================================================================================
/*!
\ingroup PkgWeightsRefShepardWeights
\brief computes the Shepard weight in 3D using the points `p` and `q` and the power parameter `a`.
\tparam GeomTraits a model of `AnalyticWeightTraits_3`
*/
template<typename GeomTraits>
typename GeomTraits::FT shepard_weight(const typename GeomTraits::Point_3&,
const typename GeomTraits::Point_3& r,
const typename GeomTraits::Point_3& p,
const typename GeomTraits::Point_3&,
const typename GeomTraits::Point_3& q,
const typename GeomTraits::FT a,
const GeomTraits& traits)
{
using FT = typename GeomTraits::FT;
const FT d = internal::distance_3(traits, q, r);
return shepard_ns::weight(traits, d, a);
const FT d = internal::distance_3(p, q, traits);
return shepard_ns::weight(d, a);
}
template<typename GeomTraits>
typename GeomTraits::FT shepard_weight(const CGAL::Point_3<GeomTraits>& t,
const CGAL::Point_3<GeomTraits>& r,
const CGAL::Point_3<GeomTraits>& p,
const CGAL::Point_3<GeomTraits>& q,
const typename GeomTraits::FT a = typename GeomTraits::FT(1))
/*!
\ingroup PkgWeightsRefShepardWeights
\brief computes the Shepard weight in 3D using the points `p` and `q`, and the power parameter `a`.
\tparam Kernel a model of `Kernel`
*/
template<typename Kernel>
#ifdef DOXYGEN_RUNNING
typename Kernel::FT shepard_weight(const CGAL::Point_3<Kernel>& p,
const CGAL::Point_3<Kernel>&,
const CGAL::Point_3<Kernel>& q,
const CGAL::Point_3<Kernel>&,
const typename Kernel::FT a = {1})
#else
typename Kernel::FT shepard_weight(const CGAL::Point_3<Kernel>& stub_l,
const CGAL::Point_3<Kernel>& p,
const CGAL::Point_3<Kernel>& stub_r,
const CGAL::Point_3<Kernel>& q,
const typename Kernel::FT a = {1})
#endif
{
const GeomTraits traits;
return shepard_weight(t, r, p, q, a, traits);
const Kernel traits;
return shepard_weight(stub_l, p, stub_r, q, a, traits);
}
/*!
\ingroup PkgWeightsRefShepardWeights
\brief computes the Shepard weight in 3D using the points `p` and `q` and the power parameter `a`.
\tparam GeomTraits a model of `AnalyticWeightTraits_3`
*/
template<typename GeomTraits>
typename GeomTraits::FT shepard_weight(const typename GeomTraits::Point_3& p,
const typename GeomTraits::Point_3& q,
@ -121,17 +173,20 @@ typename GeomTraits::FT shepard_weight(const typename GeomTraits::Point_3& p,
return shepard_weight(stub, p, stub, q, a, traits);
}
template<typename GeomTraits>
typename GeomTraits::FT shepard_weight(const CGAL::Point_3<GeomTraits>& p,
const CGAL::Point_3<GeomTraits>& q,
const typename GeomTraits::FT a = typename GeomTraits::FT(1))
/*!
\ingroup PkgWeightsRefShepardWeights
\brief computes the Shepard weight in 3D using the points `p` and `q`, and the power parameter `a`.
\tparam Kernel a model of `Kernel`
*/
template<typename Kernel>
typename Kernel::FT shepard_weight(const CGAL::Point_3<Kernel>& p,
const CGAL::Point_3<Kernel>& q,
const typename Kernel::FT a = {1})
{
CGAL::Point_3<GeomTraits> stub;
CGAL::Point_3<Kernel> stub;
return shepard_weight(stub, p, stub, q, a);
}
/// \endcond
} // namespace Weights
} // namespace CGAL

View File

@ -40,32 +40,33 @@ FT half_weight(const FT t, const FT r)
}
template<typename FT>
FT weight(const FT t1, const FT t2, const FT r)
FT weight(const FT t0, const FT t2, const FT r)
{
FT w = FT(0);
CGAL_precondition(r != FT(0));
if (r != FT(0))
w = FT(2) * (t1 + t2) / r;
w = FT(2) * (t0 + t2) / r;
return w;
}
template<typename FT>
FT weight(const FT d1, const FT d, const FT d2,
const FT A1, const FT A2,
const FT D1, const FT D2)
FT weight(const FT d0, const FT d2, const FT d,
const FT A0, const FT A2,
const FT D0, const FT D2)
{
const FT P1 = d1 * d + D1;
const FT P2 = d2 * d + D2;
const FT P0 = d * d0 + D0;
const FT P2 = d * d2 + D2;
FT w = FT(0);
CGAL_precondition(!is_zero(P1) && !is_zero(P2));
if (!is_zero(P1) && !is_zero(P2))
CGAL_precondition(!is_zero(P0) && !is_zero(P2));
if (!is_zero(P0) && !is_zero(P2))
{
const FT t1 = FT(2) * A1 / P1;
const FT t0 = FT(2) * A0 / P0;
const FT t2 = FT(2) * A2 / P2;
w = weight(t1, t2, d);
w = weight(t0, t2, d);
}
return w;
}
@ -73,9 +74,9 @@ FT weight(const FT d1, const FT d, const FT d2,
// This version is based on the positive area.
// This version is more precise for all positive cases.
template<typename GeomTraits>
typename GeomTraits::FT tangent_weight_v1(const typename GeomTraits::Point_3& t,
const typename GeomTraits::Point_3& r,
const typename GeomTraits::Point_3& p,
typename GeomTraits::FT tangent_weight_v1(const typename GeomTraits::Point_3& p0,
const typename GeomTraits::Point_3& p1,
const typename GeomTraits::Point_3& p2,
const typename GeomTraits::Point_3& q,
const GeomTraits& traits)
{
@ -83,92 +84,62 @@ typename GeomTraits::FT tangent_weight_v1(const typename GeomTraits::Point_3& t,
using Vector_3 = typename GeomTraits::Vector_3;
auto dot_product_3 = traits.compute_scalar_product_3_object();
auto construct_vector_3 = traits.construct_vector_3_object();
auto vector_3 = traits.construct_vector_3_object();
const Vector_3 v1 = construct_vector_3(q, t);
const Vector_3 v2 = construct_vector_3(q, r);
const Vector_3 v3 = construct_vector_3(q, p);
const Vector_3 v0 = vector_3(q, p0);
const Vector_3 v = vector_3(q, p1);
const Vector_3 v2 = vector_3(q, p2);
const FT l1 = internal::length_3(traits, v1);
const FT l2 = internal::length_3(traits, v2);
const FT l3 = internal::length_3(traits, v3);
const FT d0 = internal::length_3(v0, traits);
const FT d = internal::length_3(v, traits);
const FT d2 = internal::length_3(v2, traits);
const FT A1 = internal::positive_area_3(traits, r, q, t);
const FT A2 = internal::positive_area_3(traits, p, q, r);
const FT A0 = internal::positive_area_3(p1, q, p0, traits);
const FT A2 = internal::positive_area_3(p2, q, p1, traits);
const FT D1 = dot_product_3(v1, v2);
const FT D2 = dot_product_3(v2, v3);
const FT D0 = dot_product_3(v0, v);
const FT D2 = dot_product_3(v, v2);
return weight(l1, l2, l3, A1, A2, D1, D2);
return weight(d0, d2, d, A0, A2, D0, D2);
}
// This version handles both positive and negative cases.
// However, it is less precise.
template<typename GeomTraits>
typename GeomTraits::FT tangent_weight_v2(const typename GeomTraits::Point_3& t,
const typename GeomTraits::Point_3& r,
const typename GeomTraits::Point_3& p,
typename GeomTraits::FT tangent_weight_v2(const typename GeomTraits::Point_3& p0,
const typename GeomTraits::Point_3& p1,
const typename GeomTraits::Point_3& p2,
const typename GeomTraits::Point_3& q,
const GeomTraits& traits)
{
using FT = typename GeomTraits::FT;
using Vector_3 = typename GeomTraits::Vector_3;
auto construct_vector_3 = traits.construct_vector_3_object();
auto vector_3 = traits.construct_vector_3_object();
Vector_3 v1 = construct_vector_3(q, t);
Vector_3 v2 = construct_vector_3(q, r);
Vector_3 v3 = construct_vector_3(q, p);
Vector_3 v0 = vector_3(q, p0);
Vector_3 v = vector_3(q, p1);
Vector_3 v2 = vector_3(q, p2);
const FT l2 = internal::length_3(traits, v2);
const FT l2 = internal::length_3(v, traits);
internal::normalize_3(traits, v1);
internal::normalize_3(traits, v2);
internal::normalize_3(traits, v3);
internal::normalize_3(v0, traits);
internal::normalize_3(v, traits);
internal::normalize_3(v2, traits);
const double ha_rad_1 = internal::angle_3(traits, v1, v2) / 2.0;
const double ha_rad_2 = internal::angle_3(traits, v2, v3) / 2.0;
const FT t1 = static_cast<FT>(std::tan(ha_rad_1));
const double ha_rad_1 = internal::angle_3(v0, v, traits) / 2.0;
const double ha_rad_2 = internal::angle_3(v, v2, traits) / 2.0;
const FT t0 = static_cast<FT>(std::tan(ha_rad_1));
const FT t2 = static_cast<FT>(std::tan(ha_rad_2));
return weight(t1, t2, l2);
return weight(t0, t2, l2);
}
} // namespace tangent_ns
/// \endcond
/*!
\ingroup PkgWeightsRefTangentWeights
\brief computes the tangent of the half angle.
This function computes the tangent of the half angle using the precomputed
distance, area, and dot product values. The returned value is
\f$\frac{2\textbf{A}}{\textbf{d}\textbf{d_1} + \textbf{D_1}}\f$.
\tparam FT a model of `FieldNumberType`
\param d1 the first distance value
\param d2 the second distance value
\param A the area value
\param D the dot product value
\pre (d1 * d2 + D) != 0
\sa `half_tangent_weight()`
*/
template<typename FT>
FT tangent_half_angle(const FT d1, const FT d2, const FT A, const FT D)
{
FT t = FT(0);
const FT P = d1 * d2 + D;
CGAL_precondition(!is_zero(P));
if (!is_zero(P))
t = FT(2) * A / P;
return t;
}
// 2D ==============================================================================================
/*!
\ingroup PkgWeightsRefTangentWeights
@ -195,6 +166,42 @@ FT half_tangent_weight(const FT tan05, const FT d)
return tangent_ns::half_weight(tan05, d);
}
/*!
\ingroup PkgWeightsRefTangentWeights
\brief computes the tangent of the half angle.
This function computes the tangent of the half angle using the precomputed
distance, area, and dot product values. The returned value is
\f$\frac{2\textbf{A}}{\textbf{d}\textbf{l} + \textbf{D}}\f$.
\tparam FT a model of `FieldNumberType`
\param d the distance value
\param l the distance value
\param A the area value
\param D the dot product value
\pre (d * l + D) != 0
\sa `half_tangent_weight()`
*/
template<typename FT>
FT tangent_half_angle(const FT d, const FT l, const FT A, const FT D)
{
// tan(theta/2) = sin(theta) / ( 1 + cos(theta) ), also = (1 - cos(theta)) / sin(theta).
// = ( 2*A / |v1|*|v2| ) / ( 1 + v1.v2 / |v1|*|v2| )
// = 2*A / ( |v1|*|v2| + v1.v2 )
FT t = FT(0);
const FT P = d * l + D;
CGAL_precondition(!is_zero(P));
if (!is_zero(P))
t = FT(2) * A / P;
return t;
}
/*!
\ingroup PkgWeightsRefTangentWeights
@ -224,65 +231,138 @@ FT half_tangent_weight(const FT d, const FT l, const FT A, const FT D)
}
/// \cond SKIP_IN_MANUAL
template<typename GeomTraits>
typename GeomTraits::FT tangent_weight(const typename GeomTraits::Point_2& t,
const typename GeomTraits::Point_2& r,
const typename GeomTraits::Point_2& p,
typename GeomTraits::FT half_tangent_weight(const typename GeomTraits::Point_2& p0,
const typename GeomTraits::Point_2& q,
const typename GeomTraits::Point_2& p2,
const GeomTraits& traits)
{
using FT = typename GeomTraits::FT;
auto vector_2 = traits.construct_vector_2_object();
auto dot_product_2 = traits.compute_scalar_product_2_object();
auto area_2 = traits.compute_area_2_object();
const Vector_2 v0 = vector_2(q, p0);
const Vector_2 v2 = vector_2(q, p2);
const FT l0 = internal::length_2(v0, traits);
const FT l2 = internal::length_2(v2, traits);
const FT A = area_2(p2, q, p0);
const FT D = dot_product_2(v0, v2);
return half_tangent_weight(l0, l2, A, D);
}
template<typename GeomTraits>
typename GeomTraits::FT half_tangent_weight(const typename GeomTraits::Point_3& p0,
const typename GeomTraits::Point_3& q,
const typename GeomTraits::Point_3& p2,
const GeomTraits& traits)
{
using FT = typename GeomTraits::FT;
auto vector_3 = traits.construct_vector_3_object();
auto dot_product_3 = traits.compute_scalar_product_3_object();
const Vector_3 v0 = vector_3(q, p0);
const Vector_3 v2 = vector_3(q, p2);
const FT l0 = internal::length_3(v0, traits);
const FT l2 = internal::length_3(v2, traits);
const FT A = internal::area_3(p2, q, p0, traits);
const FT D = dot_product_3(v0, v2);
return half_tangent_weight(l0, l2, A, D);
}
/// \endcond
// 2D ==============================================================================================
/*!
\ingroup PkgWeightsRefTangentWeights
\brief computes the tangent weight in 2D at `q` using the points `p0`, `p1`, and `p2`
\tparam GeomTraits a model of `AnalyticWeightTraits_2`
*/
template<typename GeomTraits>
typename GeomTraits::FT tangent_weight(const typename GeomTraits::Point_2& p0,
const typename GeomTraits::Point_2& p1,
const typename GeomTraits::Point_2& p2,
const typename GeomTraits::Point_2& q,
const GeomTraits& traits)
{
using FT = typename GeomTraits::FT;
using Vector_2 = typename GeomTraits::Vector_2;
auto vector_2 = traits.construct_vector_2_object();
auto dot_product_2 = traits.compute_scalar_product_2_object();
auto construct_vector_2 = traits.construct_vector_2_object();
auto area_2 = traits.compute_area_2_object();
const Vector_2 v1 = construct_vector_2(q, t);
const Vector_2 v2 = construct_vector_2(q, r);
const Vector_2 v3 = construct_vector_2(q, p);
const Vector_2 v0 = vector_2(q, p0);
const Vector_2 v = vector_2(q, p1);
const Vector_2 v2 = vector_2(q, p2);
const FT l1 = internal::length_2(traits, v1);
const FT l2 = internal::length_2(traits, v2);
const FT l3 = internal::length_2(traits, v3);
const FT l0 = internal::length_2(v0, traits);
const FT l = internal::length_2(v, traits);
const FT l2 = internal::length_2(v2, traits);
const FT A1 = internal::area_2(traits, r, q, t);
const FT A2 = internal::area_2(traits, p, q, r);
const FT A0 = area_2(p1, q, p0);
const FT A2 = area_2(p2, q, p1);
const FT D1 = dot_product_2(v1, v2);
const FT D2 = dot_product_2(v2, v3);
const FT D0 = dot_product_2(v0, v);
const FT D2 = dot_product_2(v, v2);
return tangent_ns::weight(l1, l2, l3, A1, A2, D1, D2);
return tangent_ns::weight(l0, l2, l, A0, A2, D0, D2);
}
template<typename GeomTraits>
typename GeomTraits::FT tangent_weight(const CGAL::Point_2<GeomTraits>& t,
const CGAL::Point_2<GeomTraits>& r,
const CGAL::Point_2<GeomTraits>& p,
const CGAL::Point_2<GeomTraits>& q)
/*!
\ingroup PkgWeightsRefTangentWeights
\brief computes the tangent weight in 2D at `q` using the points `p0`, `p1`, and `p2`
\tparam Kernel a model of `Kernel`
*/
template<typename Kernel>
typename Kernel::FT tangent_weight(const CGAL::Point_2<Kernel>& p0,
const CGAL::Point_2<Kernel>& p1,
const CGAL::Point_2<Kernel>& p2,
const CGAL::Point_2<Kernel>& q)
{
const GeomTraits traits;
return tangent_weight(t, r, p, q, traits);
const Kernel traits;
return tangent_weight(p0, p1, p2, q, traits);
}
// 3D ==============================================================================================
/*!
\ingroup PkgWeightsRefTangentWeights
\brief computes the tangent weight in 3D at `q` using the points `p0`, `p1`, and `p2`
\tparam GeomTraits a model of `AnalyticWeightTraits_3`
*/
template<typename GeomTraits>
typename GeomTraits::FT tangent_weight(const typename GeomTraits::Point_3& t,
const typename GeomTraits::Point_3& r,
const typename GeomTraits::Point_3& p,
typename GeomTraits::FT tangent_weight(const typename GeomTraits::Point_3& p0,
const typename GeomTraits::Point_3& p1,
const typename GeomTraits::Point_3& p2,
const typename GeomTraits::Point_3& q,
const GeomTraits& traits)
{
// return tangent_ns::tangent_weight_v1(t, r, p, q, traits);
return tangent_ns::tangent_weight_v2(t, r, p, q, traits);
// return tangent_ns::tangent_weight_v1(p0, p1, p2, q, traits);
return tangent_ns::tangent_weight_v2(p0, p1, p2, q, traits);
}
template<typename GeomTraits>
typename GeomTraits::FT tangent_weight(const CGAL::Point_3<GeomTraits>& t,
const CGAL::Point_3<GeomTraits>& r,
const CGAL::Point_3<GeomTraits>& p,
const CGAL::Point_3<GeomTraits>& q)
/*!
\ingroup PkgWeightsRefTangentWeights
\brief computes the tangent weight in 3D at `q` using the points `p0`, `p1`, and `p2`
\tparam Kernel a model of `Kernel`
*/
template<typename Kernel>
typename Kernel::FT tangent_weight(const CGAL::Point_3<Kernel>& p0,
const CGAL::Point_3<Kernel>& p1,
const CGAL::Point_3<Kernel>& p2,
const CGAL::Point_3<Kernel>& q)
{
const GeomTraits traits;
return tangent_weight(t, r, p, q, traits);
const Kernel traits;
return tangent_weight(p0, p1, p2, q, traits);
}
// Undocumented tangent weight class.

View File

@ -26,90 +26,109 @@ namespace Weights {
namespace three_point_family_ns {
template<typename FT>
FT weight(const FT d1, const FT d2, const FT d,
const FT A1, const FT A2, const FT B,
FT weight(const FT d0, const FT d2, const FT d,
const FT A0, const FT A2, const FT B,
const FT p)
{
FT w = FT(0);
CGAL_precondition(!is_zero(A1) && !is_zero(A2));
const FT prod = A1 * A2;
CGAL_precondition(!is_zero(A0) && !is_zero(A2));
const FT prod = A0 * A2;
if (!is_zero(prod))
{
const FT r1 = internal::power(d1, p);
const FT r2 = internal::power(d2, p);
const FT r0 = internal::power(d0, p);
const FT r = internal::power(d , p);
const FT r2 = internal::power(d2, p);
w = (r2 * A1 - r * B + r1 * A2) / prod;
w = (r2 * A0 - r * B + r0 * A2) / prod;
}
return w;
}
} // namespace three_point_family_ns
/// \endcond
// 2D ==============================================================================================
/*!
\ingroup PkgWeightsRefThreePointFamilyWeights
\brief computes the three-point family weight in 2D at `q` using the points `p0`, `p1` and `p2`,
and the power parameter `a`.
\tparam GeomTraits a model of `AnalyticWeightTraits_2`
*/
template<typename GeomTraits>
typename GeomTraits::FT three_point_family_weight(const typename GeomTraits::Point_2& t,
const typename GeomTraits::Point_2& r,
const typename GeomTraits::Point_2& p,
typename GeomTraits::FT three_point_family_weight(const typename GeomTraits::Point_2& p0,
const typename GeomTraits::Point_2& p1,
const typename GeomTraits::Point_2& p2,
const typename GeomTraits::Point_2& q,
const typename GeomTraits::FT a,
const GeomTraits& traits)
{
using FT = typename GeomTraits::FT;
const FT d1 = internal::distance_2(traits, q, t);
const FT d2 = internal::distance_2(traits, q, r);
const FT d3 = internal::distance_2(traits, q, p);
auto area_2 = traits.compute_area_2_object();
const FT A1 = internal::area_2(traits, r, q, t);
const FT A2 = internal::area_2(traits, p, q, r);
const FT B = internal::area_2(traits, p, q, t);
const FT d0 = internal::distance_2(q, p0, traits);
const FT d = internal::distance_2(q, p1, traits);
const FT d2 = internal::distance_2(q, p2, traits);
return three_point_family_ns::weight(traits, d1, d2, d3, A1, A2, B, a);
const FT A0 = area_2(p1, q, p0);
const FT A2 = area_2(p2, q, p1);
const FT B = area_2(p2, q, p0);
return three_point_family_ns::weight(d0, d2, d, A0, A2, B, a);
}
template<typename GeomTraits>
typename GeomTraits::FT three_point_family_weight(const CGAL::Point_2<GeomTraits>& t,
const CGAL::Point_2<GeomTraits>& r,
const CGAL::Point_2<GeomTraits>& p,
const CGAL::Point_2<GeomTraits>& q,
const typename GeomTraits::FT a = typename GeomTraits::FT(1))
/*!
\ingroup PkgWeightsRefThreePointFamilyWeights
\brief computes the three-point family weight in 2D at `q` using the points `p0`, `p1` and `p2`,
and the power parameter `a`.
\tparam Kernel a model of `Kernel`
*/
template<typename Kernel>
typename Kernel::FT three_point_family_weight(const CGAL::Point_2<Kernel>& p0,
const CGAL::Point_2<Kernel>& p1,
const CGAL::Point_2<Kernel>& p2,
const CGAL::Point_2<Kernel>& q,
const typename Kernel::FT a = {1})
{
const GeomTraits traits;
return three_point_family_weight(t, r, p, q, a, traits);
const Kernel traits;
return three_point_family_weight(p0, p1, p2, q, a, traits);
}
namespace internal {
// 3D ==============================================================================================
/// \cond SKIP_IN_MANUAL
template<typename GeomTraits>
typename GeomTraits::FT three_point_family_weight(const typename GeomTraits::Point_3& t,
const typename GeomTraits::Point_3& r,
const typename GeomTraits::Point_3& p,
typename GeomTraits::FT three_point_family_weight(const typename GeomTraits::Point_3& p0,
const typename GeomTraits::Point_3& p1,
const typename GeomTraits::Point_3& p2,
const typename GeomTraits::Point_3& q,
const typename GeomTraits::FT a,
const GeomTraits& traits)
{
using Point_2 = typename GeomTraits::Point_2;
Point_2 tf, rf, pf, qf;
internal::flatten(traits,
t, r, p, q,
tf, rf, pf, qf);
return CGAL::Weights::three_point_family_weight(tf, rf, pf, qf, a, traits);
Point_2 p0f, p1f, p2f, qf;
internal::flatten(p0, p1, p2 , q,
p0f, p1f, p2f, qf,
traits);
return CGAL::Weights::three_point_family_weight(p0f, p1f, p2f, qf, a, traits);
}
template<typename GeomTraits>
typename GeomTraits::FT three_point_family_weight(const CGAL::Point_3<GeomTraits>& t,
const CGAL::Point_3<GeomTraits>& r,
const CGAL::Point_3<GeomTraits>& p,
const CGAL::Point_3<GeomTraits>& q,
const typename GeomTraits::FT a = typename GeomTraits::FT(1))
template<typename Kernel>
typename Kernel::FT three_point_family_weight(const CGAL::Point_3<Kernel>& p0,
const CGAL::Point_3<Kernel>& p1,
const CGAL::Point_3<Kernel>& p2,
const CGAL::Point_3<Kernel>& q,
const typename Kernel::FT a = {1})
{
const GeomTraits traits;
return three_point_family_weight(t, r, p, q, a, traits);
const Kernel traits;
return three_point_family_weight(p0, p1, p2, q, a, traits);
}
} // namespace internal
/// \endcond
} // namespace Weights

View File

@ -22,45 +22,66 @@
namespace CGAL {
namespace Weights {
/// \cond SKIP_IN_MANUAL
// 2D ==============================================================================================
/*!
\ingroup PkgWeightsRefTriangularRegionWeights
\brief computes the area of the triangular cell in 2D using the points `p`, `q`, and `r`
\tparam GeomTraits a model of `AnalyticWeightTraits_2`
*/
template<typename GeomTraits>
typename GeomTraits::FT triangular_area(const typename GeomTraits::Point_2& p,
const typename GeomTraits::Point_2& q,
const typename GeomTraits::Point_2& r,
const GeomTraits& traits)
{
return internal::positive_area_2(traits, p, q, r);
return internal::positive_area_2(p, q, r, traits);
}
template<typename GeomTraits>
typename GeomTraits::FT triangular_area(const CGAL::Point_2<GeomTraits>& p,
const CGAL::Point_2<GeomTraits>& q,
const CGAL::Point_2<GeomTraits>& r)
/*!
\ingroup PkgWeightsRefTriangularRegionWeights
\brief computes the area of the triangular cell in 2D using the points `p`, `q`, and `r`.
\tparam Kernel a model of `Kernel`
*/
template<typename Kernel>
typename Kernel::FT triangular_area(const CGAL::Point_2<Kernel>& p,
const CGAL::Point_2<Kernel>& q,
const CGAL::Point_2<Kernel>& r)
{
const GeomTraits traits;
const Kernel traits;
return triangular_area(p, q, r, traits);
}
// 3D ==============================================================================================
/*!
\ingroup PkgWeightsRefTriangularRegionWeights
\brief computes the area of the triangular cell in 3D using the points `p`, `q`, and `r`.
\tparam GeomTraits a model of `AnalyticWeightTraits_3`
*/
template<typename GeomTraits>
typename GeomTraits::FT triangular_area(const typename GeomTraits::Point_3& p,
const typename GeomTraits::Point_3& q,
const typename GeomTraits::Point_3& r,
const GeomTraits& traits)
{
return internal::positive_area_3(traits, p, q, r);
return internal::positive_area_3(p, q, r, traits);
}
template<typename GeomTraits>
typename GeomTraits::FT triangular_area(const CGAL::Point_3<GeomTraits>& p,
const CGAL::Point_3<GeomTraits>& q,
const CGAL::Point_3<GeomTraits>& r)
/*!
\ingroup PkgWeightsRefTriangularRegionWeights
\brief computes the area of the triangular cell in 3D using the points `p`, `q`, and `r`.
\tparam Kernel a model of `Kernel`
*/
template<typename Kernel>
typename Kernel::FT triangular_area(const CGAL::Point_3<Kernel>& p,
const CGAL::Point_3<Kernel>& q,
const CGAL::Point_3<Kernel>& r)
{
const GeomTraits traits;
const Kernel traits;
return triangular_area(p, q, r, traits);
}
/// \endcond
} // namespace Weights
} // namespace CGAL

View File

@ -20,7 +20,13 @@
namespace CGAL {
namespace Weights {
/// \cond SKIP_IN_MANUAL
// 2D ==============================================================================================
/*!
\ingroup PkgWeightsRefUniformRegionWeights
\brief this function always returns `1`, given three 2D points.
\tparam GeomTraits a model of `AnalyticWeightTraits_2`
*/
template<typename GeomTraits>
typename GeomTraits::FT uniform_area(const typename GeomTraits::Point_2&,
const typename GeomTraits::Point_2&,
@ -31,15 +37,27 @@ typename GeomTraits::FT uniform_area(const typename GeomTraits::Point_2&,
return FT(1);
}
template<typename GeomTraits>
typename GeomTraits::FT uniform_area(const CGAL::Point_2<GeomTraits>& p,
const CGAL::Point_2<GeomTraits>& q,
const CGAL::Point_2<GeomTraits>& r)
/*!
\ingroup PkgWeightsRefUniformRegionWeights
\brief this function always returns `1`, given three 2D points in 2D.
\tparam Kernel a model of `Kernel`
*/
template<typename Kernel>
typename Kernel::FT uniform_area(const CGAL::Point_2<Kernel>& p,
const CGAL::Point_2<Kernel>& q,
const CGAL::Point_2<Kernel>& r)
{
const GeomTraits traits;
const Kernel traits;
return uniform_area(p, q, r, traits);
}
// 3D ==============================================================================================
/*!
\ingroup PkgWeightsRefUniformRegionWeights
\brief this function always returns `1`, given three 3D points.
\tparam GeomTraits a model of `AnalyticWeightTraits_3`
*/
template<typename GeomTraits>
typename GeomTraits::FT uniform_area(const typename GeomTraits::Point_3&,
const typename GeomTraits::Point_3&,
@ -50,17 +68,20 @@ typename GeomTraits::FT uniform_area(const typename GeomTraits::Point_3&,
return FT(1);
}
template<typename GeomTraits>
typename GeomTraits::FT uniform_area(const CGAL::Point_3<GeomTraits>& p,
const CGAL::Point_3<GeomTraits>& q,
const CGAL::Point_3<GeomTraits>& r)
/*!
\ingroup PkgWeightsRefUniformRegionWeights
\brief this function always returns `1`, given three 3D points.
\tparam Kernel a model of `Kernel`
*/
template<typename Kernel>
typename Kernel::FT uniform_area(const CGAL::Point_3<Kernel>& p,
const CGAL::Point_3<Kernel>& q,
const CGAL::Point_3<Kernel>& r)
{
const GeomTraits traits;
const Kernel traits;
return uniform_area(p, q, r, traits);
}
/// \endcond
} // namespace Weights
} // namespace CGAL

View File

@ -22,51 +22,68 @@
namespace CGAL {
namespace Weights {
/// \cond SKIP_IN_MANUAL
template<typename GeomTraits>
typename GeomTraits::FT uniform_weight(
const typename GeomTraits::Point_2&,
const typename GeomTraits::Point_2&,
const typename GeomTraits::Point_2&,
const typename GeomTraits::Point_2&,
const GeomTraits&) {
// 2D ==============================================================================================
using FT = typename GeomTraits::FT;
return FT(1);
/*!
\ingroup PkgWeightsRefUniformWeights
\brief returns `1`.
\tparam GeomTraits a model of `AnalyticWeightTraits_2`
*/
template<typename GeomTraits>
typename GeomTraits::FT uniform_weight(const typename GeomTraits::Point_2&,
const typename GeomTraits::Point_2&,
const typename GeomTraits::Point_2&,
const typename GeomTraits::Point_2&,
const GeomTraits&)
{
return {1};
}
/*!
\ingroup PkgWeightsRefUniformWeights
\brief returns `1`.
\tparam Kernel a model of `Kernel`
*/
template<typename GeomTraits>
typename GeomTraits::FT uniform_weight(
const CGAL::Point_2<GeomTraits>& q,
const CGAL::Point_2<GeomTraits>& t,
const CGAL::Point_2<GeomTraits>& r,
const CGAL::Point_2<GeomTraits>& p) {
typename GeomTraits::FT uniform_weight(const CGAL::Point_2<GeomTraits>& p0,
const CGAL::Point_2<GeomTraits>& p1,
const CGAL::Point_2<GeomTraits>& p2,
const CGAL::Point_2<GeomTraits>& q)
{
const GeomTraits traits;
return uniform_weight(q, t, r, p, traits);
return uniform_weight(p0, p1, p2, q, traits);
}
template<typename GeomTraits>
typename GeomTraits::FT uniform_weight(
const typename GeomTraits::Point_3&,
const typename GeomTraits::Point_3&,
const typename GeomTraits::Point_3&,
const typename GeomTraits::Point_3&,
const GeomTraits&) {
// 3D ==============================================================================================
using FT = typename GeomTraits::FT;
return FT(1);
/*!
\ingroup PkgWeightsRefUniformWeights
\brief returns `1`.
\tparam GeomTraits a model of `AnalyticWeightTraits_2`
*/
template<typename GeomTraits>
typename GeomTraits::FT uniform_weight(const typename GeomTraits::Point_3&,
const typename GeomTraits::Point_3&,
const typename GeomTraits::Point_3&,
const typename GeomTraits::Point_3&,
const GeomTraits&)
{
return {1};
}
/*!
\ingroup PkgWeightsRefUniformWeights
\brief returns `1`.
\tparam Kernel a model of `Kernel`
*/
template<typename GeomTraits>
typename GeomTraits::FT uniform_weight(
const CGAL::Point_3<GeomTraits>& q,
const CGAL::Point_3<GeomTraits>& t,
const CGAL::Point_3<GeomTraits>& r,
const CGAL::Point_3<GeomTraits>& p) {
typename GeomTraits::FT uniform_weight(const CGAL::Point_3<GeomTraits>& p0,
const CGAL::Point_3<GeomTraits>& p1,
const CGAL::Point_3<GeomTraits>& p2,
const CGAL::Point_3<GeomTraits>& q)
{
const GeomTraits traits;
return uniform_weight(q, t, r, p, traits);
return uniform_weight(p0, p1, p2, q, traits);
}
// Undocumented uniform weight class taking as input a polygon mesh.
@ -85,8 +102,6 @@ public:
double w_ij(halfedge_descriptor) { return 1.; }
};
/// \endcond
} // namespace Weights
} // namespace CGAL

View File

@ -214,6 +214,11 @@ typename Kernel::FT tangent(const CGAL::Point_3<Kernel>& p,
return tangent(p, q, r, traits);
}
// =================================================================================================
// Computes a clamped cotangent between two 3D vectors.
// In the old version of weights in PMP, it was called "Cotangent_value_Meyer_secure".
// See Weights/internal/pmp_weights_deprecated.h for more information.
template<typename GeomTraits>
typename GeomTraits::FT cotangent_3_clamped(const typename GeomTraits::Point_3& p,
const typename GeomTraits::Point_3& q,

View File

@ -22,7 +22,13 @@
namespace CGAL {
namespace Weights {
/// \cond SKIP_IN_MANUAL
// 2D ==============================================================================================
/*!
\ingroup PkgWeightsRefVoronoiRegionWeights
\brief computes the area of the Voronoi cell in 2D using the points `p`, `q`, and `r`.
\tparam GeomTraits a model of `AnalyticWeightTraits_2`
*/
template<typename GeomTraits>
typename GeomTraits::FT voronoi_area(const typename GeomTraits::Point_2& p,
const typename GeomTraits::Point_2& q,
@ -39,20 +45,33 @@ typename GeomTraits::FT voronoi_area(const typename GeomTraits::Point_2& p,
const Point_2 m1 = midpoint_2(q, r);
const Point_2 m2 = midpoint_2(q, p);
const FT A1 = internal::positive_area_2(traits, q, m1, center);
const FT A2 = internal::positive_area_2(traits, q, center, m2);
const FT A1 = internal::positive_area_2(q, m1, center,traits);
const FT A2 = internal::positive_area_2(q, center, m2, traits);
return A1 + A2;
}
template<typename GeomTraits>
typename GeomTraits::FT voronoi_area(const CGAL::Point_2<GeomTraits>& p,
const CGAL::Point_2<GeomTraits>& q,
const CGAL::Point_2<GeomTraits>& r)
/*!
\ingroup PkgWeightsRefVoronoiRegionWeights
\brief computes the area of the Voronoi cell in 2D using the points `p`, `q`, and `r`.
\tparam Kernel a model of `Kernel`
*/
template<typename Kernel>
typename Kernel::FT voronoi_area(const CGAL::Point_2<Kernel>& p,
const CGAL::Point_2<Kernel>& q,
const CGAL::Point_2<Kernel>& r)
{
const GeomTraits traits;
const Kernel traits;
return voronoi_area(p, q, r, traits);
}
// 3D ==============================================================================================
/*!
\ingroup PkgWeightsRefVoronoiRegionWeights
\brief computes the area of the Voronoi cell in 3D using the points `p`, `q`, and `r`
\tparam GeomTraits a model of `AnalyticWeightTraits_3`.
*/
template<typename GeomTraits>
typename GeomTraits::FT voronoi_area(const typename GeomTraits::Point_3& p,
const typename GeomTraits::Point_3& q,
@ -69,22 +88,26 @@ typename GeomTraits::FT voronoi_area(const typename GeomTraits::Point_3& p,
const Point_3 m1 = midpoint_3(q, r);
const Point_3 m2 = midpoint_3(q, p);
const FT A1 = internal::positive_area_3(traits, q, m1, center);
const FT A2 = internal::positive_area_3(traits, q, center, m2);
const FT A1 = internal::positive_area_3(q, m1, center, traits);
const FT A2 = internal::positive_area_3(q, center, m2, traits);
return A1 + A2;
}
template<typename GeomTraits>
typename GeomTraits::FT voronoi_area(const CGAL::Point_3<GeomTraits>& p,
const CGAL::Point_3<GeomTraits>& q,
const CGAL::Point_3<GeomTraits>& r)
/*!
\ingroup PkgWeightsRefVoronoiRegionWeights
\brief computes the area of the Voronoi cell in 3D using the points `p`, `q`, and `r`.
\tparam Kernel a model of `Kernel`
*/
template<typename Kernel>
typename Kernel::FT voronoi_area(const CGAL::Point_3<Kernel>& p,
const CGAL::Point_3<Kernel>& q,
const CGAL::Point_3<Kernel>& r)
{
const GeomTraits traits;
const Kernel traits;
return voronoi_area(p, q, r, traits);
}
/// \endcond
} // namespace Weights
} // namespace CGAL

View File

@ -31,75 +31,92 @@ namespace Weights {
namespace wachspress_ns {
template<typename FT>
FT weight(const FT A1, const FT A2, const FT C)
FT weight(const FT A0, const FT A2, const FT C)
{
FT w = FT(0);
CGAL_precondition(A1 != FT(0) && A2 != FT(0));
const FT prod = A1 * A2;
if (prod != FT(0))
{
const FT inv = FT(1) / prod;
w = C * inv;
}
CGAL_precondition(!is_zero(A0) && !is_zero(A2));
const FT prod = A0 * A2;
if (!is_zero(prod))
w = C / prod;
return w;
}
} // wachspress_ns
} // namespace wachspress_ns
/// \endcond
// 2D ==============================================================================================
/*!
\ingroup PkgWeightsRefWachspressWeights
\brief computes the Wachspress weight in 2D at `q` using the points `p0`, `p1`, and `p2`.
\tparam GeomTraits a model of `AnalyticWeightTraits_2`
*/
template<typename GeomTraits>
typename GeomTraits::FT wachspress_weight(const typename GeomTraits::Point_2& t,
const typename GeomTraits::Point_2& r,
const typename GeomTraits::Point_2& p,
typename GeomTraits::FT wachspress_weight(const typename GeomTraits::Point_2& p0,
const typename GeomTraits::Point_2& p1,
const typename GeomTraits::Point_2& p2,
const typename GeomTraits::Point_2& q,
const GeomTraits& traits)
{
using FT = typename GeomTraits::FT;
const FT A1 = internal::area_2(traits, r, q, t);
const FT A2 = internal::area_2(traits, p, q, r);
const FT C = internal::area_2(traits, t, r, p);
return wachspress_ns::weight(A1, A2, C);
auto area_2 = traits.compute_area_2_object();
const FT A0 = area_2(p1, q, p0);
const FT A2 = area_2(p2, q, p1);
const FT C = area_2(p0, p1, p2);
return wachspress_ns::weight(A0, A2, C);
}
template<typename GeomTraits>
typename GeomTraits::FT wachspress_weight(const CGAL::Point_2<GeomTraits>& t,
const CGAL::Point_2<GeomTraits>& r,
const CGAL::Point_2<GeomTraits>& p,
const CGAL::Point_2<GeomTraits>& q)
/*!
\ingroup PkgWeightsRefWachspressWeights
\brief computes the Wachspress weight in 2D at `q` using the points `p0`, `p1`, and `p2`.
\tparam Kernel a model of `Kernel`
*/
template<typename Kernel>
typename Kernel::FT wachspress_weight(const CGAL::Point_2<Kernel>& p0,
const CGAL::Point_2<Kernel>& p1,
const CGAL::Point_2<Kernel>& p2,
const CGAL::Point_2<Kernel>& q)
{
const GeomTraits traits;
return wachspress_weight(t, r, p, q, traits);
const Kernel traits;
return wachspress_weight(p0, p1, p2, q, traits);
}
namespace internal {
// 3D ==============================================================================================
/// \cond SKIP_IN_MANUAL
template<typename GeomTraits>
typename GeomTraits::FT wachspress_weight(const typename GeomTraits::Point_3& t,
const typename GeomTraits::Point_3& r,
const typename GeomTraits::Point_3& p,
typename GeomTraits::FT wachspress_weight(const typename GeomTraits::Point_3& p0,
const typename GeomTraits::Point_3& p1,
const typename GeomTraits::Point_3& p2,
const typename GeomTraits::Point_3& q,
const GeomTraits& traits)
{
using Point_2 = typename GeomTraits::Point_2;
Point_2 tf, rf, pf, qf;
internal::flatten(traits,
t, r, p, q,
tf, rf, pf, qf);
return CGAL::Weights::wachspress_weight(tf, rf, pf, qf, traits);
Point_2 p0f, p1f, p2f, qf;
internal::flatten(p0, p1, p2, q,
p0f, p1f, p2f, qf,
traits);
return CGAL::Weights::wachspress_weight(p0f, p1f, p2f, qf, traits);
}
template<typename GeomTraits>
typename GeomTraits::FT wachspress_weight(const CGAL::Point_3<GeomTraits>& t,
const CGAL::Point_3<GeomTraits>& r,
const CGAL::Point_3<GeomTraits>& p,
const CGAL::Point_3<GeomTraits>& q)
template<typename Kernel>
typename Kernel::FT wachspress_weight(const CGAL::Point_3<Kernel>& p0,
const CGAL::Point_3<Kernel>& p1,
const CGAL::Point_3<Kernel>& p2,
const CGAL::Point_3<Kernel>& q)
{
const GeomTraits traits;
return wachspress_weight(t, r, p, q, traits);
const Kernel traits;
return wachspress_weight(p0, p1, p2, q, traits);
}
} // namespace internal
/// \endcond
/*!
@ -164,9 +181,9 @@ public:
\param point_map an instance of `PointMap` that maps a vertex from `polygon` to `Point_2`;
the default initialization is provided
\pre polygon.size() >= 3
\pre polygon is simple
\pre polygon is strictly convex
\pre `polygon.size() >= 3`
\pre `polygon` is simple
\pre `polygon` is strictly convex
*/
Wachspress_weights_2(const VertexRange& polygon,
const GeomTraits traits = GeomTraits(),
@ -331,9 +348,9 @@ private:
\return an output iterator to the element in the destination range, one past the last weight stored
\pre polygon.size() >= 3
\pre polygon is simple
\pre polygon is strictly convex
\pre `polygon.size() >= 3`
\pre `polygon` is simple
\pre `polygon` is strictly convex
*/
template<typename PointRange,
typename OutIterator,