GteIntrLine3Triangle3.h
Go to the documentation of this file.
1 // David Eberly, Geometric Tools, Redmond WA 98052
2 // Copyright (c) 1998-2017
3 // Distributed under the Boost Software License, Version 1.0.
4 // http://www.boost.org/LICENSE_1_0.txt
5 // http://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
6 // File Version: 3.0.0 (2016/06/19)
7 
8 #pragma once
9 
10 #include <Mathematics/GteVector3.h>
11 #include <Mathematics/GteLine.h>
13 #include <Mathematics/GteFIQuery.h>
14 #include <Mathematics/GteTIQuery.h>
15 
16 namespace gte
17 {
18 
19 template <typename Real>
20 class TIQuery<Real,Line3<Real>,Triangle3<Real>>
21 {
22 public:
23  struct Result
24  {
25  bool intersect;
26  };
27 
28  Result operator()(Line3<Real> const& line,
29  Triangle3<Real> const& triangle);
30 };
31 
32 template <typename Real>
33 class FIQuery<Real, Line3<Real>, Triangle3<Real>>
34 {
35 public:
36  struct Result
37  {
38  Result();
39 
40  bool intersect;
41  Real parameter;
42  Real triangleBary[3];
44  };
45 
46  Result operator()(Line3<Real> const& line,
47  Triangle3<Real> const& triangle);
48 };
49 
50 
51 template <typename Real>
54  Line3<Real> const& line, Triangle3<Real> const& triangle)
55 {
56  Result result;
57 
58  // Compute the offset origin, edges, and normal.
59  Vector3<Real> diff = line.origin - triangle.v[0];
60  Vector3<Real> edge1 = triangle.v[1] - triangle.v[0];
61  Vector3<Real> edge2 = triangle.v[2] - triangle.v[0];
62  Vector3<Real> normal = Cross(edge1, edge2);
63 
64  // Solve Q + t*D = b1*E1 + b2*E2 (Q = diff, D = line direction,
65  // E1 = edge1, E2 = edge2, N = Cross(E1,E2)) by
66  // |Dot(D,N)|*b1 = sign(Dot(D,N))*Dot(D,Cross(Q,E2))
67  // |Dot(D,N)|*b2 = sign(Dot(D,N))*Dot(D,Cross(E1,Q))
68  // |Dot(D,N)|*t = -sign(Dot(D,N))*Dot(Q,N)
69  Real DdN = Dot(line.direction, normal);
70  Real sign;
71  if (DdN > (Real)0)
72  {
73  sign = (Real)1;
74  }
75  else if (DdN < (Real)0)
76  {
77  sign = (Real)-1;
78  DdN = -DdN;
79  }
80  else
81  {
82  // Line and triangle are parallel, call it a "no intersection"
83  // even if the line and triangle are coplanar and intersecting.
84  result.intersect = false;
85  return result;
86  }
87 
88  Real DdQxE2 = sign*DotCross(line.direction, diff, edge2);
89  if (DdQxE2 >= (Real)0)
90  {
91  Real DdE1xQ = sign*DotCross(line.direction, edge1, diff);
92  if (DdE1xQ >= (Real)0)
93  {
94  if (DdQxE2 + DdE1xQ <= DdN)
95  {
96  // Line intersects triangle.
97  result.intersect = true;
98  return result;
99  }
100  // else: b1+b2 > 1, no intersection
101  }
102  // else: b2 < 0, no intersection
103  }
104  // else: b1 < 0, no intersection
105 
106  result.intersect = false;
107  return result;
108 }
109 
110 template <typename Real>
112  :
113  parameter((Real)0)
114 {
115  triangleBary[0] = (Real)0;
116  triangleBary[1] = (Real)0;
117  triangleBary[2] = (Real)0;
118 }
119 
120 template <typename Real>
123  Line3<Real> const& line, Triangle3<Real> const& triangle)
124 {
125  Result result;
126 
127  // Compute the offset origin, edges, and normal.
128  Vector3<Real> diff = line.origin - triangle.v[0];
129  Vector3<Real> edge1 = triangle.v[1] - triangle.v[0];
130  Vector3<Real> edge2 = triangle.v[2] - triangle.v[0];
131  Vector3<Real> normal = Cross(edge1, edge2);
132 
133  // Solve Q + t*D = b1*E1 + b2*E2 (Q = diff, D = line direction,
134  // E1 = edge1, E2 = edge2, N = Cross(E1,E2)) by
135  // |Dot(D,N)|*b1 = sign(Dot(D,N))*Dot(D,Cross(Q,E2))
136  // |Dot(D,N)|*b2 = sign(Dot(D,N))*Dot(D,Cross(E1,Q))
137  // |Dot(D,N)|*t = -sign(Dot(D,N))*Dot(Q,N)
138  Real DdN = Dot(line.direction, normal);
139  Real sign;
140  if (DdN > (Real)0)
141  {
142  sign = (Real)1;
143  }
144  else if (DdN < (Real)0)
145  {
146  sign = (Real)-1;
147  DdN = -DdN;
148  }
149  else
150  {
151  // Line and triangle are parallel, call it a "no intersection"
152  // even if the line and triangle are coplanar and intersecting.
153  result.intersect = false;
154  return result;
155  }
156 
157  Real DdQxE2 = sign*DotCross(line.direction, diff, edge2);
158  if (DdQxE2 >= (Real)0)
159  {
160  Real DdE1xQ = sign*DotCross(line.direction, edge1, diff);
161  if (DdE1xQ >= (Real)0)
162  {
163  if (DdQxE2 + DdE1xQ <= DdN)
164  {
165  // Line intersects triangle.
166  Real QdN = -sign*Dot(diff, normal);
167  Real inv = ((Real)1) / DdN;
168 
169  result.intersect = true;
170  result.parameter = QdN*inv;
171  result.triangleBary[1] = DdQxE2*inv;
172  result.triangleBary[2] = DdE1xQ*inv;
173  result.triangleBary[0] = (Real)1 - result.triangleBary[1]
174  - result.triangleBary[2];
175  result.point = line.origin +
176  result.parameter * line.direction;
177  return result;
178  }
179  // else: b1+b2 > 1, no intersection
180  }
181  // else: b2 < 0, no intersection
182  }
183  // else: b1 < 0, no intersection
184 
185  result.intersect = false;
186  return result;
187 }
188 
189 
190 }
DualQuaternion< Real > Dot(DualQuaternion< Real > const &d0, DualQuaternion< Real > const &d1)
DualQuaternion< Real > Cross(DualQuaternion< Real > const &d0, DualQuaternion< Real > const &d1)
Real DotCross(Vector< N, Real > const &v0, Vector< N, Real > const &v1, Vector< N, Real > const &v2)
Definition: GteVector3.h:140
Result operator()(Type0 const &primitive0, Type1 const &primitive1)
GLuint64EXT * result
Definition: glext.h:10003


geometric_tools_engine
Author(s): Yijiang Huang
autogenerated on Thu Jul 18 2019 04:00:00