GteDistPoint3Cylinder3.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/GteVector3.h>
13 
14 // The queries consider the cylinder to be a solid.
15 
16 namespace gte
17 {
18 
19 template <typename Real>
20 class DCPQuery<Real, Vector3<Real>, Cylinder3<Real>>
21 {
22 public:
23  struct Result
24  {
25  Real distance;
27  };
28 
29  Result operator()(Vector3<Real> const& point,
30  Cylinder3<Real> const& cylinder);
31 
32 private:
33  void DoQueryInfiniteCylinder(Vector3<Real> const& P, Real radius,
34  Result& result);
35 
36  void DoQueryFiniteCylinder(Vector3<Real> const& P, Real radius,
37  Real height, Result& result);
38 };
39 
40 
41 template <typename Real>
44  Vector3<Real> const& point, Cylinder3<Real> const& cylinder)
45 {
46  Result result;
47 
48  // Convert the point to the cylinder coordinate system. In this system,
49  // the point believes (0,0,0) is the cylinder axis origin and (0,0,1) is
50  // the cylinder axis direction.
51  Vector3<Real> basis[3];
52  basis[0] = cylinder.axis.direction;
54 
55  Vector3<Real> delta = point - cylinder.axis.origin;
57  {
58  Dot(basis[1], delta),
59  Dot(basis[2], delta),
60  Dot(basis[0], delta)
61  };
62 
63  if (cylinder.height == std::numeric_limits<Real>::max())
64  {
65  DoQueryInfiniteCylinder(P, cylinder.radius, result);
66  }
67  else
68  {
69  DoQueryFiniteCylinder(P, cylinder.radius, cylinder.height, result);
70  }
71 
72  // Convert the closest point from the cylinder coordinate system to the
73  // original coordinate system.
74  result.cylinderClosest = cylinder.axis.origin +
75  result.cylinderClosest[0] * basis[1] +
76  result.cylinderClosest[1] * basis[2] +
77  result.cylinderClosest[2] * basis[0];
78 
79  return result;
80 }
81 
82 template <typename Real>
83 void DCPQuery<Real, Vector3<Real>, Cylinder3<Real>>::DoQueryInfiniteCylinder(
84  Vector3<Real> const& P, Real radius, Result& result)
85 {
86  Real sqrRadius = radius * radius;
87  Real sqrDistance = P[0] * P[0] + P[1] * P[1];
88  if (sqrDistance >= sqrRadius)
89  {
90  // The point is outside the cylinder or on the cylinder wall.
91  Real distance = sqrt(sqrDistance);
92  result.distance = distance - radius;
93  Real temp = radius / distance;
94  result.cylinderClosest[0] = P[0] * temp;
95  result.cylinderClosest[1] = P[1] * temp;
96  result.cylinderClosest[2] = P[2];
97  }
98  else
99  {
100  // The point is inside the cylinder.
101  result.distance = (Real)0;
102  result.cylinderClosest = P;
103  }
104 }
105 
106 template <typename Real>
107 void DCPQuery<Real, Vector3<Real>, Cylinder3<Real>>::DoQueryFiniteCylinder(
108  Vector3<Real> const& P, Real radius, Real height, Result& result)
109 {
110  DoQueryInfiniteCylinder(P, radius, result);
111 
112  // Clamp the infinite cylinder's closest point to the finite cylinder.
113  if (result.cylinderClosest[2] > height)
114  {
115  result.cylinderClosest[2] = height;
116  result.distance = Length(result.cylinderClosest - P);
117  }
118  else if (result.cylinderClosest[2] < -height)
119  {
120  result.cylinderClosest[2] = -height;
121  result.distance = Length(result.cylinderClosest - P);
122  }
123 }
124 
125 
126 }
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)
GLint GLsizei GLsizei height
Definition: glcorearb.h:98
DualQuaternion< Real > Length(DualQuaternion< Real > const &d, bool robust=false)
Real ComputeOrthogonalComplement(int numInputs, Vector2< Real > *v, bool robust=false)
Definition: GteVector2.h:123
GLuint64EXT * result
Definition: glext.h:10003


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