Visual Computing Library
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 "triangle.h"
27
28#include <vclib/concepts/range.h>
29#include <vclib/concepts/space/polygon.h>
30#include <vclib/space/core/point.h>
31
32#include <ranges>
33#include <vector>
34
35namespace vcl {
36
51template<PointConcept PointT>
53{
54 std::vector<PointT> mPoints;
55
56public:
58 using ScalarType = PointT::ScalarType;
59
61 using PointType = PointT;
62
64 using Iterator = typename std::vector<PointT>::iterator;
65
67 using ConstIterator = typename std::vector<PointT>::const_iterator;
68
70 static const uint DIM = PointT::DIM;
71
76
82 Polygon(std::initializer_list<PointT> points) : mPoints(points) {}
83
92 template<typename Iterator>
94 requires (std::is_same_v<typename Iterator::value_type, PointT>)
95 : mPoints(begin, end)
96 {
97 }
98
105 template<Range R>
107 : mPoints(std::ranges::begin(range), std::ranges::end(range))
108 {
109 }
110
116 uint size() const { return mPoints.size(); }
117
123 void resize(uint n) { mPoints.resize(n); }
124
130 void reserve(uint n) { mPoints.reserve(n); }
131
135 void clear() { mPoints.clear(); }
136
142 void pushBack(const PointT& point) { mPoints.push_back(point); }
143
149 void pushBack(PointT&& point) { mPoints.push_back(std::move(point)); }
150
156 PointT& point(uint i) { return mPoints.at(i); }
157
163 const PointT& point(uint i) const { return mPoints.at(i); }
164
175 {
176 return mPoints.at(i).dist(mPoints[(i + 1) % mPoints.size()]);
177 }
178
190 PointT normal() const requires (PointT::DIM == 3)
191 {
192 return normal(mPoints);
193 }
194
203 PointT barycenter() const { return barycenter(mPoints); }
204
217 template<typename WIterator>
219 {
220 return weightedBarycenter(mPoints.begin(), mPoints.end(), wBegin);
221 }
222
228 ScalarType perimeter() const { return perimeter(mPoints); }
229
235 ScalarType area() const { return area(mPoints); }
236
243 PointType& operator[](uint i) { return mPoints[i]; }
244
251 const PointType& operator[](uint i) const { return mPoints[i]; }
252
256 Iterator begin() { return mPoints.begin(); }
257
261 Iterator end() { return mPoints.end(); }
262
267 ConstIterator begin() const { return mPoints.begin(); }
268
273 ConstIterator end() const { return mPoints.end(); }
274
275 // static member functions
276
291 template<typename Iterator>
292 static PointT normal(Iterator begin, Iterator end) requires (
293 std::is_same_v<typename Iterator::value_type, PointT> &&
294 PointT::DIM == 3)
295 {
296 // compute the sum of normals for each triplet of consecutive points
297 PointT sum;
298 sum.setZero();
299 for (auto i = begin; i != end; ++i) {
300 auto i1 = i;
301 ++i1;
302 if (i1 == end)
303 i1 = begin;
304
305 auto i2 = i1;
306 ++i2;
307 if (i2 == end)
308 i2 = begin;
309
310 sum += (*i1 - *i).cross(*i2 - *i);
311 }
312 sum.normalize();
313 return sum;
314 }
315
323 template<Range R>
324 static PointT normal(R&& range)
325 {
326 return normal(std::ranges::begin(range), std::ranges::end(range));
327 }
328
341 template<typename Iterator>
343 requires (std::is_same_v<typename Iterator::value_type, PointT>)
344 {
345 PointT bar;
346 bar.setZero();
347
348 uint cnt = 0;
349 for (; begin != end; ++begin) {
350 bar += *begin;
351 ++cnt;
352 }
353
354 assert(cnt);
355
356 return bar / cnt;
357 }
358
366 template<Range R>
367 static PointT barycenter(R&& range)
368 {
369 return barycenter(std::ranges::begin(range), std::ranges::end(range));
370 }
371
389 template<typename Iterator, typename WIterator>
390 static PointT weightedBarycenter(
394 requires (std::is_same_v<typename Iterator::value_type, PointT>)
395 {
396 using ScalarType = WIterator::value_type;
397
398 PointT bar;
399 bar.setZero();
400 ScalarType wSum = 0;
401
402 for (; begin != end; ++begin, ++wBegin) {
403 bar += *begin * *wBegin;
404 wSum += *wBegin;
405 }
406
407 return bar / wSum;
408 }
409
419 template<Range Rp, Range Rw>
421 {
422 return weightedBarycenter(
423 std::ranges::begin(rPolygon),
424 std::ranges::end(rPolygon),
425 std::ranges::begin(rWeights));
426 }
427
447 template<typename Iterator>
449 requires (std::is_same_v<typename Iterator::value_type, PointT>)
450 {
451 using Scalar = PointType::ScalarType;
452
453 Scalar per = 0;
454 for (auto i = begin; i != end; ++i) {
455 const PointT& p0 = *i;
456 auto i1 = i;
457 ++i;
458 if (i1 == end)
459 i1 = begin;
460 const PointT& p1 = *i1;
461 per += p0.dist(p1);
462 }
463 return per;
464 }
465
473 template<Range R>
475 {
476 return perimeter(std::ranges::begin(range), std::ranges::end(range));
477 }
478
495 template<typename Iterator>
497 requires (std::is_same_v<typename Iterator::value_type, PointT>)
498 {
499 using Scalar = PointType::ScalarType;
500
502 Scalar area = 0;
503 for (auto i = begin; i != end; ++i) {
504 const PointT& p0 = *i;
505 auto i1 = i;
506 ++i1;
507 if (i1 == end)
508 i1 = begin;
509 const PointT& p1 = *i1;
510
511 area += Triangle<PointT>::area(p0, p1, bar);
512 }
513 return area;
514 }
515
523 template<Range R>
525 {
526 return area(std::ranges::begin(range), std::ranges::end(range));
527 }
528};
529
530/* Specialization Aliases */
531
540template<typename Scalar>
542
550
558
567template<typename Scalar>
569
577
585
586} // namespace vcl
587
588#endif // VCL_SPACE_CORE_POLYGON_H
The Polygon class represents a polygon in a N-dimensional Euclidean space.
Definition polygon.h:53
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:342
uint size() const
Returns the number of points that define the polygon.
Definition polygon.h:116
PointT weightedBarycenter(WIterator wBegin) const
Computes the weighted barycenter of the polygon.
Definition polygon.h:218
static ScalarType perimeter(R &&range)
Calculates the perimeter of a polygon defined by a range of points.
Definition polygon.h:474
Polygon(Iterator begin, Iterator end)
Construct a new Polygon object from a range of points.
Definition polygon.h:93
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:390
PointT normal() const
Computes the normal of the polygon.
Definition polygon.h:190
Iterator begin()
Returns an iterator pointing to the first point of the polygon.
Definition polygon.h:256
const PointType & operator[](uint i) const
Returns the i-th point of the polygon.
Definition polygon.h:251
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:292
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:420
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:496
static PointT barycenter(R &&range)
Computes the barycenter of a container of points iterated between the iterators begin and end,...
Definition polygon.h:367
PointT::ScalarType ScalarType
The scalar type of the points that define the polygon.
Definition polygon.h:58
PointType & operator[](uint i)
Returns the i-th point of the polygon.
Definition polygon.h:243
void resize(uint n)
Resizes the polygon to contain n points.
Definition polygon.h:123
ScalarType sideLength(uint i) const
Returns the side length of the i-th side of the polygon.
Definition polygon.h:174
typename std::vector< PointT >::const_iterator ConstIterator
The const iterator type of the polygon.
Definition polygon.h:67
PointT barycenter() const
Computes the barycenter of the polygon.
Definition polygon.h:203
PointT PointType
The type of the points that define the polygon.
Definition polygon.h:61
ScalarType area() const
Returns the area of the polygon.
Definition polygon.h:235
PointT & point(uint i)
Returns the point at index i in the polygon.
Definition polygon.h:156
ConstIterator begin() const
Returns a const iterator pointing to the first point of the polygon.
Definition polygon.h:267
void clear()
Clears the polygon, removing all points.
Definition polygon.h:135
const PointT & point(uint i) const
Returns the point at index i in the polygon.
Definition polygon.h:163
ScalarType perimeter() const
Returns the perimeter of the polygon.
Definition polygon.h:228
void reserve(uint n)
Reserves space for n points in the polygon.
Definition polygon.h:130
Polygon(std::initializer_list< PointT > points)
Construct a new Polygon object from an initializer list of points.
Definition polygon.h:82
ConstIterator end() const
Returns a const iterator pointing past the last point of the polygon.
Definition polygon.h:273
static ScalarType perimeter(Iterator begin, Iterator end)
Calculates the perimeter of a polygon defined by a range of points.
Definition polygon.h:448
void pushBack(const PointT &point)
Adds a point to the back of the polygon.
Definition polygon.h:142
typename std::vector< PointT >::iterator Iterator
The iterator type of the polygon.
Definition polygon.h:64
Iterator end()
Returns an iterator pointing past the last point of the polygon.
Definition polygon.h:261
Polygon()
Construct a new empty Polygon object.
Definition polygon.h:75
void pushBack(PointT &&point)
Adds a point to the back of the polygon.
Definition polygon.h:149
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:524
static const uint DIM
The dimension of the points that define the polygon.
Definition polygon.h:70
static PointT normal(R &&range)
Computes the normal of a container of 3D points iterated between the iterators begin and end,...
Definition polygon.h:324
Polygon(R &&range)
Construct a new Polygon object from a range of points.
Definition polygon.h:106
A class representing a line segment in n-dimensional space. The class is parameterized by a PointConc...
Definition segment.h:43
ScalarType area() const
Computes the area of the triangle.
Definition triangle.h:219
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