GteIntrRay2Segment2.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 
12 #include <Mathematics/GteRay.h>
13 #include <Mathematics/GteSegment.h>
14 
15 namespace gte
16 {
17 
18 template <typename Real>
19 class TIQuery<Real, Ray2<Real>, Segment2<Real>>
20 {
21 public:
22  struct Result
23  {
24  bool intersect;
25 
26  // The number is 0 (no intersection), 1 (ray and segment intersect in
27  // a single point), or 2 (ray and segment are collinear and intersect
28  // in a segment).
30  };
31 
32  Result operator()(Ray2<Real> const& ray, Segment2<Real> const& segment);
33 };
34 
35 template <typename Real>
36 class FIQuery<Real, Ray2<Real>, Segment2<Real>>
37 {
38 public:
39  struct Result
40  {
41  bool intersect;
42 
43  // The number is 0 (no intersection), 1 (ray and segment intersect in
44  // a single point), or 2 (ray and segment are collinear and intersect
45  // in a segment).
47 
48  // If numIntersections is 1, the intersection is
49  // point[0] = ray.origin + rayParameter[0] * ray.direction
50  // = segment.center + segmentParameter[0] * segment.direction
51  // If numIntersections is 2, the endpoints of the segment of
52  // intersection are
53  // point[i] = ray.origin + rayParameter[i] * ray.direction
54  // = segment.center + segmentParameter[i] * segment.direction
55  // with rayParameter[0] <= rayParameter[1] and
56  // segmentParameter[0] <= segmentParameter[1].
57  Real rayParameter[2], segmentParameter[2];
58  Vector2<Real> point[2];
59  };
60 
61  Result operator()(Ray2<Real> const& ray, Segment2<Real> const& segment);
62 };
63 
64 
65 template <typename Real>
68  Ray2<Real> const& ray, Segment2<Real> const& segment)
69 {
70  Result result;
71  Vector2<Real> segOrigin, segDirection;
72  Real segExtent;
73  segment.GetCenteredForm(segOrigin, segDirection, segExtent);
74 
76  Line2<Real> line0(ray.origin, ray.direction);
77  Line2<Real> line1(segOrigin, segDirection);
78  auto llResult = llQuery(line0, line1);
79  if (llResult.numIntersections == 1)
80  {
81  // Test whether the line-line intersection is on the ray and segment.
82  if (llResult.line0Parameter[0] >= (Real)0
83  && std::abs(llResult.line1Parameter[0]) <= segExtent)
84  {
85  result.intersect = true;
86  result.numIntersections = 1;
87  }
88  else
89  {
90  result.intersect = false;
91  result.numIntersections = 0;
92  }
93  }
94  else if (llResult.numIntersections == std::numeric_limits<int>::max())
95  {
96  // Compute the location of the right-most point of the segment
97  // relative to the ray direction.
98  Vector2<Real> diff = segOrigin - ray.origin;
99  Real t = Dot(ray.direction, diff) + segExtent;
100  if (t > (Real)0)
101  {
102  result.intersect = true;
103  result.numIntersections = 2;
104  }
105  else if (t < (Real)0)
106  {
107  result.intersect = false;
108  result.numIntersections = 0;
109  }
110  else // t == 0
111  {
112  result.intersect = true;
113  result.numIntersections = 1;
114  }
115  }
116  else
117  {
118  result.intersect = false;
119  result.numIntersections = 0;
120  }
121 
122  return result;
123 }
124 
125 template <typename Real>
126 typename FIQuery<Real, Ray2<Real>, Segment2<Real>>::Result
128  Ray2<Real> const& ray, Segment2<Real> const& segment)
129 {
130  Result result;
131  Vector2<Real> segOrigin, segDirection;
132  Real segExtent;
133  segment.GetCenteredForm(segOrigin, segDirection, segExtent);
134 
136  Line2<Real> line0(ray.origin, ray.direction);
137  Line2<Real> line1(segOrigin, segDirection);
138  auto llResult = llQuery(line0, line1);
139  if (llResult.numIntersections == 1)
140  {
141  // Test whether the line-line intersection is on the ray and segment.
142  if (llResult.line0Parameter[0] >= (Real)0
143  && std::abs(llResult.line1Parameter[0]) <= segExtent)
144  {
145  result.intersect = true;
146  result.numIntersections = 1;
147  result.rayParameter[0] = llResult.line0Parameter[0];
148  result.segmentParameter[0] = llResult.line1Parameter[0];
149  result.point[0] = llResult.point;
150  }
151  else
152  {
153  result.intersect = false;
154  result.numIntersections = 0;
155  }
156  }
157  else if (llResult.numIntersections == std::numeric_limits<int>::max())
158  {
159  // Compute t for which segment.origin = ray.origin + t*ray.direction.
160  Vector2<Real> diff = segOrigin - ray.origin;
161  Real t = Dot(ray.direction, diff);
162 
163  // Get the ray interval.
164  std::array<Real, 2> interval0 =
165  {
166  (Real)0, std::numeric_limits<Real>::max()
167  };
168 
169  // Compute the location of the segment endpoints relative to the ray.
170  std::array<Real, 2> interval1 = { t - segExtent, t + segExtent };
171 
172  // Compute the intersection of [0,+infinity) and [tmin,tmax].
173  FIQuery<Real, std::array<Real, 2>, std::array<Real, 2>> iiQuery;
174  auto iiResult = iiQuery(interval0, interval1);
175  if (iiResult.intersect)
176  {
177  result.intersect = true;
178  result.numIntersections = iiResult.numIntersections;
179  for (int i = 0; i < iiResult.numIntersections; ++i)
180  {
181  result.rayParameter[i] = iiResult.overlap[i];
182  result.segmentParameter[i] = iiResult.overlap[i] - t;
183  result.point[i] = ray.origin +
184  result.rayParameter[i] * ray.direction;
185  }
186  }
187  else
188  {
189  result.intersect = false;
190  result.numIntersections = 0;
191  }
192  }
193  else
194  {
195  result.intersect = false;
196  result.numIntersections = 0;
197  }
198  return result;
199 }
200 
201 
202 }
gte::BSNumber< UIntegerType > abs(gte::BSNumber< UIntegerType > const &number)
Definition: GteBSNumber.h:966
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