Visual Computing Library
Loading...
Searching...
No Matches
triangle.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_TRIANGLE_H
24#define VCL_SPACE_CORE_TRIANGLE_H
25
26#include <vclib/concepts/range.h>
27#include <vclib/concepts/space/triangle.h>
28#include <vclib/space/core/point.h>
29
30namespace vcl {
31
32template<PointConcept PointT>
34{
35 std::array<PointT, 3> mPoints;
36
37public:
38 using ScalarType = PointT::ScalarType;
39
40 using PointType = PointT;
41
42 static const uint DIM = PointT::DIM;
43
44 Triangle() = default;
45
46 Triangle(const PointT& p0, const PointT& p1, const PointT& p2) :
47 mPoints(p0, p1, p2)
48 {
49 }
50
55 constexpr uint size() const { return 3; }
56
62 const PointT& point(uint i) const { return mPoints.at(i); }
63
64 PointT& point(uint i) { return mPoints.at(i); }
65
66 PointT& point0() { return mPoints[0]; }
67
68 const PointT& point0() const { return mPoints[0]; }
69
70 PointT& point1() { return mPoints[1]; }
71
72 const PointT& point1() const { return mPoints[1]; }
73
74 PointT& point2() { return mPoints[2]; }
75
76 const PointT& point2() const { return mPoints[2]; }
77
83 ScalarType sideLength(uint i) const
84 {
85 return sideLength(mPoints[0], mPoints[1], mPoints[2], i);
86 }
87
92 ScalarType sideLength0() const { return sideLength(0); }
93
98 ScalarType sideLength1() const { return sideLength(1); }
99
104 ScalarType sideLength2() const { return sideLength(2); }
105
112 PointT normal() const requires (PointT::DIM == 3)
113 {
114 return normal(mPoints[0], mPoints[1], mPoints[2]);
115 }
116
122 PointT barycenter() const
123 {
124 return barycenter(mPoints[0], mPoints[1], mPoints[2]);
125 }
126
138 PointT weightedBarycenter(ScalarType w0, ScalarType w1, ScalarType w2) const
139 {
140 return weightedBarycenter(
141 mPoints[0], mPoints[1], mPoints[2], w0, w1, w2);
142 }
143
154 {
155 return weightedBarycenter(w(0), w(1), w(2));
156 }
157
158 PointT barycentricCoordinatePoint(
159 ScalarType b0,
160 ScalarType b1,
161 ScalarType b2) const
162 {
163 return barycentricCoordinatePoint(
164 mPoints[0], mPoints[1], mPoints[2], b0, b1, b2);
165 }
166
181 {
182 return barycentricCoordinatePoint(
183 mPoints[0], mPoints[1], mPoints[2], b(0), b(1), b(2));
184 }
185
199 PointT circumcenter() const
200 {
201 return circumcenter(mPoints[0], mPoints[1], mPoints[2]);
202 }
203
209 ScalarType perimeter() const
210 {
211 return perimeter(mPoints[0], mPoints[1], mPoints[2]);
212 }
213
219 ScalarType area() const { return area(mPoints[0], mPoints[1], mPoints[2]); }
220
234 ScalarType quality() const
235 {
236 return quality(mPoints[0], mPoints[1], mPoints[2]);
237 }
238
251 ScalarType qualityRadii() const
252 {
253 return qualityRadii(mPoints[0], mPoints[1], mPoints[2]);
254 }
255
271 ScalarType qualityMeanRatio() const
272 {
273 return qualityMeanRatio(mPoints[0], mPoints[1], mPoints[2]);
274 }
275
276 /* Static member functions */
277
288 ScalarType sideLength(
289 const PointT& p0,
290 const PointT& p1,
291 const PointT& p2,
292 uint i) const
293 {
294 switch (i % 3) {
295 case 0: return p0.dist(p1);
296 case 1: return p1.dist(p2);
297 case 2: return p2.dist(p0);
298 default: throw std::out_of_range("Invalid side index");
299 }
300 }
301
314 static PointT normal(const PointT& p0, const PointT& p1, const PointT& p2)
315 requires (PointT::DIM == 3)
316 {
317 return (p1 - p0).cross(p2 - p0);
318 }
319
330 static PointT barycenter(
331 const PointT& p0,
332 const PointT& p1,
333 const PointT& p2)
334 {
335 return (p0 + p1 + p2) / 3;
336 }
337
353 static PointT weightedBarycenter(
354 const PointT& p0,
355 const PointT& p1,
356 const PointT& p2,
357 ScalarType w0,
358 ScalarType w1,
359 ScalarType w2)
360 {
361 return (p0 * w0 + p1 * w1 + p2 * w2) / (w0 + w1 + w2);
362 }
363
386 const PointT& p0,
387 const PointT& p1,
388 const PointT& p2,
389 ScalarType b0,
390 ScalarType b1,
391 ScalarType b2)
392 {
393 return p0 * b0 + p1 * b1 + p2 * b2;
394 }
395
415 static PointT circumcenter(
416 const PointT& p0,
417 const PointT& p1,
418 const PointT& p2)
419 {
420 ScalarType a2 = p1.squaredDist(p2);
421 ScalarType b2 = p2.squaredDist(p0);
422 ScalarType c2 = p0.squaredDist(p1);
423
424 PointType c = p0 * a2 * (-a2 + b2 + c2) + p1 * b2 * (a2 - b2 + c2) +
425 p2 * c2 * (a2 + b2 - c2);
426
427 c /= 2 * (a2 * b2 + a2 * c2 + b2 * c2) - a2 * a2 - b2 * b2 - c2 * c2;
428
429 return c;
430 }
431
442 static ScalarType perimeter(
443 const PointT& p0,
444 const PointT& p1,
445 const PointT& p2)
446 {
447 return p0.dist(p1) + p1.dist(p2) + p2.dist(p0);
448 }
449
461 static ScalarType area(const PointT& p0, const PointT& p1, const PointT& p2)
462 {
463 if constexpr (DIM == 2) {
464 return ((p1[0] - p0[0]) * (p2[1] - p0[1]) -
465 (p2[0] - p0[0]) * (p1[1] - p0[1])) /
466 2;
467 }
468 if constexpr (DIM == 3) {
469 return normal(p0, p1, p2).norm() / 2;
470 }
471 else {
472 // heron's formula
473 ScalarType s = perimeter() / 2;
474 return std::sqrt(
475 s * (s - p0.dist(p1)) * (s - p1.dist(p2)) * (s - p2.dist(p0)));
476 }
477 }
478
496 static ScalarType quality(
497 const PointT& p0,
498 const PointT& p1,
499 const PointT& p2)
500 {
501 ScalarType a = area();
502 if (a == 0)
503 return 0; // Area zero triangles have surely quality==0;
504
505 PointType d10 = p1 - p0;
506 PointType d20 = p2 - p0;
507 PointType d12 = p1 - p2;
508 double b =
509 std::min({d10.squaredNorm(), d20.squaredNorm(), d12.squaredNorm()});
510 if (b == 0)
511 return 0; // Again: area zero triangles have surely quality==0;
512 return (2 * a) / b;
513 }
514
532 static ScalarType qualityRadii(
533 const PointT& p0,
534 const PointT& p1,
535 const PointT& p2)
536 {
537 double a = p0.dist(p1);
538 double b = p2.dist(p0);
539 double c = p1.dist(p2);
540
541 double sum = (a + b + c) * 0.5;
542 double area2 = sum * (a + b - sum) * (a + c - sum) * (b + c - sum);
543
544 if (area2 <= 0)
545 return 0;
546
547 return (8 * area2) / (a * b * c * sum);
548 }
549
570 static ScalarType qualityMeanRatio(
571 const PointT& p0,
572 const PointT& p1,
573 const PointT& p2)
574 {
575 double a = p0.dist(p1);
576 double b = p2.dist(p0);
577 double c = p1.dist(p2);
578
579 double sum = (a + b + c) * 0.5; // semiperimeter
580 double area2 = sum * (a + b - sum) * (a + c - sum) * (b + c - sum);
581 if (area2 <= 0)
582 return 0;
583 return (4.0 * std::sqrt(3.0) * std::sqrt(area2)) /
584 (a * a + b * b + c * c);
585 }
586};
587
588/* Specialization Aliases */
589
590template<typename Scalar>
591using Triangle2 = Triangle<Point2<Scalar>>;
592
593using Triangle2f = Triangle<Point2f>;
594using Triangle2d = Triangle<Point2d>;
595
596template<typename Scalar>
597using Triangle3 = Triangle<Point3<Scalar>>;
598
599using Triangle3f = Triangle<Point3f>;
600using Triangle3d = Triangle<Point3d>;
601
602} // namespace vcl
603
604#endif // VCL_SPACE_CORE_TRIANGLE_H
A class representing a line segment in n-dimensional space. The class is parameterized by a PointConc...
Definition segment.h:43
Definition triangle.h:34
ScalarType area() const
Computes the area of the triangle.
Definition triangle.h:219
ScalarType sideLength2() const
Returns the length of the third side of the triangle.
Definition triangle.h:104
static PointT barycentricCoordinatePoint(const PointT &p0, const PointT &p1, const PointT &p2, ScalarType b0, ScalarType b1, ScalarType b2)
Computes the point in a triangle with the given barycentric coordinates.
Definition triangle.h:385
ScalarType quality() const
Calculates the quality measure of the triangle.
Definition triangle.h:234
ScalarType qualityMeanRatio() const
Compute the mean ratio of the triangle shape quality measure.
Definition triangle.h:271
ScalarType perimeter() const
Computes the perimeter of the triangle.
Definition triangle.h:209
PointT weightedBarycenter(ScalarType w0, ScalarType w1, ScalarType w2) const
Computes the weighted barycenter of the triangle.
Definition triangle.h:138
static ScalarType quality(const PointT &p0, const PointT &p1, const PointT &p2)
Calculates the quality measure of a triangle, given its three vertices.
Definition triangle.h:496
ScalarType sideLength0() const
Returns the length of the first side of the triangle.
Definition triangle.h:92
PointT barycenter() const
Computes the barycenter of the triangle.
Definition triangle.h:122
static ScalarType qualityMeanRatio(const PointT &p0, const PointT &p1, const PointT &p2)
Compute the mean ratio of a triangle shape quality measure.
Definition triangle.h:570
static PointT barycenter(const PointT &p0, const PointT &p1, const PointT &p2)
Computes the barycenter of the triangle composed by the points p0, p1, and p2.
Definition triangle.h:330
PointT normal() const
Returns the normal of the triangle.
Definition triangle.h:112
ScalarType sideLength(uint i) const
Returns the length of the i-th side of the triangle.
Definition triangle.h:83
static ScalarType area(const PointT &p0, const PointT &p1, const PointT &p2)
Computes the area of the triangle composed by the points p0, p1, and p2, considering that these three...
Definition triangle.h:461
PointT barycentricCoordinatePoint(const Point3< ScalarType > &b) const
Computes the point in the triangle with the given barycentric coordinates.
Definition triangle.h:180
PointT circumcenter() const
Compute the circumcenter of the triangle.
Definition triangle.h:199
static PointT weightedBarycenter(const PointT &p0, const PointT &p1, const PointT &p2, ScalarType w0, ScalarType w1, ScalarType w2)
Computes the weighted barycenter of a triangle composed of three points.
Definition triangle.h:353
PointT weightedBarycenter(const Point3< ScalarType > &w) const
Computes the weighted barycenter of the triangle.
Definition triangle.h:153
static PointT normal(const PointT &p0, const PointT &p1, const PointT &p2)
Computes the normal of the triangle composed by the 3D points p0, p1, and p2, considering that these ...
Definition triangle.h:314
ScalarType sideLength1() const
Returns the length of the second side of the triangle.
Definition triangle.h:98
const PointT & point(uint i) const
Returns the i-th point of the triangle.
Definition triangle.h:62
ScalarType qualityRadii() const
Compute a shape quality measure of the triangle.
Definition triangle.h:251
static ScalarType perimeter(const PointT &p0, const PointT &p1, const PointT &p2)
Computes the perimeter of the triangle composed by the points p0, p1, and p2.
Definition triangle.h:442
static PointT circumcenter(const PointT &p0, const PointT &p1, const PointT &p2)
Compute the circumcenter of a triangle.
Definition triangle.h:415
constexpr uint size() const
Returns the number of points of the triangle.
Definition triangle.h:55
ScalarType sideLength(const PointT &p0, const PointT &p1, const PointT &p2, uint i) const
Returns the length of the i-th side of the triangle composed by the points p0, p1,...
Definition triangle.h:288
static ScalarType qualityRadii(const PointT &p0, const PointT &p1, const PointT &p2)
Compute a shape quality measure of the triangle composed by points p0, p1, p2.
Definition triangle.h:532