GteDistLineSegment.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/GteLine.h>
12 #include <Mathematics/GteSegment.h>
13 
14 namespace gte
15 {
16 
17 template <int N, typename Real>
18 class DCPQuery<Real, Line<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()(Line<N, Real> const& line,
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, Line<N, Real>, Segment<N, Real>>::Result
47 DCPQuery<Real, Line<N, Real>, Segment<N, Real>>::operator()(
48  Line<N, Real> const& line, 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 = line.origin - segCenter;
57  Real a01 = -Dot(line.direction, segDirection);
58  Real b0 = Dot(diff, line.direction);
59  Real s0, s1;
60 
61  if (std::abs(a01) < (Real)1)
62  {
63  // The line and segment are not parallel.
64  Real det = (Real)1 - a01 * a01;
65  Real extDet = segExtent * det;
66  Real b1 = -Dot(diff, segDirection);
67  s1 = a01 * b0 - b1;
68 
69  if (s1 >= -extDet)
70  {
71  if (s1 <= extDet)
72  {
73  // Two interior points are closest, one on the line and one
74  // on the segment.
75  s0 = (a01 * b1 - b0) / det;
76  s1 /= det;
77  }
78  else
79  {
80  // The endpoint e1 of the segment and an interior point of
81  // the line are closest.
82  s1 = segExtent;
83  s0 = -(a01 * s1 + b0);
84  }
85  }
86  else
87  {
88  // The endpoint e0 of the segment and an interior point of the
89  // line are closest.
90  s1 = -segExtent;
91  s0 = -(a01 * s1 + b0);
92  }
93  }
94  else
95  {
96  // The line and segment are parallel. Choose the closest pair so that
97  // one point is at segment origin.
98  s1 = (Real)0;
99  s0 = -b0;
100  }
101 
102  result.parameter[0] = s0;
103  result.parameter[1] = s1;
104  result.closestPoint[0] = line.origin + s0 * line.direction;
105  result.closestPoint[1] = segCenter + s1 * segDirection;
106  diff = result.closestPoint[0] - result.closestPoint[1];
107  result.sqrDistance = Dot(diff, diff);
108  result.distance = sqrt(result.sqrDistance);
109  return result;
110 }
111 
112 
113 }
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