Gazebo Math

API Reference

7.5.1
gz/math/Vector3.hh
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2014 Open Source Robotics Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16 */
17 #ifndef GZ_MATH_VECTOR3_HH_
18 #define GZ_MATH_VECTOR3_HH_
19 
20 #include <algorithm>
21 #include <cmath>
22 #include <istream>
23 #include <limits>
24 #include <ostream>
25 
26 #include <gz/math/Helpers.hh>
27 #include <gz/math/config.hh>
28 
29 namespace gz::math
30 {
31  // Inline bracket to help doxygen filtering.
32  inline namespace GZ_MATH_VERSION_NAMESPACE {
33  //
38  template<typename T>
39  class Vector3
40  {
42  public: static const Vector3 &Zero;
43 
45  public: static const Vector3 &One;
46 
48  public: static const Vector3 &UnitX;
49 
51  public: static const Vector3 &UnitY;
52 
54  public: static const Vector3 &UnitZ;
55 
57  public: static const Vector3 &NaN;
58 
60  public: constexpr Vector3()
61  : data{0, 0, 0}
62  {
63  }
64 
69  public: constexpr Vector3(const T &_x, const T &_y, const T &_z)
70  : data{_x, _y, _z}
71  {
72  }
73 
76  public: Vector3(const Vector3<T> &_v) = default;
77 
79  public: ~Vector3() = default;
80 
83  public: T Sum() const
84  {
85  return this->data[0] + this->data[1] + this->data[2];
86  }
87 
91  public: T Distance(const Vector3<T> &_pt) const
92  {
93  return static_cast<T>(sqrt(
94  (this->data[0]-_pt[0])*(this->data[0]-_pt[0]) +
95  (this->data[1]-_pt[1])*(this->data[1]-_pt[1]) +
96  (this->data[2]-_pt[2])*(this->data[2]-_pt[2])));
97  }
98 
104  public: T Distance(T _x, T _y, T _z) const
105  {
106  return this->Distance(Vector3(_x, _y, _z));
107  }
108 
111  public: T Length() const
112  {
113  return static_cast<T>(sqrt(this->SquaredLength()));
114  }
115 
118  public: T SquaredLength() const
119  {
120  return
121  this->data[0] * this->data[0] +
122  this->data[1] * this->data[1] +
123  this->data[2] * this->data[2];
124  }
125 
128  public: Vector3 Normalize()
129  {
130  T d = this->Length();
131 
132  if (!equal<T>(d, static_cast<T>(0.0)))
133  {
134  this->data[0] /= d;
135  this->data[1] /= d;
136  this->data[2] /= d;
137  }
138 
139  return *this;
140  }
141 
144  public: Vector3 Normalized() const
145  {
146  Vector3<T> result = *this;
147  result.Normalize();
148  return result;
149  }
150 
153  public: Vector3 Round()
154  {
155  this->data[0] = static_cast<T>(std::nearbyint(this->data[0]));
156  this->data[1] = static_cast<T>(std::nearbyint(this->data[1]));
157  this->data[2] = static_cast<T>(std::nearbyint(this->data[2]));
158  return *this;
159  }
160 
163  public: Vector3 Rounded() const
164  {
165  Vector3<T> result = *this;
166  result.Round();
167  return result;
168  }
169 
174  public: inline void Set(T _x = 0, T _y = 0, T _z = 0)
175  {
176  this->data[0] = _x;
177  this->data[1] = _y;
178  this->data[2] = _z;
179  }
180 
184  public: Vector3 Cross(const Vector3<T> &_v) const
185  {
186  return Vector3(this->data[1] * _v[2] - this->data[2] * _v[1],
187  this->data[2] * _v[0] - this->data[0] * _v[2],
188  this->data[0] * _v[1] - this->data[1] * _v[0]);
189  }
190 
194  public: T Dot(const Vector3<T> &_v) const
195  {
196  return this->data[0] * _v[0] +
197  this->data[1] * _v[1] +
198  this->data[2] * _v[2];
199  }
200 
209  public: T AbsDot(const Vector3<T> &_v) const
210  {
211  return std::abs(this->data[0] * _v[0]) +
212  std::abs(this->data[1] * _v[1]) +
213  std::abs(this->data[2] * _v[2]);
214  }
215 
218  public: Vector3 Abs() const
219  {
220  return Vector3(std::abs(this->data[0]),
221  std::abs(this->data[1]),
222  std::abs(this->data[2]));
223  }
224 
227  public: Vector3 Perpendicular() const
228  {
229  static const T sqrZero = static_cast<T>(1e-06 * 1e-06);
230 
231  Vector3<T> perp = this->Cross(Vector3(1, 0, 0));
232 
233  // Check the length of the vector
234  if (perp.SquaredLength() < sqrZero)
235  {
236  perp = this->Cross(Vector3(0, 1, 0));
237  }
238 
239  return perp;
240  }
241 
247  public: static Vector3 Normal(const Vector3<T> &_v1,
248  const Vector3<T> &_v2, const Vector3<T> &_v3)
249  {
250  Vector3<T> a = _v2 - _v1;
251  Vector3<T> b = _v3 - _v1;
252  Vector3<T> n = a.Cross(b);
253  return n.Normalize();
254  }
255 
260  public: T DistToLine(const Vector3<T> &_pt1, const Vector3 &_pt2)
261  {
262  T d = ((*this) - _pt1).Cross((*this) - _pt2).Length();
263  d = d / (_pt2 - _pt1).Length();
264  return d;
265  }
266 
270  public: void Max(const Vector3<T> &_v)
271  {
272  if (_v[0] > this->data[0])
273  this->data[0] = _v[0];
274  if (_v[1] > this->data[1])
275  this->data[1] = _v[1];
276  if (_v[2] > this->data[2])
277  this->data[2] = _v[2];
278  }
279 
283  public: void Min(const Vector3<T> &_v)
284  {
285  if (_v[0] < this->data[0])
286  this->data[0] = _v[0];
287  if (_v[1] < this->data[1])
288  this->data[1] = _v[1];
289  if (_v[2] < this->data[2])
290  this->data[2] = _v[2];
291  }
292 
295  public: T Max() const
296  {
297  return std::max(std::max(this->data[0], this->data[1]), this->data[2]);
298  }
299 
302  public: T Min() const
303  {
304  return std::min(std::min(this->data[0], this->data[1]), this->data[2]);
305  }
306 
309  public: T MaxAbs() const
310  {
311  T max = std::max(std::abs(this->data[0]), std::abs(this->data[1]));
312  max = std::max(max, std::abs(this->data[2]));
313  return max;
314  }
315 
318  public: T MinAbs() const
319  {
320  T min = std::min(std::abs(this->data[0]), std::abs(this->data[1]));
321  min = std::min(min, std::abs(this->data[2]));
322  return min;
323  }
324 
328  public: Vector3 &operator=(const Vector3<T> &_v) = default;
329 
333  public: Vector3 &operator=(T _v)
334  {
335  this->data[0] = _v;
336  this->data[1] = _v;
337  this->data[2] = _v;
338 
339  return *this;
340  }
341 
345  public: Vector3 operator+(const Vector3<T> &_v) const
346  {
347  return Vector3(this->data[0] + _v[0],
348  this->data[1] + _v[1],
349  this->data[2] + _v[2]);
350  }
351 
355  public: const Vector3 &operator+=(const Vector3<T> &_v)
356  {
357  this->data[0] += _v[0];
358  this->data[1] += _v[1];
359  this->data[2] += _v[2];
360 
361  return *this;
362  }
363 
367  public: inline Vector3<T> operator+(const T _s) const
368  {
369  return Vector3<T>(this->data[0] + _s,
370  this->data[1] + _s,
371  this->data[2] + _s);
372  }
373 
378  public: friend inline Vector3<T> operator+(const T _s,
379  const Vector3<T> &_v)
380  {
381  return {_v.X() + _s, _v.Y() + _s, _v.Z() + _s};
382  }
383 
387  public: const Vector3<T> &operator+=(const T _s)
388  {
389  this->data[0] += _s;
390  this->data[1] += _s;
391  this->data[2] += _s;
392 
393  return *this;
394  }
395 
398  public: inline Vector3 operator-() const
399  {
400  return Vector3(-this->data[0], -this->data[1], -this->data[2]);
401  }
402 
406  public: inline Vector3<T> operator-(const Vector3<T> &_pt) const
407  {
408  return Vector3(this->data[0] - _pt[0],
409  this->data[1] - _pt[1],
410  this->data[2] - _pt[2]);
411  }
412 
416  public: const Vector3<T> &operator-=(const Vector3<T> &_pt)
417  {
418  this->data[0] -= _pt[0];
419  this->data[1] -= _pt[1];
420  this->data[2] -= _pt[2];
421 
422  return *this;
423  }
424 
428  public: inline Vector3<T> operator-(const T _s) const
429  {
430  return Vector3<T>(this->data[0] - _s,
431  this->data[1] - _s,
432  this->data[2] - _s);
433  }
434 
439  public: friend inline Vector3<T> operator-(const T _s,
440  const Vector3<T> &_v)
441  {
442  return {_s - _v.X(), _s - _v.Y(), _s - _v.Z()};
443  }
444 
448  public: const Vector3<T> &operator-=(const T _s)
449  {
450  this->data[0] -= _s;
451  this->data[1] -= _s;
452  this->data[2] -= _s;
453 
454  return *this;
455  }
456 
461  public: const Vector3<T> operator/(const Vector3<T> &_pt) const
462  {
463  return Vector3(this->data[0] / _pt[0],
464  this->data[1] / _pt[1],
465  this->data[2] / _pt[2]);
466  }
467 
472  public: const Vector3<T> &operator/=(const Vector3<T> &_pt)
473  {
474  this->data[0] /= _pt[0];
475  this->data[1] /= _pt[1];
476  this->data[2] /= _pt[2];
477 
478  return *this;
479  }
480 
485  public: const Vector3<T> operator/(T _v) const
486  {
487  return Vector3(this->data[0] / _v,
488  this->data[1] / _v,
489  this->data[2] / _v);
490  }
491 
496  public: const Vector3<T> &operator/=(T _v)
497  {
498  this->data[0] /= _v;
499  this->data[1] /= _v;
500  this->data[2] /= _v;
501 
502  return *this;
503  }
504 
509  public: Vector3<T> operator*(const Vector3<T> &_p) const
510  {
511  return Vector3(this->data[0] * _p[0],
512  this->data[1] * _p[1],
513  this->data[2] * _p[2]);
514  }
515 
520  public: const Vector3<T> &operator*=(const Vector3<T> &_v)
521  {
522  this->data[0] *= _v[0];
523  this->data[1] *= _v[1];
524  this->data[2] *= _v[2];
525 
526  return *this;
527  }
528 
532  public: inline Vector3<T> operator*(T _s) const
533  {
534  return Vector3<T>(this->data[0] * _s,
535  this->data[1] * _s,
536  this->data[2] * _s);
537  }
538 
543  public: friend inline Vector3<T> operator*(T _s, const Vector3<T> &_v)
544  {
545  return {_v.X() * _s, _v.Y() * _s, _v.Z() * _s};
546  }
547 
551  public: const Vector3<T> &operator*=(T _v)
552  {
553  this->data[0] *= _v;
554  this->data[1] *= _v;
555  this->data[2] *= _v;
556 
557  return *this;
558  }
559 
565  public: bool Equal(const Vector3 &_v, const T &_tol) const
566  {
567  return equal<T>(this->data[0], _v[0], _tol)
568  && equal<T>(this->data[1], _v[1], _tol)
569  && equal<T>(this->data[2], _v[2], _tol);
570  }
571 
576  public: bool operator==(const Vector3<T> &_v) const
577  {
578  return this->Equal(_v, static_cast<T>(1e-3));
579  }
580 
585  public: bool operator!=(const Vector3<T> &_v) const
586  {
587  return !(*this == _v);
588  }
589 
592  public: bool IsFinite() const
593  {
594  // std::isfinite works with floating point values,
595  // need to explicit cast to avoid ambiguity in vc++.
596  return std::isfinite(static_cast<double>(this->data[0])) &&
597  std::isfinite(static_cast<double>(this->data[1])) &&
598  std::isfinite(static_cast<double>(this->data[2]));
599  }
600 
602  public: inline void Correct()
603  {
604  // std::isfinite works with floating point values,
605  // need to explicit cast to avoid ambiguity in vc++.
606  if (!std::isfinite(static_cast<double>(this->data[0])))
607  this->data[0] = 0;
608  if (!std::isfinite(static_cast<double>(this->data[1])))
609  this->data[1] = 0;
610  if (!std::isfinite(static_cast<double>(this->data[2])))
611  this->data[2] = 0;
612  }
613 
618  public: T &operator[](const std::size_t _index)
619  {
620  return this->data[clamp(_index, GZ_ZERO_SIZE_T, GZ_TWO_SIZE_T)];
621  }
622 
627  public: T operator[](const std::size_t _index) const
628  {
629  return this->data[clamp(_index, GZ_ZERO_SIZE_T, GZ_TWO_SIZE_T)];
630  }
631 
634  public: void Round(int _precision)
635  {
636  this->data[0] = precision(this->data[0], _precision);
637  this->data[1] = precision(this->data[1], _precision);
638  this->data[2] = precision(this->data[2], _precision);
639  }
640 
645  public: bool Equal(const Vector3<T> &_v) const
646  {
647  return equal<T>(this->data[0], _v[0]) &&
648  equal<T>(this->data[1], _v[1]) &&
649  equal<T>(this->data[2], _v[2]);
650  }
651 
654  public: inline T X() const
655  {
656  return this->data[0];
657  }
658 
661  public: inline T Y() const
662  {
663  return this->data[1];
664  }
665 
668  public: inline T Z() const
669  {
670  return this->data[2];
671  }
672 
675  public: inline T &X()
676  {
677  return this->data[0];
678  }
679 
682  public: inline T &Y()
683  {
684  return this->data[1];
685  }
686 
689  public: inline T &Z()
690  {
691  return this->data[2];
692  }
693 
696  public: inline void X(const T &_v)
697  {
698  this->data[0] = _v;
699  }
700 
703  public: inline void Y(const T &_v)
704  {
705  this->data[1] = _v;
706  }
707 
710  public: inline void Z(const T &_v)
711  {
712  this->data[2] = _v;
713  }
714 
719  public: bool operator<(const Vector3<T> &_pt) const
720  {
721  return this->data[0] < _pt[0] || this->data[1] < _pt[1] ||
722  this->data[2] < _pt[2];
723  }
724 
729  public: friend std::ostream &operator<<(
730  std::ostream &_out, const gz::math::Vector3<T> &_pt)
731  {
732  for (auto i : {0, 1, 2})
733  {
734  if (i > 0)
735  _out << " ";
736 
737  appendToStream(_out, _pt[i]);
738  }
739 
740  return _out;
741  }
742 
747  public: friend std::istream &operator>>(
749  {
750  // Skip white spaces
751  _in.setf(std::ios_base::skipws);
752  T x, y, z;
753  _in >> x >> y >> z;
754  if (!_in.fail())
755  {
756  _pt.Set(x, y, z);
757  }
758  return _in;
759  }
760 
762  private: T data[3];
763  };
764 
765  namespace detail {
766 
767  template<typename T>
768  constexpr Vector3<T> gVector3Zero(0, 0, 0);
769  template<typename T>
770  constexpr Vector3<T> gVector3One(1, 1, 1);
771  template<typename T>
772  constexpr Vector3<T> gVector3UnitX(1, 0, 0);
773  template<typename T>
774  constexpr Vector3<T> gVector3UnitY(0, 1, 0);
775  template<typename T>
776  constexpr Vector3<T> gVector3UnitZ(0, 0, 1);
777  template<typename T>
778  constexpr Vector3<T> gVector3NaN(
782  } // namespace detail
783 
784  template<typename T>
785  const Vector3<T> &Vector3<T>::Zero = detail::gVector3Zero<T>;
786  template<typename T>
787  const Vector3<T> &Vector3<T>::One = detail::gVector3One<T>;
788  template<typename T>
789  const Vector3<T> &Vector3<T>::UnitX = detail::gVector3UnitX<T>;
790  template<typename T>
791  const Vector3<T> &Vector3<T>::UnitY = detail::gVector3UnitY<T>;
792  template<typename T>
793  const Vector3<T> &Vector3<T>::UnitZ = detail::gVector3UnitZ<T>;
794  template<typename T>
795  const Vector3<T> &Vector3<T>::NaN = detail::gVector3NaN<T>;
796 
800  } // namespace GZ_MATH_VERSION_NAMESPACE
801 } // namespace gz::math
802 #endif // GZ_MATH_VECTOR3_HH_