This commit is contained in:
Dmitry Anisimov 2021-05-20 16:21:22 +02:00
parent 2f086a509d
commit 693ab064ba
21 changed files with 186 additions and 157 deletions

View File

@ -19,10 +19,11 @@ void generate_regular_polygon(
vertices.clear();
vertices.reserve(n);
for (std::size_t i = 0; i < n; ++i)
for (std::size_t i = 0; i < n; ++i) {
vertices.push_back(Point_2(
static_cast<FT>(+radius * sin((CGAL_PI / n) + ((i * 2.0 * CGAL_PI) / n))),
static_cast<FT>(-radius * cos((CGAL_PI / n) + ((i * 2.0 * CGAL_PI) / n)))));
}
}
int main() {

View File

@ -23,7 +23,7 @@ public:
/*!
returns the number of vertices after meshing the domain.
*/
const std::size_t number_of_vertices() const {
std::size_t number_of_vertices() const {
}
@ -40,19 +40,18 @@ public:
verifies if the vertex with the index `query_index` is on the
boundary of the domain.
*/
const bool is_on_boundary(
bool is_on_boundary(
const std::size_t query_index) const {
}
/*!
fills `neighbors` with the indices of the vertices, which from the one-ring
fills `neighbors` with the indices of the vertices, which form the one-ring
neighborhood of the vertex with the index `query_index`, the neighbors have to
be in the counterclockwise order and form a simple polygon.
*/
void operator()(
const std::size_t query_index,
std::vector<std::size_t>& neighbors) {
const std::size_t query_index, std::vector<std::size_t>& neighbors) {
}
@ -62,8 +61,7 @@ public:
`query` point does not belong to the domain; the type `Query_2` is a model of `Kernel::Point_2`.
*/
void locate(
const Query_2& query,
std::vector<std::size_t>& indices) {
const Query_2& query, std::vector<std::size_t>& indices) {
}
};

View File

@ -13,7 +13,7 @@ models used to parameterize the class `Generalized_barycentric_coordinates_2`.
- `Mean_value_2`
- `Discrete_harmonic_2`
\deprecated This part of the package is deprecated since the version 5.2 of \cgal.
\deprecated This part of the package is deprecated since the version 5.4 of \cgal.
*/
class BarycentricCoordinates_2 {
@ -29,8 +29,7 @@ public:
type <a href="http://en.cppreference.com/w/cpp/container/vector">`std::vector`</a>.
*/
BarycentricCoordinates_2(
const std::vector<Traits::Point_2>& vertices,
const Traits& barycentric_traits) {
const std::vector<Traits::Point_2>& vertices, const Traits& barycentric_traits) {
}
@ -47,8 +46,7 @@ public:
*/
boost::optional<OutputIterator>
weights(
const Traits::Point_2& query_point,
OutputIterator& output) {
const Traits::Point_2& query_point, OutputIterator& output) {
}

View File

@ -55,9 +55,10 @@ int main() {
// Associate each polygon vertex with the corresponding function value.
Vertex_function_value vertex_function_value;
for(const auto& vertex : polygon)
for (const auto& vertex : polygon) {
vertex_function_value.insert(
std::make_pair(vertex, vertex.z()));
}
// Construct the class with the mean value weights.
Mean_value_coordinates_2 mean_value_coordinates_2(polygon);
@ -78,8 +79,9 @@ int main() {
coordinates.clear();
mean_value_coordinates_2(query, std::back_inserter(coordinates));
for (std::size_t i = 0; i < polygon.size(); ++i)
for (std::size_t i = 0; i < polygon.size(); ++i) {
boundary[i] = std::make_pair(polygon[i], coordinates[i]);
}
const FT f = CGAL::linear_interpolation(
boundary.begin(), boundary.end(), FT(1),
@ -89,8 +91,9 @@ int main() {
// Output interpolated heights.
std::cout << std::endl << "interpolated heights (all queries): " << std::endl << std::endl;
for (const auto& query : queries)
for (const auto& query : queries) {
std::cout << query.z() << std::endl;
}
std::cout << std::endl;
return EXIT_SUCCESS;

View File

@ -42,8 +42,9 @@ int main() {
CGAL::Barycentric_coordinates::wachspress_coordinates_2(
convex, query, std::back_inserter(coordinates));
for (std::size_t i = 0; i < coordinates.size() - 1; ++i)
for (std::size_t i = 0; i < coordinates.size() - 1; ++i) {
std::cout << coordinates[i] << ", ";
}
std::cout << coordinates[coordinates.size() - 1] << std::endl;
}
std::cout << std::endl;

View File

@ -71,8 +71,9 @@ int main() {
for (const auto& query : queries) {
coordinates.clear();
affine(query, std::back_inserter(coordinates));
for (std::size_t i = 0; i < coordinates.size() - 1; ++i)
for (std::size_t i = 0; i < coordinates.size() - 1; ++i) {
std::cout << coordinates[i] << ", ";
}
std::cout << coordinates[coordinates.size() - 1] << std::endl;
}
std::cout << std::endl;

View File

@ -62,8 +62,9 @@ int main() {
++count;
// Output the coordinates.
for (std::size_t i = 0; i < coordinates.size() - 1; ++i)
for (std::size_t i = 0; i < coordinates.size() - 1; ++i) {
std::cout << coordinates[i] << ", ";
}
std::cout << coordinates[coordinates.size() - 1] << std::endl;
}
std::cout << std::endl;

View File

@ -49,8 +49,9 @@ int main() {
discrete_harmonic_2.weights(center, std::back_inserter(weights));
std::cout << std::endl << "discrete harmonic weights (center): ";
for (const FT& weight : weights)
for (const FT& weight : weights) {
std::cout << weight << " ";
}
std::cout << std::endl;
// Compute discrete harmonic coordinates for the center point.
@ -58,8 +59,9 @@ int main() {
discrete_harmonic_2(center, std::back_inserter(coordinates));
std::cout << std::endl << "discrete harmonic coordinates (center): ";
for (const FT& coordinate : coordinates)
for (const FT& coordinate : coordinates) {
std::cout << coordinate << " ";
}
std::cout << std::endl;
// Construct several interior points.
@ -76,8 +78,9 @@ int main() {
for (const auto& query : interior_points) {
ws.clear();
discrete_harmonic_2.weights(query, std::back_inserter(ws));
for (std::size_t i = 0; i < ws.size() - 1; ++i)
for (std::size_t i = 0; i < ws.size() - 1; ++i) {
std::cout << ws[i] << ", ";
}
std::cout << ws[ws.size() - 1] << std::endl;
}
@ -88,8 +91,9 @@ int main() {
for (const auto& query : interior_points) {
bs.clear();
discrete_harmonic_2(query, std::back_inserter(bs));
for (std::size_t i = 0; i < bs.size() - 1; ++i)
for (std::size_t i = 0; i < bs.size() - 1; ++i) {
std::cout << bs[i] << ", ";
}
std::cout << bs[bs.size() - 1] << std::endl;
}
@ -106,8 +110,9 @@ int main() {
square, e4, std::back_inserter(coordinates), kernel, point_map);
std::cout << std::endl << "boundary coordinates (edge 2 and edge 4): ";
for (const FT& coordinate : coordinates)
for (const FT& coordinate : coordinates) {
std::cout << coordinate << " ";
}
std::cout << std::endl;
// Construct 6 other boundary points: 2 on the first and third edges respectively
@ -128,8 +133,9 @@ int main() {
bs.clear();
CGAL::Barycentric_coordinates::boundary_coordinates_2(
square, query, std::back_inserter(bs), point_map); // we can skip kernel here
for (std::size_t i = 0; i < bs.size() - 1; ++i)
for (std::size_t i = 0; i < bs.size() - 1; ++i) {
std::cout << bs[i] << ", ";
}
std::cout << bs[bs.size() - 1] << std::endl;
}
@ -145,8 +151,9 @@ int main() {
discrete_harmonic_2(r, std::back_inserter(coordinates));
std::cout << std::endl << "discrete harmonic coordinates (exterior): ";
for (const FT& coordinate : coordinates)
for (const FT& coordinate : coordinates) {
std::cout << coordinate << " ";
}
std::cout << std::endl << std::endl;
return EXIT_SUCCESS;

View File

@ -57,8 +57,9 @@ int main() {
for (std::size_t k = 0; k < 20; ++k) {
coordinates.clear();
harmonic_coordinates_2(k, std::back_inserter(coordinates));
for (std::size_t i = 0; i < coordinates.size() - 1; ++i)
for (std::size_t i = 0; i < coordinates.size() - 1; ++i) {
std::cout << coordinates[i] << ", ";
}
std::cout << coordinates[coordinates.size() - 1] << std::endl;
}
@ -72,8 +73,9 @@ int main() {
for (std::size_t k = 0; k < 20; ++k) {
coordinates.clear();
harmonic_coordinates_2(barycenters[k], std::back_inserter(coordinates));
for (std::size_t i = 0; i < coordinates.size() - 1; ++i)
for (std::size_t i = 0; i < coordinates.size() - 1; ++i) {
std::cout << coordinates[i] << ", ";
}
std::cout << coordinates[coordinates.size() - 1] << std::endl;
}
std::cout << std::endl;

View File

@ -41,8 +41,9 @@ int main() {
star_shaped, query, std::back_inserter(coordinates), policy);
// Output mean value coordinates.
for (std::size_t i = 0; i < coordinates.size() - 1; ++i)
for (std::size_t i = 0; i < coordinates.size() - 1; ++i) {
std::cout << coordinates[i] << ", ";
}
std::cout << coordinates[coordinates.size() - 1] << std::endl;
}
std::cout << std::endl;

View File

@ -28,21 +28,23 @@ int main() {
std::vector<FT> coordinates;
coordinates.reserve(queries.size() * 2);
for(const auto& query : queries)
for (const auto& query : queries) {
CGAL::Barycentric_coordinates::segment_coordinates_2(
source, target, query, std::back_inserter(coordinates));
}
// Output all segment coordinates.
std::cout << std::endl << "segment coordinates (all queries): " << std::endl << std::endl;
for (std::size_t i = 0; i < coordinates.size(); i += 2)
for (std::size_t i = 0; i < coordinates.size(); i += 2) {
std::cout <<
coordinates[i + 0] << ", " <<
coordinates[i + 1] << std::endl;
}
std::cout << std::endl;
// Get a pair of segment coordinates for the first point.
const auto pair = CGAL::Barycentric_coordinates::segment_coordinates_in_pair_2(
source, target, queries[0]);
const auto pair =
CGAL::Barycentric_coordinates::segment_coordinates_in_pair_2(source, target, queries[0]);
std::cout << "segment coordinates (query 0): " <<
pair.first << " " << pair.second << std::endl << std::endl;

View File

@ -31,22 +31,24 @@ int main() {
std::vector<FT> coordinates;
coordinates.reserve(queries.size() * 3);
for(const auto& query : queries)
for (const auto& query : queries) {
CGAL::Barycentric_coordinates::triangle_coordinates_2(
p0, p1, p2, query, std::back_inserter(coordinates));
}
// Output all triangle coordinates.
std::cout << std::endl << "triangle coordinates (all queries): " << std::endl << std::endl;
for (std::size_t i = 0; i < coordinates.size(); i += 3)
for (std::size_t i = 0; i < coordinates.size(); i += 3) {
std::cout <<
coordinates[i + 0] << ", " <<
coordinates[i + 1] << ", " <<
coordinates[i + 2] << std::endl;
}
std::cout << std::endl;
// Get a tuple of triangle coordinates for the first point.
const auto tuple = CGAL::Barycentric_coordinates::triangle_coordinates_in_tuple_2(
p0, p1, p2, queries[0]);
const auto tuple =
CGAL::Barycentric_coordinates::triangle_coordinates_in_tuple_2(p0, p1, p2, queries[0]);
std::cout << "triangle coordinates (query 0): " <<
std::get<0>(tuple) << " " << std::get<1>(tuple) << " " << std::get<2>(tuple) << std::endl << std::endl;

View File

@ -153,8 +153,7 @@ namespace Barycentric_coordinates {
*/
template<typename PointRange>
void create(
const FT max_edge_length,
const PointRange& seeds) {
const FT max_edge_length, const PointRange& seeds) {
create_triangulation();
refine_triangulation(
@ -181,8 +180,7 @@ namespace Barycentric_coordinates {
one past the last barycenter stored
*/
template<typename OutIterator>
OutIterator barycenters(
OutIterator b_begin) const {
OutIterator barycenters(OutIterator b_begin) const {
const std::size_t num_faces = get_number_of_faces();
if (num_faces == 0) return b_begin;
@ -296,10 +294,11 @@ namespace Barycentric_coordinates {
triangle.clear();
const auto fh = m_cdt.locate(query);
if (fh->is_in_domain()) {
for (std::size_t i = 0; i < 3; ++i)
for (std::size_t i = 0; i < 3; ++i) {
triangle.push_back(fh->vertex(i)->info().index);
}
}
}
/// @}
@ -334,8 +333,9 @@ namespace Barycentric_coordinates {
const std::size_t num_vertices = points.size();
add_ply_header_points(num_vertices, out);
for (const auto& point : points)
for (const auto& point : points) {
out << point << " 0 0 0 0" << std::endl;
}
save(out, file_path + ".ply");
}
@ -349,8 +349,9 @@ namespace Barycentric_coordinates {
const std::size_t num_vertices = points.size();
add_ply_header_points(num_vertices, out);
for (const auto& point : points)
for (const auto& point : points) {
out << point << " 0 0 0" << std::endl;
}
save(out, file_path + ".ply");
}
@ -417,15 +418,15 @@ namespace Barycentric_coordinates {
for (std::size_t i = 0; i < n; ++i) {
const std::size_t ip = (i + 1) % n;
if (m_vhs[i] != m_vhs[ip])
if (m_vhs[i] != m_vhs[ip]) {
m_cdt.insert_constraint(m_vhs[i], m_vhs[ip]);
}
}
}
template<typename PointRange>
void refine_triangulation(
const FT max_edge_length,
const PointRange& seeds) {
const FT max_edge_length, const PointRange& seeds) {
// 0.125 is the default shape bound that corresponds to a bound of 20.6 degrees.
Mesher mesher(m_cdt);
@ -494,9 +495,9 @@ namespace Barycentric_coordinates {
const auto fh = edge->first;
const auto nh = fh->vertex(edge->second);
if (fh->is_in_domain())
if (fh->is_in_domain()) {
vh->info().neighbors.push_back(nh->info().index);
else {
} else {
vh->info().neighbors.push_back(nh->info().index);
break;
} ++edge;

View File

@ -161,10 +161,7 @@ namespace Barycentric_coordinates {
one past the last weight stored
*/
template<typename OutIterator>
OutIterator weights(
const Point_2& query,
OutIterator w_begin) {
OutIterator weights(const Point_2& query, OutIterator w_begin) {
const bool normalize = false;
return compute(query, w_begin, normalize);
}
@ -194,10 +191,7 @@ namespace Barycentric_coordinates {
one past the last coordinate stored
*/
template<typename OutIterator>
OutIterator operator()(
const Point_2& query,
OutIterator c_begin) {
OutIterator operator()(const Point_2& query, OutIterator c_begin) {
const bool normalize = true;
return compute(query, c_begin, normalize);
}
@ -232,9 +226,7 @@ namespace Barycentric_coordinates {
template<typename OutputIterator>
OutputIterator compute(
const Point_2& query,
OutputIterator output,
const bool normalize) {
const Point_2& query, OutputIterator output, const bool normalize) {
switch (m_computation_policy) {
@ -251,11 +243,13 @@ namespace Barycentric_coordinates {
case Computation_policy_2::PRECISE_WITH_EDGE_CASES: {
const auto edge_case = verify(query, output);
if (edge_case == internal::Edge_case::BOUNDARY)
if (edge_case == internal::Edge_case::BOUNDARY) {
return output;
if (edge_case == internal::Edge_case::EXTERIOR)
}
if (edge_case == internal::Edge_case::EXTERIOR) {
std::cerr << std::endl <<
"WARNING: query does not belong to the polygon!" << std::endl;
}
if (normalize) {
return max_precision_coordinates(query, output);
} else {
@ -272,11 +266,13 @@ namespace Barycentric_coordinates {
case Computation_policy_2::FAST_WITH_EDGE_CASES: {
const auto edge_case = verify(query, output);
if (edge_case == internal::Edge_case::BOUNDARY)
if (edge_case == internal::Edge_case::BOUNDARY) {
return output;
if (edge_case == internal::Edge_case::EXTERIOR)
}
if (edge_case == internal::Edge_case::EXTERIOR) {
std::cerr << std::endl <<
"WARNING: query does not belong to the polygon!" << std::endl;
}
return m_discrete_harmonic_weights_2(query, output, normalize);
}
@ -290,18 +286,19 @@ namespace Barycentric_coordinates {
template<typename OutputIterator>
internal::Edge_case verify(
const Point_2& query,
OutputIterator output) const {
const Point_2& query, OutputIterator output) const {
const auto result = internal::locate_wrt_polygon_2(
m_polygon, query, m_traits, m_point_map);
if (!result)
if (!result) {
return internal::Edge_case::EXTERIOR;
}
const auto location = (*result).first;
const std::size_t index = (*result).second;
if (location == internal::Query_point_location::ON_UNBOUNDED_SIDE)
if (location == internal::Query_point_location::ON_UNBOUNDED_SIDE) {
return internal::Edge_case::EXTERIOR;
}
if (
location == internal::Query_point_location::ON_VERTEX ||
@ -315,8 +312,7 @@ namespace Barycentric_coordinates {
template<typename OutputIterator>
OutputIterator max_precision_coordinates(
const Point_2& query,
OutputIterator coordinates) {
const Point_2& query, OutputIterator coordinates) {
// Get the number of vertices in the polygon.
const std::size_t n = m_polygon.size();
@ -349,26 +345,31 @@ namespace Barycentric_coordinates {
// Initialize weights with the numerator of the formula (25) with p = 2 from [1].
// Then we multiply them by areas A as in the formula (5) in [1]. We also split the loop.
w[0] = r[1] * A[n - 1] - r[0] * B[0] + r[n - 1] * A[0];
for (std::size_t j = 1; j < n - 1; ++j)
for (std::size_t j = 1; j < n - 1; ++j) {
w[0] *= A[j];
}
for (std::size_t i = 1; i < n - 1; ++i) {
w[i] = r[i + 1] * A[i - 1] - r[i] * B[i] + r[i - 1] * A[i];
for (std::size_t j = 0; j < i - 1; ++j)
for (std::size_t j = 0; j < i - 1; ++j) {
w[i] *= A[j];
for (std::size_t j = i + 1; j < n; ++j)
}
for (std::size_t j = i + 1; j < n; ++j) {
w[i] *= A[j];
}
}
w[n - 1] = r[0] * A[n - 2] - r[n - 1] * B[n - 1] + r[n - 2] * A[n - 1];
for (std::size_t j = 0; j < n - 2; ++j)
for (std::size_t j = 0; j < n - 2; ++j) {
w[n - 1] *= A[j];
}
// Return coordinates.
internal::normalize(w);
for (std::size_t i = 0; i < n; ++i)
for (std::size_t i = 0; i < n; ++i) {
*(coordinates++) = w[i];
}
return coordinates;
}
};

View File

@ -189,8 +189,7 @@ namespace Barycentric_coordinates {
*/
template<typename OutIterator>
OutIterator operator()(
const Point_2& query,
OutIterator c_begin) {
const Point_2& query, OutIterator c_begin) {
CGAL_precondition(
m_setup_is_called &&
@ -281,8 +280,7 @@ namespace Barycentric_coordinates {
*/
template<typename OutIterator>
OutIterator operator()(
const std::size_t query_index,
OutIterator c_begin) {
const std::size_t query_index, OutIterator c_begin) {
CGAL_precondition(
m_setup_is_called &&
@ -301,12 +299,14 @@ namespace Barycentric_coordinates {
// Save harmonic coordinates.
const std::size_t n = m_polygon.size();
if (m_domain.is_on_boundary(query_index)) {
for (std::size_t k = 0; k < n; ++k)
for (std::size_t k = 0; k < n; ++k) {
*(c_begin++) = m_boundary(m_indices[query_index], k);
}
} else {
for (std::size_t k = 0; k < n; ++k)
for (std::size_t k = 0; k < n; ++k) {
*(c_begin++) = m_interior(m_indices[query_index], k);
}
}
return c_begin;
}
@ -510,11 +510,12 @@ namespace Barycentric_coordinates {
std::back_inserter(lambda), m_traits, m_point_map);
// Set boundary vector.
for (std::size_t k = 0; k < n; ++k)
for (std::size_t k = 0; k < n; ++k) {
boundary(indices[i], k) = lambda[k];
}
}
}
}
void set_harmonic_data(
const std::size_t numI,
@ -561,8 +562,9 @@ namespace Barycentric_coordinates {
W -= w;
if (m_domain.is_on_boundary(idx)) {
for (std::size_t k = 0; k < n; ++k)
for (std::size_t k = 0; k < n; ++k) {
b(indices[i], k) -= boundary(indices[idx], k) * w;
}
} else {
triplet_list.push_back(
TripletFT(indices[i], indices[idx], w));

View File

@ -170,10 +170,7 @@ namespace Barycentric_coordinates {
one past the last weight stored
*/
template<typename OutIterator>
OutIterator weights(
const Point_2& query,
OutIterator w_begin) {
OutIterator weights(const Point_2& query, OutIterator w_begin) {
const bool normalize = false;
return compute(query, w_begin, normalize);
}
@ -203,10 +200,7 @@ namespace Barycentric_coordinates {
one past the last coordinate stored
*/
template<typename OutIterator>
OutIterator operator()(
const Point_2& query,
OutIterator c_begin) {
OutIterator operator()(const Point_2& query, OutIterator c_begin) {
const bool normalize = true;
return compute(query, c_begin, normalize);
}
@ -248,9 +242,7 @@ namespace Barycentric_coordinates {
template<typename OutputIterator>
OutputIterator compute(
const Point_2& query,
OutputIterator output,
const bool normalize) {
const Point_2& query, OutputIterator output, const bool normalize) {
switch (m_computation_policy) {
@ -267,8 +259,9 @@ namespace Barycentric_coordinates {
case Computation_policy_2::PRECISE_WITH_EDGE_CASES: {
const auto edge_case = verify(query, output);
if (edge_case == internal::Edge_case::BOUNDARY)
if (edge_case == internal::Edge_case::BOUNDARY) {
return output;
}
if (normalize) {
return max_precision_coordinates(query, output);
} else {
@ -285,8 +278,9 @@ namespace Barycentric_coordinates {
case Computation_policy_2::FAST_WITH_EDGE_CASES: {
const auto edge_case = verify(query, output);
if (edge_case == internal::Edge_case::BOUNDARY)
if (edge_case == internal::Edge_case::BOUNDARY) {
return output;
}
return m_mean_value_weights_2(query, output, normalize);
}
@ -300,18 +294,19 @@ namespace Barycentric_coordinates {
template<typename OutputIterator>
internal::Edge_case verify(
const Point_2& query,
OutputIterator output) const {
const Point_2& query, OutputIterator output) const {
const auto result = internal::locate_wrt_polygon_2(
m_polygon, query, m_traits, m_point_map);
if (!result)
if (!result) {
return internal::Edge_case::EXTERIOR;
}
const auto location = (*result).first;
const std::size_t index = (*result).second;
if (location == internal::Query_point_location::ON_UNBOUNDED_SIDE)
if (location == internal::Query_point_location::ON_UNBOUNDED_SIDE) {
return internal::Edge_case::EXTERIOR;
}
if (
location == internal::Query_point_location::ON_VERTEX ||
@ -325,8 +320,7 @@ namespace Barycentric_coordinates {
template<typename OutputIterator>
OutputIterator max_precision_coordinates(
const Point_2& query,
OutputIterator coordinates) {
const Point_2& query, OutputIterator coordinates) {
// Get the number of vertices in the polygon.
const std::size_t n = m_polygon.size();
@ -366,39 +360,44 @@ namespace Barycentric_coordinates {
// Following section 4.2 from [2] we denote P_j = r_j*r_{j+1} + dot_product(d_j, d_{j+1}).
// Vector s_i from [1] corresponds to that one with the name d_i in [2].
for (std::size_t j = 0; j < n - 1; ++j)
for (std::size_t j = 0; j < n - 1; ++j) {
P[j] = (CGAL::max)(r[j] * r[j + 1] + m_scalar_product_2(s[j], s[j + 1]), FT(0));
}
P[n - 1] = (CGAL::max)(r[n - 1] * r[0] + m_scalar_product_2(s[n - 1], s[0]), FT(0));
// Compute mean value weights using the formula (16) from [2].
// Since the formula (16) always gives positive values,
// we have to add a proper sign to all the weight functions.
w[0] = r[n - 1] * r[1] - m_scalar_product_2(s[n - 1], s[1]);
for (std::size_t j = 1; j < n - 1; ++j)
for (std::size_t j = 1; j < n - 1; ++j) {
w[0] *= P[j];
}
w[0] = sign_of_weight(A[n - 1], A[0], B[0]) * m_sqrt(w[0]);
for (std::size_t i = 1; i < n - 1; ++i) {
w[i] = r[i - 1] * r[i + 1] - m_scalar_product_2(s[i - 1], s[i + 1]);
for (std::size_t j = 0; j < i - 1; ++j)
for (std::size_t j = 0; j < i - 1; ++j) {
w[i] *= P[j];
for(std::size_t j = i + 1; j < n; ++j)
}
for (std::size_t j = i + 1; j < n; ++j) {
w[i] *= P[j];
}
w[i] = sign_of_weight(A[i - 1], A[i], B[i]) * m_sqrt(w[i]);
}
w[n - 1] = r[n - 2] * r[0] - m_scalar_product_2(s[n - 2], s[0]);
for (std::size_t j = 0; j < n - 2; ++j)
for (std::size_t j = 0; j < n - 2; ++j) {
w[n - 1] *= P[j];
}
w[n - 1] = sign_of_weight(A[n - 2], A[n - 1], B[n - 1]) * m_sqrt(w[n - 1]);
// Return coordinates.
internal::normalize(w);
for (std::size_t i = 0; i < n; ++i)
for (std::size_t i = 0; i < n; ++i) {
*(coordinates++) = w[i];
}
return coordinates;
}

View File

@ -159,10 +159,7 @@ namespace Barycentric_coordinates {
one past the last weight stored
*/
template<typename OutIterator>
OutIterator weights(
const Point_2& query,
OutIterator w_begin) {
OutIterator weights(const Point_2& query, OutIterator w_begin) {
const bool normalize = false;
return compute(query, w_begin, normalize);
}
@ -192,10 +189,7 @@ namespace Barycentric_coordinates {
one past the last coordinate stored
*/
template<typename OutIterator>
OutIterator operator()(
const Point_2& query,
OutIterator c_begin) {
OutIterator operator()(const Point_2& query, OutIterator c_begin) {
const bool normalize = true;
return compute(query, c_begin, normalize);
}
@ -225,9 +219,7 @@ namespace Barycentric_coordinates {
template<typename OutputIterator>
OutputIterator compute(
const Point_2& query,
OutputIterator output,
const bool normalize) {
const Point_2& query, OutputIterator output, const bool normalize) {
switch (m_computation_policy) {
@ -244,11 +236,13 @@ namespace Barycentric_coordinates {
case Computation_policy_2::PRECISE_WITH_EDGE_CASES: {
const auto edge_case = verify(query, output);
if (edge_case == internal::Edge_case::BOUNDARY)
if (edge_case == internal::Edge_case::BOUNDARY) {
return output;
if (edge_case == internal::Edge_case::EXTERIOR)
}
if (edge_case == internal::Edge_case::EXTERIOR) {
std::cerr << std::endl <<
"WARNING: query does not belong to the polygon!" << std::endl;
}
if (normalize) {
return max_precision_coordinates(query, output);
} else {
@ -265,11 +259,13 @@ namespace Barycentric_coordinates {
case Computation_policy_2::FAST_WITH_EDGE_CASES: {
const auto edge_case = verify(query, output);
if (edge_case == internal::Edge_case::BOUNDARY)
if (edge_case == internal::Edge_case::BOUNDARY) {
return output;
if (edge_case == internal::Edge_case::EXTERIOR)
}
if (edge_case == internal::Edge_case::EXTERIOR) {
std::cerr << std::endl <<
"WARNING: query does not belong to the polygon!" << std::endl;
}
return m_wachspress_weights_2(query, output, normalize);
}
@ -283,18 +279,19 @@ namespace Barycentric_coordinates {
template<typename OutputIterator>
internal::Edge_case verify(
const Point_2& query,
OutputIterator output) const {
const Point_2& query, OutputIterator output) const {
const auto result = internal::locate_wrt_polygon_2(
m_polygon, query, m_traits, m_point_map);
if (!result)
if (!result) {
return internal::Edge_case::EXTERIOR;
}
const auto location = (*result).first;
const std::size_t index = (*result).second;
if (location == internal::Query_point_location::ON_UNBOUNDED_SIDE)
if (location == internal::Query_point_location::ON_UNBOUNDED_SIDE) {
return internal::Edge_case::EXTERIOR;
}
if (
location == internal::Query_point_location::ON_VERTEX ||
@ -308,8 +305,7 @@ namespace Barycentric_coordinates {
template<typename OutputIterator>
OutputIterator max_precision_coordinates(
const Point_2& query,
OutputIterator coordinates) {
const Point_2& query, OutputIterator coordinates) {
// Get the number of vertices in the polygon.
const std::size_t n = m_polygon.size();
@ -333,30 +329,35 @@ namespace Barycentric_coordinates {
// Then we multiply them by areas A as in the formula (5) from [1].
// We also split the loop.
w[0] = m_area_2(pn, p1, p2);
for(std::size_t j = 1; j < n - 1; ++j)
for (std::size_t j = 1; j < n - 1; ++j) {
w[0] *= A[j];
}
for(std::size_t i = 1; i < n - 1; ++i) {
for (std::size_t i = 1; i < n - 1; ++i) {
const auto& pi0 = get(m_point_map, *(m_polygon.begin() + (i - 1)));
const auto& pi1 = get(m_point_map, *(m_polygon.begin() + (i + 0)));
const auto& pi2 = get(m_point_map, *(m_polygon.begin() + (i + 1)));
w[i] = m_area_2(pi0, pi1, pi2);
for (std::size_t j = 0; j < i - 1; ++j)
for (std::size_t j = 0; j < i - 1; ++j) {
w[i] *= A[j];
for (std::size_t j = i + 1; j < n; ++j)
}
for (std::size_t j = i + 1; j < n; ++j) {
w[i] *= A[j];
}
}
const auto& pm = get(m_point_map, *(m_polygon.begin() + (n - 2)));
w[n - 1] = m_area_2(pm, pn, p1);
for (std::size_t j = 0; j < n - 2; ++j)
for (std::size_t j = 0; j < n - 2; ++j) {
w[n - 1] *= A[j];
}
// Return coordinates.
internal::normalize(w);
for (std::size_t i = 0; i < n; ++i)
for (std::size_t i = 0; i < n; ++i) {
*(coordinates++) = w[i];
}
return coordinates;
}
};

View File

@ -101,29 +101,30 @@ namespace internal {
// Get default values.
template<typename OutputIterator>
void get_default(
const std::size_t n,
OutputIterator output) {
const std::size_t n, OutputIterator output) {
for (std::size_t i = 0; i < n; ++i)
for (std::size_t i = 0; i < n; ++i) {
*(output++) = 0;
}
}
// Normalize values.
template<typename FT>
void normalize(std::vector<FT>& values) {
FT sum = FT(0);
for (const FT& value : values)
for (const FT& value : values) {
sum += value;
}
CGAL_assertion(sum != FT(0));
if (sum == FT(0))
return;
if (sum == FT(0)) return;
const FT inv_sum = FT(1) / sum;
for (FT& value : values)
for (FT& value : values) {
value *= inv_sum;
}
}
// Compute barycentric coordinates along the line.
template<
@ -241,8 +242,9 @@ namespace internal {
const auto& p1 = get(point_map, *(polygon.begin() + i));
const FT sq_r = squared_distance_2(query, p1);
if (sq_r < sq_tolerance)
if (sq_r < sq_tolerance) {
return std::make_pair(Query_point_location::ON_VERTEX, i);
}
const std::size_t ip = (i + 1) % n;
const auto& p2 = get(point_map, *(polygon.begin() + ip));
@ -253,9 +255,10 @@ namespace internal {
const FT A = half * cross_product_2(s1, s2);
const FT D = scalar_product_2(s1, s2);
if (CGAL::abs(A) < tolerance && D < FT(0))
if (CGAL::abs(A) < tolerance && D < FT(0)) {
return std::make_pair(Query_point_location::ON_EDGE, i);
}
}
return boost::none;
}
@ -281,8 +284,9 @@ namespace internal {
for (std::size_t i = 0; i < n; ++i) {
const auto& p1 = get(point_map, *(polygon.begin() + i));
if (p1 == query)
if (p1 == query) {
return std::make_pair(Query_point_location::ON_VERTEX, i);
}
const std::size_t ip = (i + 1) % n;
const auto& p2 = get(point_map, *(polygon.begin() + ip));
@ -325,8 +329,9 @@ namespace internal {
linear_coordinates_2(
source, target, query, std::back_inserter(b), traits);
*(coordinates++) = b[1];
for (std::size_t i = 1; i < n - 1; ++i)
for (std::size_t i = 1; i < n - 1; ++i) {
*(coordinates++) = FT(0);
}
*(coordinates++) = b[0];
return std::make_pair(coordinates, true);
@ -357,19 +362,21 @@ namespace internal {
CGAL_assertion(index >= 0 && index < n);
for (std::size_t i = 0; i < n; ++i)
if (i == index)
if (i == index) {
*(coordinates++) = FT(1);
else
} else {
*(coordinates++) = FT(0);
}
return std::make_pair(coordinates, true);
}
case Query_point_location::ON_EDGE: {
CGAL_assertion(index >= 0 && index < n);
if (index == n - 1)
if (index == n - 1) {
return coordinates_on_last_edge_2(
polygon, query, coordinates, traits, point_map);
}
const std::size_t indexp = (index + 1) % n;
const auto& source = get(point_map, *(polygon.begin() + index));

View File

@ -1,2 +1,3 @@
Università della Svizzera italiana (Switzerland) and
INRIA Sophia-Antipolis (France)
INRIA Sophia-Antipolis (France) and
GeometryFactory SARL (France)

View File

@ -1 +1 @@
2D Generalized Barycentric Coordinates for simple polygons.
Generalized Barycentric Coordinates for 2D polygons and 3D polyhedra.

View File

@ -1,4 +1,4 @@
This package offers an efficient and robust implementation of various two-dimensional
generalized barycentric coordinates defined for simple two-dimensional polygons.
If coordinates with respect to multivariate scattered points instead of a polygon are required,
please refer to natural neighbor coordinates from the package 2D and Surface Function Interpolation.
This package offers an efficient and robust implementation of various
Generalized Barycentric Coordinates defined for 2D polygons and 3D polyhedra.
If coordinates with respect to multivariate scattered 2D points are required,
please refer to Natural Neighbor Coordinates from the package 2D and Surface Function Interpolation.