mirror of https://github.com/CGAL/cgal
Merge remote-tracking branch 'origin/Weights-new_package-danston' into Barycentric_coordinates_2-danston
This commit is contained in:
commit
c1aa3c0a61
|
|
@ -67,11 +67,13 @@ with notations shown in the figure below.
|
|||
|
||||
Here, the distance is computed between the points `p` and `q`.
|
||||
|
||||
Alternative formulations are explained in \ref Weights_Implementation.
|
||||
|
||||
\cgalFigureBegin{inverse_distance_weight, inverse_distance.svg}
|
||||
Notation used for the inverse distance weight.
|
||||
\cgalFigureEnd
|
||||
|
||||
\cgalHeading{Other Formulations}
|
||||
\cgalHeading{Alternative Formulations}
|
||||
- This weight is a special case of the \ref PkgWeightsRefShepardWeights "Shepard Weight".
|
||||
|
||||
\tparam GeomTraits
|
||||
|
|
@ -94,6 +96,9 @@ being the power parameter.
|
|||
|
||||
Here, `q` is a query point and the points `p0`, `p1`, and `p2` are ordered.
|
||||
|
||||
This weight supports only planar configurations (see more in section about \ref Weights_Flattening)
|
||||
while alternative formulations are explained in \ref Weights_Implementation.
|
||||
|
||||
\cgalFigureBegin{three_point_family_weight, three_point_family.svg}
|
||||
Notation used for the three point family weight.
|
||||
\cgalFigureEnd
|
||||
|
|
@ -128,11 +133,14 @@ with notations shown in the figure below.
|
|||
|
||||
Here, `q` is a query point and the points `p0`, `p1`, and `p2` are ordered.
|
||||
|
||||
This weight supports only planar configurations (see more in section about \ref Weights_Flattening)
|
||||
while alternative formulations are explained in \ref Weights_Implementation.
|
||||
|
||||
\cgalFigureBegin{wachspress_weight, wachspress.svg}
|
||||
Notation used for the Wachspress weight.
|
||||
\cgalFigureEnd
|
||||
|
||||
\cgalHeading{Other Formulations}
|
||||
\cgalHeading{Alternative Formulations}
|
||||
- This weight is equal to the \ref PkgWeightsRefAuthalicWeights "Authalic Weight".
|
||||
- This weight is a special case of the \ref PkgWeightsRefThreePointFamilyWeights "Three Point Family Weight".
|
||||
|
||||
|
|
@ -155,11 +163,13 @@ with notations shown in the figure below.
|
|||
|
||||
Here, `q` is a query point and the points `p0`, `p1`, and `p2` are ordered.
|
||||
|
||||
Alternative formulations are explained in \ref Weights_Implementation.
|
||||
|
||||
\cgalFigureBegin{authalic_weight, authalic.svg}
|
||||
Notation used for the authalic weight.
|
||||
\cgalFigureEnd
|
||||
|
||||
\cgalHeading{Other Formulations}
|
||||
\cgalHeading{Alternative Formulations}
|
||||
- This weight is equal to the \ref PkgWeightsRefWachspressWeights "Wachspress Weight".
|
||||
- This weight is a special case of the \ref PkgWeightsRefThreePointFamilyWeights "Three Point Family Weight".
|
||||
|
||||
|
|
@ -188,11 +198,14 @@ The \f$\pm\f$ sign is a sign of the weight that depends on the configuration.
|
|||
|
||||
Here, `q` is a query point and the points `p0`, `p1`, and `p2` are ordered.
|
||||
|
||||
This weight supports only planar configurations (see more in section about \ref Weights_Flattening)
|
||||
while alternative formulations are explained in \ref Weights_Implementation.
|
||||
|
||||
\cgalFigureBegin{mean_value_weight, mean_value.svg}
|
||||
Notation used for the mean value weight.
|
||||
\cgalFigureEnd
|
||||
|
||||
\cgalHeading{Other Formulations}
|
||||
\cgalHeading{Alternative Formulations}
|
||||
- This weight is equal to the \ref PkgWeightsRefTangentWeights "Tangent Weight".
|
||||
- This weight is a special case of the \ref PkgWeightsRefThreePointFamilyWeights "Three Point Family Weight".
|
||||
|
||||
|
|
@ -220,11 +233,13 @@ with notations shown in the figure below and dot products
|
|||
|
||||
Here, `q` is a query point and the points `p0`, `p1`, and `p2` are ordered.
|
||||
|
||||
Alternative formulations are explained in \ref Weights_Implementation.
|
||||
|
||||
\cgalFigureBegin{tangent_weight, tangent.svg}
|
||||
Notation used for the tangent weight.
|
||||
\cgalFigureEnd
|
||||
|
||||
\cgalHeading{Other Formulations}
|
||||
\cgalHeading{Alternative Formulations}
|
||||
- This weight is equal to the \ref PkgWeightsRefMeanValueWeights "Mean Value Weight".
|
||||
- This weight is a special case of the \ref PkgWeightsRefThreePointFamilyWeights "Three Point Family Weight".
|
||||
|
||||
|
|
@ -247,11 +262,14 @@ with notations shown in the figure below.
|
|||
|
||||
Here, `q` is a query point and the points `p0`, `p1`, and `p2` are ordered.
|
||||
|
||||
This weight supports only planar configurations (see more in section about \ref Weights_Flattening)
|
||||
while alternative formulations are explained in \ref Weights_Implementation.
|
||||
|
||||
\cgalFigureBegin{discrete_harmonic_weight, discrete_harmonic.svg}
|
||||
Notation used for the discrete harmonic weight.
|
||||
\cgalFigureEnd
|
||||
|
||||
\cgalHeading{Other Formulations}
|
||||
\cgalHeading{Alternative Formulations}
|
||||
- This weight is equal to the \ref PkgWeightsRefCotangentWeights "Cotangent Weight".
|
||||
- This weight is a special case of the \ref PkgWeightsRefThreePointFamilyWeights "Three Point Family Weight".
|
||||
|
||||
|
|
@ -274,11 +292,13 @@ with notations shown in the figure below.
|
|||
|
||||
Here, `q` is a query point and the points `p0`, `p1`, and `p2` are ordered.
|
||||
|
||||
Alternative formulations are explained in \ref Weights_Implementation.
|
||||
|
||||
\cgalFigureBegin{cotangent_weight, cotangent.svg}
|
||||
Notation used for the cotangent weight.
|
||||
\cgalFigureEnd
|
||||
|
||||
\cgalHeading{Other Formulations}
|
||||
\cgalHeading{Alternative Formulations}
|
||||
- This weight is equal to the \ref PkgWeightsRefDiscreteHarmonicWeights "Discrete Harmonic Weight".
|
||||
- This weight is a special case of the \ref PkgWeightsRefThreePointFamilyWeights "Three Point Family Weight".
|
||||
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ Sometimes, such weights are referred as *local averaging regions*. These weights
|
|||
lengths, areas, and volumes of 2D and 3D objects.
|
||||
|
||||
|
||||
\section Weights_Interface Interface
|
||||
\section Weights_Implementation Implementation
|
||||
|
||||
All weights have a simple and unified interface. In particular, all analytic weights take
|
||||
a query point and three other points in 2D or 3D and return a unique scalar. They all
|
||||
|
|
@ -92,6 +92,48 @@ is a unique scalar.
|
|||
The parameter `traits` with a traits class can be omitted for all functions and classes
|
||||
if it can be deduced from the input point type.
|
||||
|
||||
Several weights in this package have different implementations. One reason to have it is
|
||||
explained in section about \ref Weights_Flattening. Another reason is that in different communities
|
||||
the same weights are named and computed differently. If one searches for these weights,
|
||||
one needs to know all their alternative names, which is tiresome. We provide the most common
|
||||
names and implementations of these weights.
|
||||
|
||||
|
||||
\subsection Weights_Flattening Flattening
|
||||
|
||||
\cgalFigureBegin{flattening, flattening.svg}
|
||||
The non-planar configuration (top) is flattened to the planar configuration (bottom).
|
||||
\cgalFigureEnd
|
||||
|
||||
When computing weights for a query point \f$q\f$ with respect to its neighbors
|
||||
\f$p_0\f$, \f$p_1\f$, and \f$p_2\f$, the local configuration is a quadrilateral
|
||||
[\f$p_0\f$, \f$p_1\f$, \f$p_2\f$, \f$q\f$] or two connected triangles [\f$q\f$, \f$p_0\f$, \f$p_1\f$]
|
||||
and [\f$q\f$, \f$p_1\f$, \f$p_2\f$]. When computing 3D weights, these triangles are not
|
||||
necessarily coplanar. When they are not coplanar, they can be made coplanar through the process
|
||||
called *flattening* (see the Figure above), however the latter introduces a distortion because the
|
||||
weights are computed with respect to the flattened configuration rather than to the original
|
||||
non-flat configuration. Certain weights in this package support only flat configurations,
|
||||
while other weights support both. The weights, which support non-flat configurations,
|
||||
provide the corresponding overloads with 3D points, while other weights support only
|
||||
2D point types. For example, \ref PkgWeightsRefCotangentWeights "cotangent weights" support both flat
|
||||
and non-flat configurations, while \ref PkgWeightsRefDiscreteHarmonicWeights "discrete harmonic weights"
|
||||
support only flat configurations.
|
||||
|
||||
If you still want to compute the 2D weights in 3D, you can either provide your own way to flatten
|
||||
the 3D configuration or you can use one of the projection traits available in CGAL as the
|
||||
last parameter to the weight function (see \ref Weights_Examples_ProjectionTraits for example).
|
||||
|
||||
|
||||
\subsection Weights_Edge_Cases Edge Cases
|
||||
|
||||
None of the weights in this package is defined for query points on the boundaries. The boundary cases include:
|
||||
|
||||
- *edges*, for example [\f$p_0\f$, \f$p_1\f$] or [\f$p_1\f$, \f$p_2\f$] or any polygon edge and
|
||||
- *corners*, for example \f$p_0\f$, \f$p_1\f$, or \f$p_2\f$ or any polygon corner.
|
||||
|
||||
Several weights also require other conditions to be satisifed. You should address the
|
||||
reference manual for more details.
|
||||
|
||||
|
||||
\section Weights_Examples Examples
|
||||
|
||||
|
|
@ -161,8 +203,8 @@ in the custom traits class.
|
|||
|
||||
A typical example of using weights is discretizing *Poisson* and *Laplace
|
||||
equations* which play an important role in various geometry processing applications
|
||||
such as, for example, \ref PkgSurfaceMeshDeformation "surface mesh deformation" and
|
||||
\ref PkgSurfaceMeshParameterization "surface mesh parameterization" (see
|
||||
such as, for example, \ref PkgSurfaceMeshDeformation "Surface Mesh Deformation" and
|
||||
\ref PkgSurfaceMeshParameterization "Surface Mesh Parameterization" (see
|
||||
also \ref Weights_Intro "Introduction" for more details). This example shows
|
||||
how to write the *discretized Laplacian* for all vertices of the given triangle mesh in
|
||||
matrix notation. We use the standard cotangent discretization weighted by the areas of
|
||||
|
|
@ -171,22 +213,13 @@ the mixed Voronoi cells around each mesh vertex.
|
|||
\cgalExample{Weights/weighted_laplacian.cpp}
|
||||
|
||||
|
||||
\subsection Weights_Examples_Flattening Flattening and Convergence
|
||||
\subsection Weights_Examples_Convergence Convergence
|
||||
|
||||
When computing weights for a query point `q` with respect to its neighbors
|
||||
`p0`, `p1`, and `p2`, the local configuration is a quadrilateral `[p0, p1, p2, q]`
|
||||
or two connected triangles `[q, p0, p1]` and `[q, p1, p2]`. When computing 3D weights,
|
||||
these triangles are not necessarily coplanar. When they are not coplanar, we make them coplanar,
|
||||
since several weights cannot be computed for non-coplanar triangles, however this
|
||||
so-called *flattening* introduces a distortion since the weights are computed
|
||||
not with respect to the original configuration but to its flattened version. This example
|
||||
shows how this distortion progresses when the point `q1`, which is not in the plane, moves back
|
||||
to the original flat configuration with `q0`. Moreover, this example shows how to use the
|
||||
family of weights which includes multiple types of weights in one function. In particular,
|
||||
we show how, by changing an input parameter, we converge from the Wachspress weights to
|
||||
the mean value weights.
|
||||
This little example shows how to use the family of weights which includes multiple types
|
||||
of weights in one function. In particular, we show how, by changing an input parameter,
|
||||
we converge from the Wachspress weights to the mean value weights.
|
||||
|
||||
\cgalExample{Weights/flattening.cpp}
|
||||
\cgalExample{Weights/convergence.cpp}
|
||||
|
||||
|
||||
\section Weights_History History
|
||||
|
|
|
|||
|
|
@ -5,5 +5,5 @@
|
|||
\example Weights/weighted_laplacian.cpp
|
||||
\example Weights/projection_traits.cpp
|
||||
\example Weights/custom_traits.cpp
|
||||
\example Weights/flattening.cpp
|
||||
\example Weights/convergence.cpp
|
||||
*/
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 5.9 KiB |
|
|
@ -17,7 +17,7 @@ if(CGAL_FOUND)
|
|||
create_single_source_cgal_program("coordinates_multiple_queries.cpp")
|
||||
create_single_source_cgal_program("projection_traits.cpp")
|
||||
create_single_source_cgal_program("custom_traits.cpp")
|
||||
create_single_source_cgal_program("flattening.cpp")
|
||||
create_single_source_cgal_program("convergence.cpp")
|
||||
|
||||
find_package(Eigen3 REQUIRED)
|
||||
include(CGAL_Eigen3_support)
|
||||
|
|
@ -25,11 +25,9 @@ if(CGAL_FOUND)
|
|||
create_single_source_cgal_program("weighted_laplacian.cpp")
|
||||
target_link_libraries(weighted_laplacian PUBLIC CGAL::Eigen3_support)
|
||||
else()
|
||||
message(WARNING
|
||||
"Several examples require the Eigen library, and will not be compiled.")
|
||||
message(WARNING "Several examples require the Eigen library, and will not be compiled.")
|
||||
endif()
|
||||
|
||||
else()
|
||||
message(WARNING
|
||||
"This program requires the CGAL library, and will not be compiled.")
|
||||
message(WARNING "This program requires the CGAL library, and will not be compiled.")
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -5,16 +5,16 @@
|
|||
// Typedefs.
|
||||
using Kernel = CGAL::Simple_cartesian<double>;
|
||||
using FT = typename Kernel::FT;
|
||||
using Point_3 = typename Kernel::Point_3;
|
||||
using Point_2 = typename Kernel::Point_2;
|
||||
|
||||
int main() {
|
||||
std::cout << std::fixed;
|
||||
|
||||
// 3D configuration.
|
||||
const Point_3 p0(0, 1, 1);
|
||||
const Point_3 p1(2, 0, 1);
|
||||
const Point_3 p2(7, 1, 1);
|
||||
const Point_3 q0(3, 1, 1);
|
||||
const Point_2 p0(0, 1);
|
||||
const Point_2 p1(2, 0);
|
||||
const Point_2 p2(7, 1);
|
||||
const Point_2 q0(3, 1);
|
||||
|
||||
// Choose a type of the weight:
|
||||
// e.g. 0 - Wachspress (WP) weight; 1 - mean value (MV);
|
||||
|
|
@ -35,19 +35,5 @@ int main() {
|
|||
std::cout << CGAL::Weights::three_point_family_weight(p0, p1, p2, q0, x) << std::endl;
|
||||
}
|
||||
|
||||
// Compute WP weights for q1, which is not on the plane [p0, p1, p2].
|
||||
Point_3 q1(3, 1, 2);
|
||||
std::cout << "3D wachspress (WP, q1): ";
|
||||
std::cout << CGAL::Weights::three_point_family_weight(p0, p1, p2, q1, wp) << std::endl;
|
||||
|
||||
// Converge q1 towards q0 that is we flatten the configuration.
|
||||
// We also compare the result with the authalic weight.
|
||||
std::cout << "Converge q1 to q0: " << std::endl;
|
||||
for (FT x = FT(0); x <= FT(1); x += step) {
|
||||
std::cout << "3D wachspress/authalic: ";
|
||||
q1 = Point_3(3, 1, FT(2) - x);
|
||||
std::cout << CGAL::Weights::three_point_family_weight(p0, p1, p2, q1, wp) << "/";
|
||||
std::cout << CGAL::Weights::authalic_weight(p0, p1, p2, q1) << std::endl;
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
@ -11,7 +11,9 @@ int main() {
|
|||
// Create a polygon and a query point.
|
||||
const std::vector<Point_2> polygon =
|
||||
{ Point_2(0, 0), Point_2(1, 0), Point_2(1, 1), Point_2(0, 1) };
|
||||
const Point_2 query(FT(1) / FT(2), FT(1) / FT(2));
|
||||
|
||||
const FT half = FT(1) / FT(2);
|
||||
const Point_2 query(half, half);
|
||||
|
||||
// Allocate memory for weights and coordinates.
|
||||
std::vector<FT> weights;
|
||||
|
|
|
|||
|
|
@ -1,30 +1,30 @@
|
|||
#include <CGAL/Simple_cartesian.h>
|
||||
#include <CGAL/Weights/utils.h>
|
||||
#include <CGAL/Weights/mean_value_weights.h>
|
||||
#include <CGAL/Weights/internal/Projection_traits_3.h>
|
||||
#include <CGAL/Projection_traits_xy_3.h>
|
||||
|
||||
// Typedefs.
|
||||
using Kernel = CGAL::Simple_cartesian<double>;
|
||||
using FT = typename Kernel::FT;
|
||||
using Point_3 = typename Kernel::Point_3;
|
||||
using Vector_3 = typename Kernel::Vector_3;
|
||||
using PTraits = CGAL::Weights::internal::Projection_traits_3<Kernel>;
|
||||
using PTraits = CGAL::Projection_traits_xy_3<Kernel>;
|
||||
|
||||
int main() {
|
||||
|
||||
// Create a polygon and a query point.
|
||||
const std::vector<Point_3> polygon =
|
||||
{ Point_3(0, 0, 1), Point_3(1, 0, 1), Point_3(1, 1, 0), Point_3(0, 1, 0) };
|
||||
const Point_3 query(FT(1) / FT(2), FT(1) / FT(2), FT(1) / FT(2));
|
||||
{ Point_3(0, 0, 1), Point_3(1, 0, 1), Point_3(1, 1, 1), Point_3(0, 1, 1) };
|
||||
|
||||
const FT half = FT(1) / FT(2);
|
||||
const Point_3 query(half, half, 1);
|
||||
|
||||
// Allocate memory for weights.
|
||||
std::vector<FT> weights;
|
||||
weights.reserve(polygon.size());
|
||||
|
||||
// Create projection traits with the right normal.
|
||||
const FT quater = FT(1) / FT(4);
|
||||
const Vector_3 normal(0, quater, quater);
|
||||
const PTraits ptraits(normal);
|
||||
// Create projection traits.
|
||||
const PTraits ptraits;
|
||||
|
||||
// Compute weights.
|
||||
CGAL::Weights::mean_value_weights_2(polygon, query, std::back_inserter(weights), ptraits);
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
// Typedefs.
|
||||
using Kernel = CGAL::Simple_cartesian<double>;
|
||||
using FT = typename Kernel::FT;
|
||||
using Point_2 = typename Kernel::Point_2;
|
||||
using Point_3 = typename Kernel::Point_3;
|
||||
|
||||
|
|
@ -25,8 +26,8 @@ int main() {
|
|||
std::cout << CGAL::Weights::tangent_weight(t3, r3, p3, q3) << std::endl;
|
||||
|
||||
std::cout << "2D/3D Shepard weight: ";
|
||||
std::cout << CGAL::Weights::shepard_weight(r2, q2, 2.0) << "/";
|
||||
std::cout << CGAL::Weights::shepard_weight(r3, q3, 2.0) << std::endl;
|
||||
std::cout << CGAL::Weights::shepard_weight(r2, q2, FT(2)) << "/";
|
||||
std::cout << CGAL::Weights::shepard_weight(r3, q3, FT(2)) << std::endl;
|
||||
|
||||
std::cout << "2D/3D barycentric area: ";
|
||||
std::cout << CGAL::Weights::barycentric_area(p2, q2, r2) << "/";
|
||||
|
|
|
|||
|
|
@ -153,9 +153,7 @@ namespace Weights {
|
|||
const auto squared_distance_2 =
|
||||
traits.compute_squared_distance_2_object();
|
||||
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, d2);
|
||||
}
|
||||
|
||||
template<typename GeomTraits>
|
||||
|
|
@ -184,9 +182,7 @@ namespace Weights {
|
|||
const auto squared_distance_3 =
|
||||
traits.compute_squared_distance_3_object();
|
||||
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, d2);
|
||||
}
|
||||
|
||||
template<typename GeomTraits>
|
||||
|
|
|
|||
|
|
@ -59,20 +59,6 @@ namespace Weights {
|
|||
const typename GeomTraits::Point_2& q,
|
||||
const GeomTraits& traits) { }
|
||||
|
||||
/*!
|
||||
\ingroup PkgWeightsRefDiscreteHarmonicWeights
|
||||
|
||||
\brief computes the discrete harmonic weight in 3D at `q` using the points `p0`, `p1`,
|
||||
and `p2`, given a traits class `traits` with geometric objects, predicates, and constructions.
|
||||
*/
|
||||
template<typename GeomTraits>
|
||||
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) { }
|
||||
|
||||
/*!
|
||||
\ingroup PkgWeightsRefDiscreteHarmonicWeights
|
||||
|
||||
|
|
@ -86,19 +72,6 @@ namespace Weights {
|
|||
const CGAL::Point_2<K>& p2,
|
||||
const CGAL::Point_2<K>& q) { }
|
||||
|
||||
/*!
|
||||
\ingroup PkgWeightsRefDiscreteHarmonicWeights
|
||||
|
||||
\brief computes the discrete harmonic weight in 3D at `q` using the points `p0`, `p1`,
|
||||
and `p2`, which are parameterized by a `Kernel` K.
|
||||
*/
|
||||
template<typename K>
|
||||
typename K::FT discrete_harmonic_weight(
|
||||
const CGAL::Point_3<K>& p0,
|
||||
const CGAL::Point_3<K>& p1,
|
||||
const CGAL::Point_3<K>& p2,
|
||||
const CGAL::Point_3<K>& q) { }
|
||||
|
||||
#endif // DOXYGEN_RUNNING
|
||||
|
||||
/// \cond SKIP_IN_MANUAL
|
||||
|
|
@ -137,6 +110,8 @@ namespace Weights {
|
|||
return discrete_harmonic_weight(t, r, p, q, traits);
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
|
||||
template<typename GeomTraits>
|
||||
typename GeomTraits::FT discrete_harmonic_weight(
|
||||
const typename GeomTraits::Point_3& t,
|
||||
|
|
@ -151,7 +126,8 @@ namespace Weights {
|
|||
traits,
|
||||
t, r, p, q,
|
||||
tf, rf, pf, qf);
|
||||
return discrete_harmonic_weight(tf, rf, pf, qf, traits);
|
||||
return CGAL::Weights::
|
||||
discrete_harmonic_weight(tf, rf, pf, qf, traits);
|
||||
}
|
||||
|
||||
template<typename GeomTraits>
|
||||
|
|
@ -164,6 +140,9 @@ namespace Weights {
|
|||
const GeomTraits traits;
|
||||
return discrete_harmonic_weight(t, r, p, q, traits);
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
/// \endcond
|
||||
|
||||
/*!
|
||||
|
|
|
|||
|
|
@ -1,95 +0,0 @@
|
|||
// Copyright (c) 2020 GeometryFactory SARL (France)
|
||||
// All rights reserved.
|
||||
//
|
||||
// This file is part of CGAL (www.cgal.org).
|
||||
//
|
||||
// $URL$
|
||||
// $Id$
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
||||
//
|
||||
//
|
||||
// Author(s) : Dmitry Anisimov
|
||||
//
|
||||
|
||||
#ifndef CGAL_WEIGHTS_INTERNAL_PROJECTION_TRAITS_3_H
|
||||
#define CGAL_WEIGHTS_INTERNAL_PROJECTION_TRAITS_3_H
|
||||
|
||||
// #include <CGAL/license/Weights.h>
|
||||
|
||||
#include <CGAL/Filtered_predicate_with_state.h>
|
||||
#include <CGAL/Weights/internal/Projection_traits_base_3.h>
|
||||
|
||||
namespace CGAL {
|
||||
namespace Weights {
|
||||
namespace internal {
|
||||
|
||||
template<class Filtered_kernel >
|
||||
class Filtered_projection_traits_3
|
||||
: public Projection_traits_base_3<Filtered_kernel> {
|
||||
|
||||
using K = Filtered_kernel;
|
||||
using Self = Filtered_projection_traits_3<K>;
|
||||
using Base = Projection_traits_base_3<K>;
|
||||
|
||||
using Exact_kernel = typename K::Exact_kernel;
|
||||
using Approximate_kernel = typename K::Approximate_kernel;
|
||||
|
||||
using C2E = typename K::C2E;
|
||||
using C2F = typename K::C2F;
|
||||
|
||||
public:
|
||||
using Exact_traits = Projection_traits_base_3<Exact_kernel>;
|
||||
using Filtering_traits = Projection_traits_base_3<Approximate_kernel>;
|
||||
|
||||
public:
|
||||
explicit Filtered_projection_traits_3(
|
||||
const typename K::Vector_3& normal) : Base(normal) { }
|
||||
|
||||
#define CGAL_PROJ_TRAITS_FILTER_PRED(P, Pf, ACCESSOR) \
|
||||
typedef Filtered_predicate_with_state< \
|
||||
typename Exact_traits::P, \
|
||||
typename Filtering_traits::P, \
|
||||
C2E, \
|
||||
C2F, \
|
||||
typename K::Vector_3> P; \
|
||||
P Pf() const { \
|
||||
return P(this->ACCESSOR()); \
|
||||
}
|
||||
|
||||
CGAL_PROJ_TRAITS_FILTER_PRED(
|
||||
Orientation_2,
|
||||
orientation_2_object,
|
||||
normal)
|
||||
CGAL_PROJ_TRAITS_FILTER_PRED(
|
||||
Collinear_2,
|
||||
collinear_2_object,
|
||||
normal)
|
||||
};
|
||||
|
||||
// This declaration is necessary for breaking the cyclic dependency.
|
||||
template<class Filtered_kernel>
|
||||
class Filtered_projection_traits_3;
|
||||
|
||||
template<class Kernel, bool Has_filtered_predicates = Kernel::Has_filtered_predicates>
|
||||
class Projection_traits_3
|
||||
: public Projection_traits_base_3<Kernel> {
|
||||
public:
|
||||
explicit Projection_traits_3(const typename Kernel::Vector_3& normal)
|
||||
: Projection_traits_base_3<Kernel>(normal)
|
||||
{ }
|
||||
};
|
||||
|
||||
template<class Kernel>
|
||||
class Projection_traits_3<Kernel, true>
|
||||
: public Filtered_projection_traits_3<Kernel> {
|
||||
public:
|
||||
explicit Projection_traits_3(const typename Kernel::Vector_3& normal) :
|
||||
Filtered_projection_traits_3<Kernel>(normal)
|
||||
{ }
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
} // namespace Weights
|
||||
} // namespace CGAL
|
||||
|
||||
#endif // CGAL_WEIGHTS_INTERNAL_PROJECTION_TRAITS_3_H
|
||||
|
|
@ -1,272 +0,0 @@
|
|||
// Copyright (c) 2020 GeometryFactory SARL (France)
|
||||
// All rights reserved.
|
||||
//
|
||||
// This file is part of CGAL (www.cgal.org).
|
||||
//
|
||||
// $URL$
|
||||
// $Id$
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
||||
//
|
||||
//
|
||||
// Author(s) : Dmitry Anisimov
|
||||
//
|
||||
|
||||
#ifndef CGAL_WEIGHTS_INTERNAL_PROJECTION_TRAITS_BASE_3_H
|
||||
#define CGAL_WEIGHTS_INTERNAL_PROJECTION_TRAITS_BASE_3_H
|
||||
|
||||
// #include <CGAL/license/Weights.h>
|
||||
|
||||
namespace CGAL {
|
||||
namespace Weights {
|
||||
namespace internal {
|
||||
namespace ProjectionTraitsCartesianFunctors {
|
||||
|
||||
template <class Traits>
|
||||
class Compare_along_axis {
|
||||
|
||||
using Vector_3 = typename Traits::Vector_3;
|
||||
using Point = typename Traits::Point_2;
|
||||
Vector_3 base;
|
||||
|
||||
public:
|
||||
Compare_along_axis(const Vector_3& base) : base(base) { }
|
||||
using result_type = Comparison_result;
|
||||
Comparison_result operator() (const Point &p, const Point &q) const {
|
||||
return compare(base * (p - q), 0);
|
||||
}
|
||||
};
|
||||
|
||||
template <class Traits>
|
||||
class Less_along_axis {
|
||||
|
||||
using Vector_3 = typename Traits::Vector_3;
|
||||
using Point = typename Traits::Point_2;
|
||||
Vector_3 base;
|
||||
|
||||
public:
|
||||
Less_along_axis(const Vector_3& base) : base(base) { }
|
||||
using result_type = bool;
|
||||
bool operator() (const Point &p, const Point &q) const {
|
||||
return base * (p - q) < 0;
|
||||
}
|
||||
};
|
||||
|
||||
template<class Traits>
|
||||
class Less_xy_along_axis {
|
||||
|
||||
using Vector_3 = typename Traits::Vector_3;
|
||||
using Point = typename Traits::Point_2;
|
||||
Vector_3 base1, base2;
|
||||
|
||||
public:
|
||||
Less_xy_along_axis(const Vector_3& base1, const Vector_3& base2) :
|
||||
base1(base1), base2(base2)
|
||||
{ }
|
||||
|
||||
using result_type = bool;
|
||||
bool operator() (const Point &p, const Point &q) const {
|
||||
|
||||
const Compare_along_axis<Traits> cx(base1);
|
||||
const Comparison_result crx = cx(p, q);
|
||||
if (crx == SMALLER) {
|
||||
return true;
|
||||
}
|
||||
if (crx == LARGER) {
|
||||
return false;
|
||||
}
|
||||
const Less_along_axis<Traits> ly(base2);
|
||||
return ly(p, q);
|
||||
}
|
||||
};
|
||||
|
||||
template<class Traits>
|
||||
class Equal_along_axis {
|
||||
|
||||
using Vector_3 = typename Traits::Vector_3;
|
||||
using Point = typename Traits::Point_2;
|
||||
Vector_3 base1, base2;
|
||||
|
||||
public:
|
||||
Equal_along_axis(const Vector_3& base1, const Vector_3& base2) :
|
||||
base1(base1), base2(base2)
|
||||
{ }
|
||||
|
||||
using result_type = bool;
|
||||
bool operator() (const Point &p, const Point &q) const {
|
||||
|
||||
const Compare_along_axis<Traits> cx(base1);
|
||||
const Compare_along_axis<Traits> cy(base2);
|
||||
|
||||
const Comparison_result crx = cx(p, q);
|
||||
const Comparison_result cry = cy(p, q);
|
||||
|
||||
if (crx == EQUAL && cry == EQUAL) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
template<class Traits>
|
||||
class Projected_orientation_with_normal_3 {
|
||||
|
||||
using K = typename Traits::K;
|
||||
using Point = typename Traits::Point_2;
|
||||
using Vector_3 = typename Traits::Vector_3;
|
||||
Vector_3 normal;
|
||||
|
||||
public:
|
||||
using Orientation = typename K::Orientation;
|
||||
using result_type = Orientation;
|
||||
|
||||
Projected_orientation_with_normal_3(const Vector_3& normal_) : normal(normal_) { }
|
||||
Orientation operator()(const Point& p, const Point& q, const Point& r) const {
|
||||
return orientation(q - p, r - p, normal);
|
||||
}
|
||||
};
|
||||
|
||||
template<class Traits>
|
||||
class Projected_collinear_with_normal_3 {
|
||||
|
||||
using K = typename Traits::K;
|
||||
using Point = typename Traits::Point_2;
|
||||
using Vector_3 = typename Traits::Vector_3;
|
||||
Vector_3 normal;
|
||||
|
||||
public:
|
||||
using Collinear = typename K::Collinear_3;
|
||||
using result_type = bool;
|
||||
|
||||
Projected_collinear_with_normal_3(const Vector_3& normal_) : normal(normal_) { }
|
||||
bool operator()(const Point& p, const Point& q, const Point& r) const {
|
||||
return collinear(p, q, r);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace ProjectionTraitsCartesianFunctors
|
||||
|
||||
template<class Kernel>
|
||||
class Projection_traits_base_3 {
|
||||
|
||||
using Self = Projection_traits_base_3<Kernel>;
|
||||
typename Kernel::Vector_3 n, b1, b2;
|
||||
|
||||
public:
|
||||
using K = Kernel;
|
||||
using FT = typename K::FT;
|
||||
using Point_2 = typename K::Point_3;
|
||||
using Vector_2 = typename K::Vector_3;
|
||||
using Vector_3 = typename K::Vector_3;
|
||||
|
||||
explicit Projection_traits_base_3(const Vector_3& n_) : n(n_) {
|
||||
|
||||
CGAL_precondition(n != Vector_3(0, 0, 0));
|
||||
const FT nx = n.x();
|
||||
const FT ny = n.y();
|
||||
const FT nz = n.z();
|
||||
if (CGAL::abs(nz) >= CGAL::abs(ny)) {
|
||||
b1 = Vector_3(nz, FT(0), -nx);
|
||||
} else {
|
||||
b1 = Vector_3(ny, -nx, FT(0));
|
||||
}
|
||||
b2 = cross_product(n, b1);
|
||||
}
|
||||
|
||||
const Vector_3& normal() const {
|
||||
return n;
|
||||
}
|
||||
|
||||
const Vector_3& base1() const {
|
||||
return b1;
|
||||
}
|
||||
|
||||
const Vector_3& base2() const {
|
||||
return b2;
|
||||
}
|
||||
|
||||
using Less_xy_2
|
||||
= ProjectionTraitsCartesianFunctors::Less_xy_along_axis<Self>;
|
||||
|
||||
using Equal_2
|
||||
= ProjectionTraitsCartesianFunctors::Equal_along_axis<Self>;
|
||||
|
||||
using Orientation_2
|
||||
= ProjectionTraitsCartesianFunctors::Projected_orientation_with_normal_3<Self>;
|
||||
|
||||
using Collinear_2
|
||||
= ProjectionTraitsCartesianFunctors::Projected_collinear_with_normal_3<Self>;
|
||||
|
||||
using Compute_squared_distance_2
|
||||
= typename K::Compute_squared_distance_3;
|
||||
|
||||
using Compute_squared_length_2
|
||||
= typename K::Compute_squared_length_3;
|
||||
|
||||
using Compute_scalar_product_2
|
||||
= typename K::Compute_scalar_product_3;
|
||||
|
||||
using Compute_area_2
|
||||
= typename K::Compute_area_3;
|
||||
|
||||
using Construct_vector_2
|
||||
= typename K::Construct_vector_3;
|
||||
|
||||
using Construct_circumcenter_2
|
||||
= typename K::Construct_circumcenter_3;
|
||||
|
||||
Less_xy_2
|
||||
less_xy_2_object() const {
|
||||
return Less_xy_2(this->base1(), this->base2());
|
||||
}
|
||||
|
||||
Equal_2
|
||||
equal_2_object() const {
|
||||
return Equal_2(this->base1(), this->base2());
|
||||
}
|
||||
|
||||
Orientation_2
|
||||
orientation_2_object() const {
|
||||
return Orientation_2(this->normal());
|
||||
}
|
||||
|
||||
Collinear_2
|
||||
collinear_2_object() const {
|
||||
return Collinear_2(this->normal());
|
||||
}
|
||||
|
||||
Compute_squared_distance_2
|
||||
compute_squared_distance_2_object() const {
|
||||
return Compute_squared_distance_2();
|
||||
}
|
||||
|
||||
Compute_squared_length_2
|
||||
compute_squared_length_2_object() const {
|
||||
return Compute_squared_length_2();
|
||||
}
|
||||
|
||||
Compute_scalar_product_2
|
||||
compute_scalar_product_2_object() const {
|
||||
return Compute_scalar_product_2();
|
||||
}
|
||||
|
||||
Compute_area_2
|
||||
compute_area_2_object() const {
|
||||
return Compute_area_2();
|
||||
}
|
||||
|
||||
Construct_vector_2
|
||||
construct_vector_2_object() const {
|
||||
return Construct_vector_2();
|
||||
}
|
||||
|
||||
Construct_circumcenter_2
|
||||
construct_circumcenter_2_object() const {
|
||||
return Construct_circumcenter_2();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
} // namespace Weights
|
||||
} // namespace CGAL
|
||||
|
||||
#endif // CGAL_WEIGHTS_INTERNAL_PROJECTION_TRAITS_BASE_3_H
|
||||
|
|
@ -93,20 +93,6 @@ namespace Weights {
|
|||
const typename GeomTraits::Point_2& q,
|
||||
const GeomTraits& traits) { }
|
||||
|
||||
/*!
|
||||
\ingroup PkgWeightsRefMeanValueWeights
|
||||
|
||||
\brief computes the mean value weight in 3D at `q` using the points `p0`, `p1`,
|
||||
and `p2`, given a traits class `traits` with geometric objects, predicates, and constructions.
|
||||
*/
|
||||
template<typename GeomTraits>
|
||||
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) { }
|
||||
|
||||
/*!
|
||||
\ingroup PkgWeightsRefMeanValueWeights
|
||||
|
||||
|
|
@ -120,19 +106,6 @@ namespace Weights {
|
|||
const CGAL::Point_2<K>& p2,
|
||||
const CGAL::Point_2<K>& q) { }
|
||||
|
||||
/*!
|
||||
\ingroup PkgWeightsRefMeanValueWeights
|
||||
|
||||
\brief computes the mean value weight in 3D at `q` using the points `p0`, `p1`,
|
||||
and `p2`, which are parameterized by a `Kernel` K.
|
||||
*/
|
||||
template<typename K>
|
||||
typename K::FT mean_value_weight(
|
||||
const CGAL::Point_3<K>& p0,
|
||||
const CGAL::Point_3<K>& p1,
|
||||
const CGAL::Point_3<K>& p2,
|
||||
const CGAL::Point_3<K>& q) { }
|
||||
|
||||
#endif // DOXYGEN_RUNNING
|
||||
|
||||
/// \cond SKIP_IN_MANUAL
|
||||
|
|
@ -182,6 +155,8 @@ namespace Weights {
|
|||
return mean_value_weight(t, r, p, q, traits);
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
|
||||
template<typename GeomTraits>
|
||||
typename GeomTraits::FT mean_value_weight(
|
||||
const typename GeomTraits::Point_3& t,
|
||||
|
|
@ -196,7 +171,8 @@ namespace Weights {
|
|||
traits,
|
||||
t, r, p, q,
|
||||
tf, rf, pf, qf);
|
||||
return mean_value_weight(tf, rf, pf, qf, traits);
|
||||
return CGAL::Weights::
|
||||
mean_value_weight(tf, rf, pf, qf, traits);
|
||||
}
|
||||
|
||||
template<typename GeomTraits>
|
||||
|
|
@ -209,6 +185,9 @@ namespace Weights {
|
|||
const GeomTraits traits;
|
||||
return mean_value_weight(t, r, p, q, traits);
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
/// \endcond
|
||||
|
||||
/*!
|
||||
|
|
|
|||
|
|
@ -50,6 +50,18 @@ namespace Weights {
|
|||
return w;
|
||||
}
|
||||
|
||||
template<typename FT>
|
||||
FT weight(const FT t1, const FT t2, const FT r) {
|
||||
|
||||
FT w = FT(0);
|
||||
CGAL_precondition(r != FT(0));
|
||||
if (r != FT(0)) {
|
||||
const FT inv = FT(2) / r;
|
||||
w = (t1 + t2) * inv;
|
||||
}
|
||||
return w;
|
||||
}
|
||||
|
||||
template<typename FT>
|
||||
FT weight(
|
||||
const FT d1, const FT r, const FT d2,
|
||||
|
|
@ -66,14 +78,76 @@ namespace Weights {
|
|||
const FT inv2 = FT(2) / P2;
|
||||
const FT t1 = A1 * inv1;
|
||||
const FT t2 = A2 * inv2;
|
||||
CGAL_precondition(r != FT(0));
|
||||
if (r != FT(0)) {
|
||||
const FT inv = FT(2) / r;
|
||||
w = (t1 + t2) * inv;
|
||||
}
|
||||
w = weight(t1, t2, r);
|
||||
}
|
||||
return w;
|
||||
}
|
||||
|
||||
// This is positive case only.
|
||||
// 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,
|
||||
const typename GeomTraits::Point_3& q,
|
||||
const GeomTraits& traits) {
|
||||
|
||||
using FT = typename GeomTraits::FT;
|
||||
const auto dot_product_3 =
|
||||
traits.compute_scalar_product_3_object();
|
||||
const auto construct_vector_3 =
|
||||
traits.construct_vector_3_object();
|
||||
|
||||
const auto v1 = construct_vector_3(q, t);
|
||||
const auto v2 = construct_vector_3(q, r);
|
||||
const auto v3 = construct_vector_3(q, p);
|
||||
|
||||
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 A1 = internal::positive_area_3(traits, r, q, t);
|
||||
const FT A2 = internal::positive_area_3(traits, p, q, r);
|
||||
|
||||
const FT D1 = dot_product_3(v1, v2);
|
||||
const FT D2 = dot_product_3(v2, v3);
|
||||
|
||||
return weight(l1, l2, l3, A1, A2, D1, 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,
|
||||
const typename GeomTraits::Point_3& q,
|
||||
const GeomTraits& traits) {
|
||||
|
||||
using FT = typename GeomTraits::FT;
|
||||
const auto construct_vector_3 =
|
||||
traits.construct_vector_3_object();
|
||||
|
||||
auto v1 = construct_vector_3(q, t);
|
||||
auto v2 = construct_vector_3(q, r);
|
||||
auto v3 = construct_vector_3(q, p);
|
||||
|
||||
const FT l2 = internal::length_3(traits, v2);
|
||||
|
||||
internal::normalize_3(traits, v1);
|
||||
internal::normalize_3(traits, v2);
|
||||
internal::normalize_3(traits, v3);
|
||||
|
||||
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 FT t2 = static_cast<FT>(std::tan(ha_rad_2));
|
||||
|
||||
return weight(t1, t2, l2);
|
||||
}
|
||||
}
|
||||
/// \endcond
|
||||
|
||||
|
|
@ -283,28 +357,8 @@ namespace Weights {
|
|||
const typename GeomTraits::Point_3& q,
|
||||
const GeomTraits& traits) {
|
||||
|
||||
using FT = typename GeomTraits::FT;
|
||||
const auto dot_product_3 =
|
||||
traits.compute_scalar_product_3_object();
|
||||
const auto construct_vector_3 =
|
||||
traits.construct_vector_3_object();
|
||||
|
||||
const auto v1 = construct_vector_3(q, t);
|
||||
const auto v2 = construct_vector_3(q, r);
|
||||
const auto v3 = construct_vector_3(q, p);
|
||||
|
||||
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 A1 = internal::positive_area_3(traits, r, q, t);
|
||||
const FT A2 = internal::positive_area_3(traits, p, q, r);
|
||||
|
||||
const FT D1 = dot_product_3(v1, v2);
|
||||
const FT D2 = dot_product_3(v2, v3);
|
||||
|
||||
return tangent_ns::weight(
|
||||
l1, l2, l3, A1, A2, D1, D2);
|
||||
// return tangent_ns::tangent_weight_v1(t, r, p, q, traits);
|
||||
return tangent_ns::tangent_weight_v2(t, r, p, q, traits);
|
||||
}
|
||||
|
||||
template<typename GeomTraits>
|
||||
|
|
|
|||
|
|
@ -75,22 +75,6 @@ namespace Weights {
|
|||
const typename GeomTraits::FT a,
|
||||
const GeomTraits& traits) { }
|
||||
|
||||
/*!
|
||||
\ingroup PkgWeightsRefThreePointFamilyWeights
|
||||
|
||||
\brief computes the three-point family weight in 3D at `q` using the points `p0`, `p1`,
|
||||
and `p2` and the power parameter `a`, given a traits class `traits` with geometric objects,
|
||||
predicates, and constructions.
|
||||
*/
|
||||
template<typename GeomTraits>
|
||||
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) { }
|
||||
|
||||
/*!
|
||||
\ingroup PkgWeightsRefThreePointFamilyWeights
|
||||
|
||||
|
|
@ -106,21 +90,6 @@ namespace Weights {
|
|||
const CGAL::Point_2<K>& q,
|
||||
const typename K::FT a = typename K::FT(1)) { }
|
||||
|
||||
/*!
|
||||
\ingroup PkgWeightsRefThreePointFamilyWeights
|
||||
|
||||
\brief computes the three-point family weight in 3D at `q` using the points `p0`, `p1`,
|
||||
and `p2`, which are parameterized by a `Kernel` K, and the power parameter `a`, which
|
||||
can be omitted.
|
||||
*/
|
||||
template<typename K>
|
||||
typename K::FT three_point_family_weight(
|
||||
const CGAL::Point_3<K>& p0,
|
||||
const CGAL::Point_3<K>& p1,
|
||||
const CGAL::Point_3<K>& p2,
|
||||
const CGAL::Point_3<K>& q,
|
||||
const typename K::FT a = typename K::FT(1)) { }
|
||||
|
||||
#endif // DOXYGEN_RUNNING
|
||||
|
||||
/// \cond SKIP_IN_MANUAL
|
||||
|
|
@ -159,6 +128,37 @@ namespace Weights {
|
|||
return three_point_family_weight(t, r, p, q, a, traits);
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
|
||||
// Example of flattening:
|
||||
|
||||
// 3D configuration.
|
||||
// const Point_3 p0(0, 1, 1);
|
||||
// const Point_3 p1(2, 0, 1);
|
||||
// const Point_3 p2(7, 1, 1);
|
||||
// const Point_3 q0(3, 1, 1);
|
||||
|
||||
// Choose a type of the weight:
|
||||
// e.g. 0 - Wachspress (WP) weight.
|
||||
// const FT wp = FT(0);
|
||||
|
||||
// Compute WP weights for q1, which is not on the plane [p0, p1, p2].
|
||||
|
||||
// Point_3 q1(3, 1, 2);
|
||||
// std::cout << "3D wachspress (WP, q1): ";
|
||||
// std::cout << CGAL::Weights::three_point_family_weight(p0, p1, p2, q1, wp) << std::endl;
|
||||
|
||||
// Converge q1 towards q0 that is we flatten the configuration.
|
||||
// We also compare the result with the authalic weight.
|
||||
|
||||
// std::cout << "Converge q1 to q0: " << std::endl;
|
||||
// for (FT x = FT(0); x <= FT(1); x += step) {
|
||||
// std::cout << "3D wachspress/authalic: ";
|
||||
// q1 = Point_3(3, 1, FT(2) - x);
|
||||
// std::cout << CGAL::Weights::three_point_family_weight(p0, p1, p2, q1, wp) << "/";
|
||||
// std::cout << CGAL::Weights::authalic_weight(p0, p1, p2, q1) << std::endl;
|
||||
// }
|
||||
|
||||
template<typename GeomTraits>
|
||||
typename GeomTraits::FT three_point_family_weight(
|
||||
const typename GeomTraits::Point_3& t,
|
||||
|
|
@ -174,7 +174,8 @@ namespace Weights {
|
|||
traits,
|
||||
t, r, p, q,
|
||||
tf, rf, pf, qf);
|
||||
return three_point_family_weight(tf, rf, pf, qf, a, traits);
|
||||
return CGAL::Weights::
|
||||
three_point_family_weight(tf, rf, pf, qf, a, traits);
|
||||
}
|
||||
|
||||
template<typename GeomTraits>
|
||||
|
|
@ -189,6 +190,9 @@ namespace Weights {
|
|||
const GeomTraits traits;
|
||||
return three_point_family_weight(t, r, p, q, a, traits);
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
/// \endcond
|
||||
|
||||
} // namespace Weights
|
||||
|
|
|
|||
|
|
@ -57,20 +57,6 @@ namespace Weights {
|
|||
const typename GeomTraits::Point_2& q,
|
||||
const GeomTraits& traits) { }
|
||||
|
||||
/*!
|
||||
\ingroup PkgWeightsRefWachspressWeights
|
||||
|
||||
\brief computes the Wachspress weight in 3D at `q` using the points `p0`, `p1`,
|
||||
and `p2`, given a traits class `traits` with geometric objects, predicates, and constructions.
|
||||
*/
|
||||
template<typename GeomTraits>
|
||||
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) { }
|
||||
|
||||
/*!
|
||||
\ingroup PkgWeightsRefWachspressWeights
|
||||
|
||||
|
|
@ -84,19 +70,6 @@ namespace Weights {
|
|||
const CGAL::Point_2<K>& p2,
|
||||
const CGAL::Point_2<K>& q) { }
|
||||
|
||||
/*!
|
||||
\ingroup PkgWeightsRefWachspressWeights
|
||||
|
||||
\brief computes the Wachspress weight in 3D at `q` using the points `p0`, `p1`,
|
||||
and `p2`, which are parameterized by a `Kernel` K.
|
||||
*/
|
||||
template<typename K>
|
||||
typename K::FT wachspress_weight(
|
||||
const CGAL::Point_3<K>& p0,
|
||||
const CGAL::Point_3<K>& p1,
|
||||
const CGAL::Point_3<K>& p2,
|
||||
const CGAL::Point_3<K>& q) { }
|
||||
|
||||
#endif // DOXYGEN_RUNNING
|
||||
|
||||
/// \cond SKIP_IN_MANUAL
|
||||
|
|
@ -126,6 +99,8 @@ namespace Weights {
|
|||
return wachspress_weight(t, r, p, q, traits);
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
|
||||
template<typename GeomTraits>
|
||||
typename GeomTraits::FT wachspress_weight(
|
||||
const typename GeomTraits::Point_3& t,
|
||||
|
|
@ -140,7 +115,8 @@ namespace Weights {
|
|||
traits,
|
||||
t, r, p, q,
|
||||
tf, rf, pf, qf);
|
||||
return wachspress_weight(tf, rf, pf, qf, traits);
|
||||
return CGAL::Weights::
|
||||
wachspress_weight(tf, rf, pf, qf, traits);
|
||||
}
|
||||
|
||||
template<typename GeomTraits>
|
||||
|
|
@ -153,6 +129,9 @@ namespace Weights {
|
|||
const GeomTraits traits;
|
||||
return wachspress_weight(t, r, p, q, traits);
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
/// \endcond
|
||||
|
||||
/*!
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ if(CGAL_FOUND)
|
|||
create_single_source_cgal_program("test_shepard_weights.cpp")
|
||||
create_single_source_cgal_program("test_inverse_distance_weights.cpp")
|
||||
create_single_source_cgal_program("test_three_point_family_weights.cpp")
|
||||
create_single_source_cgal_program("test_projected_weights.cpp")
|
||||
|
||||
create_single_source_cgal_program("test_wachspress_weights.cpp")
|
||||
create_single_source_cgal_program("test_authalic_weights.cpp")
|
||||
|
|
@ -33,6 +34,5 @@ if(CGAL_FOUND)
|
|||
create_single_source_cgal_program("test_mixed_voronoi_region_weights.cpp")
|
||||
|
||||
else()
|
||||
message(WARNING
|
||||
"This program requires the CGAL library, and will not be compiled.")
|
||||
message(WARNING "This program requires the CGAL library, and will not be compiled.")
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,557 @@
|
|||
#ifndef CGAL_WEIGHTS_TESTS_UTILS_H
|
||||
#define CGAL_WEIGHTS_TESTS_UTILS_H
|
||||
|
||||
// STL includes.
|
||||
#include <array>
|
||||
#include <vector>
|
||||
#include <cassert>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
||||
// CGAL includes.
|
||||
#include <CGAL/assertions.h>
|
||||
#include <CGAL/Projection_traits_xy_3.h>
|
||||
#include <CGAL/Weights/utils.h>
|
||||
|
||||
namespace tests {
|
||||
|
||||
template<typename FT>
|
||||
FT get_tolerance() {
|
||||
return FT(1) / FT(10000000000);
|
||||
}
|
||||
|
||||
template<typename Kernel>
|
||||
std::vector< std::array<typename Kernel::Point_2, 3> >
|
||||
get_all_triangles() {
|
||||
|
||||
using Point_2 = typename Kernel::Point_2;
|
||||
const std::array<Point_2, 3> triangle0 = {
|
||||
Point_2(-1, 0), Point_2(0, -1), Point_2(1, 0)
|
||||
};
|
||||
const std::array<Point_2, 3> triangle1 = {
|
||||
Point_2(-2, 0), Point_2(0, -1), Point_2(2, 0)
|
||||
};
|
||||
const std::array<Point_2, 3> triangle2 = {
|
||||
Point_2(-2, 0), Point_2(-2, -2), Point_2(2, 0)
|
||||
};
|
||||
const std::array<Point_2, 3> triangle3 = {
|
||||
Point_2(-2, 0), Point_2(2, -2), Point_2(2, 0)
|
||||
};
|
||||
return { triangle0, triangle1, triangle2, triangle3 };
|
||||
}
|
||||
|
||||
template<typename Kernel>
|
||||
std::vector< std::array<typename Kernel::Point_2, 3> >
|
||||
get_symmetric_triangles() {
|
||||
|
||||
using Point_2 = typename Kernel::Point_2;
|
||||
const std::array<Point_2, 3> triangle0 = {
|
||||
Point_2(-1, 0), Point_2(0, -1), Point_2(1, 0)
|
||||
};
|
||||
const std::array<Point_2, 3> triangle1 = {
|
||||
Point_2(-2, 0), Point_2(0, -1), Point_2(2, 0)
|
||||
};
|
||||
const std::array<Point_2, 3> triangle2 = {
|
||||
Point_2(-3, 0), Point_2(0, -1), Point_2(3, 0)
|
||||
};
|
||||
return { triangle0, triangle1, triangle2 };
|
||||
}
|
||||
|
||||
template<typename Kernel>
|
||||
std::vector< std::array<typename Kernel::Point_2, 3> >
|
||||
get_uniform_triangles() {
|
||||
|
||||
using Point_2 = typename Kernel::Point_2;
|
||||
const std::array<Point_2, 3> triangle0 = {
|
||||
Point_2(-1, 0), Point_2(0, -1), Point_2(1, 0)
|
||||
};
|
||||
const std::array<Point_2, 3> triangle1 = {
|
||||
Point_2(-2, 0), Point_2(0, -2), Point_2(2, 0)
|
||||
};
|
||||
const std::array<Point_2, 3> triangle2 = {
|
||||
Point_2(1, 0), Point_2(-1, 0), Point_2(-1, -2)
|
||||
};
|
||||
const std::array<Point_2, 3> triangle3 = {
|
||||
Point_2(1, -2), Point_2(1, 0), Point_2(-1, 0)
|
||||
};
|
||||
return { triangle0, triangle1, triangle2, triangle3 };
|
||||
}
|
||||
|
||||
template<typename Kernel>
|
||||
std::vector< std::vector<typename Kernel::Point_2> >
|
||||
get_all_polygons() {
|
||||
|
||||
using Point_2 = typename Kernel::Point_2;
|
||||
const std::vector<Point_2> polygon0 = {
|
||||
Point_2(-2, -2), Point_2(2, -2), Point_2(0, 2)
|
||||
};
|
||||
const std::vector<Point_2> polygon1 = {
|
||||
Point_2(-1, -1), Point_2(1, -1), Point_2(1, 1), Point_2(-1, 1)
|
||||
};
|
||||
const std::vector<Point_2> polygon2 = {
|
||||
Point_2(-2, 0), Point_2(0, -2), Point_2(2, 0), Point_2(0, 2)
|
||||
};
|
||||
const std::vector<Point_2> polygon3 = {
|
||||
Point_2(-2, -2), Point_2(2, -2), Point_2(2, 0), Point_2(0, 2), Point_2(-2, 0)
|
||||
};
|
||||
return { polygon0, polygon1, polygon2, polygon3 };
|
||||
}
|
||||
|
||||
template<
|
||||
typename Kernel,
|
||||
typename Weight_wrapper>
|
||||
bool test_query(
|
||||
const Weight_wrapper& wrapper,
|
||||
const typename Kernel::Point_2& query,
|
||||
const std::array<typename Kernel::Point_2, 3>& neighbors) {
|
||||
|
||||
using FT = typename Kernel::FT;
|
||||
using Point_2 = typename Kernel::Point_2;
|
||||
using Point_3 = typename Kernel::Point_3;
|
||||
const FT tol = get_tolerance<FT>();
|
||||
|
||||
// 2D configuration.
|
||||
const Point_2& t2 = neighbors[0];
|
||||
const Point_2& r2 = neighbors[1];
|
||||
const Point_2& p2 = neighbors[2];
|
||||
const Point_2& q2 = query;
|
||||
|
||||
// 3D configuration.
|
||||
const Point_3 t3(t2.x(), t2.y(), 1);
|
||||
const Point_3 r3(r2.x(), r2.y(), 1);
|
||||
const Point_3 p3(p2.x(), p2.y(), 1);
|
||||
const Point_3 q3(q2.x(), q2.y(), 1);
|
||||
|
||||
const auto a2 = wrapper.weight_a(t2, r2, p2, q2);
|
||||
const auto b2 = wrapper.weight_b(t2, r2, p2, q2);
|
||||
CGAL_assertion(a2 >= FT(0) && b2 >= FT(0));
|
||||
if (a2 < FT(0) || b2 < FT(0)) return false;
|
||||
CGAL_assertion(CGAL::abs(a2 - b2) < tol);
|
||||
if (CGAL::abs(a2 - b2) >= tol) return false;
|
||||
|
||||
if (wrapper.supports_3d()) {
|
||||
const auto a3 = wrapper.weight_a(t3, r3, p3, q3);
|
||||
const auto b3 = wrapper.weight_b(t3, r3, p3, q3);
|
||||
CGAL_assertion(a3 >= FT(0) && b3 >= FT(0));
|
||||
if (a3 < FT(0) || b3 < FT(0)) return false;
|
||||
CGAL_assertion(CGAL::abs(a3 - b3) < tol);
|
||||
if (CGAL::abs(a3 - b3) >= tol) return false;
|
||||
CGAL_assertion(CGAL::abs(a2 - a3) < tol);
|
||||
CGAL_assertion(CGAL::abs(b2 - b3) < tol);
|
||||
if (CGAL::abs(a2 - a3) >= tol) return false;
|
||||
if (CGAL::abs(b2 - b3) >= tol) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<
|
||||
typename Kernel,
|
||||
typename Weight_wrapper>
|
||||
bool test_symmetry_x(
|
||||
const Weight_wrapper& wrapper,
|
||||
const std::array<typename Kernel::Point_2, 3>& neighbors,
|
||||
const typename Kernel::FT& x) {
|
||||
|
||||
using FT = typename Kernel::FT;
|
||||
using Point_2 = typename Kernel::Point_2;
|
||||
using Point_3 = typename Kernel::Point_3;
|
||||
const FT tol = get_tolerance<FT>();
|
||||
|
||||
// 2D configuration.
|
||||
const Point_2& t2 = neighbors[0];
|
||||
const Point_2& r2 = neighbors[1];
|
||||
const Point_2& p2 = neighbors[2];
|
||||
|
||||
// 3D configuration.
|
||||
const Point_3 t3(t2.x(), t2.y(), 1);
|
||||
const Point_3 r3(r2.x(), r2.y(), 1);
|
||||
const Point_3 p3(p2.x(), p2.y(), 1);
|
||||
|
||||
const auto a2 = wrapper.weight_a(t2, r2, p2, Point_2(-x, 0));
|
||||
const auto b2 = wrapper.weight_a(t2, r2, p2, Point_2(+x, 0));
|
||||
CGAL_assertion(a2 >= FT(0) && b2 >= FT(0));
|
||||
if (a2 < FT(0) || b2 < FT(0)) return false;
|
||||
CGAL_assertion(CGAL::abs(a2 - b2) < tol);
|
||||
if (CGAL::abs(a2 - b2) >= tol) return false;
|
||||
|
||||
if (wrapper.supports_3d()) {
|
||||
const auto a3 = wrapper.weight_a(t3, r3, p3, Point_3(-x, 0, 1));
|
||||
const auto b3 = wrapper.weight_a(t3, r3, p3, Point_3(+x, 0, 1));
|
||||
CGAL_assertion(a3 >= FT(0) && b3 >= FT(0));
|
||||
if (a3 < FT(0) || b3 < FT(0)) return false;
|
||||
CGAL_assertion(CGAL::abs(a3 - b3) < tol);
|
||||
if (CGAL::abs(a3 - b3) >= tol) return false;
|
||||
CGAL_assertion(CGAL::abs(a2 - a3) < tol);
|
||||
CGAL_assertion(CGAL::abs(b2 - b3) < tol);
|
||||
if (CGAL::abs(a2 - a3) >= tol) return false;
|
||||
if (CGAL::abs(b2 - b3) >= tol) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<
|
||||
typename Kernel,
|
||||
typename Weight_wrapper_1,
|
||||
typename Weight_wrapper_2>
|
||||
bool test_compare(
|
||||
const Weight_wrapper_1& wrapper1,
|
||||
const Weight_wrapper_2& wrapper2,
|
||||
const typename Kernel::Point_2& query,
|
||||
const std::array<typename Kernel::Point_2, 3>& neighbors) {
|
||||
|
||||
using FT = typename Kernel::FT;
|
||||
using Point_2 = typename Kernel::Point_2;
|
||||
using Point_3 = typename Kernel::Point_3;
|
||||
const FT tol = get_tolerance<FT>();
|
||||
|
||||
// 2D configuration.
|
||||
const Point_2& t2 = neighbors[0];
|
||||
const Point_2& r2 = neighbors[1];
|
||||
const Point_2& p2 = neighbors[2];
|
||||
const Point_2& q2 = query;
|
||||
|
||||
// 3D configuration.
|
||||
const Point_3 t3(t2.x(), t2.y(), 1);
|
||||
const Point_3 r3(r2.x(), r2.y(), 1);
|
||||
const Point_3 p3(p2.x(), p2.y(), 1);
|
||||
const Point_3 q3(q2.x(), q2.y(), 1);
|
||||
|
||||
const auto a2 = wrapper1.weight_a(t2, r2, p2, q2);
|
||||
const auto b2 = wrapper2.weight_a(t2, r2, p2, q2);
|
||||
CGAL_assertion(a2 >= FT(0) && b2 >= FT(0));
|
||||
if (a2 < FT(0) || b2 < FT(0)) return false;
|
||||
CGAL_assertion(CGAL::abs(a2 - b2) < tol);
|
||||
if (CGAL::abs(a2 - b2) >= tol) return false;
|
||||
|
||||
if (wrapper1.supports_3d() && wrapper2.supports_3d()) {
|
||||
const auto a3 = wrapper1.weight_a(t3, r3, p3, q3);
|
||||
const auto b3 = wrapper2.weight_a(t3, r3, p3, q3);
|
||||
CGAL_assertion(a3 >= FT(0) && b3 >= FT(0));
|
||||
if (a3 < FT(0) || b3 < FT(0)) return false;
|
||||
CGAL_assertion(CGAL::abs(a3 - b3) < tol);
|
||||
if (CGAL::abs(a3 - b3) >= tol) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<
|
||||
typename Kernel,
|
||||
typename Weight_wrapper>
|
||||
bool test_neighbors(
|
||||
const Weight_wrapper& wrapper,
|
||||
const std::array<typename Kernel::Point_2, 3>& neighbors) {
|
||||
|
||||
using FT = typename Kernel::FT;
|
||||
using Point_2 = typename Kernel::Point_2;
|
||||
using Point_3 = typename Kernel::Point_3;
|
||||
const FT tol = get_tolerance<FT>();
|
||||
|
||||
// 2D configuration.
|
||||
const Point_2& p2 = neighbors[0];
|
||||
const Point_2& q2 = neighbors[1];
|
||||
const Point_2& r2 = neighbors[2];
|
||||
|
||||
// 3D configuration.
|
||||
const Point_3 p3(p2.x(), p2.y(), 1);
|
||||
const Point_3 q3(q2.x(), q2.y(), 1);
|
||||
const Point_3 r3(r2.x(), r2.y(), 1);
|
||||
|
||||
const auto a2 = wrapper.weight(p2, q2, r2);
|
||||
const auto a3 = wrapper.weight(p3, q3, r3);
|
||||
CGAL_assertion(a2 >= FT(0) && a3 >= FT(0));
|
||||
if (a2 < FT(0) || a3 < FT(0)) return false;
|
||||
CGAL_assertion(CGAL::abs(a2 - a3) < tol);
|
||||
if (CGAL::abs(a2 - a3) >= tol) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
template<
|
||||
typename Kernel,
|
||||
typename Weight_wrapper>
|
||||
bool test_area(
|
||||
const Weight_wrapper& wrapper,
|
||||
const std::array<typename Kernel::Point_2, 3>& neighbors) {
|
||||
|
||||
using FT = typename Kernel::FT;
|
||||
using Point_2 = typename Kernel::Point_2;
|
||||
using Point_3 = typename Kernel::Point_3;
|
||||
|
||||
// 2D configuration.
|
||||
const Point_2& p2 = neighbors[0];
|
||||
const Point_2& q2 = neighbors[1];
|
||||
const Point_2& r2 = neighbors[2];
|
||||
|
||||
// 3D configuration.
|
||||
const Point_3 p3(p2.x(), p2.y(), 1);
|
||||
const Point_3 q3(q2.x(), q2.y(), 1);
|
||||
const Point_3 r3(r2.x(), r2.y(), 1);
|
||||
|
||||
const auto a2 = wrapper.weight(p2, q2, r2);
|
||||
const auto a3 = wrapper.weight(p3, q3, r3);
|
||||
CGAL_assertion(a2 <= CGAL::Weights::area(p2, q2, r2));
|
||||
CGAL_assertion(a3 <= CGAL::Weights::area(p3, q3, r3));
|
||||
if (a2 > CGAL::Weights::area(p2, q2, r2)) return false;
|
||||
if (a3 > CGAL::Weights::area(p3, q3, r3)) return false;
|
||||
CGAL_assertion(a2 >= FT(0));
|
||||
CGAL_assertion(a3 >= FT(0));
|
||||
if (a2 < FT(0)) return false;
|
||||
if (a3 < FT(0)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename FT, typename Point>
|
||||
bool test_coordinates(
|
||||
const Point& query,
|
||||
const std::vector<Point>& polygon,
|
||||
const std::vector<FT>& weights) {
|
||||
|
||||
CGAL_assertion(weights.size() > 0);
|
||||
if (weights.size() == 0) return false;
|
||||
|
||||
// Compute the sum of weights.
|
||||
const FT tol = get_tolerance<FT>();
|
||||
FT sum = FT(0);
|
||||
for (const FT& weight : weights) {
|
||||
sum += weight;
|
||||
}
|
||||
CGAL_assertion(sum >= tol);
|
||||
if (sum < tol) return false;
|
||||
|
||||
// Compute coordinates.
|
||||
std::vector<FT> coordinates;
|
||||
coordinates.reserve(weights.size());
|
||||
for (const FT& weight : weights) {
|
||||
coordinates.push_back(weight / sum);
|
||||
}
|
||||
CGAL_assertion(coordinates.size() == weights.size());
|
||||
if (coordinates.size() != weights.size()) return false;
|
||||
|
||||
// Test partition of unity.
|
||||
sum = FT(0);
|
||||
for (const FT& coordinate : coordinates) {
|
||||
sum += coordinate;
|
||||
}
|
||||
CGAL_assertion(CGAL::abs(FT(1) - sum) < tol);
|
||||
if (CGAL::abs(FT(1) - sum) >= tol) return false;
|
||||
|
||||
// Test linear precision.
|
||||
FT x = FT(0), y = FT(0);
|
||||
for (std::size_t i = 0; i < polygon.size(); ++i) {
|
||||
x += coordinates[i] * polygon[i].x();
|
||||
y += coordinates[i] * polygon[i].y();
|
||||
}
|
||||
CGAL_assertion(CGAL::abs(query.x() - x) < tol);
|
||||
CGAL_assertion(CGAL::abs(query.y() - y) < tol);
|
||||
if (CGAL::abs(query.x() - x) >= tol) return false;
|
||||
if (CGAL::abs(query.y() - y) >= tol) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
template<
|
||||
typename Kernel,
|
||||
typename Weight_wrapper>
|
||||
bool test_on_polygon(
|
||||
const Weight_wrapper& wrapper,
|
||||
const typename Kernel::Point_2& query_2,
|
||||
const std::vector<typename Kernel::Point_2>& polygon_2) {
|
||||
|
||||
// Get weights.
|
||||
using FT = typename Kernel::FT;
|
||||
CGAL_assertion(polygon_2.size() >= 3);
|
||||
if (polygon_2.size() < 3) return false;
|
||||
|
||||
// 2D version.
|
||||
std::vector<FT> weights_2;
|
||||
weights_2.reserve(polygon_2.size());
|
||||
wrapper.compute_on_polygon(
|
||||
polygon_2, query_2, Kernel(), std::back_inserter(weights_2));
|
||||
CGAL_assertion(weights_2.size() == polygon_2.size());
|
||||
if (weights_2.size() != polygon_2.size()) return false;
|
||||
if (!test_coordinates(query_2, polygon_2, weights_2)) return false;
|
||||
|
||||
// 3D version.
|
||||
using Point_3 = typename Kernel::Point_3;
|
||||
const Point_3 query_3(query_2.x(), query_2.y(), 1);
|
||||
std::vector<Point_3> polygon_3;
|
||||
polygon_3.reserve(polygon_2.size());
|
||||
for (const auto& vertex_2 : polygon_2) {
|
||||
polygon_3.push_back(Point_3(vertex_2.x(), vertex_2.y(), 1));
|
||||
}
|
||||
CGAL_assertion(polygon_3.size() == polygon_2.size());
|
||||
if (polygon_3.size() != polygon_2.size()) return false;
|
||||
const CGAL::Projection_traits_xy_3<Kernel> ptraits;
|
||||
|
||||
std::vector<FT> weights_3;
|
||||
weights_3.reserve(polygon_3.size());
|
||||
wrapper.compute_on_polygon(
|
||||
polygon_3, query_3, ptraits, std::back_inserter(weights_3));
|
||||
CGAL_assertion(weights_3.size() == polygon_3.size());
|
||||
if (weights_3.size() != polygon_3.size()) return false;
|
||||
if (!test_coordinates(query_3, polygon_3, weights_3)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
template<
|
||||
typename Kernel,
|
||||
typename Weight_wrapper>
|
||||
bool test_barycentric_properties(
|
||||
const Weight_wrapper& wrapper,
|
||||
const typename Kernel::Point_2& query,
|
||||
const std::vector<typename Kernel::Point_2>& polygon) {
|
||||
|
||||
// Get weights.
|
||||
using FT = typename Kernel::FT;
|
||||
const std::size_t n = polygon.size();
|
||||
CGAL_assertion(n >= 3);
|
||||
if (n < 3) return false;
|
||||
|
||||
// Check properties.
|
||||
std::vector<FT> weights;
|
||||
weights.reserve(n);
|
||||
for (std::size_t i = 0; i < n; ++i) {
|
||||
const std::size_t im = (i + n - 1) % n;
|
||||
const std::size_t ip = (i + 1) % n;
|
||||
const auto& t = polygon[im];
|
||||
const auto& r = polygon[i];
|
||||
const auto& p = polygon[ip];
|
||||
const auto& q = query;
|
||||
const FT weight = wrapper.weight_a(t, r, p, q);
|
||||
weights.push_back(weight);
|
||||
}
|
||||
CGAL_assertion(weights.size() == n);
|
||||
if (weights.size() != n) return false;
|
||||
if (!test_coordinates(query, polygon, weights)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
template<
|
||||
typename Kernel,
|
||||
typename Weight_wrapper_1,
|
||||
typename Weight_wrapper_2>
|
||||
bool test_analytic_weight(
|
||||
const Weight_wrapper_1& weight,
|
||||
const Weight_wrapper_2& alternative) {
|
||||
|
||||
using FT = typename Kernel::FT;
|
||||
using Point_2 = typename Kernel::Point_2;
|
||||
|
||||
// Data.
|
||||
const FT q = FT(1) / FT(4);
|
||||
const FT h = FT(1) / FT(2);
|
||||
const FT t = FT(3) / FT(4);
|
||||
|
||||
const Point_2 zero(0, 0);
|
||||
const std::vector<Point_2> queries = {
|
||||
Point_2(-q, 0), Point_2(+q, 0), Point_2(0, -q), Point_2(0, +q),
|
||||
Point_2(-h, 0), Point_2(+h, 0), Point_2(0, -h), Point_2(0, +h),
|
||||
Point_2(-t, 0), Point_2(+t, 0), Point_2(0, -t), Point_2(0, +t)
|
||||
};
|
||||
|
||||
// Test query points.
|
||||
auto configs = get_all_triangles<Kernel>();
|
||||
for (const auto& config : configs) {
|
||||
if (!test_query<Kernel>(weight, zero, config)) return false;
|
||||
for (const auto& query : queries) {
|
||||
if (!test_query<Kernel>(weight, query, config)) return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Test alternative formulations.
|
||||
for (const auto& config : configs) {
|
||||
if (!test_compare<Kernel>(weight, alternative, zero, config)) {
|
||||
return false;
|
||||
}
|
||||
for (const auto& query : queries) {
|
||||
if (!test_compare<Kernel>(weight, alternative, query, config)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Test symmetry along x axis.
|
||||
configs = get_symmetric_triangles<Kernel>();
|
||||
for (const auto& config : configs) {
|
||||
if (!test_symmetry_x<Kernel>(weight, config, q)) return false;
|
||||
if (!test_symmetry_x<Kernel>(weight, config, h)) return false;
|
||||
if (!test_symmetry_x<Kernel>(weight, config, t)) return false;
|
||||
}
|
||||
|
||||
// Test barycentric properties.
|
||||
if (weight.is_barycentric()) {
|
||||
const auto polygons = get_all_polygons<Kernel>();
|
||||
for (const auto& polygon : polygons) {
|
||||
if (!test_barycentric_properties<Kernel>(weight, zero, polygon)) {
|
||||
return false;
|
||||
}
|
||||
for (const auto& query : queries) {
|
||||
if (!test_barycentric_properties<Kernel>(weight, query, polygon)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<
|
||||
typename Kernel,
|
||||
typename Weight_wrapper_1,
|
||||
typename Weight_wrapper_2>
|
||||
bool test_barycentric_weight(
|
||||
const Weight_wrapper_1& weight,
|
||||
const Weight_wrapper_2& alternative) {
|
||||
|
||||
using FT = typename Kernel::FT;
|
||||
using Point_2 = typename Kernel::Point_2;
|
||||
|
||||
// Data.
|
||||
const FT q = FT(1) / FT(4);
|
||||
const FT h = FT(1) / FT(2);
|
||||
const Point_2 zero(0, 0);
|
||||
const std::vector<Point_2> queries = {
|
||||
Point_2(-h, 0), Point_2(+h, 0), Point_2(-q, 0), Point_2(+q, 0),
|
||||
Point_2( 0, -h), Point_2( 0, +h), Point_2( 0, -q), Point_2( 0, +q),
|
||||
Point_2(-h, -h), Point_2(+h, +h), Point_2(-q, -q), Point_2(+q, +q),
|
||||
Point_2(-h, +q), Point_2(+h, -q), Point_2(-q, +h), Point_2(+q, -h)
|
||||
};
|
||||
|
||||
// Test analytic formulations.
|
||||
if (!test_analytic_weight<Kernel>(weight, alternative)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Test on polygons.
|
||||
const auto polygons = get_all_polygons<Kernel>();
|
||||
for (const auto& polygon : polygons) {
|
||||
if (!test_on_polygon<Kernel>(weight, zero, polygon)) return false;
|
||||
for (const auto& query : queries) {
|
||||
if (!test_on_polygon<Kernel>(weight, query, polygon)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<
|
||||
typename Kernel,
|
||||
typename Weight_wrapper>
|
||||
bool test_region_weight(const Weight_wrapper& weight) {
|
||||
|
||||
// Test neighborhoods.
|
||||
auto configs = get_all_triangles<Kernel>();
|
||||
for (const auto& config : configs) {
|
||||
if (!test_neighbors<Kernel>(weight, config)) return false;
|
||||
}
|
||||
|
||||
// Test areas.
|
||||
configs = get_uniform_triangles<Kernel>();
|
||||
for (const auto& config : configs) {
|
||||
if (!test_area<Kernel>(weight, config)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace tests
|
||||
|
||||
#endif // CGAL_WEIGHTS_TESTS_UTILS_H
|
||||
|
|
@ -0,0 +1,265 @@
|
|||
#ifndef CGAL_WEIGHTS_TESTS_WRAPPERS_H
|
||||
#define CGAL_WEIGHTS_TESTS_WRAPPERS_H
|
||||
|
||||
// STL includes.
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
// CGAL includes.
|
||||
#include <CGAL/Weights.h>
|
||||
|
||||
namespace wrappers {
|
||||
|
||||
template<typename Kernel>
|
||||
struct Authalic_wrapper {
|
||||
using FT = typename Kernel::FT;
|
||||
template<typename Point>
|
||||
FT weight_a(const Point& t, const Point& r, const Point& p, const Point& q) const {
|
||||
return CGAL::Weights::authalic_weight(t, r, p, q);
|
||||
}
|
||||
template<typename Point>
|
||||
FT weight_b(const Point& t, const Point& r, const Point& p, const Point& q) const {
|
||||
return
|
||||
CGAL::Weights::half_authalic_weight(
|
||||
CGAL::Weights::cotangent(t, r, q),
|
||||
CGAL::Weights::squared_distance(q, r)) +
|
||||
CGAL::Weights::half_authalic_weight(
|
||||
CGAL::Weights::cotangent(q, r, p),
|
||||
CGAL::Weights::squared_distance(q, r));
|
||||
}
|
||||
bool supports_3d() const { return true; }
|
||||
bool is_barycentric() const { return true; }
|
||||
};
|
||||
|
||||
template<typename Kernel>
|
||||
struct Cotangent_wrapper {
|
||||
using FT = typename Kernel::FT;
|
||||
template<typename Point>
|
||||
FT weight_a(const Point& t, const Point& r, const Point& p, const Point& q) const {
|
||||
return CGAL::Weights::cotangent_weight(t, r, p, q);
|
||||
}
|
||||
template<typename Point>
|
||||
FT weight_b(const Point& t, const Point& r, const Point& p, const Point& q) const {
|
||||
return
|
||||
CGAL::Weights::half_cotangent_weight(
|
||||
CGAL::Weights::cotangent(q, t, r)) +
|
||||
CGAL::Weights::half_cotangent_weight(
|
||||
CGAL::Weights::cotangent(r, p, q));
|
||||
}
|
||||
bool supports_3d() const { return true; }
|
||||
bool is_barycentric() const { return true; }
|
||||
};
|
||||
|
||||
template<typename Kernel>
|
||||
struct Tangent_wrapper {
|
||||
using FT = typename Kernel::FT;
|
||||
template<typename Point>
|
||||
FT weight_a(const Point& t, const Point& r, const Point& p, const Point& q) const {
|
||||
return CGAL::Weights::tangent_weight(t, r, p, q);
|
||||
}
|
||||
template<typename Point>
|
||||
FT weight_b(const Point& t, const Point& r, const Point& p, const Point& q) const {
|
||||
return
|
||||
CGAL::Weights::half_tangent_weight(
|
||||
CGAL::Weights::distance(r, q),
|
||||
CGAL::Weights::distance(t, q),
|
||||
CGAL::Weights::area(r, q, t),
|
||||
CGAL::Weights::scalar_product(r, q, t)) +
|
||||
CGAL::Weights::half_tangent_weight(
|
||||
CGAL::Weights::distance(r, q),
|
||||
CGAL::Weights::distance(p, q),
|
||||
CGAL::Weights::area(p, q, r),
|
||||
CGAL::Weights::scalar_product(p, q, r));
|
||||
}
|
||||
bool supports_3d() const { return true; }
|
||||
bool is_barycentric() const { return true; }
|
||||
};
|
||||
|
||||
template<typename Kernel>
|
||||
struct Wachspress_wrapper {
|
||||
using FT = typename Kernel::FT;
|
||||
using Point_2 = typename Kernel::Point_2;
|
||||
using Point_3 = typename Kernel::Point_3;
|
||||
FT weight_a(const Point_2& t, const Point_2& r, const Point_2& p, const Point_2& q) const {
|
||||
return CGAL::Weights::wachspress_weight(t, r, p, q);
|
||||
}
|
||||
FT weight_a(const Point_3&, const Point_3&, const Point_3&, const Point_3&) const {
|
||||
return FT(-1);
|
||||
}
|
||||
template<typename Point>
|
||||
FT weight_b(const Point& t, const Point& r, const Point& p, const Point& q) const {
|
||||
return weight_a(t, r, p, q);
|
||||
}
|
||||
template<typename Polygon, typename Point, typename Traits, typename OutputIterator>
|
||||
void compute_on_polygon(
|
||||
const Polygon& polygon, const Point& query, const Traits& traits, OutputIterator out) const {
|
||||
CGAL::Weights::wachspress_weights_2(polygon, query, out, traits);
|
||||
}
|
||||
bool supports_3d() const { return false; }
|
||||
bool is_barycentric() const { return true; }
|
||||
};
|
||||
|
||||
template<typename Kernel>
|
||||
struct Discrete_harmonic_wrapper {
|
||||
using FT = typename Kernel::FT;
|
||||
using Point_2 = typename Kernel::Point_2;
|
||||
using Point_3 = typename Kernel::Point_3;
|
||||
FT weight_a(const Point_2& t, const Point_2& r, const Point_2& p, const Point_2& q) const {
|
||||
return CGAL::Weights::discrete_harmonic_weight(t, r, p, q);
|
||||
}
|
||||
FT weight_a(const Point_3&, const Point_3&, const Point_3&, const Point_3&) const {
|
||||
return FT(-1);
|
||||
}
|
||||
template<typename Point>
|
||||
FT weight_b(const Point& t, const Point& r, const Point& p, const Point& q) const {
|
||||
return weight_a(t, r, p, q);
|
||||
}
|
||||
template<typename Polygon, typename Point, typename Traits, typename OutputIterator>
|
||||
void compute_on_polygon(
|
||||
const Polygon& polygon, const Point& query, const Traits& traits, OutputIterator out) const {
|
||||
CGAL::Weights::discrete_harmonic_weights_2(polygon, query, out, traits);
|
||||
}
|
||||
bool supports_3d() const { return false; }
|
||||
bool is_barycentric() const { return true; }
|
||||
};
|
||||
|
||||
template<typename Kernel>
|
||||
struct Mean_value_wrapper {
|
||||
using FT = typename Kernel::FT;
|
||||
using Point_2 = typename Kernel::Point_2;
|
||||
using Point_3 = typename Kernel::Point_3;
|
||||
FT weight_a(const Point_2& t, const Point_2& r, const Point_2& p, const Point_2& q) const {
|
||||
return CGAL::Weights::mean_value_weight(t, r, p, q);
|
||||
}
|
||||
FT weight_a(const Point_3&, const Point_3&, const Point_3&, const Point_3&) const {
|
||||
return FT(-1);
|
||||
}
|
||||
template<typename Point>
|
||||
FT weight_b(const Point& t, const Point& r, const Point& p, const Point& q) const {
|
||||
return weight_a(t, r, p, q);
|
||||
}
|
||||
template<typename Polygon, typename Point, typename Traits, typename OutputIterator>
|
||||
void compute_on_polygon(
|
||||
const Polygon& polygon, const Point& query, const Traits& traits, OutputIterator out) const {
|
||||
CGAL::Weights::mean_value_weights_2(polygon, query, out, traits);
|
||||
}
|
||||
bool supports_3d() const { return false; }
|
||||
bool is_barycentric() const { return true; }
|
||||
};
|
||||
|
||||
template<typename Kernel>
|
||||
struct Three_point_family_wrapper {
|
||||
using FT = typename Kernel::FT;
|
||||
using Point_2 = typename Kernel::Point_2;
|
||||
using Point_3 = typename Kernel::Point_3;
|
||||
const FT a;
|
||||
Three_point_family_wrapper(const FT a) : a(a) { }
|
||||
FT weight_a(const Point_2& t, const Point_2& r, const Point_2& p, const Point_2& q) const {
|
||||
return CGAL::Weights::three_point_family_weight(t, r, p, q, a);
|
||||
}
|
||||
FT weight_a(const Point_3&, const Point_3&, const Point_3&, const Point_3&) const {
|
||||
return FT(-1);
|
||||
}
|
||||
template<typename Point>
|
||||
FT weight_b(const Point& t, const Point& r, const Point& p, const Point& q) const {
|
||||
return weight_a(t, r, p, q);
|
||||
}
|
||||
bool supports_3d() const { return false; }
|
||||
bool is_barycentric() const { return true; }
|
||||
};
|
||||
|
||||
template<typename Kernel>
|
||||
struct Uniform_region_wrapper {
|
||||
using FT = typename Kernel::FT;
|
||||
template<typename Point>
|
||||
FT weight(const Point& p, const Point& q, const Point& r) const {
|
||||
return CGAL::Weights::uniform_area(p, q, r);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Kernel>
|
||||
struct Triangular_region_wrapper {
|
||||
using FT = typename Kernel::FT;
|
||||
template<typename Point>
|
||||
FT weight(const Point& p, const Point& q, const Point& r) const {
|
||||
return CGAL::Weights::triangular_area(p, q, r);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Kernel>
|
||||
struct Barycentric_region_wrapper {
|
||||
using FT = typename Kernel::FT;
|
||||
template<typename Point>
|
||||
FT weight(const Point& p, const Point& q, const Point& r) const {
|
||||
return CGAL::Weights::barycentric_area(p, q, r);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Kernel>
|
||||
struct Voronoi_region_wrapper {
|
||||
using FT = typename Kernel::FT;
|
||||
template<typename Point>
|
||||
FT weight(const Point& p, const Point& q, const Point& r) const {
|
||||
return CGAL::Weights::voronoi_area(p, q, r);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Kernel>
|
||||
struct Mixed_voronoi_region_wrapper {
|
||||
using FT = typename Kernel::FT;
|
||||
template<typename Point>
|
||||
FT weight(const Point& p, const Point& q, const Point& r) const {
|
||||
return CGAL::Weights::mixed_voronoi_area(p, q, r);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Kernel>
|
||||
struct Uniform_wrapper {
|
||||
using FT = typename Kernel::FT;
|
||||
template<typename Point>
|
||||
FT weight_a(const Point& t, const Point& r, const Point& p, const Point& q) const {
|
||||
return CGAL::Weights::uniform_weight(t, r, p, q);
|
||||
}
|
||||
template<typename Point>
|
||||
FT weight_b(const Point& t, const Point& r, const Point& p, const Point& q) const {
|
||||
return weight_a(t, r, p, q);
|
||||
}
|
||||
bool supports_3d() const { return true; }
|
||||
bool is_barycentric() const { return false; }
|
||||
};
|
||||
|
||||
template<typename Kernel>
|
||||
struct Inverse_distance_wrapper {
|
||||
using FT = typename Kernel::FT;
|
||||
template<typename Point>
|
||||
FT weight_a(const Point& t, const Point& r, const Point& p, const Point& q) const {
|
||||
return CGAL::Weights::inverse_distance_weight(t, r, p, q);
|
||||
}
|
||||
template<typename Point>
|
||||
FT weight_b(const Point& t, const Point& r, const Point& p, const Point& q) const {
|
||||
return weight_a(t, r, p, q);
|
||||
}
|
||||
bool supports_3d() const { return true; }
|
||||
bool is_barycentric() const { return false; }
|
||||
};
|
||||
|
||||
template<typename Kernel>
|
||||
struct Shepard_wrapper {
|
||||
using FT = typename Kernel::FT;
|
||||
const FT a;
|
||||
Shepard_wrapper(const FT a) : a(a) { }
|
||||
template<typename Point>
|
||||
FT weight_a(const Point& t, const Point& r, const Point& p, const Point& q) const {
|
||||
return CGAL::Weights::shepard_weight(t, r, p, q, a);
|
||||
}
|
||||
template<typename Point>
|
||||
FT weight_b(const Point& t, const Point& r, const Point& p, const Point& q) const {
|
||||
return weight_a(t, r, p, q);
|
||||
}
|
||||
bool supports_3d() const { return true; }
|
||||
bool is_barycentric() const { return false; }
|
||||
};
|
||||
|
||||
} // namespace wrappers
|
||||
|
||||
#endif // CGAL_WEIGHTS_TESTS_WRAPPERS_H
|
||||
|
|
@ -1,52 +1,26 @@
|
|||
#include <CGAL/Simple_cartesian.h>
|
||||
#include <CGAL/Weights/utils.h>
|
||||
#include <CGAL/Weights/authalic_weights.h>
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
||||
|
||||
#include "include/utils.h"
|
||||
#include "include/wrappers.h"
|
||||
|
||||
// Typedefs.
|
||||
using Kernel = CGAL::Simple_cartesian<double>;
|
||||
using Point_2 = typename Kernel::Point_2;
|
||||
using Point_3 = typename Kernel::Point_3;
|
||||
using SCKER = CGAL::Simple_cartesian<double>;
|
||||
using EPICK = CGAL::Exact_predicates_inexact_constructions_kernel;
|
||||
using EPECK = CGAL::Exact_predicates_exact_constructions_kernel;
|
||||
|
||||
template<typename Kernel>
|
||||
bool test_kernel() {
|
||||
const wrappers::Authalic_wrapper<Kernel> aut;
|
||||
const wrappers::Wachspress_wrapper<Kernel> whp;
|
||||
return tests::test_analytic_weight<Kernel>(aut, whp);
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
||||
// 2D configuration.
|
||||
const Point_2 t2 = Point_2(-1, 0);
|
||||
const Point_2 r2 = Point_2( 0, -1);
|
||||
const Point_2 p2 = Point_2( 1, 0);
|
||||
const Point_2 q2 = Point_2( 0, 0);
|
||||
|
||||
// 3D configuration.
|
||||
const Point_3 t3 = Point_3(-1, 0, 1);
|
||||
const Point_3 r3 = Point_3( 0, -1, 1);
|
||||
const Point_3 p3 = Point_3( 1, 0, 1);
|
||||
const Point_3 q3 = Point_3( 0, 0, 1);
|
||||
|
||||
// Compute weights.
|
||||
std::cout << "2D authalic: " <<
|
||||
CGAL::Weights::authalic_weight(t2, r2, p2, q2) << std::endl;
|
||||
std::cout << "3D authalic: " <<
|
||||
CGAL::Weights::authalic_weight(t3, r3, p3, q3) << std::endl;
|
||||
std::cout << "--------------" << std::endl;
|
||||
|
||||
// Construct a 2D weight.
|
||||
const auto w2 =
|
||||
CGAL::Weights::half_authalic_weight(
|
||||
CGAL::Weights::cotangent(t2, r2, q2),
|
||||
CGAL::Weights::squared_distance(q2, r2)) +
|
||||
CGAL::Weights::half_authalic_weight(
|
||||
CGAL::Weights::cotangent(q2, r2, p2),
|
||||
CGAL::Weights::squared_distance(q2, r2));
|
||||
std::cout << "2D authalic: " << w2 << std::endl;
|
||||
|
||||
// Construct a 3D weight.
|
||||
const auto w3 =
|
||||
CGAL::Weights::half_authalic_weight(
|
||||
CGAL::Weights::cotangent(t3, r3, q3),
|
||||
CGAL::Weights::squared_distance(q3, r3)) +
|
||||
CGAL::Weights::half_authalic_weight(
|
||||
CGAL::Weights::cotangent(q3, r3, p3),
|
||||
CGAL::Weights::squared_distance(q3, r3));
|
||||
std::cout << "3D authalic: " << w3 << std::endl;
|
||||
|
||||
assert(test_kernel<SCKER>());
|
||||
assert(test_kernel<EPICK>());
|
||||
assert(test_kernel<EPECK>());
|
||||
std::cout << "* test_authalic_weights: SUCCESS" << std::endl;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,28 +1,25 @@
|
|||
#include <CGAL/Simple_cartesian.h>
|
||||
#include <CGAL/Weights/barycentric_region_weights.h>
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
||||
|
||||
#include "include/utils.h"
|
||||
#include "include/wrappers.h"
|
||||
|
||||
// Typedefs.
|
||||
using Kernel = CGAL::Simple_cartesian<double>;
|
||||
using Point_2 = typename Kernel::Point_2;
|
||||
using Point_3 = typename Kernel::Point_3;
|
||||
using SCKER = CGAL::Simple_cartesian<double>;
|
||||
using EPICK = CGAL::Exact_predicates_inexact_constructions_kernel;
|
||||
using EPECK = CGAL::Exact_predicates_exact_constructions_kernel;
|
||||
|
||||
template<typename Kernel>
|
||||
bool test_kernel() {
|
||||
const wrappers::Barycentric_region_wrapper<Kernel> bar;
|
||||
return tests::test_region_weight<Kernel>(bar);
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
||||
// 2D configuration.
|
||||
const Point_2 p2 = Point_2(-1, 0);
|
||||
const Point_2 q2 = Point_2( 0, 0);
|
||||
const Point_2 r2 = Point_2( 0, 1);
|
||||
|
||||
// 3D configuration.
|
||||
const Point_3 p3 = Point_3(-1, 0, 1);
|
||||
const Point_3 q3 = Point_3( 0, 0, 1);
|
||||
const Point_3 r3 = Point_3( 0, 1, 1);
|
||||
|
||||
// Compute weights.
|
||||
std::cout << "2D barycentric: " <<
|
||||
CGAL::Weights::barycentric_area(p2, q2, r2) << std::endl;
|
||||
std::cout << "3D barycentric: " <<
|
||||
CGAL::Weights::barycentric_area(p3, q3, r3) << std::endl;
|
||||
|
||||
assert(test_kernel<SCKER>());
|
||||
assert(test_kernel<EPICK>());
|
||||
assert(test_kernel<EPECK>());
|
||||
std::cout << "* test_barycentric_region_weights: SUCCESS" << std::endl;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,48 +1,26 @@
|
|||
#include <CGAL/Simple_cartesian.h>
|
||||
#include <CGAL/Weights/utils.h>
|
||||
#include <CGAL/Weights/cotangent_weights.h>
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
||||
|
||||
#include "include/utils.h"
|
||||
#include "include/wrappers.h"
|
||||
|
||||
// Typedefs.
|
||||
using Kernel = CGAL::Simple_cartesian<double>;
|
||||
using Point_2 = typename Kernel::Point_2;
|
||||
using Point_3 = typename Kernel::Point_3;
|
||||
using SCKER = CGAL::Simple_cartesian<double>;
|
||||
using EPICK = CGAL::Exact_predicates_inexact_constructions_kernel;
|
||||
using EPECK = CGAL::Exact_predicates_exact_constructions_kernel;
|
||||
|
||||
template<typename Kernel>
|
||||
bool test_kernel() {
|
||||
const wrappers::Cotangent_wrapper<Kernel> cot;
|
||||
const wrappers::Discrete_harmonic_wrapper<Kernel> dhw;
|
||||
return tests::test_analytic_weight<Kernel>(cot, dhw);
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
||||
// 2D configuration.
|
||||
const Point_2 t2 = Point_2(-1, 0);
|
||||
const Point_2 r2 = Point_2( 0, -1);
|
||||
const Point_2 p2 = Point_2( 1, 0);
|
||||
const Point_2 q2 = Point_2( 0, 0);
|
||||
|
||||
// 3D configuration.
|
||||
const Point_3 t3 = Point_3(-1, 0, 1);
|
||||
const Point_3 r3 = Point_3( 0, -1, 1);
|
||||
const Point_3 p3 = Point_3( 1, 0, 1);
|
||||
const Point_3 q3 = Point_3( 0, 0, 1);
|
||||
|
||||
// Compute weights.
|
||||
std::cout << "2D cotangent: " <<
|
||||
CGAL::Weights::cotangent_weight(t2, r2, p2, q2) << std::endl;
|
||||
std::cout << "3D cotangent: " <<
|
||||
CGAL::Weights::cotangent_weight(t3, r3, p3, q3) << std::endl;
|
||||
std::cout << "---------------" << std::endl;
|
||||
|
||||
// Construct a 2D weight.
|
||||
const auto w2 =
|
||||
CGAL::Weights::half_cotangent_weight(
|
||||
CGAL::Weights::cotangent(q2, t2, r2)) +
|
||||
CGAL::Weights::half_cotangent_weight(
|
||||
CGAL::Weights::cotangent(r2, p2, q2));
|
||||
std::cout << "2D cotangent: " << w2 << std::endl;
|
||||
|
||||
// Construct a 3D weight.
|
||||
const auto w3 =
|
||||
CGAL::Weights::half_cotangent_weight(
|
||||
CGAL::Weights::cotangent(q3, t3, r3)) +
|
||||
CGAL::Weights::half_cotangent_weight(
|
||||
CGAL::Weights::cotangent(r3, p3, q3));
|
||||
std::cout << "3D cotangent: " << w3 << std::endl;
|
||||
|
||||
assert(test_kernel<SCKER>());
|
||||
assert(test_kernel<EPICK>());
|
||||
assert(test_kernel<EPECK>());
|
||||
std::cout << "* test_cotangent_weights: SUCCESS" << std::endl;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,62 +1,54 @@
|
|||
#include <CGAL/Simple_cartesian.h>
|
||||
#include <CGAL/Weights/discrete_harmonic_weights.h>
|
||||
#include <CGAL/Weights/internal/Projection_traits_3.h>
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
||||
|
||||
#include "include/utils.h"
|
||||
#include "include/wrappers.h"
|
||||
|
||||
// Typedefs.
|
||||
using Kernel = CGAL::Simple_cartesian<double>;
|
||||
using Point_2 = typename Kernel::Point_2;
|
||||
using Point_3 = typename Kernel::Point_3;
|
||||
using SCKER = CGAL::Simple_cartesian<double>;
|
||||
using EPICK = CGAL::Exact_predicates_inexact_constructions_kernel;
|
||||
using EPECK = CGAL::Exact_predicates_exact_constructions_kernel;
|
||||
|
||||
template<typename Kernel>
|
||||
void test_overloads() {
|
||||
using FT = typename Kernel::FT;
|
||||
using Point_2 = typename Kernel::Point_2;
|
||||
using Point_3 = typename Kernel::Point_3;
|
||||
const Point_2 t1(-1, 0);
|
||||
const Point_2 r1( 0, -1);
|
||||
const Point_2 p1( 1, 0);
|
||||
const Point_2 q1( 0, 0);
|
||||
const Point_3 t2(-1, 0, 1);
|
||||
const Point_3 r2( 0, -1, 1);
|
||||
const Point_3 p2( 1, 0, 1);
|
||||
const Point_3 q2( 0, 0, 1);
|
||||
const FT a2 = CGAL::Weights::discrete_harmonic_weight(t1, r1, p1, q1);
|
||||
const FT a3 = CGAL::Weights::internal::discrete_harmonic_weight(t2, r2, p2, q2);
|
||||
assert(a2 >= FT(0));
|
||||
assert(a3 >= FT(0));
|
||||
assert(a2 == a3);
|
||||
struct Traits : public Kernel { };
|
||||
assert(CGAL::Weights::discrete_harmonic_weight(t1, r1, p1, q1, Traits()) == a2);
|
||||
assert(CGAL::Weights::internal::discrete_harmonic_weight(t2, r2, p2, q2, Traits()) == a3);
|
||||
CGAL::Projection_traits_xy_3<Kernel> ptraits;
|
||||
const FT a23 = CGAL::Weights::discrete_harmonic_weight(t2, r2, p2, q2, ptraits);
|
||||
assert(a23 >= FT(0));
|
||||
assert(a23 == a2 && a23 == a3);
|
||||
}
|
||||
|
||||
template<typename Kernel>
|
||||
bool test_kernel() {
|
||||
test_overloads<Kernel>();
|
||||
const wrappers::Discrete_harmonic_wrapper<Kernel> dhw;
|
||||
const wrappers::Cotangent_wrapper<Kernel> cot;
|
||||
return tests::test_barycentric_weight<Kernel>(dhw, cot);
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
||||
// 2D configuration.
|
||||
const Point_2 t2 = Point_2(-1, 0);
|
||||
const Point_2 r2 = Point_2( 0, -1);
|
||||
const Point_2 p2 = Point_2( 1, 0);
|
||||
const Point_2 q2 = Point_2( 0, 0);
|
||||
|
||||
// 3D configuration.
|
||||
const Point_3 t3 = Point_3(-1, 0, 1);
|
||||
const Point_3 r3 = Point_3( 0, -1, 1);
|
||||
const Point_3 p3 = Point_3( 1, 0, 1);
|
||||
const Point_3 q3 = Point_3( 0, 0, 1);
|
||||
|
||||
// Compute weights.
|
||||
std::cout << "2D discrete harmonic: " <<
|
||||
CGAL::Weights::discrete_harmonic_weight(t2, r2, p2, q2) << std::endl;
|
||||
std::cout << "3D discrete harmonic: " <<
|
||||
CGAL::Weights::discrete_harmonic_weight(t3, r3, p3, q3) << std::endl;
|
||||
|
||||
// Compute weights on a polygon.
|
||||
|
||||
// 2D configuration.
|
||||
const std::vector<Point_2> polygon2 = {t2, r2, p2, Point_2(0, 1)};
|
||||
|
||||
std::vector<double> weights2;
|
||||
weights2.reserve(polygon2.size());
|
||||
CGAL::Weights::discrete_harmonic_weights_2(
|
||||
polygon2, q2, std::back_inserter(weights2));
|
||||
|
||||
std::cout << "2D discrete harmonic (polygon): ";
|
||||
for (const double weight2 : weights2)
|
||||
std::cout << weight2 << " ";
|
||||
std::cout << std::endl;
|
||||
|
||||
// 3D configuration.
|
||||
CGAL::Weights::internal::Projection_traits_3<Kernel> ptraits(
|
||||
typename Kernel::Vector_3(0, 0, 1));
|
||||
|
||||
const std::vector<Point_3> polygon3 = {t3, r3, p3, Point_3(0, 1, 1)};
|
||||
|
||||
std::vector<double> weights3;
|
||||
weights3.reserve(polygon3.size());
|
||||
CGAL::Weights::discrete_harmonic_weights_2(
|
||||
polygon3, q3, std::back_inserter(weights3), ptraits);
|
||||
|
||||
std::cout << "3D discrete harmonic (polygon): ";
|
||||
for (const double weight3 : weights3)
|
||||
std::cout << weight3 << " ";
|
||||
std::cout << std::endl;
|
||||
|
||||
assert(test_kernel<SCKER>());
|
||||
assert(test_kernel<EPICK>());
|
||||
assert(test_kernel<EPECK>());
|
||||
std::cout << "* test_discrete_harmonic_weights: SUCCESS" << std::endl;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,37 +1,47 @@
|
|||
#include <CGAL/Simple_cartesian.h>
|
||||
#include <CGAL/Weights/inverse_distance_weights.h>
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
||||
|
||||
#include "include/utils.h"
|
||||
#include "include/wrappers.h"
|
||||
|
||||
// Typedefs.
|
||||
using Kernel = CGAL::Simple_cartesian<double>;
|
||||
using Point_2 = typename Kernel::Point_2;
|
||||
using Point_3 = typename Kernel::Point_3;
|
||||
using SCKER = CGAL::Simple_cartesian<double>;
|
||||
using EPICK = CGAL::Exact_predicates_inexact_constructions_kernel;
|
||||
using EPECK = CGAL::Exact_predicates_exact_constructions_kernel;
|
||||
|
||||
template<typename Kernel>
|
||||
void test_overloads() {
|
||||
using FT = typename Kernel::FT;
|
||||
using Point_2 = typename Kernel::Point_2;
|
||||
using Point_3 = typename Kernel::Point_3;
|
||||
const Point_2 p1(0, 0);
|
||||
const Point_2 q1(1, 0);
|
||||
const Point_3 p2(0, 0, 1);
|
||||
const Point_3 q2(1, 0, 1);
|
||||
const FT a2 = CGAL::Weights::inverse_distance_weight(p1, q1);
|
||||
const FT a3 = CGAL::Weights::inverse_distance_weight(p2, q2);
|
||||
assert(a2 == FT(1));
|
||||
assert(a3 == FT(1));
|
||||
assert(CGAL::Weights::inverse_distance_weight(p1, p1, q1, q1) == a2);
|
||||
assert(CGAL::Weights::inverse_distance_weight(p2, p2, q2, q2) == a3);
|
||||
struct Traits : public Kernel { };
|
||||
assert(CGAL::Weights::inverse_distance_weight(p1, p1, q1, q1, Traits()) == a2);
|
||||
assert(CGAL::Weights::inverse_distance_weight(p2, p2, q2, q2, Traits()) == a3);
|
||||
}
|
||||
|
||||
template<typename Kernel>
|
||||
bool test_kernel() {
|
||||
test_overloads<Kernel>();
|
||||
const wrappers::Inverse_distance_wrapper<Kernel> idw;
|
||||
const wrappers::Shepard_wrapper<Kernel> spw(1);
|
||||
return tests::test_analytic_weight<Kernel>(idw, spw);
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
||||
// 2D configuration.
|
||||
const Point_2 t2 = Point_2(-1, 0);
|
||||
const Point_2 r2 = Point_2( 0, -1);
|
||||
const Point_2 p2 = Point_2( 1, 0);
|
||||
const Point_2 q2 = Point_2( 0, 0);
|
||||
|
||||
// 3D configuration.
|
||||
const Point_3 t3 = Point_3(-1, 0, 1);
|
||||
const Point_3 r3 = Point_3( 0, -1, 1);
|
||||
const Point_3 p3 = Point_3( 1, 0, 1);
|
||||
const Point_3 q3 = Point_3( 0, 0, 1);
|
||||
|
||||
// Compute weights.
|
||||
std::cout << "2D inverse distance: " <<
|
||||
CGAL::Weights::inverse_distance_weight(t2, r2, p2, q2) << std::endl;
|
||||
std::cout << "3D inverse distance: " <<
|
||||
CGAL::Weights::inverse_distance_weight(t3, r3, p3, q3) << std::endl;
|
||||
std::cout << "----------------------" << std::endl;
|
||||
|
||||
// Overloads.
|
||||
std::cout << "2D inverse distance: " <<
|
||||
CGAL::Weights::inverse_distance_weight(q2, r2) << std::endl;
|
||||
std::cout << "3D inverse distance: " <<
|
||||
CGAL::Weights::inverse_distance_weight(q3, r3) << std::endl;
|
||||
|
||||
assert(test_kernel<SCKER>());
|
||||
assert(test_kernel<EPICK>());
|
||||
assert(test_kernel<EPECK>());
|
||||
std::cout << "* test_inverse_distance_weights: SUCCESS" << std::endl;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,62 +1,54 @@
|
|||
#include <CGAL/Simple_cartesian.h>
|
||||
#include <CGAL/Weights/mean_value_weights.h>
|
||||
#include <CGAL/Weights/internal/Projection_traits_3.h>
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
||||
|
||||
#include "include/utils.h"
|
||||
#include "include/wrappers.h"
|
||||
|
||||
// Typedefs.
|
||||
using Kernel = CGAL::Simple_cartesian<double>;
|
||||
using Point_2 = typename Kernel::Point_2;
|
||||
using Point_3 = typename Kernel::Point_3;
|
||||
using SCKER = CGAL::Simple_cartesian<double>;
|
||||
using EPICK = CGAL::Exact_predicates_inexact_constructions_kernel;
|
||||
using EPECK = CGAL::Exact_predicates_exact_constructions_kernel;
|
||||
|
||||
template<typename Kernel>
|
||||
void test_overloads() {
|
||||
using FT = typename Kernel::FT;
|
||||
using Point_2 = typename Kernel::Point_2;
|
||||
using Point_3 = typename Kernel::Point_3;
|
||||
const Point_2 t1(-1, 0);
|
||||
const Point_2 r1( 0, -1);
|
||||
const Point_2 p1( 1, 0);
|
||||
const Point_2 q1( 0, 0);
|
||||
const Point_3 t2(-1, 0, 1);
|
||||
const Point_3 r2( 0, -1, 1);
|
||||
const Point_3 p2( 1, 0, 1);
|
||||
const Point_3 q2( 0, 0, 1);
|
||||
const FT a2 = CGAL::Weights::mean_value_weight(t1, r1, p1, q1);
|
||||
const FT a3 = CGAL::Weights::internal::mean_value_weight(t2, r2, p2, q2);
|
||||
assert(a2 >= FT(0));
|
||||
assert(a3 >= FT(0));
|
||||
assert(a2 == a3);
|
||||
struct Traits : public Kernel { };
|
||||
assert(CGAL::Weights::mean_value_weight(t1, r1, p1, q1, Traits()) == a2);
|
||||
assert(CGAL::Weights::internal::mean_value_weight(t2, r2, p2, q2, Traits()) == a3);
|
||||
CGAL::Projection_traits_xy_3<Kernel> ptraits;
|
||||
const FT a23 = CGAL::Weights::mean_value_weight(t2, r2, p2, q2, ptraits);
|
||||
assert(a23 >= FT(0));
|
||||
assert(a23 == a2 && a23 == a3);
|
||||
}
|
||||
|
||||
template<typename Kernel>
|
||||
bool test_kernel() {
|
||||
test_overloads<Kernel>();
|
||||
const wrappers::Mean_value_wrapper<Kernel> mvw;
|
||||
const wrappers::Tangent_wrapper<Kernel> tan;
|
||||
return tests::test_barycentric_weight<Kernel>(mvw, tan);
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
||||
// 2D configuration.
|
||||
const Point_2 t2 = Point_2(-1, 0);
|
||||
const Point_2 r2 = Point_2( 0, -1);
|
||||
const Point_2 p2 = Point_2( 1, 0);
|
||||
const Point_2 q2 = Point_2( 0, 0);
|
||||
|
||||
// 3D configuration.
|
||||
const Point_3 t3 = Point_3(-1, 0, 1);
|
||||
const Point_3 r3 = Point_3( 0, -1, 1);
|
||||
const Point_3 p3 = Point_3( 1, 0, 1);
|
||||
const Point_3 q3 = Point_3( 0, 0, 1);
|
||||
|
||||
// Compute weights.
|
||||
std::cout << "2D mean value: " <<
|
||||
CGAL::Weights::mean_value_weight(t2, r2, p2, q2) << std::endl;
|
||||
std::cout << "3D mean value: " <<
|
||||
CGAL::Weights::mean_value_weight(t3, r3, p3, q3) << std::endl;
|
||||
|
||||
// Compute weights on a polygon.
|
||||
|
||||
// 2D configuration.
|
||||
const std::vector<Point_2> polygon2 = {t2, r2, p2, Point_2(0, 1)};
|
||||
|
||||
std::vector<double> weights2;
|
||||
weights2.reserve(polygon2.size());
|
||||
CGAL::Weights::mean_value_weights_2(
|
||||
polygon2, q2, std::back_inserter(weights2));
|
||||
|
||||
std::cout << "2D mean value (polygon): ";
|
||||
for (const double weight2 : weights2)
|
||||
std::cout << weight2 << " ";
|
||||
std::cout << std::endl;
|
||||
|
||||
// 3D configuration.
|
||||
CGAL::Weights::internal::Projection_traits_3<Kernel> ptraits(
|
||||
typename Kernel::Vector_3(0, 0, 1));
|
||||
|
||||
const std::vector<Point_3> polygon3 = {t3, r3, p3, Point_3(0, 1, 1)};
|
||||
|
||||
std::vector<double> weights3;
|
||||
weights3.reserve(polygon3.size());
|
||||
CGAL::Weights::mean_value_weights_2(
|
||||
polygon3, q3, std::back_inserter(weights3), ptraits);
|
||||
|
||||
std::cout << "3D mean value (polygon): ";
|
||||
for (const double weight3 : weights3)
|
||||
std::cout << weight3 << " ";
|
||||
std::cout << std::endl;
|
||||
|
||||
assert(test_kernel<SCKER>());
|
||||
assert(test_kernel<EPICK>());
|
||||
assert(test_kernel<EPECK>());
|
||||
std::cout << "* test_mean_value_weights: SUCCESS" << std::endl;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,28 +1,25 @@
|
|||
#include <CGAL/Simple_cartesian.h>
|
||||
#include <CGAL/Weights/mixed_voronoi_region_weights.h>
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
||||
|
||||
#include "include/utils.h"
|
||||
#include "include/wrappers.h"
|
||||
|
||||
// Typedefs.
|
||||
using Kernel = CGAL::Simple_cartesian<double>;
|
||||
using Point_2 = typename Kernel::Point_2;
|
||||
using Point_3 = typename Kernel::Point_3;
|
||||
using SCKER = CGAL::Simple_cartesian<double>;
|
||||
using EPICK = CGAL::Exact_predicates_inexact_constructions_kernel;
|
||||
using EPECK = CGAL::Exact_predicates_exact_constructions_kernel;
|
||||
|
||||
template<typename Kernel>
|
||||
bool test_kernel() {
|
||||
const wrappers::Mixed_voronoi_region_wrapper<Kernel> mix;
|
||||
return tests::test_region_weight<Kernel>(mix);
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
||||
// 2D configuration.
|
||||
const Point_2 p2 = Point_2(-1, 0);
|
||||
const Point_2 q2 = Point_2( 0, 0);
|
||||
const Point_2 r2 = Point_2( 0, 1);
|
||||
|
||||
// 3D configuration.
|
||||
const Point_3 p3 = Point_3(-1, 0, 1);
|
||||
const Point_3 q3 = Point_3( 0, 0, 1);
|
||||
const Point_3 r3 = Point_3( 0, 1, 1);
|
||||
|
||||
// Compute weights.
|
||||
std::cout << "2D mixed voronoi: " <<
|
||||
CGAL::Weights::mixed_voronoi_area(p2, q2, r2) << std::endl;
|
||||
std::cout << "3D mixed voronoi: " <<
|
||||
CGAL::Weights::mixed_voronoi_area(p3, q3, r3) << std::endl;
|
||||
|
||||
assert(test_kernel<SCKER>());
|
||||
assert(test_kernel<EPICK>());
|
||||
assert(test_kernel<EPECK>());
|
||||
std::cout << "* test_mixed_voronoi_region_weights: SUCCESS" << std::endl;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,119 @@
|
|||
#include <CGAL/Simple_cartesian.h>
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
||||
#include <CGAL/Projection_traits_xy_3.h>
|
||||
#include <CGAL/Projection_traits_xz_3.h>
|
||||
#include <CGAL/Projection_traits_yz_3.h>
|
||||
#include <CGAL/Weights.h>
|
||||
|
||||
// Typedefs.
|
||||
using SCKER = CGAL::Simple_cartesian<double>;
|
||||
using EPICK = CGAL::Exact_predicates_inexact_constructions_kernel;
|
||||
using EPECK = CGAL::Exact_predicates_exact_constructions_kernel;
|
||||
|
||||
template<typename Kernel>
|
||||
void test_kernel() {
|
||||
using FT = typename Kernel::FT;
|
||||
using Point_2 = typename Kernel::Point_2;
|
||||
using Point_3 = typename Kernel::Point_3;
|
||||
|
||||
using XY_Traits = CGAL::Projection_traits_xy_3<Kernel>;
|
||||
using XZ_Traits = CGAL::Projection_traits_xz_3<Kernel>;
|
||||
using YZ_Traits = CGAL::Projection_traits_yz_3<Kernel>;
|
||||
|
||||
const XY_Traits xy_traits;
|
||||
const XZ_Traits xz_traits;
|
||||
const YZ_Traits yz_traits;
|
||||
|
||||
const Point_2 t(-1, 0);
|
||||
const Point_2 r( 0, -1);
|
||||
const Point_2 p( 1, 0);
|
||||
const Point_2 q( 0, 0);
|
||||
|
||||
// XY.
|
||||
const Point_3 t1(t.x(), t.y(), 1);
|
||||
const Point_3 r1(r.x(), r.y(), 1);
|
||||
const Point_3 p1(p.x(), p.y(), 1);
|
||||
const Point_3 q1(q.x(), q.y(), 1);
|
||||
|
||||
// XZ.
|
||||
const Point_3 t2(t.x(), 1, t.y());
|
||||
const Point_3 r2(r.x(), 1, r.y());
|
||||
const Point_3 p2(p.x(), 1, p.y());
|
||||
const Point_3 q2(q.x(), 1, q.y());
|
||||
|
||||
// YZ.
|
||||
const Point_3 t3(1, t.x(), t.y());
|
||||
const Point_3 r3(1, r.x(), r.y());
|
||||
const Point_3 p3(1, p.x(), p.y());
|
||||
const Point_3 q3(1, q.x(), q.y());
|
||||
|
||||
const FT ref_value = FT(4);
|
||||
assert(CGAL::Weights::authalic_weight(t1, r1, p1, q1, xy_traits) == ref_value);
|
||||
assert(CGAL::Weights::authalic_weight(t2, r2, p2, q2, xz_traits) == ref_value);
|
||||
assert(CGAL::Weights::authalic_weight(t3, r3, p3, q3, yz_traits) == ref_value);
|
||||
|
||||
assert(CGAL::Weights::wachspress_weight(t1, r1, p1, q1, xy_traits) == ref_value);
|
||||
assert(CGAL::Weights::wachspress_weight(t2, r2, p2, q2, xz_traits) == ref_value);
|
||||
assert(CGAL::Weights::wachspress_weight(t3, r3, p3, q3, yz_traits) == ref_value);
|
||||
|
||||
assert(CGAL::Weights::cotangent_weight(t1, r1, p1, q1, xy_traits) == ref_value);
|
||||
assert(CGAL::Weights::cotangent_weight(t2, r2, p2, q2, xz_traits) == ref_value);
|
||||
assert(CGAL::Weights::cotangent_weight(t3, r3, p3, q3, yz_traits) == ref_value);
|
||||
|
||||
assert(CGAL::Weights::discrete_harmonic_weight(t1, r1, p1, q1, xy_traits) == ref_value);
|
||||
assert(CGAL::Weights::discrete_harmonic_weight(t2, r2, p2, q2, xz_traits) == ref_value);
|
||||
assert(CGAL::Weights::discrete_harmonic_weight(t3, r3, p3, q3, yz_traits) == ref_value);
|
||||
|
||||
assert(CGAL::Weights::tangent_weight(t1, r1, p1, q1, xy_traits) == ref_value);
|
||||
assert(CGAL::Weights::tangent_weight(t2, r2, p2, q2, xz_traits) == ref_value);
|
||||
assert(CGAL::Weights::tangent_weight(t3, r3, p3, q3, yz_traits) == ref_value);
|
||||
|
||||
assert(CGAL::Weights::mean_value_weight(t1, r1, p1, q1, xy_traits) == ref_value);
|
||||
assert(CGAL::Weights::mean_value_weight(t2, r2, p2, q2, xz_traits) == ref_value);
|
||||
assert(CGAL::Weights::mean_value_weight(t3, r3, p3, q3, yz_traits) == ref_value);
|
||||
|
||||
assert(CGAL::Weights::uniform_area(t1, r1, p1, xy_traits) == FT(1));
|
||||
assert(CGAL::Weights::uniform_area(t2, r2, p2, xz_traits) == FT(1));
|
||||
assert(CGAL::Weights::uniform_area(t3, r3, p3, yz_traits) == FT(1));
|
||||
|
||||
assert(CGAL::Weights::triangular_area(t1, r1, p1, xy_traits) >= FT(0));
|
||||
assert(CGAL::Weights::triangular_area(t2, r2, p2, xz_traits) >= FT(0));
|
||||
assert(CGAL::Weights::triangular_area(t3, r3, p3, yz_traits) >= FT(0));
|
||||
|
||||
assert(CGAL::Weights::barycentric_area(t1, r1, p1, xy_traits) >= FT(0));
|
||||
assert(CGAL::Weights::barycentric_area(t2, r2, p2, xz_traits) >= FT(0));
|
||||
assert(CGAL::Weights::barycentric_area(t3, r3, p3, yz_traits) >= FT(0));
|
||||
|
||||
assert(CGAL::Weights::voronoi_area(t1, r1, p1, xy_traits) >= FT(0));
|
||||
assert(CGAL::Weights::voronoi_area(t2, r2, p2, xz_traits) >= FT(0));
|
||||
assert(CGAL::Weights::voronoi_area(t3, r3, p3, yz_traits) >= FT(0));
|
||||
|
||||
assert(CGAL::Weights::mixed_voronoi_area(t1, r1, p1, xy_traits) >= FT(0));
|
||||
assert(CGAL::Weights::mixed_voronoi_area(t2, r2, p2, xz_traits) >= FT(0));
|
||||
assert(CGAL::Weights::mixed_voronoi_area(t3, r3, p3, yz_traits) >= FT(0));
|
||||
|
||||
assert(CGAL::Weights::uniform_weight(t1, r1, p1, q1, xy_traits) == FT(1));
|
||||
assert(CGAL::Weights::uniform_weight(t2, r2, p2, q2, xz_traits) == FT(1));
|
||||
assert(CGAL::Weights::uniform_weight(t3, r3, p3, q3, yz_traits) == FT(1));
|
||||
|
||||
assert(CGAL::Weights::inverse_distance_weight(t1, r1, p1, q1, xy_traits) == FT(1));
|
||||
assert(CGAL::Weights::inverse_distance_weight(t2, r2, p2, q2, xz_traits) == FT(1));
|
||||
assert(CGAL::Weights::inverse_distance_weight(t3, r3, p3, q3, yz_traits) == FT(1));
|
||||
|
||||
assert(CGAL::Weights::shepard_weight(t1, r1, p1, q1, 1, xy_traits) == FT(1));
|
||||
assert(CGAL::Weights::shepard_weight(t2, r2, p2, q2, 1, xz_traits) == FT(1));
|
||||
assert(CGAL::Weights::shepard_weight(t3, r3, p3, q3, 1, yz_traits) == FT(1));
|
||||
|
||||
assert(CGAL::Weights::three_point_family_weight(t1, r1, p1, q1, 1, xy_traits) == ref_value);
|
||||
assert(CGAL::Weights::three_point_family_weight(t2, r2, p2, q2, 1, xz_traits) == ref_value);
|
||||
assert(CGAL::Weights::three_point_family_weight(t3, r3, p3, q3, 1, yz_traits) == ref_value);
|
||||
}
|
||||
|
||||
int main() {
|
||||
test_kernel<SCKER>();
|
||||
test_kernel<EPICK>();
|
||||
test_kernel<EPECK>();
|
||||
std::cout << "* test_projected_weights: SUCCESS" << std::endl;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
@ -1,37 +1,49 @@
|
|||
#include <CGAL/Simple_cartesian.h>
|
||||
#include <CGAL/Weights/shepard_weights.h>
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
||||
|
||||
#include "include/utils.h"
|
||||
#include "include/wrappers.h"
|
||||
|
||||
// Typedefs.
|
||||
using Kernel = CGAL::Simple_cartesian<double>;
|
||||
using Point_2 = typename Kernel::Point_2;
|
||||
using Point_3 = typename Kernel::Point_3;
|
||||
using SCKER = CGAL::Simple_cartesian<double>;
|
||||
using EPICK = CGAL::Exact_predicates_inexact_constructions_kernel;
|
||||
using EPECK = CGAL::Exact_predicates_exact_constructions_kernel;
|
||||
|
||||
template<typename Kernel>
|
||||
void test_overloads() {
|
||||
using FT = typename Kernel::FT;
|
||||
using Point_2 = typename Kernel::Point_2;
|
||||
using Point_3 = typename Kernel::Point_3;
|
||||
const Point_2 p1(0, 0);
|
||||
const Point_2 q1(1, 0);
|
||||
const Point_3 p2(0, 0, 1);
|
||||
const Point_3 q2(1, 0, 1);
|
||||
const FT a2 = CGAL::Weights::shepard_weight(p1, q1);
|
||||
const FT a3 = CGAL::Weights::shepard_weight(p2, q2);
|
||||
assert(a2 == FT(1));
|
||||
assert(a3 == FT(1));
|
||||
assert(CGAL::Weights::shepard_weight(p1, p1, q1, q1) == a2);
|
||||
assert(CGAL::Weights::shepard_weight(p2, p2, q2, q2) == a3);
|
||||
struct Traits : public Kernel { };
|
||||
assert(CGAL::Weights::shepard_weight(p1, p1, q1, q1, 1, Traits()) == a2);
|
||||
assert(CGAL::Weights::shepard_weight(p2, p2, q2, q2, 1, Traits()) == a3);
|
||||
}
|
||||
|
||||
template<typename Kernel>
|
||||
bool test_kernel() {
|
||||
test_overloads<Kernel>();
|
||||
const wrappers::Shepard_wrapper<Kernel> spwa(1);
|
||||
const wrappers::Shepard_wrapper<Kernel> spwb(2);
|
||||
const wrappers::Inverse_distance_wrapper<Kernel> idw;
|
||||
assert(tests::test_analytic_weight<Kernel>(spwa, idw));
|
||||
return tests::test_analytic_weight<Kernel>(spwb, spwb);
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
||||
// 2D configuration.
|
||||
const Point_2 t2 = Point_2(-1, 0);
|
||||
const Point_2 r2 = Point_2( 0, -1);
|
||||
const Point_2 p2 = Point_2( 1, 0);
|
||||
const Point_2 q2 = Point_2( 0, 0);
|
||||
|
||||
// 3D configuration.
|
||||
const Point_3 t3 = Point_3(-1, 0, 1);
|
||||
const Point_3 r3 = Point_3( 0, -1, 1);
|
||||
const Point_3 p3 = Point_3( 1, 0, 1);
|
||||
const Point_3 q3 = Point_3( 0, 0, 1);
|
||||
|
||||
// Compute weights.
|
||||
std::cout << "2D shepard: " <<
|
||||
CGAL::Weights::shepard_weight(t2, r2, p2, q2) << std::endl;
|
||||
std::cout << "3D shepard: " <<
|
||||
CGAL::Weights::shepard_weight(t3, r3, p3, q3, 1.0) << std::endl;
|
||||
std::cout << "-------------" << std::endl;
|
||||
|
||||
// Overloads.
|
||||
std::cout << "2D shepard: " <<
|
||||
CGAL::Weights::shepard_weight(q2, r2) << std::endl;
|
||||
std::cout << "3D shepard: " <<
|
||||
CGAL::Weights::shepard_weight(q3, r3, 1.0) << std::endl;
|
||||
|
||||
assert(test_kernel<SCKER>());
|
||||
assert(test_kernel<EPICK>());
|
||||
assert(test_kernel<EPECK>());
|
||||
std::cout << "* test_shepard_weights: SUCCESS" << std::endl;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,64 +1,26 @@
|
|||
#include <CGAL/Simple_cartesian.h>
|
||||
#include <CGAL/Weights/utils.h>
|
||||
#include <CGAL/Weights/tangent_weights.h>
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
||||
|
||||
#include "include/utils.h"
|
||||
#include "include/wrappers.h"
|
||||
|
||||
// Typedefs.
|
||||
using Kernel = CGAL::Simple_cartesian<double>;
|
||||
using Point_2 = typename Kernel::Point_2;
|
||||
using Point_3 = typename Kernel::Point_3;
|
||||
using SCKER = CGAL::Simple_cartesian<double>;
|
||||
using EPICK = CGAL::Exact_predicates_inexact_constructions_kernel;
|
||||
using EPECK = CGAL::Exact_predicates_exact_constructions_kernel;
|
||||
|
||||
template<typename Kernel>
|
||||
bool test_kernel() {
|
||||
const wrappers::Tangent_wrapper<Kernel> tan;
|
||||
const wrappers::Mean_value_wrapper<Kernel> mvw;
|
||||
return tests::test_analytic_weight<Kernel>(tan, mvw);
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
||||
// 2D configuration.
|
||||
const Point_2 t2 = Point_2(-1, 0);
|
||||
const Point_2 r2 = Point_2( 0, -1);
|
||||
const Point_2 p2 = Point_2( 1, 0);
|
||||
const Point_2 q2 = Point_2( 0, 0);
|
||||
|
||||
// 3D configuration.
|
||||
const Point_3 t3 = Point_3(-1, 0, 1);
|
||||
const Point_3 r3 = Point_3( 0, -1, 1);
|
||||
const Point_3 p3 = Point_3( 1, 0, 1);
|
||||
const Point_3 q3 = Point_3( 0, 0, 1);
|
||||
|
||||
// Compute weights.
|
||||
std::cout << "2D tangent: " <<
|
||||
CGAL::Weights::tangent_weight(t2, r2, p2, q2) << std::endl;
|
||||
std::cout << "3D tangent: " <<
|
||||
CGAL::Weights::tangent_weight(t3, r3, p3, q3) << std::endl;
|
||||
std::cout << "-------------" << std::endl;
|
||||
|
||||
// Construct a 2D weight.
|
||||
const auto w2 =
|
||||
CGAL::Weights::half_tangent_weight(
|
||||
CGAL::Weights::distance(r2, q2),
|
||||
CGAL::Weights::distance(t2, q2),
|
||||
CGAL::Weights::area(r2, q2, t2),
|
||||
CGAL::Weights::scalar_product(r2, q2, t2)) +
|
||||
CGAL::Weights::half_tangent_weight(
|
||||
CGAL::Weights::distance(r2, q2),
|
||||
CGAL::Weights::distance(p2, q2),
|
||||
CGAL::Weights::area(p2, q2, r2),
|
||||
CGAL::Weights::scalar_product(p2, q2, r2));
|
||||
std::cout << "2D tangent: " << w2 << std::endl;
|
||||
|
||||
// Construct a 3D weight.
|
||||
const auto w3 =
|
||||
CGAL::Weights::half_tangent_weight(
|
||||
CGAL::Weights::tangent_half_angle(
|
||||
CGAL::Weights::distance(r3, q3),
|
||||
CGAL::Weights::distance(t3, q3),
|
||||
CGAL::Weights::area(r3, q3, t3),
|
||||
CGAL::Weights::scalar_product(r3, q3, t3)),
|
||||
CGAL::Weights::distance(r3, q3)) +
|
||||
CGAL::Weights::half_tangent_weight(
|
||||
CGAL::Weights::tangent_half_angle(
|
||||
CGAL::Weights::distance(r3, q3),
|
||||
CGAL::Weights::distance(p3, q3),
|
||||
CGAL::Weights::area(p3, q3, r3),
|
||||
CGAL::Weights::scalar_product(p3, q3, r3)),
|
||||
CGAL::Weights::distance(r3, q3));
|
||||
std::cout << "3D tangent: " << w3 << std::endl;
|
||||
|
||||
assert(test_kernel<SCKER>());
|
||||
assert(test_kernel<EPICK>());
|
||||
assert(test_kernel<EPECK>());
|
||||
std::cout << "* test_tangent_weights: SUCCESS" << std::endl;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,30 +1,64 @@
|
|||
#include <CGAL/Simple_cartesian.h>
|
||||
#include <CGAL/Weights/three_point_family_weights.h>
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
||||
|
||||
#include "include/utils.h"
|
||||
#include "include/wrappers.h"
|
||||
|
||||
// Typedefs.
|
||||
using Kernel = CGAL::Simple_cartesian<double>;
|
||||
using Point_2 = typename Kernel::Point_2;
|
||||
using Point_3 = typename Kernel::Point_3;
|
||||
using SCKER = CGAL::Simple_cartesian<double>;
|
||||
using EPICK = CGAL::Exact_predicates_inexact_constructions_kernel;
|
||||
using EPECK = CGAL::Exact_predicates_exact_constructions_kernel;
|
||||
|
||||
template<typename Kernel>
|
||||
void test_overloads() {
|
||||
using FT = typename Kernel::FT;
|
||||
using Point_2 = typename Kernel::Point_2;
|
||||
using Point_3 = typename Kernel::Point_3;
|
||||
const Point_2 t1(-1, 0);
|
||||
const Point_2 r1( 0, -1);
|
||||
const Point_2 p1( 1, 0);
|
||||
const Point_2 q1( 0, 0);
|
||||
const Point_3 t2(-1, 0, 1);
|
||||
const Point_3 r2( 0, -1, 1);
|
||||
const Point_3 p2( 1, 0, 1);
|
||||
const Point_3 q2( 0, 0, 1);
|
||||
const FT a2 = CGAL::Weights::three_point_family_weight(t1, r1, p1, q1);
|
||||
const FT a3 = CGAL::Weights::internal::three_point_family_weight(t2, r2, p2, q2);
|
||||
assert(a2 >= FT(0));
|
||||
assert(a3 >= FT(0));
|
||||
assert(a2 == a3);
|
||||
struct Traits : public Kernel { };
|
||||
assert(CGAL::Weights::three_point_family_weight(t1, r1, p1, q1, 1, Traits()) == a2);
|
||||
assert(CGAL::Weights::internal::three_point_family_weight(t2, r2, p2, q2, 1, Traits()) == a3);
|
||||
CGAL::Projection_traits_xy_3<Kernel> ptraits;
|
||||
const FT a23 = CGAL::Weights::three_point_family_weight(t2, r2, p2, q2, 0, ptraits);
|
||||
assert(a23 >= FT(0));
|
||||
assert(a23 == a2 && a23 == a3);
|
||||
}
|
||||
|
||||
template<typename Kernel>
|
||||
bool test_kernel() {
|
||||
test_overloads<Kernel>();
|
||||
using FT = typename Kernel::FT;
|
||||
const FT h = FT(1) / FT(2);
|
||||
const wrappers::Three_point_family_wrapper<Kernel> tpfa(0);
|
||||
const wrappers::Three_point_family_wrapper<Kernel> tpfb(1);
|
||||
const wrappers::Three_point_family_wrapper<Kernel> tpfc(2);
|
||||
const wrappers::Three_point_family_wrapper<Kernel> tpfd(h);
|
||||
const wrappers::Wachspress_wrapper<Kernel> whp;
|
||||
const wrappers::Mean_value_wrapper<Kernel> mvw;
|
||||
const wrappers::Discrete_harmonic_wrapper<Kernel> dhw;
|
||||
assert(tests::test_analytic_weight<Kernel>(tpfa, whp));
|
||||
assert(tests::test_analytic_weight<Kernel>(tpfb, mvw));
|
||||
assert(tests::test_analytic_weight<Kernel>(tpfc, dhw));
|
||||
return tests::test_analytic_weight<Kernel>(tpfd, tpfd);
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
||||
// 2D configuration.
|
||||
const Point_2 t2 = Point_2(-1, 0);
|
||||
const Point_2 r2 = Point_2( 0, -1);
|
||||
const Point_2 p2 = Point_2( 1, 0);
|
||||
const Point_2 q2 = Point_2( 0, 0);
|
||||
|
||||
// 3D configuration.
|
||||
const Point_3 t3 = Point_3(-1, 0, 1);
|
||||
const Point_3 r3 = Point_3( 0, -1, 1);
|
||||
const Point_3 p3 = Point_3( 1, 0, 1);
|
||||
const Point_3 q3 = Point_3( 0, 0, 1);
|
||||
|
||||
// Compute weights.
|
||||
std::cout << "2D family: " <<
|
||||
CGAL::Weights::three_point_family_weight(t2, r2, p2, q2) << std::endl;
|
||||
std::cout << "3D family: " <<
|
||||
CGAL::Weights::three_point_family_weight(t3, r3, p3, q3, 1.0) << std::endl;
|
||||
|
||||
assert(test_kernel<SCKER>());
|
||||
assert(test_kernel<EPICK>());
|
||||
assert(test_kernel<EPECK>());
|
||||
std::cout << "* test_three_point_family_weights: SUCCESS" << std::endl;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,28 +1,25 @@
|
|||
#include <CGAL/Simple_cartesian.h>
|
||||
#include <CGAL/Weights/triangular_region_weights.h>
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
||||
|
||||
#include "include/utils.h"
|
||||
#include "include/wrappers.h"
|
||||
|
||||
// Typedefs.
|
||||
using Kernel = CGAL::Simple_cartesian<double>;
|
||||
using Point_2 = typename Kernel::Point_2;
|
||||
using Point_3 = typename Kernel::Point_3;
|
||||
using SCKER = CGAL::Simple_cartesian<double>;
|
||||
using EPICK = CGAL::Exact_predicates_inexact_constructions_kernel;
|
||||
using EPECK = CGAL::Exact_predicates_exact_constructions_kernel;
|
||||
|
||||
template<typename Kernel>
|
||||
bool test_kernel() {
|
||||
const wrappers::Triangular_region_wrapper<Kernel> tri;
|
||||
return tests::test_region_weight<Kernel>(tri);
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
||||
// 2D configuration.
|
||||
const Point_2 p2 = Point_2(-1, 0);
|
||||
const Point_2 q2 = Point_2( 0, 0);
|
||||
const Point_2 r2 = Point_2( 0, 1);
|
||||
|
||||
// 3D configuration.
|
||||
const Point_3 p3 = Point_3(-1, 0, 1);
|
||||
const Point_3 q3 = Point_3( 0, 0, 1);
|
||||
const Point_3 r3 = Point_3( 0, 1, 1);
|
||||
|
||||
// Compute weights.
|
||||
std::cout << "2D triangle: " <<
|
||||
CGAL::Weights::triangular_area(p2, q2, r2) << std::endl;
|
||||
std::cout << "3D triangle: " <<
|
||||
CGAL::Weights::triangular_area(p3, q3, r3) << std::endl;
|
||||
|
||||
assert(test_kernel<SCKER>());
|
||||
assert(test_kernel<EPICK>());
|
||||
assert(test_kernel<EPECK>());
|
||||
std::cout << "* test_triangular_region_weights: SUCCESS" << std::endl;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,35 +1,42 @@
|
|||
#include <CGAL/Simple_cartesian.h>
|
||||
#include <CGAL/Weights/uniform_region_weights.h>
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
||||
|
||||
#include "include/utils.h"
|
||||
#include "include/wrappers.h"
|
||||
|
||||
// Typedefs.
|
||||
using Kernel = CGAL::Simple_cartesian<double>;
|
||||
using Point_2 = typename Kernel::Point_2;
|
||||
using Point_3 = typename Kernel::Point_3;
|
||||
using SCKER = CGAL::Simple_cartesian<double>;
|
||||
using EPICK = CGAL::Exact_predicates_inexact_constructions_kernel;
|
||||
using EPECK = CGAL::Exact_predicates_exact_constructions_kernel;
|
||||
|
||||
template<typename Kernel>
|
||||
void test_overloads() {
|
||||
using FT = typename Kernel::FT;
|
||||
using Point_2 = typename Kernel::Point_2;
|
||||
using Point_3 = typename Kernel::Point_3;
|
||||
const FT a = CGAL::Weights::uniform_area();
|
||||
assert(a == FT(1));
|
||||
const Point_2 p(0, 0);
|
||||
const Point_3 q(0, 0, 0);
|
||||
assert(CGAL::Weights::uniform_area(p, p, p) == a);
|
||||
assert(CGAL::Weights::uniform_area(q, q, q) == a);
|
||||
struct Traits : public Kernel { };
|
||||
assert(CGAL::Weights::uniform_area(p, p, p, Traits()) == a);
|
||||
assert(CGAL::Weights::uniform_area(q, q, q, Traits()) == a);
|
||||
}
|
||||
|
||||
template<typename Kernel>
|
||||
bool test_kernel() {
|
||||
test_overloads<Kernel>();
|
||||
const wrappers::Uniform_region_wrapper<Kernel> uni;
|
||||
return tests::test_region_weight<Kernel>(uni);
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
||||
// 2D configuration.
|
||||
const Point_2 p2 = Point_2(-1, 0);
|
||||
const Point_2 q2 = Point_2( 0, 0);
|
||||
const Point_2 r2 = Point_2( 0, 1);
|
||||
|
||||
// 3D configuration.
|
||||
const Point_3 p3 = Point_3(-1, 0, 1);
|
||||
const Point_3 q3 = Point_3( 0, 0, 1);
|
||||
const Point_3 r3 = Point_3( 0, 1, 1);
|
||||
|
||||
// Compute weights.
|
||||
std::cout << "2D uniform: " <<
|
||||
CGAL::Weights::uniform_area(p2, q2, r2) << std::endl;
|
||||
std::cout << "3D uniform: " <<
|
||||
CGAL::Weights::uniform_area(p3, q3, r3) << std::endl;
|
||||
std::cout << "-------------" << std::endl;
|
||||
|
||||
// Overloads.
|
||||
std::cout << "2D uniform: " <<
|
||||
CGAL::Weights::uniform_area() << std::endl;
|
||||
std::cout << "3D uniform: " <<
|
||||
CGAL::Weights::uniform_area() << std::endl;
|
||||
|
||||
assert(test_kernel<SCKER>());
|
||||
assert(test_kernel<EPICK>());
|
||||
assert(test_kernel<EPECK>());
|
||||
std::cout << "* test_uniform_region_weights: SUCCESS" << std::endl;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,37 +1,42 @@
|
|||
#include <CGAL/Simple_cartesian.h>
|
||||
#include <CGAL/Weights/uniform_weights.h>
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
||||
|
||||
#include "include/utils.h"
|
||||
#include "include/wrappers.h"
|
||||
|
||||
// Typedefs.
|
||||
using Kernel = CGAL::Simple_cartesian<double>;
|
||||
using Point_2 = typename Kernel::Point_2;
|
||||
using Point_3 = typename Kernel::Point_3;
|
||||
using SCKER = CGAL::Simple_cartesian<double>;
|
||||
using EPICK = CGAL::Exact_predicates_inexact_constructions_kernel;
|
||||
using EPECK = CGAL::Exact_predicates_exact_constructions_kernel;
|
||||
|
||||
template<typename Kernel>
|
||||
void test_overloads() {
|
||||
using FT = typename Kernel::FT;
|
||||
using Point_2 = typename Kernel::Point_2;
|
||||
using Point_3 = typename Kernel::Point_3;
|
||||
const FT a = CGAL::Weights::uniform_weight();
|
||||
assert(a == FT(1));
|
||||
const Point_2 p(0, 0);
|
||||
const Point_3 q(0, 0, 0);
|
||||
assert(CGAL::Weights::uniform_weight(p, p, p, p) == a);
|
||||
assert(CGAL::Weights::uniform_weight(q, q, q, q) == a);
|
||||
struct Traits : public Kernel { };
|
||||
assert(CGAL::Weights::uniform_weight(p, p, p, p, Traits()) == a);
|
||||
assert(CGAL::Weights::uniform_weight(q, q, q, q, Traits()) == a);
|
||||
}
|
||||
|
||||
template<typename Kernel>
|
||||
bool test_kernel() {
|
||||
test_overloads<Kernel>();
|
||||
const wrappers::Uniform_wrapper<Kernel> uni;
|
||||
return tests::test_analytic_weight<Kernel>(uni, uni);
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
||||
// 2D configuration.
|
||||
const Point_2 t2 = Point_2(-1, 0);
|
||||
const Point_2 r2 = Point_2( 0, -1);
|
||||
const Point_2 p2 = Point_2( 1, 0);
|
||||
const Point_2 q2 = Point_2( 0, 0);
|
||||
|
||||
// 3D configuration.
|
||||
const Point_3 t3 = Point_3(-1, 0, 1);
|
||||
const Point_3 r3 = Point_3( 0, -1, 1);
|
||||
const Point_3 p3 = Point_3( 1, 0, 1);
|
||||
const Point_3 q3 = Point_3( 0, 0, 1);
|
||||
|
||||
// Compute weights.
|
||||
std::cout << "2D uniform: " <<
|
||||
CGAL::Weights::uniform_weight(t2, r2, p2, q2) << std::endl;
|
||||
std::cout << "3D uniform: " <<
|
||||
CGAL::Weights::uniform_weight(t3, r3, p3, q3) << std::endl;
|
||||
std::cout << "-------------" << std::endl;
|
||||
|
||||
// Overloads.
|
||||
std::cout << "2D uniform: " <<
|
||||
CGAL::Weights::uniform_weight() << std::endl;
|
||||
std::cout << "3D uniform: " <<
|
||||
CGAL::Weights::uniform_weight() << std::endl;
|
||||
|
||||
assert(test_kernel<SCKER>());
|
||||
assert(test_kernel<EPICK>());
|
||||
assert(test_kernel<EPECK>());
|
||||
std::cout << "* test_uniform_weights: SUCCESS" << std::endl;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,28 +1,25 @@
|
|||
#include <CGAL/Simple_cartesian.h>
|
||||
#include <CGAL/Weights/voronoi_region_weights.h>
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
||||
|
||||
#include "include/utils.h"
|
||||
#include "include/wrappers.h"
|
||||
|
||||
// Typedefs.
|
||||
using Kernel = CGAL::Simple_cartesian<double>;
|
||||
using Point_2 = typename Kernel::Point_2;
|
||||
using Point_3 = typename Kernel::Point_3;
|
||||
using SCKER = CGAL::Simple_cartesian<double>;
|
||||
using EPICK = CGAL::Exact_predicates_inexact_constructions_kernel;
|
||||
using EPECK = CGAL::Exact_predicates_exact_constructions_kernel;
|
||||
|
||||
template<typename Kernel>
|
||||
bool test_kernel() {
|
||||
const wrappers::Voronoi_region_wrapper<Kernel> vor;
|
||||
return tests::test_region_weight<Kernel>(vor);
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
||||
// 2D configuration.
|
||||
const Point_2 p2 = Point_2(-1, 0);
|
||||
const Point_2 q2 = Point_2( 0, 0);
|
||||
const Point_2 r2 = Point_2( 0, 1);
|
||||
|
||||
// 3D configuration.
|
||||
const Point_3 p3 = Point_3(-1, 0, 1);
|
||||
const Point_3 q3 = Point_3( 0, 0, 1);
|
||||
const Point_3 r3 = Point_3( 0, 1, 1);
|
||||
|
||||
// Compute weights.
|
||||
std::cout << "2D voronoi: " <<
|
||||
CGAL::Weights::voronoi_area(p2, q2, r2) << std::endl;
|
||||
std::cout << "3D voronoi: " <<
|
||||
CGAL::Weights::voronoi_area(p3, q3, r3) << std::endl;
|
||||
|
||||
assert(test_kernel<SCKER>());
|
||||
assert(test_kernel<EPICK>());
|
||||
assert(test_kernel<EPECK>());
|
||||
std::cout << "* test_voronoi_region_weights: SUCCESS" << std::endl;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,110 +1,54 @@
|
|||
#include <CGAL/Simple_cartesian.h>
|
||||
#include <CGAL/Weights/wachspress_weights.h>
|
||||
#include <CGAL/Weights/internal/Projection_traits_3.h>
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
||||
|
||||
#include "include/utils.h"
|
||||
#include "include/wrappers.h"
|
||||
|
||||
// Typedefs.
|
||||
using Kernel = CGAL::Simple_cartesian<double>;
|
||||
using FT = typename Kernel::FT;
|
||||
using Point_2 = typename Kernel::Point_2;
|
||||
using Point_3 = typename Kernel::Point_3;
|
||||
using SCKER = CGAL::Simple_cartesian<double>;
|
||||
using EPICK = CGAL::Exact_predicates_inexact_constructions_kernel;
|
||||
using EPECK = CGAL::Exact_predicates_exact_constructions_kernel;
|
||||
|
||||
int main() {
|
||||
|
||||
// 2D configuration.
|
||||
const Point_2 t2 = Point_2(-1, 0);
|
||||
const Point_2 r2 = Point_2( 0, -1);
|
||||
const Point_2 p2 = Point_2( 1, 0);
|
||||
const Point_2 q2 = Point_2( 0, 0);
|
||||
|
||||
// 3D configuration.
|
||||
const Point_3 t3 = Point_3(-1, 0, 1);
|
||||
const Point_3 r3 = Point_3( 0, -1, 1);
|
||||
const Point_3 p3 = Point_3( 1, 0, 1);
|
||||
const Point_3 q3 = Point_3( 0, 0, 1);
|
||||
|
||||
// Compute weights.
|
||||
std::cout << "2D wachspress: " <<
|
||||
CGAL::Weights::wachspress_weight(t2, r2, p2, q2) << std::endl;
|
||||
std::cout << "3D wachspress: " <<
|
||||
CGAL::Weights::wachspress_weight(t3, r3, p3, q3) << std::endl;
|
||||
|
||||
// 2D configuration.
|
||||
const std::vector<Point_2> polygon2 = {t2, r2, p2, Point_2(0, 1)};
|
||||
|
||||
std::vector<double> weights2;
|
||||
weights2.reserve(polygon2.size());
|
||||
CGAL::Weights::wachspress_weights_2(
|
||||
polygon2, q2, std::back_inserter(weights2));
|
||||
|
||||
std::cout << "2D wachspress (polygon): ";
|
||||
for (const double weight2 : weights2)
|
||||
std::cout << weight2 << " ";
|
||||
std::cout << std::endl;
|
||||
|
||||
// 3D configuration.
|
||||
CGAL::Weights::internal::Projection_traits_3<Kernel> ptraits(
|
||||
typename Kernel::Vector_3(0, 0, 1));
|
||||
|
||||
const std::vector<Point_3> polygon3 = {t3, r3, p3, Point_3(0, 1, 1)};
|
||||
|
||||
std::vector<double> weights3;
|
||||
weights3.reserve(polygon3.size());
|
||||
CGAL::Weights::wachspress_weights_2(
|
||||
polygon3, q3, std::back_inserter(weights3), ptraits);
|
||||
|
||||
std::cout << "3D wachspress (polygon): ";
|
||||
for (const double weight3 : weights3)
|
||||
std::cout << weight3 << " ";
|
||||
std::cout << std::endl;
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
template<typename Kernel>
|
||||
void test_overloads() {
|
||||
using FT = typename Kernel::FT;
|
||||
using Point_2 = typename Kernel::Point_2;
|
||||
using Point_3 = typename Kernel::Point_3;
|
||||
const Point_2 t1(-1, 0);
|
||||
const Point_2 r1( 0, -1);
|
||||
const Point_2 p1( 1, 0);
|
||||
const Point_2 q1( 0, 0);
|
||||
const Point_3 t2(-1, 0, 1);
|
||||
const Point_3 r2( 0, -1, 1);
|
||||
const Point_3 p2( 1, 0, 1);
|
||||
const Point_3 q2( 0, 0, 1);
|
||||
const FT a2 = CGAL::Weights::wachspress_weight(t1, r1, p1, q1);
|
||||
const FT a3 = CGAL::Weights::internal::wachspress_weight(t2, r2, p2, q2);
|
||||
assert(a2 >= FT(0));
|
||||
assert(a3 >= FT(0));
|
||||
assert(a2 == a3);
|
||||
struct Traits : public Kernel { };
|
||||
assert(CGAL::Weights::wachspress_weight(t1, r1, p1, q1, Traits()) == a2);
|
||||
assert(CGAL::Weights::internal::wachspress_weight(t2, r2, p2, q2, Traits()) == a3);
|
||||
CGAL::Projection_traits_xy_3<Kernel> ptraits;
|
||||
const FT a23 = CGAL::Weights::wachspress_weight(t2, r2, p2, q2, ptraits);
|
||||
assert(a23 >= FT(0));
|
||||
assert(a23 == a2 && a23 == a3);
|
||||
}
|
||||
|
||||
// Merge it with the current test!
|
||||
template<typename Kernel>
|
||||
bool test_kernel() {
|
||||
test_overloads<Kernel>();
|
||||
const wrappers::Wachspress_wrapper<Kernel> whp;
|
||||
const wrappers::Authalic_wrapper<Kernel> aut;
|
||||
return tests::test_barycentric_weight<Kernel>(whp, aut);
|
||||
}
|
||||
|
||||
// 2D configuration.
|
||||
// const Point_2 query2 = Point_2(+FT(0), FT(0));
|
||||
// const Point_2 vm2 = Point_2(+FT(1), FT(0));
|
||||
// const Point_2 vj2 = Point_2(+FT(0), FT(1));
|
||||
// const Point_2 vp2 = Point_2(-FT(1), FT(0));
|
||||
// Am = 0.5, Aj = 0.5, C = 1, B = 0.
|
||||
|
||||
// 3D configuration 1. All points are coplanar on a horizontal plane.
|
||||
// const Point_3 query3 = Point_3(+FT(0), FT(0), FT(1));
|
||||
// const Point_3 vm3 = Point_3(+FT(1), FT(0), FT(1));
|
||||
// const Point_3 vj3 = Point_3(+FT(0), FT(1), FT(1));
|
||||
// const Point_3 vp3 = Point_3(-FT(1), FT(0), FT(1));
|
||||
// Am = 0.5, Aj = 0.5, C = 1, B = 0, 2D : 4.
|
||||
|
||||
// 3D configuration 2. All points are coplanar on an arbitrary plane.
|
||||
// const Point_3 query3 = Point_3(-3.25022842347400, +3.9956322466210, +4.000000000000);
|
||||
// const Point_3 vm3 = Point_3(-4.82908178925400, -0.9535525880045, +0.000000000000);
|
||||
// const Point_3 vj3 = Point_3(-0.09833607144587, +1.9562179601920, -1.812058795517);
|
||||
// const Point_3 vp3 = Point_3(+4.54574179746300, +7.9148892979530, +0.000000000000);
|
||||
// Am = 17.701, Aj = 26.574, C = 13.804, B = 30.471, 3D: 0.0293453.
|
||||
|
||||
// 3D configuration 3. The first three points are coplanar whereas vp3 is slightly offsetted.
|
||||
// const Point_3 query3 = Point_3(-3.25022842347400, +3.9956322466210, +4.0000000000000);
|
||||
// const Point_3 vm3 = Point_3(-4.82908178925400, -0.9535525880045, +0.0000000000000);
|
||||
// const Point_3 vj3 = Point_3(-0.09833607144587, +1.9562179601920, -1.8120587955170);
|
||||
// const Point_3 vp3 = Point_3(+4.22658807629900, +8.2522664687610, -0.2914612626125);
|
||||
|
||||
// My area Am should coincide with the area below, but my areas Aj, C, and B should be
|
||||
// closer to the second configuration than areas below.
|
||||
// Am = 17.701, Aj = 26.641, C = 13.896, B = 30.524, 3D: 0.0293359.
|
||||
|
||||
// 3D configuration 3. The first three points are coplanar whereas vp3 is even more slightly offsetted.
|
||||
// This configuration should converge to the second one comparing to the previous one.
|
||||
// const Point_3 query3 = Point_3(-3.25022842347400, +3.9956322466210, +4.0000000000000);
|
||||
// const Point_3 vm3 = Point_3(-4.82908178925400, -0.9535525880045, +0.0000000000000);
|
||||
// const Point_3 vj3 = Point_3(-0.09833607144587, +1.9562179601920, -1.8120587955170);
|
||||
// const Point_3 vp3 = Point_3(+4.41756058270700, +8.0503895685670, -0.1170591355154);
|
||||
|
||||
// My area Am should coincide with the area below, but my areas Aj, C, and B should be
|
||||
// closer to the second configuration than areas below.
|
||||
// Am = 17.701, Aj = 26.585, C = 13.819, B = 30.480, 3D: 0.0293438.
|
||||
|
||||
// Compute weights.
|
||||
// WP wp;
|
||||
// std::cout << "2D wachspress: " << wp(query2, vm2, vj2, vp2) << std::endl;
|
||||
// std::cout << "3D wachspress: " << wp(query3, vm3, vj3, vp3) << std::endl;
|
||||
int main() {
|
||||
assert(test_kernel<SCKER>());
|
||||
assert(test_kernel<EPICK>());
|
||||
assert(test_kernel<EPECK>());
|
||||
std::cout << "* test_wachspress_weights: SUCCESS" << std::endl;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,24 +1,17 @@
|
|||
To discuss:
|
||||
* When computing weights one by one, we recompute certain areas/distances multiple times and so using them e.g. in barycentric coordinates is not efficient. What should we do about that?
|
||||
* When computing weights one by one, we recompute certain areas/distances multiple times and so using them e.g. in barycentric coordinates is not efficient. What should we do about that? Nothing.
|
||||
* Why do we have in the orbifold_Tutte_parameterizer "+tangent_weight" while in the MVC_post_processor it is "-tangent_weight"? I have fixed that.
|
||||
* Do I need to cut-zero the dh weights in the orbifold_Tutte_parameterizer? (line 837) I do cut it for the moment. Otherwise, the results are not equal to the original version.
|
||||
* Do I need to cut-zero the dh weights in the orbifold_Tutte_parameterizer? (line 837)? I do cut it for the moment. Otherwise, the results are not equal to the original version.
|
||||
* Skeletonization uses the weird secure version for the cotangent weights.
|
||||
* In skeletonization, the final example results are not determenistic.
|
||||
* Should I remove the positive area from the Tangent_weight and substitute it by computing tan(alpha/2)? In this case, I will keep the correct sign in any configuration.
|
||||
* What about using a solution that we currently use in the triangulate_hole_with_cdt() instead of flattening?
|
||||
* Should I remove the positive area from the Tangent_weight and substitute it by computing tan(alpha/2)? In this case, I will keep the correct sign in any configuration. Yes. I did that.
|
||||
|
||||
Later:
|
||||
* Cleanup tests.
|
||||
* Comment the code.
|
||||
* Check memory leaking.
|
||||
* Add more pictures/figures.
|
||||
* Add a concept test as in the heat_method.
|
||||
* Try to combine cotangent wrappers from the tools.h. Not sure if this is necessary.
|
||||
* Try to combine mvc and dhc in the orbifold parameterization. Not sure if this is necessary.
|
||||
* Mention that tangent_weight_3 uses positive areas (no distortions) and can be used only for PMP, while mean_value_weight_2/3 e.g. can have different signs/distortions for 2D and 3D versions due to the flattening of the 3D region.
|
||||
* Fix all other packages with respect to the new interface.
|
||||
* Check memory leaking.
|
||||
|
||||
To do now:
|
||||
* What happens with WP/MV/DH weights on the polygon boundary?
|
||||
* Check if this code works with the Projection_traits_xy class. E.g. the latter does not have the object Construct_centroid_2.
|
||||
* Add missing functions in Triangulation_2_projection_3 traits.
|
||||
* Mention that tangent_weight_3 uses positive areas (no distortions) and can be used only for PMP, while mean_value_weight_2/3 e.g. can have different signs/distortions for 2D and 3D versions due to the flattening of the 3D region. See above.
|
||||
* Fix all other packages with respect to the new interface.
|
||||
Loading…
Reference in New Issue