Thea
Triangle3.hpp
1 //============================================================================
2 //
3 // This file is part of the Thea toolkit.
4 //
5 // This software is distributed under the BSD license, as detailed in the
6 // accompanying LICENSE.txt file. Portions are derived from other works:
7 // their respective licenses and copyright information are reproduced in
8 // LICENSE.txt and/or in the relevant source files.
9 //
10 // Author: Siddhartha Chaudhuri
11 // First version: 2009
12 //
13 //============== License for line-triangle distance calculation ==============
14 //
15 // David Eberly, Geometric Tools, Redmond WA 98052
16 // Copyright (c) 1998-2017
17 // Distributed under the Boost Software License, Version 1.0.
18 // http://www.boost.org/LICENSE_1_0.txt
19 // http://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
20 // File Version: 3.0.0 (2016/06/19)
21 //
22 //============================================================================
23 
24 #ifndef __Thea_Triangle3_hpp__
25 #define __Thea_Triangle3_hpp__
26 
27 #include "Common.hpp"
28 #include "AxisAlignedBox3.hpp"
29 #include "Ball3.hpp"
30 #include "Box3.hpp"
31 #include "LineSegment3.hpp"
32 #include "Math.hpp"
33 #include "Plane3.hpp"
34 #include "RayIntersectable3.hpp"
35 #include <limits>
36 
37 namespace Thea {
38 
45 {
46  public:
49 
51  TriangleLocalVertexTriple3(Vector3 const & v0, Vector3 const & v1, Vector3 const & v2)
52  {
53  vertices[0] = v0;
54  vertices[1] = v1;
55  vertices[2] = v2;
56  }
57 
59  Vector3 const & getVertex(int i) const { return vertices[i]; }
60 
61  private:
62  Vector3 vertices[3];
63 
64 }; // TriangleLocalVertexTriple3
65 
66 // Internal functions
67 namespace Triangle3Internal {
68 
69 /* Triangle/triangle intersection test routine,
70  * by Tomas Moller, 1997.
71  * See article "A Fast Triangle-Triangle Intersection Test",
72  * Journal of Graphics Tools, 2(2), 1997
73  * updated: 2001-06-20 (added line of intersection)
74  *
75  * int tri_tri_intersect(Real const V0[3],Real const V1[3],Real const V2[3],
76  * Real const U0[3],Real const U1[3],Real const U2[3])
77  *
78  * parameters: vertices of triangle 1: V0,V1,V2
79  * vertices of triangle 2: U0,U1,U2
80  * result : returns 1 if the triangles intersect, otherwise 0
81  *
82  * Here is a version withouts divisions (a little faster)
83  * int NoDivTriTriIsect(Real const V0[3],Real const V1[3],Real const V2[3],
84  * Real const U0[3],Real const U1[3],Real const U2[3]);
85  *
86  * This version computes the line of intersection as well (if they are not coplanar):
87  * int tri_tri_intersect_with_isectline(Real const V0[3],Real const V1[3],Real const V2[3],
88  * Real const U0[3],Real const U1[3],Real const U2[3],int *coplanar,
89  * Real isectpt1[3],Real isectpt2[3]);
90  * coplanar returns whether the tris are coplanar
91  * isectpt1, isectpt2 are the endpoints of the line of intersection
92  */
93 
94 THEA_API int tri_tri_intersect(Real const V0[3],Real const V1[3],Real const V2[3],
95  Real const U0[3],Real const U1[3],Real const U2[3]);
96 
97 THEA_API int NoDivTriTriIsect(Real const V0[3],Real const V1[3],Real const V2[3],
98  Real const U0[3],Real const U1[3],Real const U2[3]);
99 
100 THEA_API int tri_tri_intersect_with_isectline(Real const V0[3],Real const V1[3],Real const V2[3],
101  Real const U0[3],Real const U1[3],Real const U2[3],int *coplanar,
102  Real isectpt1[3],Real isectpt2[3]);
103 
104 // Check if a point is inside a triangle.
105 THEA_API bool isPointInsideTriangle(Vector3 const & v0,
106  Vector3 const & v1,
107  Vector3 const & v2,
108  int primary_axis,
109  Vector3 const & p);
110 
111 // Closest point on the perimeter of a triangle.
112 THEA_API Vector3 closestPointOnTrianglePerimeter(Vector3 const & v0,
113  Vector3 const & v1,
114  Vector3 const & v2,
115  Vector3 const & point);
116 
117 // Intersection time of a ray with a triangle. Returns a negative value if the ray does not intersect the triangle.
118 THEA_API Real rayTriangleIntersectionTime(Ray3 const & ray, Vector3 const & v0, Vector3 const & edge01, Vector3 const & edge02);
119 
120 } // namespace Triangle3Internal
121 
134 template <typename VertexTripleT = TriangleLocalVertexTriple3>
135 class /* THEA_DLL_LOCAL */ Triangle3Base : public RayIntersectable3
136 {
137  public:
138  typedef VertexTripleT VertexTriple;
139 
140  protected:
143 
145  explicit Triangle3Base(VertexTriple const & vertices_) : vertices(vertices_) { update(); }
146 
149  : vertices(src.vertices), plane(src.plane), primary_axis(src.primary_axis), centroid(src.centroid), edge01(src.edge01),
150  edge02(src.edge02), area(src.area)
151  {}
152 
153  public:
155  void set(VertexTriple const & vertices_) { vertices = vertices_; update(); }
156 
161  void update() const
162  {
163  Vector3 v0 = getVertex(0), v1 = getVertex(1), v2 = getVertex(2);
164 
165  plane = Plane3::fromThreePoints(v0, v1, v2);
166  primary_axis = (int)Math::maxAbsAxis(plane.getNormal());
167 
168  centroid = (v0 + v1 + v2) / 3;
169  edge01 = v1 - v0;
170  edge02 = v2 - v0;
171 
172  area = 0.5f * std::fabs(plane.getNormal().dot(edge01.cross(edge02))); // exploit precomputed normal to avoid sqrt
173  }
174 
176  Vector3 getVertex(int i) const { return vertices.getVertex(i); }
177 
179  VertexTriple const & getVertices() const { return vertices; }
180 
182  Plane3 const & getPlane() const { return plane; }
183 
185  intx getPrimaryAxis() const { return primary_axis; }
186 
188  Vector3 const & getNormal() const { return plane.getNormal(); }
189 
191  Vector3 const & getCentroid() const { return centroid; }
192 
194  Vector3 const & getEdge01() const { return edge01; }
195 
197  Vector3 const & getEdge02() const { return edge02; }
198 
200  Real getArea() const { return area; }
201 
203  Vector3 randomPoint() const
204  {
205  // From G3D::Triangle
206 
207  // Choose a random point in the parallelogram
208  float s = Random::common().uniform01();
209  float t = Random::common().uniform01();
210 
211  if (s + t > 1.0f)
212  {
213  // Outside the triangle; reflect about the diagonal of the parallelogram
214  t = 1.0f - t;
215  s = 1.0f - s;
216  }
217 
218  return s * edge01 + t * edge02 + getVertex(0);
219  }
220 
222  Vector3 barycentricCoordinates(Vector3 const & p) const
223  {
224  if (area <= 0)
225  return Vector3::Zero();
226 
227  Vector3 const & n = getNormal();
228  Vector3 p0 = getVertex(0) - p;
229  Vector3 p1 = getVertex(1) - p;
230  Vector3 p2 = getVertex(2) - p;
231 
232  Real b0 = n.dot(p1.cross(p2)) / (2 * area);
233  Real b1 = n.dot(p2.cross(p0)) / (2 * area);
234 
235  return Vector3(b0, b1, 1 - b0 - b1);
236  }
237 
240  {
241  Vector3 v0 = getVertex(0), v1 = getVertex(1), v2 = getVertex(2);
242  return AxisAlignedBox3(v0.cwiseMin(v1.cwiseMin(v2)), v0.cwiseMax(v1.cwiseMax(v2)));
243  }
244 
246  bool intersects(Vector3 const & p) const { return contains(p); }
247 
249  template <typename OtherVertexTripleT> bool intersects(Triangle3Base<OtherVertexTripleT> const & other) const
250  {
251  Vector3 p0 = getVertex(0); Vector3 p1 = getVertex(1); Vector3 p2 = getVertex(2);
252  Vector3 q0 = other.getVertex(0); Vector3 q1 = other.getVertex(1); Vector3 q2 = other.getVertex(2);
253 
254  Real v0[3] = { p0.x(), p0.y(), p0.z() };
255  Real v1[3] = { p1.x(), p1.y(), p1.z() };
256  Real v2[3] = { p2.x(), p2.y(), p2.z() };
257 
258  Real u0[3] = { q0.x(), q0.y(), q0.z() };
259  Real u1[3] = { q1.x(), q1.y(), q1.z() };
260  Real u2[3] = { q2.x(), q2.y(), q2.z() };
261 
262  return Triangle3Internal::NoDivTriTriIsect(v0, v1, v2, u0, u1, u2);
263  }
264 
269  template <typename OtherVertexTripleT>
270  bool intersects(Triangle3Base<OtherVertexTripleT> const & other, bool & coplanar, LineSegment3 & seg) const
271  {
272  Vector3 p0 = getVertex(0); Vector3 p1 = getVertex(1); Vector3 p2 = getVertex(2);
273  Vector3 q0 = other.getVertex(0); Vector3 q1 = other.getVertex(1); Vector3 q2 = other.getVertex(2);
274 
275  int i_coplanar;
276  Vector3 isectpt1, isectpt2;
277  int isec = Triangle3Internal::tri_tri_intersect_with_isectline(&p0[0], &p1[0], &p2[0], &q0[0], &q1[0], &q2[0],
278  &i_coplanar, &isectpt1[0], &isectpt2[0]);
279  if (isec)
280  {
281  coplanar = (bool)i_coplanar;
282  if (!coplanar)
283  seg = LineSegment3(isectpt1, isectpt2);
284 
285  return true;
286  }
287 
288  return false;
289  }
290 
292  bool intersects(Ball3 const & ball) const { throw Error("Triangle3: Intersection with ball not implemented"); }
293 
295  bool intersects(AxisAlignedBox3 const & aab) const { throw Error("Triangle3: Intersection with AAB not implemented"); }
296 
298  bool intersects(Box3 const & box) const { throw Error("Triangle3: Intersection with oriented box not implemented"); }
299 
301  bool contains(Vector3 const & p) const
302  {
303  return Triangle3Internal::isPointInsideTriangle(getVertex(0), getVertex(1), getVertex(2), primary_axis, p);
304  }
305 
307  Real distance(Vector3 const & p) const { return std::sqrt(squaredDistance(p)); }
308 
310  Real squaredDistance(Vector3 const & p) const
311  {
312  return (closestPoint(p) - p).squaredNorm();
313  }
314 
316  Vector3 closestPoint(Vector3 const & p) const
317  {
318  // Project the point onto the plane of the triangle
319  Vector3 proj = plane.closestPoint(p);
320 
321  if (contains(proj))
322  return proj;
323  else // the closest point is on the perimeter instead
324  return Triangle3Internal::closestPointOnTrianglePerimeter(getVertex(0), getVertex(1), getVertex(2), p);
325  }
326 
328  template <typename OtherVertexTripleT>
329  Real distance(Triangle3Base<OtherVertexTripleT> const & other) const { return std::sqrt(squaredDistance(other)); }
330 
334  template <typename OtherVertexTripleT>
335  Real squaredDistance(Triangle3Base<OtherVertexTripleT> const & other, Vector3 * this_pt = nullptr,
336  Vector3 * other_pt = nullptr) const
337  {
338  // From Christer Ericson, "Real-Time Collision Detection", Morgan-Kaufman, 2005.
339 
340  Vector3 c1(0, 0, 0), c2(0, 0, 0); // squash an uninitialized variable warning
341  Real min_sqdist = std::numeric_limits<Real>::max();
342 
343  // First test for intersection
344  bool coplanar;
345  LineSegment3 seg;
346  if (intersects(other, coplanar, seg))
347  {
348  if (coplanar)
349  c1 = c2 = (Real)0.5 * (getCentroid() + other.getCentroid()); // FIXME: This needn't be in the intersection
350  else
351  c1 = c2 = (Real)0.5 * (seg.getPoint(0) + seg.getPoint(1));
352 
353  min_sqdist = 0;
354  }
355  else
356  {
357  // Edge-edge distances
358  Vector3 p, q;
359  Real d2, s, t;
360  for (int i = 0; i < 3; ++i)
361  {
362  int i2 = (i + 1) % 3;
363 
364  for (int j = 0; j < 3; ++j)
365  {
366  int j2 = (j + 1) % 3;
367  d2 = Internal::closestPtSegmentSegment<3, Real>(getVertex(i), getVertex(i2), false,
368  other.getVertex(j), other.getVertex(j2), false,
369  s, t, p, q);
370  if (d2 < min_sqdist)
371  {
372  min_sqdist = d2;
373  c1 = p;
374  c2 = q;
375  }
376  }
377  }
378 
379  // Distance from vertex of triangle 2 to triangle 1, if the former projects inside the latter
380  for (int i = 0; i < 3; ++i)
381  {
382  q = other.getVertex(i);
383  p = getPlane().closestPoint(q);
384  if (contains(p))
385  {
386  d2 = (p - q).squaredNorm();
387  if (d2 < min_sqdist)
388  {
389  min_sqdist = d2;
390  c1 = p;
391  c2 = q;
392  }
393  }
394  }
395 
396  // Distance from vertex of triangle 1 to triangle 2, if the former projects inside the latter
397  for (int i = 0; i < 3; ++i)
398  {
399  p = getVertex(i);
400  q = other.getPlane().closestPoint(p);
401  if (other.contains(q))
402  {
403  d2 = (p - q).squaredNorm();
404  if (d2 < min_sqdist)
405  {
406  min_sqdist = d2;
407  c1 = p;
408  c2 = q;
409  }
410  }
411  }
412  }
413 
414  if (this_pt) *this_pt = c1;
415  if (other_pt) *other_pt = c2;
416 
417  return min_sqdist;
418  }
419 
421  Real distance(Ball3 const & ball) const
422  {
423  return std::max(distance(ball.getCenter()) - ball.getRadius(), static_cast<Real>(0));
424  }
425 
427  Real squaredDistance(Ball3 const & ball, Vector3 * this_pt = nullptr, Vector3 * ball_pt = nullptr) const
428  {
429  if (!this_pt && !ball_pt)
430  {
431  Real x = distance(ball);
432  return x * x;
433  }
434 
435  Vector3 c1 = closestPoint(ball.getCenter());
436  Vector3 c2;
437 
438  Vector3 diff = c1 - ball.getCenter();
439  Real d2 = diff.squaredNorm();
440  Real r2 = ball.getRadius() * ball.getRadius();
441  if (d2 < r2) // point inside ball
442  {
443  c2 = c1;
444  d2 = 0;
445  }
446  else
447  {
448  if (r2 < 1e-30)
449  c2 = ball.getCenter();
450  else
451  {
452  c2 = ball.getCenter() + std::sqrt(r2 / d2) * diff;
453  d2 = (c1 - c2).squaredNorm();
454  }
455  }
456 
457  if (this_pt) *this_pt = c1;
458  if (ball_pt) *ball_pt = c2;
459 
460  return d2;
461  }
462 
464  Real distance(Line3 const & line) const
465  {
466  return std::sqrt(squaredDistance(line));
467  }
468 
472  Real squaredDistance(Line3 const & line, Vector3 * this_pt = nullptr, Vector3 * line_pt = nullptr) const
473  {
474  // Two tests where one would suffice, but for now it avoids having to code a new function or modify an existing one.
475  // Shift the ray origins to ensure the rays overlap and there are no errors at line.getPoint().
476 
477  // Forward half
478  {
479  Ray3 ray(line.getPoint() - line.getDirection(), line.getDirection());
480  Real t = rayIntersectionTime(ray);
481  if (t >= 0)
482  {
483  Vector3 c = ray.getPoint(t);
484  if (this_pt) *this_pt = c;
485  if (line_pt) *line_pt = c;
486  return 0;
487  }
488  }
489 
490  // Backward half
491  {
492  Ray3 ray(line.getPoint() + line.getDirection(), -line.getDirection());
493  Real t = rayIntersectionTime(ray);
494  if (t >= 0)
495  {
496  Vector3 c = ray.getPoint(t);
497  if (this_pt) *this_pt = c;
498  if (line_pt) *line_pt = c;
499  return 0;
500  }
501  }
502 
503  return squaredDistanceToPerimeter(line, this_pt, line_pt);
504  }
505 
507  Real distance(LineSegment3 const & seg) const
508  {
509  return std::sqrt(squaredDistance(seg));
510  }
511 
515  Real squaredDistance(LineSegment3 const & seg, Vector3 * this_pt = nullptr, Vector3 * seg_pt = nullptr) const
516  {
517  // From https://www.geometrictools.com/GTEngine/Include/Mathematics/GteDistLine3Triangle3.h
518 
519  Ray3 ray(seg.getEndpoint(0), seg.getDirection());
520  Real t = rayIntersectionTime(ray);
521  if (t >= 0 && t <= 1)
522  {
523  Vector3 c = ray.getPoint(t);
524  if (this_pt) *this_pt = c;
525  if (seg_pt) *seg_pt = c;
526  return 0;
527  }
528 
529  return squaredDistanceToPerimeter(seg, this_pt, seg_pt);
530  }
531 
533  Real distance(Ray3 const & ray) const
534  {
535  return std::sqrt(squaredDistance(ray));
536  }
537 
541  Real squaredDistance(Ray3 const & ray, Vector3 * this_pt = nullptr, Vector3 * ray_pt = nullptr) const
542  {
543  // From https://www.geometrictools.com/GTEngine/Include/Mathematics/GteDistLine3Triangle3.h
544 
545  Real t = rayIntersectionTime(ray);
546  if (t >= 0)
547  {
548  Vector3 c = ray.getPoint(t);
549  if (this_pt) *this_pt = c;
550  if (ray_pt) *ray_pt = c;
551  return 0;
552  }
553 
554  return squaredDistanceToPerimeter(ray, this_pt, ray_pt);
555  }
556 
557  Real rayIntersectionTime(Ray3 const & ray, Real max_time = -1) const
558  {
559  Real t = Triangle3Internal::rayTriangleIntersectionTime(ray, getVertex(0), getEdge01(), getEdge02());
560  return (max_time >= 0 && t > max_time) ? -1 : t;
561  }
562 
563  RayIntersection3 rayIntersection(Ray3 const & ray, Real max_time = -1) const
564  {
565  Real t = Triangle3Internal::rayTriangleIntersectionTime(ray, getVertex(0), getEdge01(), getEdge02());
566  if (t >= 0 && (max_time < 0 || t <= max_time))
567  {
568  Vector3 n = getNormal();
569  return RayIntersection3(t, &n);
570  }
571 
572  return RayIntersection3(-1);
573  }
574 
575  protected:
580  template <typename LineLikeT>
581  Real squaredDistanceToPerimeter(LineLikeT const & line, Vector3 * this_pt = nullptr, Vector3 * line_pt = nullptr) const
582  {
583  // From https://www.geometrictools.com/GTEngine/Include/Mathematics/GteDistLine3Triangle3.h
584 
585  Real d2 = -1;
586  Vector3 c1, c2;
587  for (int i = 0; i < 3; ++i)
588  {
589  LineSegment3 edge(getVertex(i), getVertex((i + 1) % 3));
590  Real edge_d2 = edge.squaredDistance(line, (this_pt ? &c1 : nullptr), (line_pt ? &c2 : nullptr));
591  if (d2 < 0 || edge_d2 < d2)
592  {
593  d2 = edge_d2;
594  if (this_pt) *this_pt = c1;
595  if (line_pt) *line_pt = c2;
596  }
597  }
598 
599  return d2;
600  }
601 
602  VertexTriple vertices;
603 
604  // Cached properties computed from the vertices
605  mutable Plane3 plane;
606  mutable int primary_axis;
607  mutable Vector3 centroid;
608  mutable Vector3 edge01;
609  mutable Vector3 edge02;
610  mutable Real area;
611 
612 }; // class Triangle3Base
613 
614 // Forward declaration
615 template <typename VertexTripleT = TriangleLocalVertexTriple3> class Triangle3;
616 
623 template <>
624 class THEA_API Triangle3<TriangleLocalVertexTriple3> : public Triangle3Base<TriangleLocalVertexTriple3>
625 {
626  private:
628 
629  public:
630  THEA_DECL_SMART_POINTERS(Triangle3)
631 
632 
634 
636  explicit Triangle3(TriangleLocalVertexTriple3 const & vertices_) : BaseT(vertices_) {}
637 
639  Triangle3(Vector3 const & v0, Vector3 const & v1, Vector3 const & v2) : BaseT(TriangleLocalVertexTriple3(v0, v1, v2)) {}
640 
642  Triangle3(Triangle3 const & src) : BaseT(src) {}
643 
645  Triangle3 transform(Matrix4 const & m) const
646  {
647  return Triangle3(Math::hmul(m, BaseT::getVertex(0)),
648  Math::hmul(m, BaseT::getVertex(1)),
649  Math::hmul(m, BaseT::getVertex(2)));
650  }
651 
653  void set(Vector3 const & v0, Vector3 const & v1, Vector3 const & v2)
654  {
655  BaseT::set(TriangleLocalVertexTriple3(v0, v1, v2));
656  update();
657  }
658 
660  Triangle3 localClone() const { return *this; }
661 
662 }; // class Triangle3<TriangleLocalVertexTriple3>
663 
666 
677 template <typename VertexTripleT>
678 class /* THEA_API */ Triangle3 : public Triangle3Base<VertexTripleT>
679 {
680  private:
681  typedef Triangle3Base<VertexTripleT> BaseT;
682 
683  public:
684  THEA_DECL_SMART_POINTERS(Triangle3)
685 
686 
688 
690  explicit Triangle3(VertexTripleT const & vertices_) : BaseT(vertices_) {}
691 
693  Triangle3(Triangle3 const & src) : BaseT(src) {}
694 
696  LocalTriangle3 transform(Matrix4 const & m) const
697  {
698  return LocalTriangle3(m * BaseT::getVertex(0), m * BaseT::getVertex(1), m * BaseT::getVertex(2));
699  }
700 
703  {
704  return LocalTriangle3(BaseT::getVertex(0), BaseT::getVertex(1), BaseT::getVertex(2));
705  }
706 
707 }; // class Triangle3
708 
709 } // namespace Thea
710 
711 #endif
Real distance(LineSegment3 const &seg) const
Get the distance of this triangle from a line segment.
Definition: Triangle3.hpp:507
Triangle3 localClone() const
Get a copy of this triangle (for consistency with the default template).
Definition: Triangle3.hpp:660
A ball in N-space.
Definition: BallN.hpp:33
Vector3 centroid
Centroid of the triangle (mean of three vertices).
Definition: Triangle3.hpp:607
Triangle3Base(VertexTriple const &vertices_)
Construct from a set of vertices.
Definition: Triangle3.hpp:145
bool intersects(Vector3 const &p) const
Check if the triangle intersects (that is, contains) a point.
Definition: Triangle3.hpp:246
VectorT const & getPoint() const
Get a point on the line.
Definition: LineN.hpp:73
std::ptrdiff_t intx
A signed integer suitable for indexing a structure held in memory.
Definition: Platform.hpp:161
T squaredDistance(VectorT const &p) const
Get the square of the distance of the line from a given point.
Triangle3(VertexTripleT const &vertices_)
Construct from a set of vertices.
Definition: Triangle3.hpp:690
A ray in N-dimensional space, having an originating point and a direction vector (not necessarily uni...
Definition: RayN.hpp:27
Vector3 const & getCentroid() const
Get the centroid of the triangle.
Definition: Triangle3.hpp:191
Plane3 const & getPlane() const
Get the plane of the triangle.
Definition: Triangle3.hpp:182
Root namespace for the Thea library.
void update() const
Update the properties of the triangle, assuming the positions of its three corners have changed...
Definition: Triangle3.hpp:161
Vector3 const & getNormal() const
Get the normal of the triangle (right-hand rule, going round vertices in order 0, 1...
Definition: Triangle3.hpp:188
Plane3 plane
Plane of the triangle.
Definition: Triangle3.hpp:605
VectorT const & getDirection() const
Get the unnormalized direction vector of the segment from the first endpoint to the second...
T getRadius() const
Get the radius of the ball.
Definition: BallN.hpp:59
bool intersects(Triangle3Base< OtherVertexTripleT > const &other, bool &coplanar, LineSegment3 &seg) const
Check if the triangle intersects another triangle.
Definition: Triangle3.hpp:270
Triangle3(Vector3 const &v0, Vector3 const &v1, Vector3 const &v2)
Construct from a set of vertices.
Definition: Triangle3.hpp:639
Vector3 barycentricCoordinates(Vector3 const &p) const
Get the barycentric coordinates of a point assumed to be in the plane of the triangle.
Definition: Triangle3.hpp:222
Eigen::Matrix< T, N-1, 1, O2, R2, C2 > hmul(Eigen::Matrix< T, N, N, O1, R1, C1 > const &m, Eigen::Matrix< T, N-1, 1, O2, R2, C2 > const &v)
Convenience function to multiply a 4x4 matrix by a 3-vector, by converting to homogeneous coordinates...
Definition: MatrixUtil.hpp:122
Eigen::Index maxAbsAxis(Eigen::MatrixBase< Derived > const &v)
Get the coordinate of a vector with the largest absolute value.
Definition: MatrixUtil.hpp:109
Real squaredDistance(Triangle3Base< OtherVertexTripleT > const &other, Vector3 *this_pt=nullptr, Vector3 *other_pt=nullptr) const
Get the squared distance between this triangle and another triangle, and optionally return the closes...
Definition: Triangle3.hpp:335
Real squaredDistance(LineSegment3 const &seg, Vector3 *this_pt=nullptr, Vector3 *seg_pt=nullptr) const
Get the squared distance between this triangle and a line segment, and optionally return the closest ...
Definition: Triangle3.hpp:515
Vector3 getVertex(int i) const
Get a vertex of the triangle.
Definition: Triangle3.hpp:176
Real distance(Ball3 const &ball) const
Get the distance of this triangle from a ball.
Definition: Triangle3.hpp:421
Real getArea() const
Get the area of the triangle.
Definition: Triangle3.hpp:200
Real distance(Vector3 const &p) const
Get the distance of the triangle from a point.
Definition: Triangle3.hpp:307
bool intersects(Box3 const &box) const
Check if the triangle intersects an oriented box.
Definition: Triangle3.hpp:298
Triangle3(Triangle3 const &src)
Copy constructor.
Definition: Triangle3.hpp:693
Vector3 edge02
vertices[2] - vertices[0]
Definition: Triangle3.hpp:609
VertexTripleT VertexTriple
Stores and provides access to the triangle&#39;s vertices.
Definition: Triangle3.hpp:138
VectorT getPoint(Real t) const
Get a point on the line segment: t = 0 maps to the first endpoint and t = 1 maps to the second...
TriangleLocalVertexTriple3()
Default constructor.
Definition: Triangle3.hpp:48
Base class for a triangle in 3-space, with precomputed properties for fast access.
Definition: Triangle3.hpp:135
Real squaredDistanceToPerimeter(LineLikeT const &line, Vector3 *this_pt=nullptr, Vector3 *line_pt=nullptr) const
Get the squared distance between the perimiter of this triangle and a line-like object (Line3...
Definition: Triangle3.hpp:581
LineSegmentN< 3, Real > LineSegment3
The default line segment class in 3-dimensional real space.
A triangle in 3-space, with precomputed properties for fast access.
Definition: Triangle3.hpp:615
Vector3 const & getEdge02() const
Get the edge vector corresponding to getVertex(2) - getVertex(0).
Definition: Triangle3.hpp:197
Stores the positions of a triangle&#39;s three vertices locally, and provides access to them...
Definition: Triangle3.hpp:44
Triangle3Base()
Default constructor.
Definition: Triangle3.hpp:142
Vector3 const & getVertex(int i) const
Get the i&#39;th vertex.
Definition: Triangle3.hpp:59
AxisAlignedBoxN< 3, Real > AxisAlignedBox3
The default axis-aligned box class in 3-dimensional real space.
int primary_axis
Primary axis (closest to normal).
Definition: Triangle3.hpp:606
AxisAlignedBox3 getBounds() const
Get a bounding box for the triangle.
Definition: Triangle3.hpp:239
Triangle3(TriangleLocalVertexTriple3 const &vertices_)
Construct from a set of vertices.
Definition: Triangle3.hpp:636
A straight line in N-dimensional space, where N is any positive (non-zero) integer and T is a field...
Definition: LineN.hpp:25
Triangle3Base(Triangle3Base const &src)
Copy constructor.
Definition: Triangle3.hpp:148
Real squaredDistance(Ray3 const &ray, Vector3 *this_pt=nullptr, Vector3 *ray_pt=nullptr) const
Get the squared distance between this triangle and a ray, and optionally return the closest pair of p...
Definition: Triangle3.hpp:541
Vector3 edge01
vertices[1] - vertices[0]
Definition: Triangle3.hpp:608
VectorT const & getDirection() const
Get the unit direction vector of the line.
Definition: LineN.hpp:76
static Random & common()
A shared, threadsafe random number generator.
Definition: Random.hpp:222
Vector3 randomPoint() const
Get a uniformly distributed random sample from the triangle.
Definition: Triangle3.hpp:203
VectorT getPoint(T const &t) const
Get a parametrized point on the ray.
Definition: RayN.hpp:87
Vector3 const & getEdge01() const
Get the edge vector corresponding to getVertex(1) - getVertex(0).
Definition: Triangle3.hpp:194
Real squaredDistance(Vector3 const &p) const
Get the squared distance of the triangle from a point.
Definition: Triangle3.hpp:310
VertexTriple const & getVertices() const
Get the vertices of the triangle.
Definition: Triangle3.hpp:179
Triangle3(Triangle3 const &src)
Copy constructor.
Definition: Triangle3.hpp:642
Real squaredDistance(Ball3 const &ball, Vector3 *this_pt=nullptr, Vector3 *ball_pt=nullptr) const
Get the squared distance between this triangle and a ball, and optionally return the closest pair of ...
Definition: Triangle3.hpp:427
std::runtime_error Error
An error class.
Definition: Error.hpp:27
Abstract base class for an object that supports ray intersection queries in N-space.
virtual Real uniform01()
Uniform random real number in the range [0, 1].
Definition: Random.hpp:126
Real squaredDistance(Line3 const &line, Vector3 *this_pt=nullptr, Vector3 *line_pt=nullptr) const
Get the squared distance between this triangle and an infinite line, and optionally return the closes...
Definition: Triangle3.hpp:472
bool intersects(Ball3 const &ball) const
Check if the triangle intersects a ball.
Definition: Triangle3.hpp:292
TriangleLocalVertexTriple3(Vector3 const &v0, Vector3 const &v1, Vector3 const &v2)
Initializing constructor.
Definition: Triangle3.hpp:51
A triangle with three vertex positions stored locally, in the class itself.
Definition: Triangle3.hpp:624
Real distance(Line3 const &line) const
Get the distance of this triangle from an infinite line.
Definition: Triangle3.hpp:464
VectorT const & getCenter() const
Get the center of the ball.
Definition: BallN.hpp:53
A description of the intersection point of a ray with an object.
Vector3 closestPoint(Vector3 const &p) const
Get the point on this triangle closest to a given point.
Definition: Triangle3.hpp:316
bool intersects(AxisAlignedBox3 const &aab) const
Check if the triangle intersects an axis-aligned box.
Definition: Triangle3.hpp:295
Real area
Triangle area.
Definition: Triangle3.hpp:610
LocalTriangle3 transform(Matrix4 const &m) const
Transform the triangle by a 4x4 matrix and return the result.
Definition: Triangle3.hpp:696
bool intersects(Triangle3Base< OtherVertexTripleT > const &other) const
Check if the triangle intersects another triangle.
Definition: Triangle3.hpp:249
bool contains(Vector3 const &p) const
Check if the triangle contains a point.
Definition: Triangle3.hpp:301
Triangle3< TriangleLocalVertexTriple3 > LocalTriangle3
A triangle with three vertex positions stored locally, in the class itself.
Definition: Triangle3.hpp:665
VertexTriple vertices
The vertices of the triangle.
Definition: Triangle3.hpp:602
VectorT getEndpoint(int i) const
Get an endpoint of the line segment: 0 returns the first endpoint and 1 returns the second...
LocalTriangle3 localClone() const
Get a new triangle that simply stores copies of the vertex positions of this triangle.
Definition: Triangle3.hpp:702
Triangle3 transform(Matrix4 const &m) const
Transform the triangle by a 4x4 matrix and return the result.
Definition: Triangle3.hpp:645
intx getPrimaryAxis() const
Get the primary axis of the triangle (closest to normal).
Definition: Triangle3.hpp:185
Real distance(Ray3 const &ray) const
Get the distance of this triangle from a ray.
Definition: Triangle3.hpp:533
Real distance(Triangle3Base< OtherVertexTripleT > const &other) const
Get the distance of the triangle from another triangle.
Definition: Triangle3.hpp:329