20 #ifndef MIRTK_Triangle_H 21 #define MIRTK_Triangle_H 23 #include "mirtk/Math.h" 24 #include "mirtk/Vector3.h" 25 #include "mirtk/Matrix3x3.h" 26 #include "mirtk/VtkMath.h" 45 static void Center(
const double a[3],
const double b[3],
const double c[3],
double center[3]);
55 static double BoundingSphereRadius(
const double a[3],
const double b[3],
const double c[3],
double *center =
nullptr);
64 static void NormalDirection(
const double a[3],
const double b[3],
const double c[3],
double n[3]);
81 static void Normal(
const double a[3],
const double b[3],
const double c[3],
double n[3]);
90 static Matrix3x3
NormalJacobian(
const double a[3],
const double b[3],
const double c[3]);
100 static Matrix3x3
NormalJacobian(
const double a[3],
const double b[3],
const double c[3],
const Matrix3x3 &dn);
108 static Matrix3x3
NormalJacobian(
const double n[3],
const Matrix3x3 &dn);
125 static double DoubleArea(
const double a[3],
const double b[3],
const double c[3]);
143 static double Area(
const double a[3],
const double b[3],
const double c[3]);
161 static double SignedArea2D(
const double a[2],
const double b[2],
const double c[2]);
170 static double DoubleSignedArea2D(
const double a[2],
const double b[2],
const double c[2]);
179 static double Area2D(
const double a[2],
const double b[2],
const double c[2]);
188 static double DoubleArea2D(
const double a[2],
const double b[2],
const double c[2]);
197 static double Cotangent(
double a[3],
double b[3],
double c[3]);
205 static void Angles(
const double a[3],
const double b[3],
const double c[3],
double angle[3]);
210 static double MinAngle(
const double a[3],
const double b[3],
const double c[3]);
215 static double MaxAngle(
const double a[3],
const double b[3],
const double c[3]);
219 const double a2[3],
const double b2[3],
const double c2[3]);
223 const double a2[3],
const double b2[3],
const double c2[3],
224 int &coplanar,
double *p1,
double *p2);
228 const double a2[3],
const double b2[3],
const double c2[3],
229 double *p1,
double *p2);
233 const double a2[3],
const double b2[3],
const double c2[3],
234 double *p1,
double *p2);
237 static double DistanceBetweenTriangles(
const double a1[3],
const double b1[3],
const double c1[3],
const double n1[3],
238 const double a2[3],
const double b2[3],
const double c2[3],
const double n2[3],
239 double *p1,
double *p2);
243 const double a2[3],
const double b2[3],
const double c2[3],
244 double *p1,
double *p2);
258 inline void Triangle::Center(
const double a[3],
const double b[3],
const double c[3],
double center[3])
260 center[0] = (a[0] + b[0] + c[0]) / 3.0;
261 center[1] = (a[1] + b[1] + c[1]) / 3.0;
262 center[2] = (a[2] + b[2] + c[2]) / 3.0;
270 if (center) memcpy(center, p, 3 *
sizeof(
double));
271 return sqrt(max(max(vtkMath::Distance2BetweenPoints(a, p),
272 vtkMath::Distance2BetweenPoints(b, p)),
273 vtkMath::Distance2BetweenPoints(c, p)));
284 vtkMath::Subtract(b, a, ab);
285 vtkMath::Subtract(c, a, ac);
286 vtkMath::Cross(ab, ac, n);
290 inline void Triangle::Normal(
const double a[3],
const double b[3],
const double c[3],
double n[3])
294 if ((l = vtkMath::Norm(n)) != 0.) {
295 n[0] /= l, n[1] /= l, n[2] /= l;
308 return vtkMath::Norm(n);
312 inline double Triangle::Area(
const double a[3],
const double b[3],
const double c[3])
320 return (a[0]*b[1] - a[1]*b[0]) + (b[0]*c[1] - b[1]*c[0]) + (c[0]*a[1] - c[1]*a[0]);
346 inline void Triangle::Angles(
const double a[3],
const double b[3],
const double c[3],
double angle[3])
348 const double ab2 = vtkMath::Distance2BetweenPoints(a, b), ab = sqrt(ab2);
349 const double ac2 = vtkMath::Distance2BetweenPoints(a, c), ac = sqrt(ac2);
350 const double bc2 = vtkMath::Distance2BetweenPoints(b, c), bc = sqrt(bc2);
351 angle[0] = acos((ab2 + ac2 - bc2) / (2.0 * ab * ac));
352 angle[1] = acos((ab2 + bc2 - ac2) / (2.0 * ab * bc));
353 angle[2] = acos((ac2 + bc2 - ab2) / (2.0 * ac * bc));
361 return min(min(angle[0], angle[1]), angle[2]);
369 return max(max(angle[0], angle[1]), angle[2]);
376 double ba[3], bc[3], n[3];
377 vtkMath::Subtract(a, b, ba);
378 vtkMath::Subtract(c, b, bc);
379 vtkMath::Cross(ba, bc, n);
380 return vtkMath::Dot(ba, bc) / vtkMath::Norm(n);
404 const double m01 = c[2] - b[2];
405 const double m02 = b[1] - c[1];
406 const double m12 = c[0] - b[0];
407 return Matrix3x3(0., m01, m02, -m01, 0., m12, -m02, -m12, 0.);
414 const double l2 = n.SquaredLength();
415 if (l2 == 0.)
return Matrix3x3(0.);
417 const double l = sqrt(l2);
418 const double l3 = l2 * l;
419 const double d = 1. / l;
421 const double m00 = n[0] * n[0] / l3;
422 const double m01 = n[0] * n[1] / l3;
423 const double m02 = n[0] * n[2] / l3;
424 const double m11 = n[1] * n[1] / l3;
425 const double m12 = n[1] * n[2] / l3;
426 const double m22 = n[2] * n[2] / l3;
428 return Matrix3x3(m00 + d, m01, m02,
430 m02, m12, m22 + d) * dn;
437 const double l2 = vtkMath::Dot(n, n);
438 if (l2 == 0.)
return Matrix3x3(0.);
440 const double l = sqrt(l2);
441 const double l3 = l2 * l;
442 const double d = 1. / l;
444 const double m00 = n[0] * n[0] / l3;
445 const double m01 = n[0] * n[1] / l3;
446 const double m02 = n[0] * n[2] / l3;
447 const double m11 = n[1] * n[1] / l3;
448 const double m12 = n[1] * n[2] / l3;
449 const double m22 = n[2] * n[2] / l3;
451 return Matrix3x3(m00 + d, m01, m02,
453 m02, m12, m22 + d) * dn;
458 ::NormalJacobian(
const double a[3],
const double b[3],
const double c[3],
const Matrix3x3 &dn)
496 const double a2[3],
const double b2[3],
const double c2[3],
497 double *p1,
double *p2)
501 return sqrt(vtkMath::Distance2BetweenPoints(p1, p2));
508 const double a2[3],
const double b2[3],
const double c2[3],
509 double *p1,
double *p2)
511 double d, dmin = vtkMath::Distance2BetweenPoints(a1, a2);
512 const double *x1 = a1, *x2 = a2;
514 d = vtkMath::Distance2BetweenPoints(a1, b2);
515 if (d < dmin) dmin = d, x1 = a1, x2 = b2;
517 d = vtkMath::Distance2BetweenPoints(a1, c2);
518 if (d < dmin) dmin = d, x1 = a1, x2 = c2;
520 d = vtkMath::Distance2BetweenPoints(b1, a2);
521 if (d < dmin) dmin = d, x1 = b1, x2 = a2;
523 d = vtkMath::Distance2BetweenPoints(b1, b2);
524 if (d < dmin) dmin = d, x1 = b1, x2 = b2;
526 d = vtkMath::Distance2BetweenPoints(b1, c2);
527 if (d < dmin) dmin = d, x1 = b1, x2 = c2;
529 d = vtkMath::Distance2BetweenPoints(c1, a2);
530 if (d < dmin) dmin = d, x1 = c1, x2 = a2;
532 d = vtkMath::Distance2BetweenPoints(c1, b2);
533 if (d < dmin) dmin = d, x1 = c1, x2 = b2;
535 d = vtkMath::Distance2BetweenPoints(c1, c2);
536 if (d < dmin) dmin = d, x1 = c1, x2 = c2;
538 if (p1) memcpy(p1, x1, 3 *
sizeof(
double));
539 if (p2) memcpy(p2, x2, 3 *
sizeof(
double));
547 const double a2[3],
const double b2[3],
const double c2[3],
548 double *p1,
double *p2)
559 #endif // MIRTK_Triangle_H static double Cotangent(double a[3], double b[3], double c[3])
static double Area(const double a[3], const double b[3], const double c[3])
static double DoubleArea2D(const double a[2], const double b[2], const double c[2])
static double MinAngle(const double a[3], const double b[3], const double c[3])
static Matrix3x3 NormalDirectionJacobian(const double a[3], const double b[3], const double c[3])
static double Area2D(const double a[2], const double b[2], const double c[2])
static Matrix3x3 NormalJacobian(const double a[3], const double b[3], const double c[3])
static bool TriangleTriangleIntersection(const double a1[3], const double b1[3], const double c1[3], const double a2[3], const double b2[3], const double c2[3])
Tests whether two triangles intersect each other.
static void NormalDirection(const double a[3], const double b[3], const double c[3], double n[3])
static double DistanceBetweenCorners(const double a1[3], const double b1[3], const double c1[3], const double a2[3], const double b2[3], const double c2[3], double *p1, double *p2)
Compute distance between closest corner points of two triangles.
static double DoubleArea(const double a[3], const double b[3], const double c[3])
static double DoubleSignedArea2D(const double a[2], const double b[2], const double c[2])
static Vector3 AreaGradient(const double a[3], const double b[3], const double c[3])
static double SignedArea2D(const double a[2], const double b[2], const double c[2])
static void Angles(const double a[3], const double b[3], const double c[3], double angle[3])
static double BoundingSphereRadius(const double a[3], const double b[3], const double c[3], double *center=nullptr)
static double DistanceBetweenTriangles(const double a1[3], const double b1[3], const double c1[3], const double n1[3], const double a2[3], const double b2[3], const double c2[3], const double n2[3], double *p1, double *p2)
Compute distance between closest points of two triangles.
static double DistanceBetweenCenters(const double a1[3], const double b1[3], const double c1[3], const double a2[3], const double b2[3], const double c2[3], double *p1, double *p2)
Compute distance between triangle center points.
static double MaxAngle(const double a[3], const double b[3], const double c[3])
static void Center(const double a[3], const double b[3], const double c[3], double center[3])
static void Normal(const double a[3], const double b[3], const double c[3], double n[3])
static Vector3 DoubleAreaGradient(const double a[3], const double b[3], const double c[3])