Visual Computing Library  devel
Loading...
Searching...
No Matches
polygon.h
1/*****************************************************************************
2 * VCLib *
3 * Visual Computing Library *
4 * *
5 * Copyright(C) 2021-2025 *
6 * Visual Computing Lab *
7 * ISTI - Italian National Research Council *
8 * *
9 * All rights reserved. *
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the Mozilla Public License Version 2.0 as published *
13 * by the Mozilla Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * Mozilla Public License Version 2.0 *
20 * (https://www.mozilla.org/en-US/MPL/2.0/) for more details. *
21 ****************************************************************************/
22
23#ifndef VCL_SPACE_CORE_POLYGON_H
24#define VCL_SPACE_CORE_POLYGON_H
25
26#include "point.h"
27#include "triangle.h"
28
29#include <ranges>
30#include <vector>
31
32namespace vcl {
33
48template<PointConcept PointT>
50{
51 std::vector<PointT> mPoints;
52
53public:
55 using ScalarType = PointT::ScalarType;
56
58 using PointType = PointT;
59
61 using Iterator = typename std::vector<PointT>::iterator;
62
64 using ConstIterator = typename std::vector<PointT>::const_iterator;
65
67 static const uint DIM = PointT::DIM;
68
73
79 Polygon(std::initializer_list<PointT> points) : mPoints(points) {}
80
89 template<typename Iterator>
91 requires (std::is_same_v<typename Iterator::value_type, PointT>)
92 : mPoints(begin, end)
93 {
94 }
95
102 template<Range R>
104 : mPoints(std::ranges::begin(range), std::ranges::end(range))
105 {
106 }
107
113 uint size() const { return mPoints.size(); }
114
120 void resize(uint n) { mPoints.resize(n); }
121
127 void reserve(uint n) { mPoints.reserve(n); }
128
132 void clear() { mPoints.clear(); }
133
139 void pushBack(const PointT& point) { mPoints.push_back(point); }
140
146 void pushBack(PointT&& point) { mPoints.push_back(std::move(point)); }
147
153 PointT& point(uint i) { return mPoints.at(i); }
154
160 const PointT& point(uint i) const { return mPoints.at(i); }
161
172 {
173 return mPoints.at(i).dist(mPoints[(i + 1) % mPoints.size()]);
174 }
175
187 PointT normal() const requires (PointT::DIM == 3)
188 {
189 return normal(mPoints);
190 }
191
200 PointT barycenter() const { return barycenter(mPoints); }
201
214 template<typename WIterator>
216 {
217 return weightedBarycenter(mPoints.begin(), mPoints.end(), wBegin);
218 }
219
225 ScalarType perimeter() const { return perimeter(mPoints); }
226
232 ScalarType area() const { return area(mPoints); }
233
240 PointType& operator[](uint i) { return mPoints[i]; }
241
248 const PointType& operator[](uint i) const { return mPoints[i]; }
249
253 Iterator begin() { return mPoints.begin(); }
254
258 Iterator end() { return mPoints.end(); }
259
264 ConstIterator begin() const { return mPoints.begin(); }
265
270 ConstIterator end() const { return mPoints.end(); }
271
272 // static member functions
273
288 template<typename Iterator>
289 static PointT normal(Iterator begin, Iterator end) requires (
290 std::is_same_v<typename Iterator::value_type, PointT> &&
291 PointT::DIM == 3)
292 {
293 // compute the sum of normals for each triplet of consecutive points
294 PointT sum;
295 sum.setZero();
296 for (auto i = begin; i != end; ++i) {
297 auto i1 = i;
298 ++i1;
299 if (i1 == end)
300 i1 = begin;
301
302 auto i2 = i1;
303 ++i2;
304 if (i2 == end)
305 i2 = begin;
306
307 sum += (*i1 - *i).cross(*i2 - *i);
308 }
309 sum.normalize();
310 return sum;
311 }
312
320 template<Range R>
321 static PointT normal(R&& range)
322 {
323 return normal(std::ranges::begin(range), std::ranges::end(range));
324 }
325
338 template<typename Iterator>
340 requires (std::is_same_v<typename Iterator::value_type, PointT>)
341 {
342 PointT bar;
343 bar.setZero();
344
345 uint cnt = 0;
346 for (; begin != end; ++begin) {
347 bar += *begin;
348 ++cnt;
349 }
350
351 assert(cnt);
352
353 return bar / cnt;
354 }
355
363 template<Range R>
364 static PointT barycenter(R&& range)
365 {
366 return barycenter(std::ranges::begin(range), std::ranges::end(range));
367 }
368
386 template<typename Iterator, typename WIterator>
387 static PointT weightedBarycenter(
391 requires (std::is_same_v<typename Iterator::value_type, PointT>)
392 {
393 using ScalarType = WIterator::value_type;
394
395 PointT bar;
396 bar.setZero();
397 ScalarType wSum = 0;
398
399 for (; begin != end; ++begin, ++wBegin) {
400 bar += *begin * *wBegin;
401 wSum += *wBegin;
402 }
403
404 return bar / wSum;
405 }
406
416 template<Range Rp, Range Rw>
418 {
419 return weightedBarycenter(
420 std::ranges::begin(rPolygon),
421 std::ranges::end(rPolygon),
422 std::ranges::begin(rWeights));
423 }
424
444 template<typename Iterator>
446 requires (std::is_same_v<typename Iterator::value_type, PointT>)
447 {
448 using Scalar = PointType::ScalarType;
449
450 Scalar per = 0;
451 for (auto i = begin; i != end; ++i) {
452 const PointT& p0 = *i;
453 auto i1 = i;
454 ++i;
455 if (i1 == end)
456 i1 = begin;
457 const PointT& p1 = *i1;
458 per += p0.dist(p1);
459 }
460 return per;
461 }
462
470 template<Range R>
472 {
473 return perimeter(std::ranges::begin(range), std::ranges::end(range));
474 }
475
492 template<typename Iterator>
494 requires (std::is_same_v<typename Iterator::value_type, PointT>)
495 {
496 using Scalar = PointType::ScalarType;
497
499 Scalar area = 0;
500 for (auto i = begin; i != end; ++i) {
501 const PointT& p0 = *i;
502 auto i1 = i;
503 ++i1;
504 if (i1 == end)
505 i1 = begin;
506 const PointT& p1 = *i1;
507
508 area += Triangle<PointT>::area(p0, p1, bar);
509 }
510 return area;
511 }
512
520 template<Range R>
522 {
523 return area(std::ranges::begin(range), std::ranges::end(range));
524 }
525};
526
527/* Specialization Aliases */
528
537template<typename Scalar>
539
547
555
564template<typename Scalar>
566
574
582
583/* Concepts */
584
595template<typename T>
596concept PolygonConcept = std::derived_from< // same type or derived type
597 std::remove_cvref_t<T>,
598 Polygon<typename RemoveRef<T>::PointType>>;
599
610template<typename T>
611concept Polygon2Concept = PolygonConcept<T> && RemoveRef<T>::DIM == 2;
612
623template<typename T>
624concept Polygon3Concept = PolygonConcept<T> && RemoveRef<T>::DIM == 3;
625
626} // namespace vcl
627
628#endif // VCL_SPACE_CORE_POLYGON_H
A class representing a box in N-dimensional space.
Definition box.h:46
The Polygon class represents a polygon in a N-dimensional Euclidean space.
Definition polygon.h:50
static PointT barycenter(Iterator begin, Iterator end)
Computes the barycenter of a container of points iterated between the iterators begin and end,...
Definition polygon.h:339
uint size() const
Returns the number of points that define the polygon.
Definition polygon.h:113
PointT weightedBarycenter(WIterator wBegin) const
Computes the weighted barycenter of the polygon.
Definition polygon.h:215
static ScalarType perimeter(R &&range)
Calculates the perimeter of a polygon defined by a range of points.
Definition polygon.h:471
Polygon(Iterator begin, Iterator end)
Construct a new Polygon object from a range of points.
Definition polygon.h:90
static PointT weightedBarycenter(Iterator begin, Iterator end, WIterator wBegin)
Computes the weighted barycenter of a container of 3D points iterated between the iterators begin and...
Definition polygon.h:387
PointT normal() const
Computes the normal of the polygon.
Definition polygon.h:187
Iterator begin()
Returns an iterator pointing to the first point of the polygon.
Definition polygon.h:253
const PointType & operator[](uint i) const
Returns the i-th point of the polygon.
Definition polygon.h:248
static PointT normal(Iterator begin, Iterator end)
Computes the normal of a container of 3D points iterated between the iterators begin and end,...
Definition polygon.h:289
static PointT weightedBarycenter(Rp &&rPolygon, Rw &&rWeights)
Computes the weighted barycenter of a container of 3D points iterated between the iterators begin and...
Definition polygon.h:417
static ScalarType area(Iterator begin, Iterator end)
Calculates the area of a polygon. This function works also with simple triangles, but it is less effi...
Definition polygon.h:493
static PointT barycenter(R &&range)
Computes the barycenter of a container of points iterated between the iterators begin and end,...
Definition polygon.h:364
PointT::ScalarType ScalarType
The scalar type of the points that define the polygon.
Definition polygon.h:55
PointType & operator[](uint i)
Returns the i-th point of the polygon.
Definition polygon.h:240
void resize(uint n)
Resizes the polygon to contain n points.
Definition polygon.h:120
ScalarType sideLength(uint i) const
Returns the side length of the i-th side of the polygon.
Definition polygon.h:171
typename std::vector< PointT >::const_iterator ConstIterator
The const iterator type of the polygon.
Definition polygon.h:64
PointT barycenter() const
Computes the barycenter of the polygon.
Definition polygon.h:200
PointT PointType
The type of the points that define the polygon.
Definition polygon.h:58
ScalarType area() const
Returns the area of the polygon.
Definition polygon.h:232
PointT & point(uint i)
Returns the point at index i in the polygon.
Definition polygon.h:153
ConstIterator begin() const
Returns a const iterator pointing to the first point of the polygon.
Definition polygon.h:264
void clear()
Clears the polygon, removing all points.
Definition polygon.h:132
const PointT & point(uint i) const
Returns the point at index i in the polygon.
Definition polygon.h:160
ScalarType perimeter() const
Returns the perimeter of the polygon.
Definition polygon.h:225
void reserve(uint n)
Reserves space for n points in the polygon.
Definition polygon.h:127
Polygon(std::initializer_list< PointT > points)
Construct a new Polygon object from an initializer list of points.
Definition polygon.h:79
ConstIterator end() const
Returns a const iterator pointing past the last point of the polygon.
Definition polygon.h:270
static ScalarType perimeter(Iterator begin, Iterator end)
Calculates the perimeter of a polygon defined by a range of points.
Definition polygon.h:445
void pushBack(const PointT &point)
Adds a point to the back of the polygon.
Definition polygon.h:139
typename std::vector< PointT >::iterator Iterator
The iterator type of the polygon.
Definition polygon.h:61
Iterator end()
Returns an iterator pointing past the last point of the polygon.
Definition polygon.h:258
Polygon()
Construct a new empty Polygon object.
Definition polygon.h:72
void pushBack(PointT &&point)
Adds a point to the back of the polygon.
Definition polygon.h:146
static ScalarType area(R &&range)
Calculates the area of a polygon. This function works also with simple triangles, but it is less effi...
Definition polygon.h:521
static const uint DIM
The dimension of the points that define the polygon.
Definition polygon.h:67
static PointT normal(R &&range)
Computes the normal of a container of 3D points iterated between the iterators begin and end,...
Definition polygon.h:321
Polygon(R &&range)
Construct a new Polygon object from a range of points.
Definition polygon.h:103
ScalarType area() const
Computes the area of the triangle.
Definition triangle.h:217
Utility concept that is evaluated true the Range R is an Input Range and has a value_type that is con...
Definition range.h:89
A concept representing a 2D Polygon.
Definition polygon.h:611
A concept representing a 3D Polygon.
Definition polygon.h:624
A concept representing a Polygon.
Definition polygon.h:596