GteIntrLine2Triangle2.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/GteVector2.h>
11 #include <Mathematics/GteLine.h>
13 #include <Mathematics/GteFIQuery.h>
14 #include <Mathematics/GteTIQuery.h>
15 
16 // The queries consider the triangle to be a solid.
17 
18 namespace gte
19 {
20 
21 template <typename Real>
22 class TIQuery<Real, Line2<Real>, Triangle2<Real>>
23 {
24 public:
25  struct Result
26  {
27  bool intersect;
28  };
29 
30  Result operator()(Line2<Real> const& line,
31  Triangle2<Real> const& triangle);
32 };
33 
34 template <typename Real>
35 class FIQuery<Real, Line2<Real>, Triangle2<Real>>
36 {
37 public:
38  struct Result
39  {
40  bool intersect;
42  std::array<Real, 2> parameter;
43  std::array<Vector2<Real>, 2> point;
44  };
45 
46  Result operator()(Line2<Real> const& line,
47  Triangle2<Real> const& triangle);
48 
49 protected:
50  void DoQuery(Vector2<Real> const& lineOrigin,
51  Vector2<Real> const& lineDirection, Triangle2<Real> const& triangle,
52  Result& result);
53 };
54 
55 
56 template <typename Real>
59  Line2<Real> const& line, Triangle2<Real> const& triangle)
60 {
61  Result result;
62 
63  // Determine on which side of the line the vertices lie. The table of
64  // possibilities is listed next with n = numNegative, p = numPositive, and
65  // z = numZero.
66  //
67  // n p z intersection
68  // ------------------------------------
69  // 0 3 0 none
70  // 0 2 1 vertex
71  // 0 1 2 edge
72  // 0 0 3 none (degenerate triangle)
73  // 1 2 0 segment (2 edges clipped)
74  // 1 1 1 segment (1 edge clipped)
75  // 1 0 2 edge
76  // 2 1 0 segment (2 edges clipped)
77  // 2 0 1 vertex
78  // 3 0 0 none
79 
80  Real s[3];
81  int numPositive = 0, numNegative = 0, numZero = 0;
82  for (int i = 0; i < 3; ++i)
83  {
84  Vector2<Real> diff = triangle.v[i] - line.origin;
85  s[i] = DotPerp(line.direction, diff);
86  if (s[i] >(Real)0)
87  {
88  ++numPositive;
89  }
90  else if (s[i] < (Real)0)
91  {
92  ++numNegative;
93  }
94  else
95  {
96  ++numZero;
97  }
98  }
99 
100  result.intersect =
101  (numZero == 0 && (numPositive == 0 || numNegative == 0)) ||
102  (numZero == 3);
103 
104  return result;
105 }
106 
107 template <typename Real>
110  Line2<Real> const& line, Triangle2<Real> const& triangle)
111 {
112  Result result;
113  DoQuery(line.origin, line.direction, triangle, result);
114  for (int i = 0; i < result.numIntersections; ++i)
115  {
116  result.point[i] = line.origin + result.parameter[i] * line.direction;
117  }
118  return result;
119 }
120 
121 template <typename Real>
123  Vector2<Real> const& lineOrigin, Vector2<Real> const& lineDirection,
124  Triangle2<Real> const& triangle, Result& result)
125 {
126  // Determine on which side of the line the vertices lie. The table of
127  // possibilities is listed next with n = numNegative, p = numPositive, and
128  // z = numZero.
129  //
130  // n p z intersection
131  // ------------------------------------
132  // 0 3 0 none
133  // 0 2 1 vertex
134  // 0 1 2 edge
135  // 0 0 3 none (degenerate triangle)
136  // 1 2 0 segment (2 edges clipped)
137  // 1 1 1 segment (1 edge clipped)
138  // 1 0 2 edge
139  // 2 1 0 segment (2 edges clipped)
140  // 2 0 1 vertex
141  // 3 0 0 none
142 
143  Real s[3];
144  int numPositive = 0, numNegative = 0, numZero = 0;
145  for (int i = 0; i < 3; ++i)
146  {
147  Vector2<Real> diff = triangle.v[i] - lineOrigin;
148  s[i] = DotPerp(lineDirection, diff);
149  if (s[i] >(Real)0)
150  {
151  ++numPositive;
152  }
153  else if (s[i] < (Real)0)
154  {
155  ++numNegative;
156  }
157  else
158  {
159  ++numZero;
160  }
161  }
162 
163  if (numZero == 0 && numPositive > 0 && numNegative > 0)
164  {
165  result.intersect = true;
166  result.numIntersections = 2;
167  Real sign = (Real)3 - numPositive * (Real)2;
168  for (int i0 = 0; i0 < 3; ++i0)
169  {
170  if (sign * s[i0] >(Real)0)
171  {
172  int i1 = (i0 + 1) % 3, i2 = (i0 + 2) % 3;
173  Real s1 = s[i1] / (s[i1] - s[i0]);
174  Vector2<Real> p1 = (triangle.v[i1] - lineOrigin) +
175  s1 * (triangle.v[i0] - triangle.v[i1]);
176  result.parameter[0] = Dot(lineDirection, p1);
177  Real s2 = s[i2] / (s[i2] - s[i0]);
178  Vector2<Real> p2 = (triangle.v[i2] - lineOrigin) +
179  s2 * (triangle.v[i0] - triangle.v[i2]);
180  result.parameter[1] = Dot(lineDirection, p2);
181  break;
182  }
183  }
184  return;
185  }
186 
187  if (numZero == 1)
188  {
189  result.intersect = true;
190  for (int i0 = 0; i0 < 3; ++i0)
191  {
192  if (s[i0] == (Real)0)
193  {
194  int i1 = (i0 + 1) % 3, i2 = (i0 + 2) % 3;
195  result.parameter[0] =
196  Dot(lineDirection, triangle.v[i0] - lineOrigin);
197  if (numPositive == 2 || numNegative == 2)
198  {
199  result.numIntersections = 1;
200 
201  // Used by derived classes.
202  result.parameter[1] = result.parameter[0];
203  }
204  else
205  {
206  result.numIntersections = 2;
207  Real s1 = s[i1] / (s[i1] - s[i2]);
208  Vector2<Real> p1 = (triangle.v[i1] - lineOrigin) +
209  s1 * (triangle.v[i2] - triangle.v[i1]);
210  result.parameter[1] = Dot(lineDirection, p1);
211  }
212  break;
213  }
214  }
215  return;
216  }
217 
218  if (numZero == 2)
219  {
220  result.intersect = true;
221  result.numIntersections = 2;
222  for (int i0 = 0; i0 < 3; ++i0)
223  {
224  if (s[i0] != (Real)0)
225  {
226  int i1 = (i0 + 1) % 3, i2 = (i0 + 2) % 3;
227  result.parameter[0] =
228  Dot(lineDirection, triangle.v[i1] - lineOrigin);
229  result.parameter[1] =
230  Dot(lineDirection, triangle.v[i2] - lineOrigin);
231  break;
232  }
233  }
234  return;
235  }
236 
237  // (n,p,z) one of (3,0,0), (0,3,0), (0,0,3)
238  result.intersect = false;
239  result.numIntersections = 0;
240 }
241 
242 
243 }
Real DotPerp(Vector2< Real > const &v0, Vector2< Real > const &v1)
Definition: GteVector2.h:117
DualQuaternion< Real > Dot(DualQuaternion< Real > const &d0, DualQuaternion< Real > const &d1)
GLdouble s
Definition: glext.h:231
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat s1
Definition: glext.h:9013
Result operator()(Type0 const &primitive0, Type1 const &primitive1)
std::array< Vector< N, Real >, 3 > v
Definition: GteTriangle.h:30
GLuint64EXT * result
Definition: glext.h:10003


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