GteDistRaySegment.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 
11 #include <Mathematics/GteRay.h>
12 #include <Mathematics/GteSegment.h>
13 
14 namespace gte
15 {
16 
17 template <int N, typename Real>
18 class DCPQuery<Real, Ray<N, Real>, Segment<N, Real>>
19 {
20 public:
21  struct Result
22  {
24  Real parameter[2];
25  Vector<N, Real> closestPoint[2];
26  };
27 
28  // The centered form of the 'segment' is used. Thus, parameter[1] of
29  // the result is in [-e,e], where e = |segment.p[1] - segment.p[0]|/2.
30  Result operator()(Ray<N, Real> const& ray,
31  Segment<N, Real> const& segment);
32 };
33 
34 // Template aliases for convenience.
35 template <int N, typename Real>
37 
38 template <typename Real>
40 
41 template <typename Real>
43 
44 
45 template <int N, typename Real>
46 typename DCPQuery<Real, Ray<N, Real>, Segment<N, Real>>::Result
47 DCPQuery<Real, Ray<N, Real>, Segment<N, Real>>::operator()(
48  Ray<N, Real> const& ray, Segment<N, Real> const& segment)
49 {
50  Result result;
51 
52  Vector<N, Real> segCenter, segDirection;
53  Real segExtent;
54  segment.GetCenteredForm(segCenter, segDirection, segExtent);
55 
56  Vector<N, Real> diff = ray.origin - segCenter;
57  Real a01 = -Dot(ray.direction, segDirection);
58  Real b0 = Dot(diff, ray.direction);
59  Real s0, s1;
60 
61  if (std::abs(a01) < (Real)1)
62  {
63  // The ray and segment are not parallel.
64  Real det = (Real)1 - a01 * a01;
65  Real extDet = segExtent*det;
66  Real b1 = -Dot(diff, segDirection);
67  s0 = a01 * b1 - b0;
68  s1 = a01 * b0 - b1;
69 
70  if (s0 >= (Real)0)
71  {
72  if (s1 >= -extDet)
73  {
74  if (s1 <= extDet) // region 0
75  {
76  // Minimum at interior points of ray and segment.
77  s0 /= det;
78  s1 /= det;
79  }
80  else // region 1
81  {
82  s1 = segExtent;
83  s0 = std::max(-(a01*s1 + b0), (Real)0);
84  }
85  }
86  else // region 5
87  {
88  s1 = -segExtent;
89  s0 = std::max(-(a01*s1 + b0), (Real)0);
90  }
91  }
92  else
93  {
94  if (s1 <= -extDet) // region 4
95  {
96  s0 = -(-a01*segExtent + b0);
97  if (s0 > (Real)0)
98  {
99  s1 = -segExtent;
100  }
101  else
102  {
103  s0 = (Real)0;
104  s1 = -b1;
105  if (s1 < -segExtent)
106  {
107  s1 = -segExtent;
108  }
109  else if (s1 > segExtent)
110  {
111  s1 = segExtent;
112  }
113  }
114  }
115  else if (s1 <= extDet) // region 3
116  {
117  s0 = (Real)0;
118  s1 = -b1;
119  if (s1 < -segExtent)
120  {
121  s1 = -segExtent;
122  }
123  else if (s1 > segExtent)
124  {
125  s1 = segExtent;
126  }
127  }
128  else // region 2
129  {
130  s0 = -(a01*segExtent + b0);
131  if (s0 > (Real)0)
132  {
133  s1 = segExtent;
134  }
135  else
136  {
137  s0 = (Real)0;
138  s1 = -b1;
139  if (s1 < -segExtent)
140  {
141  s1 = -segExtent;
142  }
143  else if (s1 > segExtent)
144  {
145  s1 = segExtent;
146  }
147  }
148  }
149  }
150  }
151  else
152  {
153  // Ray and segment are parallel.
154  if (a01 > (Real)0)
155  {
156  // Opposite direction vectors.
157  s1 = -segExtent;
158  }
159  else
160  {
161  // Same direction vectors.
162  s1 = segExtent;
163  }
164 
165  s0 = std::max(-(a01*s1 + b0), (Real)0);
166  }
167 
168  result.parameter[0] = s0;
169  result.parameter[1] = s1;
170  result.closestPoint[0] = ray.origin + s0 * ray.direction;
171  result.closestPoint[1] = segCenter + s1 * segDirection;
172  diff = result.closestPoint[0] - result.closestPoint[1];
173  result.sqrDistance = Dot(diff, diff);
174  result.distance = sqrt(result.sqrDistance);
175  return result;
176 }
177 
178 
179 }
gte::BSNumber< UIntegerType > abs(gte::BSNumber< UIntegerType > const &number)
Definition: GteBSNumber.h:966
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat s0
Definition: glext.h:9013
GLsizei GLsizei GLfloat distance
Definition: glext.h:9704
Result operator()(Type0 const &primitive0, Type1 const &primitive1)
DualQuaternion< Real > Dot(DualQuaternion< Real > const &d0, DualQuaternion< Real > const &d1)
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat s1
Definition: glext.h:9013
GLuint64EXT * result
Definition: glext.h:10003


geometric_tools_engine
Author(s): Yijiang Huang
autogenerated on Thu Jul 18 2019 03:59:59