GteIntrRay2Ray2.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/GteRay.h>
12 
13 namespace gte
14 {
15 
16 template <typename Real>
17 class TIQuery<Real, Ray2<Real>, Ray2<Real>>
18 {
19 public:
20  struct Result
21  {
22  bool intersect;
23 
24  // The number is 0 (no intersection), 1 (rays intersect in a
25  // single point), 2 (rays are collinear and intersect in a segment;
26  // ray directions are opposite of each other), or
27  // std::numeric_limits<int>::max() (intersection is a ray; ray
28  // directions are the same).
30  };
31 
32  Result operator()(Ray2<Real> const& ray0, Ray2<Real> const& ray1);
33 };
34 
35 template <typename Real>
36 class FIQuery<Real, Ray2<Real>, Ray2<Real>>
37 {
38 public:
39  struct Result
40  {
41  bool intersect;
42 
43  // The number is 0 (no intersection), 1 (rays intersect in a
44  // single point), 2 (rays are collinear and intersect in a segment;
45  // ray directions are opposite of each other), or
46  // std::numeric_limits<int>::max() (intersection is a ray; ray
47  // directions are the same).
49 
50  // If numIntersections is 1, the intersection is
51  // point[0] = ray0.origin + ray0Parameter[0] * ray0.direction
52  // = ray1.origin + ray1Parameter[0] * ray1.direction
53  // If numIntersections is 2, the segment of intersection is formed by
54  // the ray origins,
55  // ray0Parameter[0] = ray1Parameter[0] = 0
56  // point[0] = ray0.origin
57  // = ray1.origin + ray1Parameter[1] * ray1.direction
58  // point[1] = ray1.origin
59  // = ray0.origin + ray0Parameter[1] * ray0.direction
60  // where ray0Parameter[1] >= 0 and ray1Parameter[1] >= 0.
61  // If numIntersections is maxInt, let
62  // ray1.origin = ray0.origin + t * ray0.direction
63  // then
64  // ray0Parameter[] = { max(t,0), +maxReal }
65  // ray1Parameter[] = { -min(t,0), +maxReal }
66  // point[0] = ray0.origin + ray0Parameter[0] * ray0.direction
67  Real ray0Parameter[2], ray1Parameter[2];
68  Vector2<Real> point[2];
69  };
70 
71  Result operator()(Ray2<Real> const& ray0, Ray2<Real> const& ray1);
72 };
73 
74 
75 template <typename Real>
76 typename TIQuery<Real, Ray2<Real>, Ray2<Real>>::Result
78  Ray2<Real> const& ray0, Ray2<Real> const& ray1)
79 {
80  Result result;
82  Line2<Real> line0(ray0.origin, ray0.direction);
83  Line2<Real> line1(ray1.origin, ray1.direction);
84  auto llResult = llQuery(line0, line1);
85  if (llResult.numIntersections == 1)
86  {
87  // Test whether the line-line intersection is on the rays.
88  if (llResult.line0Parameter[0] >= (Real)0
89  && llResult.line1Parameter[0] >= (Real)0)
90  {
91  result.intersect = true;
92  result.numIntersections = 1;
93  }
94  else
95  {
96  result.intersect = false;
97  result.numIntersections = 0;
98  }
99  }
100  else if (llResult.numIntersections == std::numeric_limits<int>::max())
101  {
102  if (Dot(ray0.direction, ray1.direction) > (Real)0)
103  {
104  // The rays are collinear and in the same direction, so they must
105  // overlap.
106  result.intersect = true;
107  result.numIntersections = std::numeric_limits<int>::max();
108  }
109  else
110  {
111  // The rays are collinear but in opposite directions. Test
112  // whether they overlap. Ray0 has interval [0,+infinity) and
113  // ray1 has interval (-infinity,t] relative to ray0.direction.
114  Vector2<Real> diff = ray1.origin - ray0.origin;
115  Real t = Dot(ray0.direction, diff);
116  if (t > (Real)0)
117  {
118  result.intersect = true;
119  result.numIntersections = 2;
120  }
121  else if (t < (Real)0)
122  {
123  result.intersect = false;
124  result.numIntersections = 0;
125  }
126  else // t == 0
127  {
128  result.intersect = true;
129  result.numIntersections = 1;
130  }
131  }
132  }
133  else
134  {
135  result.intersect = false;
136  result.numIntersections = 0;
137  }
138 
139  return result;
140 }
141 
142 template <typename Real>
143 typename FIQuery<Real, Ray2<Real>, Ray2<Real>>::Result
145  Ray2<Real> const& ray0, Ray2<Real> const& ray1)
146 {
147  Result result;
149  Line2<Real> line0(ray0.origin, ray0.direction);
150  Line2<Real> line1(ray1.origin, ray1.direction);
151  auto llResult = llQuery(line0, line1);
152  if (llResult.numIntersections == 1)
153  {
154  // Test whether the line-line intersection is on the rays.
155  if (llResult.line0Parameter[0] >= (Real)0
156  && llResult.line1Parameter[0] >= (Real)0)
157  {
158  result.intersect = true;
159  result.numIntersections = 1;
160  result.ray0Parameter[0] = llResult.line0Parameter[0];
161  result.ray1Parameter[0] = llResult.line1Parameter[0];
162  result.point[0] = llResult.point;
163  }
164  else
165  {
166  result.intersect = false;
167  result.numIntersections = 0;
168  }
169  }
170  else if (llResult.numIntersections == std::numeric_limits<int>::max())
171  {
172  // Compute t for which ray1.origin = ray0.origin + t*ray0.direction.
173  Real maxReal = std::numeric_limits<Real>::max();
174  Vector2<Real> diff = ray1.origin - ray0.origin;
175  Real t = Dot(ray0.direction, diff);
176  if (Dot(ray0.direction, ray1.direction) > (Real)0)
177  {
178  // The rays are collinear and in the same direction, so they must
179  // overlap.
180  result.intersect = true;
181  result.numIntersections = std::numeric_limits<int>::max();
182  if (t >= (Real)0)
183  {
184  result.ray0Parameter[0] = t;
185  result.ray0Parameter[1] = maxReal;
186  result.ray1Parameter[0] = (Real)0;
187  result.ray1Parameter[1] = maxReal;
188  result.point[0] = ray1.origin;
189  }
190  else
191  {
192  result.ray0Parameter[0] = (Real)0;
193  result.ray0Parameter[1] = maxReal;
194  result.ray1Parameter[0] = -t;
195  result.ray1Parameter[1] = maxReal;
196  result.point[0] = ray0.origin;
197  }
198  }
199  else
200  {
201  // The rays are collinear but in opposite directions. Test
202  // whether they overlap. Ray0 has interval [0,+infinity) and
203  // ray1 has interval (-infinity,t1] relative to ray0.direction.
204  if (t >= (Real)0)
205  {
206  result.intersect = true;
207  result.numIntersections = 2;
208  result.ray0Parameter[0] = (Real)0;
209  result.ray0Parameter[1] = t;
210  result.ray1Parameter[0] = (Real)0;
211  result.ray1Parameter[1] = t;
212  result.point[0] = ray0.origin;
213  result.point[1] = ray1.origin;
214  }
215  else
216  {
217  result.intersect = false;
218  result.numIntersections = 0;
219  }
220  }
221  }
222  else
223  {
224  result.intersect = false;
225  result.numIntersections = 0;
226  }
227 
228  return result;
229 }
230 
231 
232 }
DualQuaternion< Real > Dot(DualQuaternion< Real > const &d0, DualQuaternion< Real > const &d1)
GLdouble GLdouble t
Definition: glext.h:239
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