GteDistPoint3ConvexPolyhedron3.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.5.0 (2016/11/25)
7 
8 #pragma once
9 
13 #include <memory>
14 
15 namespace gte
16 {
17 
18 template <typename Real>
19 class DCPQuery<Real, Vector3<Real>, ConvexPolyhedron3<Real>>
20 {
21 public:
22  // Construction. If you have no knowledge of the number of faces for the
23  // convex polyhedra you plan on applying the query to, pass 'numTriangles'
24  // of zero. This is a request to the operator() function to create the
25  // LCP solver for each query, and this requires memory allocation and
26  // deallocation per query. If you plan on applying the query multiple
27  // times to a single polyhedron, even if the vertices of the polyhedron
28  // are modified for each query, then pass 'numTriangles' to be the number
29  // of triangle faces for that polyhedron. This lets the operator()
30  // function know to create the LCP solver once at construction time, thus
31  // avoiding the memory management costs during the query.
32  DCPQuery(int numTriangles = 0);
33 
34  struct Result
35  {
37 
38  // These members are valid only when queryIsSuccessful is true;
39  // otherwise, they are all set to zero.
41  Vector3<Real> closestPoint[2];
42 
43  // The number of iterations used by LCPSolver regardless of whether
44  // the query is successful.
46  };
47 
48  // The default maximum iterations is 81 (n = 9, maxIterations = n*n). If
49  // the solver fails to converge, try increasing the maximum number of
50  // iterations.
51  void SetMaxLCPIterations(int maxLCPIterations);
52 
53  Result operator()(Vector3<Real> const& point, ConvexPolyhedron3<Real> const& polyhedron);
54 
55 private:
57  std::unique_ptr<LCPSolver<Real>> mLCP;
58 };
59 
60 
61 template <typename Real>
63 {
64  if (numTriangles > 0)
65  {
66  int const n = numTriangles + 3;
67  mLCP = std::make_unique<LCPSolver<Real>>(n);
68  mMaxLCPIterations = mLCP->GetMaxIterations();
69  }
70  else
71  {
72  mMaxLCPIterations = 0;
73  }
74 }
75 
76 template <typename Real>
77 void DCPQuery<Real, Vector3<Real>, ConvexPolyhedron3<Real>>::SetMaxLCPIterations(int maxLCPIterations)
78 {
79  mMaxLCPIterations = maxLCPIterations;
80  if (mLCP)
81  {
82  mLCP->SetMaxIterations(mMaxLCPIterations);
83  }
84 }
85 
86 template <typename Real>
87 typename DCPQuery<Real, Vector3<Real>, ConvexPolyhedron3<Real>>::Result
88 DCPQuery<Real, Vector3<Real>, ConvexPolyhedron3<Real>>::operator()(
89  Vector3<Real> const& point, ConvexPolyhedron3<Real> const& polyhedron)
90 {
91  Result result;
92 
93  int const numTriangles = static_cast<int>(polyhedron.planes.size());
94  if (numTriangles == 0)
95  {
96  // The polyhedron planes and aligned box need to be created.
97  result.queryIsSuccessful = false;
98  for (int i = 0; i < 3; ++i)
99  {
100  result.closestPoint[0][i] = (Real)0;
101  result.closestPoint[1][i] = (Real)0;
102  }
103  result.distance = (Real)0;
104  result.sqrDistance = (Real)0;
105  result.numLCPIterations = 0;
106  return result;
107  }
108 
109  int const n = numTriangles + 3;
110 
111  // Translate the point and convex polyhedron so that the polyhedron is in
112  // the first octant. The translation is not explicit; rather, the q and M
113  // for the LCP are initialized using the translation information.
114  Vector4<Real> hmin = HLift(polyhedron.alignedBox.min, (Real)1);
115 
116  std::vector<Real> q(n);
117  for (int r = 0; r < 3; ++r)
118  {
119  q[r] = polyhedron.alignedBox.min[r] - point[r];
120  }
121  for (int r = 3, t = 0; r < n; ++r, ++t)
122  {
123  q[r] = -Dot(polyhedron.planes[t], hmin);
124  }
125 
126  std::vector<Real> M(n * n);
127  M[0] = (Real)1; M[1] = (Real)0; M[2] = (Real)0;
128  M[n] = (Real)0; M[n + 1] = (Real)1; M[n + 2] = (Real)0;
129  M[2 * n] = (Real)0; M[2 * n + 1] = (Real)0; M[2 * n + 2] = (Real)1;
130  for (int t = 0, c = 3; t < numTriangles; ++t, ++c)
131  {
132  Vector3<Real> normal = HProject(polyhedron.planes[t]);
133  for (int r = 0; r < 3; ++r)
134  {
135  M[c + n * r] = normal[r];
136  M[r + n * c] = -normal[r];
137  }
138  }
139  for (int r = 3; r < n; ++r)
140  {
141  for (int c = 3; c < n; ++c)
142  {
143  M[c + n * r] = (Real)0;
144  }
145  }
146 
147  bool needsLCP = (mLCP == nullptr);
148  if (needsLCP)
149  {
150  mLCP = std::make_unique<LCPSolver<Real>>(n);
151  if (mMaxLCPIterations > 0)
152  {
153  mLCP->SetMaxIterations(mMaxLCPIterations);
154  }
155  }
156 
157  std::vector<Real> w(n), z(n);
158  if (mLCP->Solve(q, M, w, z))
159  {
160  result.queryIsSuccessful = true;
161  result.closestPoint[0] = point;
162  for (int i = 0; i < 3; ++i)
163  {
164  result.closestPoint[1][i] = z[i] + polyhedron.alignedBox.min[i];
165  }
166 
167  Vector3<Real> diff = result.closestPoint[1] - result.closestPoint[0];
168  result.sqrDistance = Dot(diff, diff);
169  result.distance = Function<Real>::Sqrt(result.sqrDistance);
170  }
171  else
172  {
173  // If you reach this case, the maximum number of iterations was not
174  // specified to be large enough or there is a problem due to
175  // floating-point rounding errors. If you believe the latter is
176  // true, file a bug report.
177  result.queryIsSuccessful = false;
178  }
179 
180  result.numLCPIterations = mLCP->GetNumIterations();
181  if (needsLCP)
182  {
183  mLCP = nullptr;
184  }
185  return result;
186 }
187 
188 }
GLdouble n
Definition: glcorearb.h:2003
GLsizei GLsizei GLfloat distance
Definition: glext.h:9704
static Real Sqrt(Real const &x)
Definition: GteFunctions.h:937
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:852
GVector< Real > HLift(GVector< Real > const &v, Real last)
Definition: GteGVector.h:574
const GLubyte * c
Definition: glext.h:11671
Result operator()(Type0 const &primitive0, Type1 const &primitive1)
GVector< Real > HProject(GVector< Real > const &v)
Definition: GteGVector.h:587
DualQuaternion< Real > Dot(DualQuaternion< Real > const &d0, DualQuaternion< Real > const &d1)
GLdouble GLdouble t
Definition: glext.h:239
GLdouble GLdouble GLdouble z
Definition: glcorearb.h:843
GLboolean r
Definition: glcorearb.h:1217
GLdouble GLdouble GLdouble GLdouble q
Definition: glext.h:255
GLuint64EXT * result
Definition: glext.h:10003


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