Simplex.hpp
Go to the documentation of this file.
1 /*
2  * Original work Copyright (c) 2007-2009 Erin Catto http://www.box2d.org
3  * Modified work Copyright (c) 2017 Louis Langholtz https://github.com/louis-langholtz/PlayRho
4  *
5  * This software is provided 'as-is', without any express or implied
6  * warranty. In no event will the authors be held liable for any damages
7  * arising from the use of this software.
8  * Permission is granted to anyone to use this software for any purpose,
9  * including commercial applications, and to alter it and redistribute it
10  * freely, subject to the following restrictions:
11  * 1. The origin of this software must not be misrepresented; you must not
12  * claim that you wrote the original software. If you use this software
13  * in a product, an acknowledgment in the product documentation would be
14  * appreciated but is not required.
15  * 2. Altered source versions must be plainly marked as such, and must not be
16  * misrepresented as being the original software.
17  * 3. This notice may not be removed or altered from any source distribution.
18  */
19 
20 #ifndef PLAYRHO_COLLISION_SIMPLEX_HPP
21 #define PLAYRHO_COLLISION_SIMPLEX_HPP
22 
26 #include <array>
27 
28 namespace playrho {
29 namespace d2 {
30 
33  using SimplexEdges = ArrayList<SimplexEdge, MaxSimplexEdges,
34  std::remove_const<decltype(MaxSimplexEdges)>::type>;
35 
37  IndexPair3 GetIndexPairs(const SimplexEdges& collection) noexcept;
38 
43  Length2 CalcSearchDirection(const SimplexEdges& simplexEdges) noexcept;
44 
59  class Simplex
60  {
61  public:
62 
67 
75  std::remove_const<decltype(MaxSimplexEdges)>::type>;
76 
81  struct Cache
82  {
85  Real metric = GetInvalid<Real>();
86 
90  };
91 
93  static Cache GetCache(const SimplexEdges& edges) noexcept;
94 
96  static Real CalcMetric(const SimplexEdges& simplexEdges);
97 
99  static Simplex Get(const SimplexEdge& s0) noexcept;
100 
112  static Simplex Get(const SimplexEdge& s0, const SimplexEdge& s1) noexcept;
113 
118  static Simplex Get(const SimplexEdge& s0, const SimplexEdge& s1, const SimplexEdge& s2) noexcept;
119 
124  static Simplex Get(const SimplexEdges& edges) noexcept;
125 
126  Simplex() = default;
127 
129  PLAYRHO_CONSTEXPR inline SimplexEdges GetEdges() const noexcept;
130 
132  const SimplexEdge& GetSimplexEdge(size_type index) const noexcept;
133 
135  PLAYRHO_CONSTEXPR inline Real GetCoefficient(size_type index) const noexcept;
136 
138  PLAYRHO_CONSTEXPR inline size_type size() const noexcept;
139 
140  private:
141 
143  Simplex(const SimplexEdges& simplexEdges, const Coefficients& normalizedWeights) noexcept;
144 
149  SimplexEdges m_simplexEdges;
150 
158  Coefficients m_normalizedWeights;
159  };
160 
161  inline Simplex::Cache Simplex::GetCache(const SimplexEdges& edges) noexcept
162  {
163  return Simplex::Cache{Simplex::CalcMetric(edges), GetIndexPairs(edges)};
164  }
165 
166  inline Simplex::Simplex(const SimplexEdges& simplexEdges,
167  const Coefficients& normalizedWeights) noexcept:
168  m_simplexEdges{simplexEdges}, m_normalizedWeights{normalizedWeights}
169  {
170  assert(simplexEdges.size() == normalizedWeights.size());
171 #ifndef NDEBUG
172  const auto sum = std::accumulate(begin(normalizedWeights), end(normalizedWeights),
173  Real{0});
174  assert(AlmostEqual(Real{1}, sum));
175 #endif
176  }
177 
179  {
180  return m_simplexEdges;
181  }
182 
183  const inline SimplexEdge& Simplex::GetSimplexEdge(size_type index) const noexcept
184  {
185  return m_simplexEdges[index];
186  }
187 
189  {
190  return m_normalizedWeights[index];
191  }
192 
196  {
197  return m_simplexEdges.size();
198  }
199 
201  inline Length2 GetScaledDelta(const Simplex& simplex, Simplex::size_type index)
202  {
203  return GetPointDelta(simplex.GetSimplexEdge(index)) * simplex.GetCoefficient(index);
204  }
205 
208  {
209  switch (simplex.size())
210  {
211  case 1: return GetScaledDelta(simplex, 0);
212  case 2: return GetScaledDelta(simplex, 0) + GetScaledDelta(simplex, 1);
213  case 3: return Length2{0_m, 0_m};
214  default: return Length2{0_m, 0_m};
215  }
216  }
217 
218 } // namespace d2
219 } // namespace playrho
220 
221 #endif // PLAYRHO_COLLISION_SIMPLEX_HPP