cyclic_vec.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014-2017, the neonavigation authors
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * * Neither the name of the copyright holder nor the names of its
14  * contributors may be used to endorse or promote products derived from
15  * this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #ifndef PLANNER_CSPACE_CYCLIC_VEC_H
31 #define PLANNER_CSPACE_CYCLIC_VEC_H
32 
33 #define _USE_MATH_DEFINES
34 #include <cfloat>
35 #include <cmath>
36 #include <initializer_list>
37 #include <list>
38 #include <map>
39 #include <memory>
40 #include <unordered_map>
41 #include <vector>
42 
43 #include <boost/chrono.hpp>
44 
46 
47 namespace planner_cspace
48 {
49 namespace cyclic_vec_type_conversion_rule
50 {
51 template <typename T>
52 void convert(const T val, float& ret)
53 {
54  ret = val;
55 }
56 inline void convert(const int val, float& ret)
57 {
58  ret = val;
59 }
60 inline void convert(const float val, int& ret)
61 {
62  ret = std::lround(val);
63 }
64 
65 inline void normalizeFloatAngle(float& val)
66 {
67  if (val > M_PI)
68  val -= 2 * M_PI;
69  else if (val < -M_PI)
70  val += 2 * M_PI;
71 }
72 inline void normalizeFloatAngle(int&)
73 {
74 }
75 } // namespace cyclic_vec_type_conversion_rule
76 
77 template <int DIM, int NONCYCLIC, typename T>
79 {
80 protected:
81  static_assert(
82  std::is_same<float, T>() || std::is_same<int, T>(), "T must be float or int");
83  T e_[DIM];
84 
85  template <typename T2, typename... ArgList>
86  void setElements(const int i, const T2& first, const ArgList&... rest) noexcept
87  {
88  assert(i < DIM);
89 
91  setElements(i + 1, rest...);
92  }
93  void setElements(const int i) noexcept
94  {
95  assert(i == DIM);
96  }
97 
98  template <typename... ArgList>
100  const int i,
101  const int res, const ArgList&... rest)
102  {
103  cycleElement(i, res);
104  cycleElements(i + 1, rest...);
105  }
106  void cycleElement(const int i, const int res)
107  {
108  assert(i < DIM);
109 
110  e_[i] = e_[i] % res;
111  if (e_[i] < res / 2 - res)
112  e_[i] += res;
113  else if (e_[i] >= res / 2)
114  e_[i] -= res;
115  }
116  void cycleElements(const int i)
117  {
118  assert(i == DIM);
119  }
120  template <typename... ArgList>
122  const int i,
123  const int res, const ArgList&... rest)
124  {
125  cycleUnsignedElement(i, res);
126  cycleUnsignedElements(i + 1, rest...);
127  }
128  void cycleUnsignedElement(const int i, const int res)
129  {
130  assert(i < DIM);
131 
132  e_[i] = e_[i] % res;
133  if (e_[i] < 0)
134  e_[i] += res;
135  }
136  void cycleUnsignedElements(const int i)
137  {
138  assert(i == DIM);
139  }
140 
141 public:
142  template <typename T2>
144  {
145  for (int i = 0; i < DIM; i++)
147  }
148  template <typename... ArgList>
149  explicit CyclicVecBase(const float& v, const ArgList&... args) noexcept
150  {
151  setElements(0, v, args...);
152  }
153  template <typename... ArgList>
154  explicit CyclicVecBase(const int& v, const ArgList&... args) noexcept
155  {
156  setElements(0, v, args...);
157  }
158  CyclicVecBase() noexcept
159  {
160  for (int i = 0; i < DIM; i++)
161  e_[i] = 0;
162  }
163  template <typename T2>
165  {
166  for (int i = 0; i < DIM; i++)
167  if (v.e_[i] != e_[i])
168  return false;
169  return true;
170  }
171  template <typename T2>
173  {
174  return !(*this == v);
175  }
176  template <typename T2>
178  {
180  for (int i = 0; i < DIM; i++)
181  {
182  out[i] += v[i];
183  }
184  return out;
185  }
186  template <typename T2>
188  {
190  for (int i = 0; i < DIM; i++)
191  {
192  out[i] -= v[i];
193  }
194  return out;
195  }
196  template <typename T2>
198  {
200  for (int i = 0; i < DIM; i++)
201  {
202  out[i] = e_[i] * v[i];
203  }
204  return out;
205  }
207  {
208  return (*this)[0] * a[1] - (*this)[1] * a[0];
209  }
211  {
212  return (*this)[0] * a[0] + (*this)[1] * a[1];
213  }
214  float distLine2d(
216  const CyclicVecBase<DIM, NONCYCLIC, T>& b) const
217  {
218  return (b - a).cross2d((*this) - a) / (b - a).len();
219  }
222  const CyclicVecBase<DIM, NONCYCLIC, T>& b) const
223  {
224  const auto to_a = (*this) - a;
225  if ((b - a).dot2d(to_a) <= 0)
226  return to_a.len();
227  const auto to_b = (*this) - b;
228  if ((a - b).dot2d(to_b) <= 0)
229  return to_b.len();
230  return std::abs(distLine2d(a, b));
231  }
232  T& operator[](const int& x)
233  {
234  return e_[x];
235  }
236  const T& operator[](const int& x) const
237  {
238  return e_[x];
239  }
240  T sqlen() const
241  {
242  T out = 0;
243  for (int i = 0; i < NONCYCLIC; i++)
244  {
245  out += e_[i] * e_[i];
246  }
247  return out;
248  }
249  float len() const
250  {
251  return std::sqrt(sqlen());
252  }
253  float gridToLenFactor() const
254  {
255  const auto l = len();
256  return l / static_cast<int>(l);
257  }
258  float norm() const
259  {
260  float out = 0;
261  for (int i = 0; i < DIM; i++)
262  {
263  out += std::pow(e_[i], 2);
264  }
265  return std::sqrt(out);
266  }
267 
268  void rotate(const float ang)
269  {
270  const auto tmp = *this;
271  const float cos_v = cosf(ang);
272  const float sin_v = sinf(ang);
273 
274  cyclic_vec_type_conversion_rule::convert(cos_v * tmp[0] - sin_v * tmp[1], e_[0]);
275  cyclic_vec_type_conversion_rule::convert(sin_v * tmp[0] + cos_v * tmp[1], e_[1]);
276  this->e_[2] = tmp[2] + ang;
278  }
279 
280  // Cyclic operations
281  template <typename... ArgList>
282  void cycle(const int res, const ArgList&... rest)
283  {
284  static_assert(
285  std::is_same<int, T>(), "cycle is provided only for int");
286  cycleElements(NONCYCLIC, res, rest...);
287  }
288  template <typename... ArgList>
289  void cycleUnsigned(const int res, const ArgList&... rest)
290  {
291  static_assert(
292  std::is_same<int, T>(), "cycle is provided only for int");
293  cycleUnsignedElements(NONCYCLIC, res, rest...);
294  }
296  {
297  static_assert(
298  std::is_same<int, T>(), "cycle is provided only for int");
299  for (int i = NONCYCLIC; i < DIM; ++i)
300  cycleElement(i, res[i]);
301  }
303  {
304  static_assert(
305  std::is_same<int, T>(), "cycle is provided only for int");
306  for (int i = NONCYCLIC; i < DIM; ++i)
307  cycleUnsignedElement(i, res[i]);
308  }
309 
310  // Hash
311  size_t operator()(const CyclicVecBase& key) const
312  {
313  size_t hash = static_cast<size_t>(key.e_[0]);
314  for (int i = 1; i < DIM; i++)
315  {
316  const size_t n = 8 * sizeof(std::size_t) * i / DIM;
317  const size_t x = static_cast<size_t>(key.e_[i]);
318  hash ^= (x << n) | (x >> ((8 * sizeof(size_t)) - n));
319  }
320  return hash;
321  }
322 
324  {
325  static_assert(
326  std::is_same<int, T>(), "isExceeded is provided only for T=int");
327  for (int i = 0; i < NONCYCLIC; ++i)
328  {
329  if (static_cast<unsigned int>((*this)[i]) >= static_cast<unsigned int>(v[i]))
330  return true;
331  }
332  return false;
333  }
334 };
335 
336 template <int DIM, int NONCYCLIC>
338 template <int DIM, int NONCYCLIC>
340 
341 } // namespace planner_cspace
342 
343 #endif // PLANNER_CSPACE_CYCLIC_VEC_H
void cycle(const int res, const ArgList &...rest)
Definition: cyclic_vec.h:282
const T & operator[](const int &x) const
Definition: cyclic_vec.h:236
CyclicVecBase(const int &v, const ArgList &...args) noexcept
Definition: cyclic_vec.h:154
void cycle(const CyclicVecBase< DIM, NONCYCLIC, T > &res)
Definition: cyclic_vec.h:295
void setElements(const int i, const T2 &first, const ArgList &...rest) noexcept
Definition: cyclic_vec.h:86
void cycleUnsigned(const int res, const ArgList &...rest)
Definition: cyclic_vec.h:289
float dot2d(const CyclicVecBase< DIM, NONCYCLIC, T > &a) const
Definition: cyclic_vec.h:210
size_t operator()(const CyclicVecBase &key) const
Definition: cyclic_vec.h:311
void cycleUnsigned(const CyclicVecBase< DIM, NONCYCLIC, T > &res)
Definition: cyclic_vec.h:302
void setElements(const int i) noexcept
Definition: cyclic_vec.h:93
CyclicVecBase(const float &v, const ArgList &...args) noexcept
Definition: cyclic_vec.h:149
void cycleUnsignedElements(const int i, const int res, const ArgList &...rest)
Definition: cyclic_vec.h:121
CyclicVecBase< DIM, NONCYCLIC, T2 > operator-(const CyclicVecBase< DIM, NONCYCLIC, T2 > &v) const
Definition: cyclic_vec.h:187
float cross2d(const CyclicVecBase< DIM, NONCYCLIC, T > &a) const
Definition: cyclic_vec.h:206
void cycleElement(const int i, const int res)
Definition: cyclic_vec.h:106
CyclicVecBase< DIM, NONCYCLIC, T2 > operator*(const CyclicVecBase< DIM, NONCYCLIC, T2 > &v) const
Definition: cyclic_vec.h:197
void rotate(const float ang)
Definition: cyclic_vec.h:268
float distLine2d(const CyclicVecBase< DIM, NONCYCLIC, T > &a, const CyclicVecBase< DIM, NONCYCLIC, T > &b) const
Definition: cyclic_vec.h:214
CyclicVecBase(const CyclicVecBase< DIM, NONCYCLIC, T2 > &c) noexcept
Definition: cyclic_vec.h:143
TFSIMD_FORCE_INLINE const tfScalar & x() const
void cycleUnsignedElements(const int i)
Definition: cyclic_vec.h:136
bool operator!=(const CyclicVecBase< DIM, NONCYCLIC, T2 > &v) const
Definition: cyclic_vec.h:172
bool isExceeded(const CyclicVecBase< DIM, NONCYCLIC, int > &v) const
Definition: cyclic_vec.h:323
void cycleElements(const int i, const int res, const ArgList &...rest)
Definition: cyclic_vec.h:99
void cycleUnsignedElement(const int i, const int res)
Definition: cyclic_vec.h:128
float gridToLenFactor() const
Definition: cyclic_vec.h:253
T & operator[](const int &x)
Definition: cyclic_vec.h:232
float distLinestrip2d(const CyclicVecBase< DIM, NONCYCLIC, T > &a, const CyclicVecBase< DIM, NONCYCLIC, T > &b) const
Definition: cyclic_vec.h:220
CyclicVecBase< DIM, NONCYCLIC, T2 > operator+(const CyclicVecBase< DIM, NONCYCLIC, T2 > &v) const
Definition: cyclic_vec.h:177
void convert(const T val, float &ret)
Definition: cyclic_vec.h:52
void cycleElements(const int i)
Definition: cyclic_vec.h:116
bool operator==(const CyclicVecBase< DIM, NONCYCLIC, T2 > &v) const
Definition: cyclic_vec.h:164


planner_cspace
Author(s): Atsushi Watanabe
autogenerated on Wed May 12 2021 02:20:42