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 \endverbatim
This weight is computed as 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 with notations shown in the figure below and \f$a\f$ any real number
being the power parameter. being the power parameter.
@ -142,7 +142,7 @@ a model of `AnalyticWeightTraits_3` for 3D points
\endverbatim \endverbatim
This weight is computed as 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. with notations shown in the figure below.
Here, `q` is a query point and the points `p0`, `p1`, and `p2` are its neighbors. 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 \endverbatim
This weight is computed as 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 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_2 = (p_1 - q) \cdot (p_2 - q)\f$, and
\f$D = (p_0 - q) \cdot (p_2 - q)\f$. \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 This weight is computed as
\f$w = 2 \frac{t_1 + t_2}{d}\f$, where \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$ \f$t_2 = \frac{2 A_2}{d d_2 + D_2}\f$
with notations shown in the figure below and dot products 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$. \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. 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 \endverbatim
This weight is computed as 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. with notations shown in the figure below.
Here, `q` is a query point and the points `p0`, `p1`, and `p2` are its neighbors. 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. \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 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` \tparam FT a model of `FieldNumberType`
\param cot the cotangent value \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()` \sa `authalic_weight()`
*/ */
template<typename FT> 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> template<typename GeomTraits>
typename GeomTraits::FT authalic_weight(const typename GeomTraits::Point_2& t, typename GeomTraits::FT authalic_weight(const typename GeomTraits::Point_2& p0,
const typename GeomTraits::Point_2& r, const typename GeomTraits::Point_2& p1,
const typename GeomTraits::Point_2& p, const typename GeomTraits::Point_2& p2,
const typename GeomTraits::Point_2& q, const typename GeomTraits::Point_2& q,
const GeomTraits& traits) const GeomTraits& traits)
{ {
using FT = typename GeomTraits::FT; 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(); 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); return authalic_ns::weight(cot_gamma, cot_beta, sq_d);
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);
} }
template<typename GeomTraits> /*!
typename GeomTraits::FT authalic_weight(const CGAL::Point_2<GeomTraits>& t, \ingroup PkgWeightsRefAuthalicWeights
const CGAL::Point_2<GeomTraits>& r, \brief computes the authalic weight in 2D at `q` using the points `p0`, `p1`, and `p2`.
const CGAL::Point_2<GeomTraits>& p, \tparam Kernel a model of `Kernel`
const CGAL::Point_2<GeomTraits>& q) */
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; const Kernel traits;
return authalic_weight(t, r, p, q, 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> template<typename GeomTraits>
typename GeomTraits::FT authalic_weight(const typename GeomTraits::Point_3& t, typename GeomTraits::FT authalic_weight(const typename GeomTraits::Point_3& p0,
const typename GeomTraits::Point_3& r, const typename GeomTraits::Point_3& p1,
const typename GeomTraits::Point_3& p, const typename GeomTraits::Point_3& p2,
const typename GeomTraits::Point_3& q, const typename GeomTraits::Point_3& q,
const GeomTraits& traits) const GeomTraits& traits)
{ {
using FT = typename GeomTraits::FT; 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(); 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); return authalic_ns::weight(cot_gamma, cot_beta, sq_d);
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);
} }
template<typename GeomTraits> /*!
typename GeomTraits::FT authalic_weight(const CGAL::Point_3<GeomTraits>& t, \ingroup PkgWeightsRefAuthalicWeights
const CGAL::Point_3<GeomTraits>& r, \brief computes the authalic weight in 3D at `q` using the points `p0`, `p1`, and `p2`.
const CGAL::Point_3<GeomTraits>& p, \tparam Kernel a model of `Kernel`
const CGAL::Point_3<GeomTraits>& q) */
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; const Kernel traits;
return authalic_weight(t, r, p, q, traits); return authalic_weight(p0, p1, p2, q, traits);
} }
} // namespace Weights } // namespace Weights

View File

@ -22,6 +22,13 @@
namespace CGAL { namespace CGAL {
namespace Weights { 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> template<typename GeomTraits>
typename GeomTraits::FT barycentric_area(const typename GeomTraits::Point_2& p, typename GeomTraits::FT barycentric_area(const typename GeomTraits::Point_2& p,
const typename GeomTraits::Point_2& q, 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 m1 = midpoint_2(q, r);
const Point_2 m2 = midpoint_2(q, p); const Point_2 m2 = midpoint_2(q, p);
const FT A1 = internal::positive_area_2(traits, q, m1, center); const FT A1 = internal::positive_area_2(q, m1, center, traits);
const FT A2 = internal::positive_area_2(traits, q, center, m2); const FT A2 = internal::positive_area_2(q, center, m2, traits);
return A1 + A2; return A1 + A2;
} }
template<typename GeomTraits> /*!
typename GeomTraits::FT barycentric_area(const CGAL::Point_2<GeomTraits>& p, \ingroup PkgWeightsRefBarycentricRegionWeights
const CGAL::Point_2<GeomTraits>& q, \brief computes the area of the barycentric cell in 2D using the points `p`, `q`, and `r`.
const CGAL::Point_2<GeomTraits>& 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); 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> template<typename GeomTraits>
typename GeomTraits::FT barycentric_area(const typename GeomTraits::Point_3& p, typename GeomTraits::FT barycentric_area(const typename GeomTraits::Point_3& p,
const typename GeomTraits::Point_3& q, 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 m1 = midpoint_3(q, r);
const Point_3 m2 = midpoint_3(q, p); const Point_3 m2 = midpoint_3(q, p);
const FT A1 = internal::positive_area_3(traits, q, m1, center); const FT A1 = internal::positive_area_3(q, m1, center, traits);
const FT A2 = internal::positive_area_3(traits, q, center, m2); const FT A2 = internal::positive_area_3(q, center, m2, traits);
return A1 + A2; return A1 + A2;
} }
template<typename GeomTraits> /*!
typename GeomTraits::FT barycentric_area(const CGAL::Point_3<GeomTraits>& p, \ingroup PkgWeightsRefBarycentricRegionWeights
const CGAL::Point_3<GeomTraits>& q, \brief computes the area of the barycentric cell in 3D using the points `p`, `q`, and `r`.
const CGAL::Point_3<GeomTraits>& 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); 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); 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> template<typename GeomTraits>
typename GeomTraits::FT cotangent_weight(const typename GeomTraits::Point_2& t, typename GeomTraits::FT cotangent_weight(const typename GeomTraits::Point_2& p0,
const typename GeomTraits::Point_2& r, const typename GeomTraits::Point_2& p1,
const typename GeomTraits::Point_2& p, const typename GeomTraits::Point_2& p2,
const typename GeomTraits::Point_2& q, const typename GeomTraits::Point_2& q,
const GeomTraits& traits) const GeomTraits& traits)
{ {
using FT = typename GeomTraits::FT; using FT = typename GeomTraits::FT;
const FT cot_beta = internal::cotangent_2(traits, q, t, r); const FT cot_beta = cotangent_2(q, p0, p1, traits);
const FT cot_gamma = internal::cotangent_2(traits, r, p, q); const FT cot_gamma = cotangent_2(p1, p2, q, traits);
return cotangent_ns::weight(cot_beta, cot_gamma); return cotangent_ns::weight(cot_beta, cot_gamma);
} }
template<typename GeomTraits> /*!
typename GeomTraits::FT cotangent_weight(const CGAL::Point_2<GeomTraits>& t, \ingroup PkgWeightsRefCotangentWeights
const CGAL::Point_2<GeomTraits>& r, \brief computes the cotangent weight in 2D at `q` using the points `p0`, `p1`, and `p2`.
const CGAL::Point_2<GeomTraits>& p, \tparam Kernel a model of `Kernel`
const CGAL::Point_2<GeomTraits>& q) */
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; Kernel traits;
return cotangent_weight(t, r, p, q, 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> template<typename GeomTraits>
typename GeomTraits::FT cotangent_weight(const typename GeomTraits::Point_3& t, typename GeomTraits::FT cotangent_weight(const typename GeomTraits::Point_3& p0,
const typename GeomTraits::Point_3& r, const typename GeomTraits::Point_3& p1,
const typename GeomTraits::Point_3& p, const typename GeomTraits::Point_3& p2,
const typename GeomTraits::Point_3& q, const typename GeomTraits::Point_3& q,
const GeomTraits& traits) const GeomTraits& traits)
{ {
using FT = typename GeomTraits::FT; using FT = typename GeomTraits::FT;
const FT cot_beta = internal::cotangent_3(traits, q, t, r); const FT cot_beta = cotangent_3(q, p0, p1, traits);
const FT cot_gamma = internal::cotangent_3(traits, r, p, q); const FT cot_gamma = cotangent_3(p1, p2, q, traits);
return cotangent_ns::weight(cot_beta, cot_gamma); return cotangent_ns::weight(cot_beta, cot_gamma);
} }
template<typename GeomTraits> /*!
typename GeomTraits::FT cotangent_weight(const CGAL::Point_3<GeomTraits>& t, \ingroup PkgWeightsRefCotangentWeights
const CGAL::Point_3<GeomTraits>& r, \brief computes the cotangent weight in 3D at `q` using the points `p0`, `p1`, and `p2`.
const CGAL::Point_3<GeomTraits>& p, \tparam Kernel a model of `Kernel`
const CGAL::Point_3<GeomTraits>& q) */
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; Kernel traits;
return cotangent_weight(t, r, p, q, traits); return cotangent_weight(p0, p1, p2, q, traits);
} }
/// \cond SKIP_IN_MANUAL
// Undocumented cotangent weight class. // Undocumented cotangent weight class.
//
// Its constructor takes a polygon mesh and a vertex to point map // Its constructor takes a polygon mesh and a vertex to point map
// and its operator() is defined based on the halfedge_descriptor only. // and its operator() is defined based on the halfedge_descriptor only.
// This version is currently used in: // This version is currently used in:
@ -219,6 +244,7 @@ public:
}; };
// Undocumented cotangent weight class. // Undocumented cotangent weight class.
//
// Its constructor takes a boolean flag to choose between default and clamped // 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 // versions of the cotangent weights and its operator() is defined based on the
// halfedge_descriptor, polygon mesh, and vertex to point map. // halfedge_descriptor, polygon mesh, and vertex to point map.
@ -460,6 +486,8 @@ private:
} }
}; };
/// \endcond
} // namespace Weights } // namespace Weights
} // namespace CGAL } // namespace CGAL

View File

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

View File

@ -38,29 +38,53 @@ FT weight(const FT d)
} // namespace inverse_distance_ns } // 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> template<typename GeomTraits>
typename GeomTraits::FT inverse_distance_weight(const typename GeomTraits::Point_2&, 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&,
const typename GeomTraits::Point_2& q, const typename GeomTraits::Point_2& q,
const GeomTraits& traits) const GeomTraits& traits)
{ {
using FT = typename GeomTraits::FT; 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); return inverse_distance_ns::weight(d);
} }
template<typename GeomTraits> /*!
typename GeomTraits::FT inverse_distance_weight(const CGAL::Point_2<GeomTraits>& t, \ingroup PkgWeightsRefInverseDistanceWeights
const CGAL::Point_2<GeomTraits>& r, \brief computes the inverse distance weight in 2D using the points `p` and `q`.
const CGAL::Point_2<GeomTraits>& p, \tparam Kernel a model of `Kernel`
const CGAL::Point_2<GeomTraits>& q) */
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; const Kernel traits;
return inverse_distance_weight(t, r, p, q, 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> template<typename GeomTraits>
typename GeomTraits::FT inverse_distance_weight(const typename GeomTraits::Point_2& p, typename GeomTraits::FT inverse_distance_weight(const typename GeomTraits::Point_2& p,
const typename GeomTraits::Point_2& q, 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); return inverse_distance_weight(stub, p, stub, q, traits);
} }
template<typename GeomTraits> /*!
typename GeomTraits::FT inverse_distance_weight(const CGAL::Point_2<GeomTraits>& p, \ingroup PkgWeightsRefInverseDistanceWeights
const CGAL::Point_2<GeomTraits>& q) \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); 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> template<typename GeomTraits>
typename GeomTraits::FT inverse_distance_weight(const typename GeomTraits::Point_3&, 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&,
const typename GeomTraits::Point_3& q, const typename GeomTraits::Point_3& q,
const GeomTraits& traits) const GeomTraits& traits)
{ {
using FT = typename GeomTraits::FT; 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); return inverse_distance_ns::weight(d);
} }
template<typename GeomTraits> /*!
typename GeomTraits::FT inverse_distance_weight(const CGAL::Point_3<GeomTraits>& t, \ingroup PkgWeightsRefInverseDistanceWeights
const CGAL::Point_3<GeomTraits>& r, \brief computes the inverse distance weight in 3D using the points `p` and `q`.
const CGAL::Point_3<GeomTraits>& p, \tparam Kernel a model of `Kernel`
const CGAL::Point_3<GeomTraits>& q) */
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; const Kernel traits;
return inverse_distance_weight(t, r, p, q, 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> template<typename GeomTraits>
typename GeomTraits::FT inverse_distance_weight(const typename GeomTraits::Point_3& p, typename GeomTraits::FT inverse_distance_weight(const typename GeomTraits::Point_3& p,
const typename GeomTraits::Point_3& q, 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); return inverse_distance_weight(stub, p, stub, q, traits);
} }
template<typename GeomTraits> /*!
typename GeomTraits::FT inverse_distance_weight(const CGAL::Point_3<GeomTraits>& p, \ingroup PkgWeightsRefInverseDistanceWeights
const CGAL::Point_3<GeomTraits>& q) \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); return inverse_distance_weight(stub, p, stub, q);
} }
/// \endcond
} // namespace Weights } // namespace Weights
} // namespace CGAL } // namespace CGAL

View File

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

View File

@ -22,7 +22,13 @@
namespace CGAL { namespace CGAL {
namespace Weights { 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> template<typename GeomTraits>
typename GeomTraits::FT mixed_voronoi_area(const typename GeomTraits::Point_2& p, typename GeomTraits::FT mixed_voronoi_area(const typename GeomTraits::Point_2& p,
const typename GeomTraits::Point_2& q, 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 m1 = midpoint_2(q, r);
const Point_2 m2 = midpoint_2(q, p); const Point_2 m2 = midpoint_2(q, p);
const FT A1 = internal::positive_area_2(traits, q, m1, center); const FT A1 = internal::positive_area_2(q, m1, center, traits);
const FT A2 = internal::positive_area_2(traits, q, center, m2); const FT A2 = internal::positive_area_2(q, center, m2, traits);
return A1 + A2; 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> template<typename GeomTraits>
typename GeomTraits::FT mixed_voronoi_area(const CGAL::Point_2<GeomTraits>& p, typename GeomTraits::FT mixed_voronoi_area(const CGAL::Point_2<GeomTraits>& p,
const CGAL::Point_2<GeomTraits>& q, 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); 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> template<typename GeomTraits>
typename GeomTraits::FT mixed_voronoi_area(const typename GeomTraits::Point_3& p, typename GeomTraits::FT mixed_voronoi_area(const typename GeomTraits::Point_3& p,
const typename GeomTraits::Point_3& q, 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 m1 = midpoint_3(q, r);
const Point_3 m2 = midpoint_3(q, p); const Point_3 m2 = midpoint_3(q, p);
const FT A1 = internal::positive_area_3(traits, q, m1, center); const FT A1 = internal::positive_area_3(q, m1, center, traits);
const FT A2 = internal::positive_area_3(traits, q, center, m2); const FT A2 = internal::positive_area_3(q, center, m2, traits);
return A1 + A2; return A1 + A2;
} }
template<typename GeomTraits> /*!
typename GeomTraits::FT mixed_voronoi_area(const CGAL::Point_3<GeomTraits>& p, \ingroup PkgWeightsRefMixedVoronoiRegionWeights
const CGAL::Point_3<GeomTraits>& q, \brief computes the area of the mixed Voronoi cell in 3D using the points `p`, `q`, and `r`.
const CGAL::Point_3<GeomTraits>& 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); return mixed_voronoi_area(p, q, r, traits);
} }
/// \endcond
} // namespace Weights } // namespace Weights
} // namespace CGAL } // namespace CGAL

View File

@ -26,13 +26,9 @@ namespace Weights {
namespace shepard_ns { namespace shepard_ns {
template<typename GeomTraits> template<typename FT>
typename GeomTraits::FT weight(const GeomTraits& traits, FT weight(const FT d, const FT p)
const typename GeomTraits::FT d,
const typename GeomTraits::FT p)
{ {
using FT = typename GeomTraits::FT;
FT w = FT(0); FT w = FT(0);
CGAL_precondition(is_positive(d)); CGAL_precondition(is_positive(d));
if(is_positive(d)) if(is_positive(d))
@ -43,31 +39,57 @@ typename GeomTraits::FT weight(const GeomTraits& traits,
} // namespace shepard_ns } // 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> template<typename GeomTraits>
typename GeomTraits::FT shepard_weight(const typename GeomTraits::Point_2&, 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&,
const typename GeomTraits::Point_2& q, const typename GeomTraits::Point_2& q,
const typename GeomTraits::FT a, const typename GeomTraits::FT a,
const GeomTraits& traits) const GeomTraits& traits)
{ {
using FT = typename GeomTraits::FT; using FT = typename GeomTraits::FT;
const FT d = internal::distance_2(p, q, traits);
const FT d = internal::distance_2(traits, q, r); return shepard_ns::weight(d, a);
return shepard_ns::weight(traits, d, a);
} }
template<typename GeomTraits> /*!
typename GeomTraits::FT shepard_weight(const CGAL::Point_2<GeomTraits>& t, \ingroup PkgWeightsRefShepardWeights
const CGAL::Point_2<GeomTraits>& r, \brief computes the Shepard weight in 2D using the points `p` and `q`, and the power parameter `a`
const CGAL::Point_2<GeomTraits>& p, \tparam Kernel a model of `Kernel`
const CGAL::Point_2<GeomTraits>& q, */
const typename GeomTraits::FT a = typename GeomTraits::FT(1)) 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; const Kernel traits;
return shepard_weight(t, r, p, q, a, 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> template<typename GeomTraits>
typename GeomTraits::FT shepard_weight(const typename GeomTraits::Point_2& p, typename GeomTraits::FT shepard_weight(const typename GeomTraits::Point_2& p,
const typename GeomTraits::Point_2& q, 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); return shepard_weight(stub, p, stub, q, a, traits);
} }
template<typename GeomTraits> /*!
typename GeomTraits::FT shepard_weight(const CGAL::Point_2<GeomTraits>& p, \ingroup PkgWeightsRefShepardWeights
const CGAL::Point_2<GeomTraits>& q, \brief computes the Shepard weight in 2D using the points `p` and `q`, and the power parameter `a`.
const typename GeomTraits::FT a = typename GeomTraits::FT(1)) \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); 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> template<typename GeomTraits>
typename GeomTraits::FT shepard_weight(const typename GeomTraits::Point_3&, 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&,
const typename GeomTraits::Point_3& q, const typename GeomTraits::Point_3& q,
const typename GeomTraits::FT a, const typename GeomTraits::FT a,
const GeomTraits& traits) const GeomTraits& traits)
{ {
using FT = typename GeomTraits::FT; using FT = typename GeomTraits::FT;
const FT d = internal::distance_3(traits, q, r); const FT d = internal::distance_3(p, q, traits);
return shepard_ns::weight(traits, d, a); return shepard_ns::weight(d, a);
} }
template<typename GeomTraits> /*!
typename GeomTraits::FT shepard_weight(const CGAL::Point_3<GeomTraits>& t, \ingroup PkgWeightsRefShepardWeights
const CGAL::Point_3<GeomTraits>& r, \brief computes the Shepard weight in 3D using the points `p` and `q`, and the power parameter `a`.
const CGAL::Point_3<GeomTraits>& p, \tparam Kernel a model of `Kernel`
const CGAL::Point_3<GeomTraits>& q, */
const typename GeomTraits::FT a = typename GeomTraits::FT(1)) 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; const Kernel traits;
return shepard_weight(t, r, p, q, a, 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> template<typename GeomTraits>
typename GeomTraits::FT shepard_weight(const typename GeomTraits::Point_3& p, typename GeomTraits::FT shepard_weight(const typename GeomTraits::Point_3& p,
const typename GeomTraits::Point_3& q, 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); return shepard_weight(stub, p, stub, q, a, traits);
} }
template<typename GeomTraits> /*!
typename GeomTraits::FT shepard_weight(const CGAL::Point_3<GeomTraits>& p, \ingroup PkgWeightsRefShepardWeights
const CGAL::Point_3<GeomTraits>& q, \brief computes the Shepard weight in 3D using the points `p` and `q`, and the power parameter `a`.
const typename GeomTraits::FT a = typename GeomTraits::FT(1)) \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); return shepard_weight(stub, p, stub, q, a);
} }
/// \endcond
} // namespace Weights } // namespace Weights
} // namespace CGAL } // namespace CGAL

View File

@ -40,32 +40,33 @@ FT half_weight(const FT t, const FT r)
} }
template<typename FT> 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); FT w = FT(0);
CGAL_precondition(r != FT(0)); CGAL_precondition(r != FT(0));
if (r != FT(0)) if (r != FT(0))
w = FT(2) * (t1 + t2) / r; w = FT(2) * (t0 + t2) / r;
return w; return w;
} }
template<typename FT> template<typename FT>
FT weight(const FT d1, const FT d, const FT d2, FT weight(const FT d0, const FT d2, const FT d,
const FT A1, const FT A2, const FT A0, const FT A2,
const FT D1, const FT D2) const FT D0, const FT D2)
{ {
const FT P1 = d1 * d + D1; const FT P0 = d * d0 + D0;
const FT P2 = d2 * d + D2; const FT P2 = d * d2 + D2;
FT w = FT(0); FT w = FT(0);
CGAL_precondition(!is_zero(P1) && !is_zero(P2)); CGAL_precondition(!is_zero(P0) && !is_zero(P2));
if (!is_zero(P1) && !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; const FT t2 = FT(2) * A2 / P2;
w = weight(t1, t2, d); w = weight(t0, t2, d);
} }
return w; 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 based on the positive area.
// This version is more precise for all positive cases. // This version is more precise for all positive cases.
template<typename GeomTraits> template<typename GeomTraits>
typename GeomTraits::FT tangent_weight_v1(const typename GeomTraits::Point_3& t, typename GeomTraits::FT tangent_weight_v1(const typename GeomTraits::Point_3& p0,
const typename GeomTraits::Point_3& r, const typename GeomTraits::Point_3& p1,
const typename GeomTraits::Point_3& p, const typename GeomTraits::Point_3& p2,
const typename GeomTraits::Point_3& q, const typename GeomTraits::Point_3& q,
const GeomTraits& traits) 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; using Vector_3 = typename GeomTraits::Vector_3;
auto dot_product_3 = traits.compute_scalar_product_3_object(); 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 v0 = vector_3(q, p0);
const Vector_3 v2 = construct_vector_3(q, r); const Vector_3 v = vector_3(q, p1);
const Vector_3 v3 = construct_vector_3(q, p); const Vector_3 v2 = vector_3(q, p2);
const FT l1 = internal::length_3(traits, v1); const FT d0 = internal::length_3(v0, traits);
const FT l2 = internal::length_3(traits, v2); const FT d = internal::length_3(v, traits);
const FT l3 = internal::length_3(traits, v3); const FT d2 = internal::length_3(v2, traits);
const FT A1 = internal::positive_area_3(traits, r, q, t); const FT A0 = internal::positive_area_3(p1, q, p0, traits);
const FT A2 = internal::positive_area_3(traits, p, q, r); const FT A2 = internal::positive_area_3(p2, q, p1, traits);
const FT D1 = dot_product_3(v1, v2); const FT D0 = dot_product_3(v0, v);
const FT D2 = dot_product_3(v2, v3); 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. // This version handles both positive and negative cases.
// However, it is less precise. // However, it is less precise.
template<typename GeomTraits> template<typename GeomTraits>
typename GeomTraits::FT tangent_weight_v2(const typename GeomTraits::Point_3& t, typename GeomTraits::FT tangent_weight_v2(const typename GeomTraits::Point_3& p0,
const typename GeomTraits::Point_3& r, const typename GeomTraits::Point_3& p1,
const typename GeomTraits::Point_3& p, const typename GeomTraits::Point_3& p2,
const typename GeomTraits::Point_3& q, const typename GeomTraits::Point_3& q,
const GeomTraits& traits) const GeomTraits& traits)
{ {
using FT = typename GeomTraits::FT; using FT = typename GeomTraits::FT;
using Vector_3 = typename GeomTraits::Vector_3; 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 v0 = vector_3(q, p0);
Vector_3 v2 = construct_vector_3(q, r); Vector_3 v = vector_3(q, p1);
Vector_3 v3 = construct_vector_3(q, p); 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(v0, traits);
internal::normalize_3(traits, v2); internal::normalize_3(v, traits);
internal::normalize_3(traits, v3); internal::normalize_3(v2, traits);
const double ha_rad_1 = internal::angle_3(traits, v1, v2) / 2.0; const double ha_rad_1 = internal::angle_3(v0, v, traits) / 2.0;
const double ha_rad_2 = internal::angle_3(traits, v2, v3) / 2.0; const double ha_rad_2 = internal::angle_3(v, v2, traits) / 2.0;
const FT t1 = static_cast<FT>(std::tan(ha_rad_1)); const FT t0 = static_cast<FT>(std::tan(ha_rad_1));
const FT t2 = static_cast<FT>(std::tan(ha_rad_2)); const FT t2 = static_cast<FT>(std::tan(ha_rad_2));
return weight(t1, t2, l2); return weight(t0, t2, l2);
} }
} // namespace tangent_ns } // namespace tangent_ns
/// \endcond /// \endcond
/*! // 2D ==============================================================================================
\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;
}
/*! /*!
\ingroup PkgWeightsRefTangentWeights \ingroup PkgWeightsRefTangentWeights
@ -195,6 +166,42 @@ FT half_tangent_weight(const FT tan05, const FT d)
return tangent_ns::half_weight(tan05, 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 \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 /// \cond SKIP_IN_MANUAL
template<typename GeomTraits> template<typename GeomTraits>
typename GeomTraits::FT tangent_weight(const typename GeomTraits::Point_2& t, typename GeomTraits::FT half_tangent_weight(const typename GeomTraits::Point_2& p0,
const typename GeomTraits::Point_2& r, const typename GeomTraits::Point_2& q,
const typename GeomTraits::Point_2& p, 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 typename GeomTraits::Point_2& q,
const GeomTraits& traits) const GeomTraits& traits)
{ {
using FT = typename GeomTraits::FT; using FT = typename GeomTraits::FT;
using Vector_2 = typename GeomTraits::Vector_2; 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 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 v0 = vector_2(q, p0);
const Vector_2 v2 = construct_vector_2(q, r); const Vector_2 v = vector_2(q, p1);
const Vector_2 v3 = construct_vector_2(q, p); const Vector_2 v2 = vector_2(q, p2);
const FT l1 = internal::length_2(traits, v1); const FT l0 = internal::length_2(v0, traits);
const FT l2 = internal::length_2(traits, v2); const FT l = internal::length_2(v, traits);
const FT l3 = internal::length_2(traits, v3); const FT l2 = internal::length_2(v2, traits);
const FT A1 = internal::area_2(traits, r, q, t); const FT A0 = area_2(p1, q, p0);
const FT A2 = internal::area_2(traits, p, q, r); const FT A2 = area_2(p2, q, p1);
const FT D1 = dot_product_2(v1, v2); const FT D0 = dot_product_2(v0, v);
const FT D2 = dot_product_2(v2, v3); 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, \ingroup PkgWeightsRefTangentWeights
const CGAL::Point_2<GeomTraits>& r, \brief computes the tangent weight in 2D at `q` using the points `p0`, `p1`, and `p2`
const CGAL::Point_2<GeomTraits>& p, \tparam Kernel a model of `Kernel`
const CGAL::Point_2<GeomTraits>& q) */
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; const Kernel traits;
return tangent_weight(t, r, p, q, 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> template<typename GeomTraits>
typename GeomTraits::FT tangent_weight(const typename GeomTraits::Point_3& t, typename GeomTraits::FT tangent_weight(const typename GeomTraits::Point_3& p0,
const typename GeomTraits::Point_3& r, const typename GeomTraits::Point_3& p1,
const typename GeomTraits::Point_3& p, const typename GeomTraits::Point_3& p2,
const typename GeomTraits::Point_3& q, const typename GeomTraits::Point_3& q,
const GeomTraits& traits) const GeomTraits& traits)
{ {
// return tangent_ns::tangent_weight_v1(t, r, p, q, traits); // return tangent_ns::tangent_weight_v1(p0, p1, p2, q, traits);
return tangent_ns::tangent_weight_v2(t, r, p, 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, \ingroup PkgWeightsRefTangentWeights
const CGAL::Point_3<GeomTraits>& r, \brief computes the tangent weight in 3D at `q` using the points `p0`, `p1`, and `p2`
const CGAL::Point_3<GeomTraits>& p, \tparam Kernel a model of `Kernel`
const CGAL::Point_3<GeomTraits>& q) */
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; const Kernel traits;
return tangent_weight(t, r, p, q, traits); return tangent_weight(p0, p1, p2, q, traits);
} }
// Undocumented tangent weight class. // Undocumented tangent weight class.

View File

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

View File

@ -22,45 +22,66 @@
namespace CGAL { namespace CGAL {
namespace Weights { 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> template<typename GeomTraits>
typename GeomTraits::FT triangular_area(const typename GeomTraits::Point_2& p, typename GeomTraits::FT triangular_area(const typename GeomTraits::Point_2& p,
const typename GeomTraits::Point_2& q, const typename GeomTraits::Point_2& q,
const typename GeomTraits::Point_2& r, const typename GeomTraits::Point_2& r,
const GeomTraits& traits) 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, \ingroup PkgWeightsRefTriangularRegionWeights
const CGAL::Point_2<GeomTraits>& q, \brief computes the area of the triangular cell in 2D using the points `p`, `q`, and `r`.
const CGAL::Point_2<GeomTraits>& 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); 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> template<typename GeomTraits>
typename GeomTraits::FT triangular_area(const typename GeomTraits::Point_3& p, typename GeomTraits::FT triangular_area(const typename GeomTraits::Point_3& p,
const typename GeomTraits::Point_3& q, const typename GeomTraits::Point_3& q,
const typename GeomTraits::Point_3& r, const typename GeomTraits::Point_3& r,
const GeomTraits& traits) 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, \ingroup PkgWeightsRefTriangularRegionWeights
const CGAL::Point_3<GeomTraits>& q, \brief computes the area of the triangular cell in 3D using the points `p`, `q`, and `r`.
const CGAL::Point_3<GeomTraits>& 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); return triangular_area(p, q, r, traits);
} }
/// \endcond
} // namespace Weights } // namespace Weights
} // namespace CGAL } // namespace CGAL

View File

@ -20,7 +20,13 @@
namespace CGAL { namespace CGAL {
namespace Weights { 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> template<typename GeomTraits>
typename GeomTraits::FT uniform_area(const typename GeomTraits::Point_2&, typename GeomTraits::FT uniform_area(const typename GeomTraits::Point_2&,
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); return FT(1);
} }
template<typename GeomTraits> /*!
typename GeomTraits::FT uniform_area(const CGAL::Point_2<GeomTraits>& p, \ingroup PkgWeightsRefUniformRegionWeights
const CGAL::Point_2<GeomTraits>& q, \brief this function always returns `1`, given three 2D points in 2D.
const CGAL::Point_2<GeomTraits>& r) \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); 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> template<typename GeomTraits>
typename GeomTraits::FT uniform_area(const typename GeomTraits::Point_3&, typename GeomTraits::FT uniform_area(const typename GeomTraits::Point_3&,
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); return FT(1);
} }
template<typename GeomTraits> /*!
typename GeomTraits::FT uniform_area(const CGAL::Point_3<GeomTraits>& p, \ingroup PkgWeightsRefUniformRegionWeights
const CGAL::Point_3<GeomTraits>& q, \brief this function always returns `1`, given three 3D points.
const CGAL::Point_3<GeomTraits>& r) \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); return uniform_area(p, q, r, traits);
} }
/// \endcond
} // namespace Weights } // namespace Weights
} // namespace CGAL } // namespace CGAL

View File

@ -22,51 +22,68 @@
namespace CGAL { namespace CGAL {
namespace Weights { namespace Weights {
/// \cond SKIP_IN_MANUAL // 2D ==============================================================================================
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&) {
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> template<typename GeomTraits>
typename GeomTraits::FT uniform_weight( typename GeomTraits::FT uniform_weight(const CGAL::Point_2<GeomTraits>& p0,
const CGAL::Point_2<GeomTraits>& q, const CGAL::Point_2<GeomTraits>& p1,
const CGAL::Point_2<GeomTraits>& t, const CGAL::Point_2<GeomTraits>& p2,
const CGAL::Point_2<GeomTraits>& r, const CGAL::Point_2<GeomTraits>& q)
const CGAL::Point_2<GeomTraits>& p) { {
const GeomTraits traits; const GeomTraits traits;
return uniform_weight(q, t, r, p, traits); return uniform_weight(p0, p1, p2, q, traits);
} }
template<typename GeomTraits> // 3D ==============================================================================================
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&) {
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> template<typename GeomTraits>
typename GeomTraits::FT uniform_weight( typename GeomTraits::FT uniform_weight(const CGAL::Point_3<GeomTraits>& p0,
const CGAL::Point_3<GeomTraits>& q, const CGAL::Point_3<GeomTraits>& p1,
const CGAL::Point_3<GeomTraits>& t, const CGAL::Point_3<GeomTraits>& p2,
const CGAL::Point_3<GeomTraits>& r, const CGAL::Point_3<GeomTraits>& q)
const CGAL::Point_3<GeomTraits>& p) { {
const GeomTraits traits; 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. // Undocumented uniform weight class taking as input a polygon mesh.
@ -85,8 +102,6 @@ public:
double w_ij(halfedge_descriptor) { return 1.; } double w_ij(halfedge_descriptor) { return 1.; }
}; };
/// \endcond
} // namespace Weights } // namespace Weights
} // namespace CGAL } // namespace CGAL

View File

@ -214,6 +214,11 @@ typename Kernel::FT tangent(const CGAL::Point_3<Kernel>& p,
return tangent(p, q, r, traits); 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> template<typename GeomTraits>
typename GeomTraits::FT cotangent_3_clamped(const typename GeomTraits::Point_3& p, typename GeomTraits::FT cotangent_3_clamped(const typename GeomTraits::Point_3& p,
const typename GeomTraits::Point_3& q, const typename GeomTraits::Point_3& q,

View File

@ -22,7 +22,13 @@
namespace CGAL { namespace CGAL {
namespace Weights { 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> template<typename GeomTraits>
typename GeomTraits::FT voronoi_area(const typename GeomTraits::Point_2& p, typename GeomTraits::FT voronoi_area(const typename GeomTraits::Point_2& p,
const typename GeomTraits::Point_2& q, 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 m1 = midpoint_2(q, r);
const Point_2 m2 = midpoint_2(q, p); const Point_2 m2 = midpoint_2(q, p);
const FT A1 = internal::positive_area_2(traits, q, m1, center); const FT A1 = internal::positive_area_2(q, m1, center,traits);
const FT A2 = internal::positive_area_2(traits, q, center, m2); const FT A2 = internal::positive_area_2(q, center, m2, traits);
return A1 + A2; return A1 + A2;
} }
template<typename GeomTraits> /*!
typename GeomTraits::FT voronoi_area(const CGAL::Point_2<GeomTraits>& p, \ingroup PkgWeightsRefVoronoiRegionWeights
const CGAL::Point_2<GeomTraits>& q, \brief computes the area of the Voronoi cell in 2D using the points `p`, `q`, and `r`.
const CGAL::Point_2<GeomTraits>& 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); 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> template<typename GeomTraits>
typename GeomTraits::FT voronoi_area(const typename GeomTraits::Point_3& p, typename GeomTraits::FT voronoi_area(const typename GeomTraits::Point_3& p,
const typename GeomTraits::Point_3& q, 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 m1 = midpoint_3(q, r);
const Point_3 m2 = midpoint_3(q, p); const Point_3 m2 = midpoint_3(q, p);
const FT A1 = internal::positive_area_3(traits, q, m1, center); const FT A1 = internal::positive_area_3(q, m1, center, traits);
const FT A2 = internal::positive_area_3(traits, q, center, m2); const FT A2 = internal::positive_area_3(q, center, m2, traits);
return A1 + A2; return A1 + A2;
} }
template<typename GeomTraits> /*!
typename GeomTraits::FT voronoi_area(const CGAL::Point_3<GeomTraits>& p, \ingroup PkgWeightsRefVoronoiRegionWeights
const CGAL::Point_3<GeomTraits>& q, \brief computes the area of the Voronoi cell in 3D using the points `p`, `q`, and `r`.
const CGAL::Point_3<GeomTraits>& 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); return voronoi_area(p, q, r, traits);
} }
/// \endcond
} // namespace Weights } // namespace Weights
} // namespace CGAL } // namespace CGAL

View File

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