Visual Computing Library  devel
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 "point.h"
27
28namespace vcl {
29
30template<PointConcept PointT>
32{
33 std::array<PointT, 3> mPoints;
34
35public:
36 using ScalarType = PointT::ScalarType;
37
38 using PointType = PointT;
39
40 static const uint DIM = PointT::DIM;
41
42 Triangle() = default;
43
44 Triangle(const PointT& p0, const PointT& p1, const PointT& p2) :
45 mPoints(p0, p1, p2)
46 {
47 }
48
53 constexpr uint size() const { return 3; }
54
60 const PointT& point(uint i) const { return mPoints.at(i); }
61
62 PointT& point(uint i) { return mPoints.at(i); }
63
64 PointT& point0() { return mPoints[0]; }
65
66 const PointT& point0() const { return mPoints[0]; }
67
68 PointT& point1() { return mPoints[1]; }
69
70 const PointT& point1() const { return mPoints[1]; }
71
72 PointT& point2() { return mPoints[2]; }
73
74 const PointT& point2() const { return mPoints[2]; }
75
81 ScalarType sideLength(uint i) const
82 {
83 return sideLength(mPoints[0], mPoints[1], mPoints[2], i);
84 }
85
90 ScalarType sideLength0() const { return sideLength(0); }
91
96 ScalarType sideLength1() const { return sideLength(1); }
97
102 ScalarType sideLength2() const { return sideLength(2); }
103
110 PointT normal() const requires (PointT::DIM == 3)
111 {
112 return normal(mPoints[0], mPoints[1], mPoints[2]);
113 }
114
120 PointT barycenter() const
121 {
122 return barycenter(mPoints[0], mPoints[1], mPoints[2]);
123 }
124
136 PointT weightedBarycenter(ScalarType w0, ScalarType w1, ScalarType w2) const
137 {
138 return weightedBarycenter(
139 mPoints[0], mPoints[1], mPoints[2], w0, w1, w2);
140 }
141
152 {
153 return weightedBarycenter(w(0), w(1), w(2));
154 }
155
156 PointT barycentricCoordinatePoint(
157 ScalarType b0,
158 ScalarType b1,
159 ScalarType b2) const
160 {
161 return barycentricCoordinatePoint(
162 mPoints[0], mPoints[1], mPoints[2], b0, b1, b2);
163 }
164
179 {
180 return barycentricCoordinatePoint(
181 mPoints[0], mPoints[1], mPoints[2], b(0), b(1), b(2));
182 }
183
197 PointT circumcenter() const
198 {
199 return circumcenter(mPoints[0], mPoints[1], mPoints[2]);
200 }
201
207 ScalarType perimeter() const
208 {
209 return perimeter(mPoints[0], mPoints[1], mPoints[2]);
210 }
211
217 ScalarType area() const { return area(mPoints[0], mPoints[1], mPoints[2]); }
218
232 ScalarType quality() const
233 {
234 return quality(mPoints[0], mPoints[1], mPoints[2]);
235 }
236
249 ScalarType qualityRadii() const
250 {
251 return qualityRadii(mPoints[0], mPoints[1], mPoints[2]);
252 }
253
269 ScalarType qualityMeanRatio() const
270 {
271 return qualityMeanRatio(mPoints[0], mPoints[1], mPoints[2]);
272 }
273
274 /* Static member functions */
275
286 ScalarType sideLength(
287 const PointT& p0,
288 const PointT& p1,
289 const PointT& p2,
290 uint i) const
291 {
292 switch (i % 3) {
293 case 0: return p0.dist(p1);
294 case 1: return p1.dist(p2);
295 case 2: return p2.dist(p0);
296 default: throw std::out_of_range("Invalid side index");
297 }
298 }
299
312 static PointT normal(const PointT& p0, const PointT& p1, const PointT& p2)
313 requires (PointT::DIM == 3)
314 {
315 return (p1 - p0).cross(p2 - p0);
316 }
317
328 static PointT barycenter(
329 const PointT& p0,
330 const PointT& p1,
331 const PointT& p2)
332 {
333 return (p0 + p1 + p2) / 3;
334 }
335
351 static PointT weightedBarycenter(
352 const PointT& p0,
353 const PointT& p1,
354 const PointT& p2,
355 ScalarType w0,
356 ScalarType w1,
357 ScalarType w2)
358 {
359 return (p0 * w0 + p1 * w1 + p2 * w2) / (w0 + w1 + w2);
360 }
361
384 const PointT& p0,
385 const PointT& p1,
386 const PointT& p2,
387 ScalarType b0,
388 ScalarType b1,
389 ScalarType b2)
390 {
391 return p0 * b0 + p1 * b1 + p2 * b2;
392 }
393
413 static PointT circumcenter(
414 const PointT& p0,
415 const PointT& p1,
416 const PointT& p2)
417 {
418 ScalarType a2 = p1.squaredDist(p2);
419 ScalarType b2 = p2.squaredDist(p0);
420 ScalarType c2 = p0.squaredDist(p1);
421
422 PointType c = p0 * a2 * (-a2 + b2 + c2) + p1 * b2 * (a2 - b2 + c2) +
423 p2 * c2 * (a2 + b2 - c2);
424
425 c /= 2 * (a2 * b2 + a2 * c2 + b2 * c2) - a2 * a2 - b2 * b2 - c2 * c2;
426
427 return c;
428 }
429
440 static ScalarType perimeter(
441 const PointT& p0,
442 const PointT& p1,
443 const PointT& p2)
444 {
445 return p0.dist(p1) + p1.dist(p2) + p2.dist(p0);
446 }
447
459 static ScalarType area(const PointT& p0, const PointT& p1, const PointT& p2)
460 {
461 if constexpr (DIM == 2) {
462 return ((p1[0] - p0[0]) * (p2[1] - p0[1]) -
463 (p2[0] - p0[0]) * (p1[1] - p0[1])) /
464 2;
465 }
466 if constexpr (DIM == 3) {
467 return normal(p0, p1, p2).norm() / 2;
468 }
469 else {
470 // heron's formula
471 ScalarType s = perimeter() / 2;
472 return std::sqrt(
473 s * (s - p0.dist(p1)) * (s - p1.dist(p2)) * (s - p2.dist(p0)));
474 }
475 }
476
494 static ScalarType quality(
495 const PointT& p0,
496 const PointT& p1,
497 const PointT& p2)
498 {
499 ScalarType a = area();
500 if (a == 0)
501 return 0; // Area zero triangles have surely quality==0;
502
503 PointType d10 = p1 - p0;
504 PointType d20 = p2 - p0;
505 PointType d12 = p1 - p2;
506 double b =
507 std::min({d10.squaredNorm(), d20.squaredNorm(), d12.squaredNorm()});
508 if (b == 0)
509 return 0; // Again: area zero triangles have surely quality==0;
510 return (2 * a) / b;
511 }
512
530 static ScalarType qualityRadii(
531 const PointT& p0,
532 const PointT& p1,
533 const PointT& p2)
534 {
535 double a = p0.dist(p1);
536 double b = p2.dist(p0);
537 double c = p1.dist(p2);
538
539 double sum = (a + b + c) * 0.5;
540 double area2 = sum * (a + b - sum) * (a + c - sum) * (b + c - sum);
541
542 if (area2 <= 0)
543 return 0;
544
545 return (8 * area2) / (a * b * c * sum);
546 }
547
568 static ScalarType qualityMeanRatio(
569 const PointT& p0,
570 const PointT& p1,
571 const PointT& p2)
572 {
573 double a = p0.dist(p1);
574 double b = p2.dist(p0);
575 double c = p1.dist(p2);
576
577 double sum = (a + b + c) * 0.5; // semiperimeter
578 double area2 = sum * (a + b - sum) * (a + c - sum) * (b + c - sum);
579 if (area2 <= 0)
580 return 0;
581 return (4.0 * std::sqrt(3.0) * std::sqrt(area2)) /
582 (a * a + b * b + c * c);
583 }
584};
585
586/* Specialization Aliases */
587
588template<typename Scalar>
589using Triangle2 = Triangle<Point2<Scalar>>;
590
591using Triangle2f = Triangle<Point2f>;
592using Triangle2d = Triangle<Point2d>;
593
594template<typename Scalar>
595using Triangle3 = Triangle<Point3<Scalar>>;
596
597using Triangle3f = Triangle<Point3f>;
598using Triangle3d = Triangle<Point3d>;
599
600} // namespace vcl
601
602#endif // VCL_SPACE_CORE_TRIANGLE_H
A class representing a box in N-dimensional space.
Definition box.h:46
Definition triangle.h:32
ScalarType area() const
Computes the area of the triangle.
Definition triangle.h:217
ScalarType sideLength2() const
Returns the length of the third side of the triangle.
Definition triangle.h:102
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:383
ScalarType quality() const
Calculates the quality measure of the triangle.
Definition triangle.h:232
ScalarType qualityMeanRatio() const
Compute the mean ratio of the triangle shape quality measure.
Definition triangle.h:269
ScalarType perimeter() const
Computes the perimeter of the triangle.
Definition triangle.h:207
PointT weightedBarycenter(ScalarType w0, ScalarType w1, ScalarType w2) const
Computes the weighted barycenter of the triangle.
Definition triangle.h:136
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:494
ScalarType sideLength0() const
Returns the length of the first side of the triangle.
Definition triangle.h:90
PointT barycenter() const
Computes the barycenter of the triangle.
Definition triangle.h:120
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:568
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:328
PointT normal() const
Returns the normal of the triangle.
Definition triangle.h:110
ScalarType sideLength(uint i) const
Returns the length of the i-th side of the triangle.
Definition triangle.h:81
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:459
PointT barycentricCoordinatePoint(const Point3< ScalarType > &b) const
Computes the point in the triangle with the given barycentric coordinates.
Definition triangle.h:178
PointT circumcenter() const
Compute the circumcenter of the triangle.
Definition triangle.h:197
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:351
PointT weightedBarycenter(const Point3< ScalarType > &w) const
Computes the weighted barycenter of the triangle.
Definition triangle.h:151
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:312
ScalarType sideLength1() const
Returns the length of the second side of the triangle.
Definition triangle.h:96
const PointT & point(uint i) const
Returns the i-th point of the triangle.
Definition triangle.h:60
ScalarType qualityRadii() const
Compute a shape quality measure of the triangle.
Definition triangle.h:249
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:440
static PointT circumcenter(const PointT &p0, const PointT &p1, const PointT &p2)
Compute the circumcenter of a triangle.
Definition triangle.h:413
constexpr uint size() const
Returns the number of points of the triangle.
Definition triangle.h:53
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:286
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:530