NumCpp  2.1.0
A C++ implementation of the Python Numpy library
Quaternion.hpp
Go to the documentation of this file.
1 #pragma once
30 
33 #include "NumCpp/Core/Types.hpp"
36 #include "NumCpp/Functions/dot.hpp"
39 #include "NumCpp/Linalg/hat.hpp"
40 #include "NumCpp/NdArray.hpp"
42 #include "NumCpp/Utils/num2str.hpp"
43 #include "NumCpp/Utils/sqr.hpp"
44 #include "NumCpp/Vector/Vec3.hpp"
45 
46 #include <array>
47 #include <cmath>
48 #include <iostream>
49 #include <string>
50 
51 namespace nc
52 {
53  namespace rotations
54  {
55  //================================================================================
56  // Class Description:
58  class Quaternion
59  {
60  public:
61  //============================================================================
62  // Method Description:
65  Quaternion() = default;
66 
67  //============================================================================
68  // Method Description:
75  Quaternion(double roll, double pitch, double yaw) noexcept
76  {
77  eulerToQuat(roll, pitch, yaw);
78  }
79 
80  //============================================================================
81  // Method Description:
89  Quaternion(double inI, double inJ, double inK, double inS) noexcept :
90  components_{ inI, inJ, inK, inS }
91  {
92  normalize();
93  }
94 
95  //============================================================================
96  // Method Description:
103  Quaternion(const NdArray<double>& inArray) :
104  components_{ 0.0, 0.0, 0.0, 0.0 }
105  {
106  if (inArray.size() == 3)
107  {
108  // euler angles
109  eulerToQuat(inArray[0], inArray[1], inArray[2]);
110  }
111  else if (inArray.size() == 4)
112  {
113  // quaternion i, j, k, s components
114  stl_algorithms::copy(inArray.cbegin(), inArray.cend(), components_.begin());
115  normalize();
116  }
117  else if (inArray.size() == 9)
118  {
119  // direction cosine matrix
120  dcmToQuat(inArray);
121  }
122  else
123  {
124  THROW_INVALID_ARGUMENT_ERROR("input array is not a valid size.");
125  }
126  }
127 
128  //============================================================================
129  // Method Description:
135  Quaternion(const Vec3& inAxis, double inAngle) noexcept
136  {
137  // normalize the input vector
138  Vec3 normAxis = inAxis.normalize();
139 
140  const double halfAngle = inAngle / 2.0;
141  const double sinHalfAngle = std::sin(halfAngle);
142 
143  components_[0] = normAxis.x * sinHalfAngle;
144  components_[1] = normAxis.y * sinHalfAngle;
145  components_[2] = normAxis.z * sinHalfAngle;
146  components_[3] = std::cos(halfAngle);
147  }
148 
149  //============================================================================
150  // Method Description:
156  Quaternion(const NdArray<double>& inAxis, double inAngle) :
157  Quaternion(Vec3(inAxis), inAngle)
158  {}
159 
160  //============================================================================
161  // Method Description:
171  static NdArray<double> angularVelocity(const Quaternion& inQuat1, const Quaternion& inQuat2, double inTime)
172  {
173  NdArray<double> q0 = inQuat1.toNdArray();
174  NdArray<double> q1 = inQuat2.toNdArray();
175 
176  NdArray<double> qDot = q1 - q0;
177  qDot /= inTime;
178 
179  NdArray<double> eyeTimesScalar(3);
180  eyeTimesScalar.zeros();
181  eyeTimesScalar(0, 0) = inQuat2.s();
182  eyeTimesScalar(1, 1) = inQuat2.s();
183  eyeTimesScalar(2, 2) = inQuat2.s();
184 
185  NdArray<double> epsilonHat = linalg::hat<double>(inQuat2.i(), inQuat2.j(), inQuat2.k());
186  NdArray<double> q(4, 3);
187  q.put(Slice(0, 3), Slice(0, 3), eyeTimesScalar + epsilonHat);
188  q(3, 0) = -inQuat2.i();
189  q(3, 1) = -inQuat2.j();
190  q(3, 2) = -inQuat2.k();
191 
192  NdArray<double> omega = q.transpose().dot(qDot.transpose());
193  return omega *= 2.0;
194  }
195 
196  //============================================================================
197  // Method Description:
206  NdArray<double> angularVelocity(const Quaternion& inQuat2, double inTime) const
207  {
208  return angularVelocity(*this, inQuat2, inTime);
209  }
210 
211  //============================================================================
212  // Method Description:
218  Quaternion conjugate() const noexcept
219  {
220  return {-i(), -j(), -k(), s()};
221  }
222 
223  //============================================================================
224  // Method Description:
230  double i() const noexcept
231  {
232  return components_[0];
233  }
234 
235  //============================================================================
236  // Method Description:
242  static Quaternion identity() noexcept
243  {
244  return {};
245  }
246 
247  //============================================================================
248  // Method Description:
254  Quaternion inverse() const noexcept
255  {
257  return conjugate();
258  }
259 
260  //============================================================================
261  // Method Description:
267  double j() const noexcept
268  {
269  return components_[1];
270  }
271 
272  //============================================================================
273  // Method Description:
279  double k() const noexcept
280  {
281  return components_[2];
282  }
283 
284  //============================================================================
285  // Method Description:
294  static Quaternion nlerp(const Quaternion& inQuat1, const Quaternion& inQuat2, double inPercent)
295  {
296  if (inPercent < 0.0 || inPercent > 1.0)
297  {
298  THROW_INVALID_ARGUMENT_ERROR("input percent must be of the range [0,1].");
299  }
300 
301  if (utils::essentiallyEqual(inPercent, 0.0))
302  {
303  return inQuat1;
304  }
305  if (utils::essentiallyEqual(inPercent, 1.0))
306  {
307  return inQuat2;
308  }
309 
310  const double oneMinus = 1.0 - inPercent;
311  std::array<double, 4> newComponents{};
312 
313  stl_algorithms::transform(inQuat1.components_.begin(), inQuat1.components_.end(),
314  inQuat2.components_.begin(), newComponents.begin(),
315  [inPercent, oneMinus](double component1, double component2) -> double
316  {
317  return oneMinus * component1 + inPercent * component2;
318  });
319 
320  return {newComponents[0], newComponents[1], newComponents[2], newComponents[3]};
321  }
322 
323  //============================================================================
324  // Method Description:
332  Quaternion nlerp(const Quaternion& inQuat2, double inPercent) const
333  {
334  return nlerp(*this, inQuat2, inPercent);
335  }
336 
337  //============================================================================
338  // Method Description:
343  double pitch() const noexcept
344  {
345  return std::asin(2 * (s() * j() - k() * i()));
346  }
347 
348  //============================================================================
349  // Method Description:
352  void print() const
353  {
354  std::cout << *this;
355  }
356 
357  //============================================================================
358  // Method Description:
363  double roll() const noexcept
364  {
365  return std::atan2(2 * (s() * i() + j() * k()),
366  1 - 2 * (utils::sqr(i()) + utils::sqr(j())));
367  }
368 
369  //============================================================================
370  // Method Description:
378  NdArray<double> rotate(const NdArray<double>& inVector) const
379  {
380  if (inVector.size() != 3)
381  {
382  THROW_INVALID_ARGUMENT_ERROR("input inVector must be a cartesion vector of length = 3.");
383  }
384 
385  return *this * inVector;
386  }
387 
388  //============================================================================
389  // Method Description:
397  Vec3 rotate(const Vec3& inVec3) const
398  {
399  return *this * inVec3;
400  }
401 
402  //============================================================================
403  // Method Description:
409  double s() const noexcept
410  {
411  return components_[3];
412  }
413 
414  //============================================================================
415  // Method Description:
424  static Quaternion slerp(const Quaternion& inQuat1, const Quaternion& inQuat2, double inPercent)
425  {
426  if (inPercent < 0 || inPercent > 1)
427  {
428  THROW_INVALID_ARGUMENT_ERROR("input percent must be of the range [0, 1]");
429  }
430 
431  if (inPercent == 0)
432  {
433  return inQuat1;
434  }
435  if (inPercent == 1)
436  {
437  return inQuat2;
438  }
439 
440  double dotProduct = dot<double>(inQuat1.toNdArray(), inQuat2.toNdArray()).item();
441 
442  // If the dot product is negative, the quaternions
443  // have opposite handed-ness and slerp won't take
444  // the shorter path. Fix by reversing one quaternion.
445  Quaternion quat1Copy(inQuat1);
446  if (dotProduct < 0.0)
447  {
448  quat1Copy *= -1;
449  dotProduct *= -1;
450  }
451 
452  constexpr double DOT_THRESHOLD = 0.9995;
453  if (dotProduct > DOT_THRESHOLD) {
454  // If the inputs are too close for comfort, linearly interpolate
455  // and normalize the result.
456  return nlerp(inQuat1, inQuat2, inPercent);
457  }
458 
459  dotProduct = clip(dotProduct, -1.0, 1.0); // Robustness: Stay within domain of acos()
460  const double theta0 = std::acos(dotProduct); // angle between input vectors
461  const double theta = theta0 * inPercent; // angle between v0 and result
462 
463  const double s0 = std::cos(theta) - dotProduct * std::sin(theta) / std::sin(theta0); // == sin(theta_0 - theta) / sin(theta_0)
464  const double s1 = std::sin(theta) / std::sin(theta0);
465 
466  NdArray<double> interpQuat = (inQuat1.toNdArray() * s0) + (inQuat2.toNdArray() * s1);
467  return Quaternion(interpQuat);
468  }
469 
470  //============================================================================
471  // Method Description:
479  Quaternion slerp(const Quaternion& inQuat2, double inPercent) const
480  {
481  return slerp(*this, inQuat2, inPercent);
482  }
483 
484  //============================================================================
485  // Method Description:
491  std::string str() const
492  {
493  std::string output = "[" + utils::num2str(i()) + ", " + utils::num2str(j()) +
494  ", " + utils::num2str(k()) + ", " + utils::num2str(s()) + "]\n";
495 
496  return output;
497  }
498 
499  //============================================================================
500  // Method Description:
507  {
508  NdArray<double> dcm(3);
509 
510  const double q0 = i();
511  const double q1 = j();
512  const double q2 = k();
513  const double q3 = s();
514 
515  const double q0sqr = utils::sqr(q0);
516  const double q1sqr = utils::sqr(q1);
517  const double q2sqr = utils::sqr(q2);
518  const double q3sqr = utils::sqr(q3);
519 
520  dcm(0, 0) = q3sqr + q0sqr - q1sqr - q2sqr;
521  dcm(0, 1) = 2 * (q0 * q1 - q3 * q2);
522  dcm(0, 2) = 2 * (q0 * q2 + q3 * q1);
523  dcm(1, 0) = 2 * (q0 * q1 + q3 * q2);
524  dcm(1, 1) = q3sqr + q1sqr - q0sqr - q2sqr;
525  dcm(1, 2) = 2 * (q1 * q2 - q3 * q0);
526  dcm(2, 0) = 2 * (q0 * q2 - q3 * q1);
527  dcm(2, 1) = 2 * (q1 * q2 + q3 * q0);
528  dcm(2, 2) = q3sqr + q2sqr - q0sqr - q1sqr;
529 
530  return dcm;
531  }
532 
533  //============================================================================
534  // Method Description:
541  {
542  auto componentsCopy = components_;
543  return NdArray<double>(componentsCopy);
544  }
545 
546  //============================================================================
547  // Method Description:
555  static Quaternion xRotation(double inAngle) noexcept
556  {
557  const Vec3 eulerAxis = { 1.0, 0.0, 0.0 };
558  return Quaternion(eulerAxis, inAngle);
559  }
560 
561  //============================================================================
562  // Method Description:
567  double yaw() const noexcept
568  {
569  return std::atan2(2 * (s() * k() + i() * j()),
570  1 - 2 * (utils::sqr(j()) + utils::sqr(k())));
571  }
572 
573  //============================================================================
574  // Method Description:
582  static Quaternion yRotation(double inAngle) noexcept
583  {
584  const Vec3 eulerAxis = { 0.0, 1.0, 0.0 };
585  return Quaternion(eulerAxis, inAngle);
586  }
587 
588  //============================================================================
589  // Method Description:
597  static Quaternion zRotation(double inAngle) noexcept
598  {
599  const Vec3 eulerAxis = { 0.0, 0.0, 1.0 };
600  return Quaternion(eulerAxis, inAngle);
601  }
602 
603  //============================================================================
604  // Method Description:
612  bool operator==(const Quaternion& inRhs) const noexcept
613  {
614  const auto comparitor = [](double value1, double value2) noexcept -> bool
615  {
616  return utils::essentiallyEqual(value1, value2);
617  };
618 
619  return stl_algorithms::equal(components_.begin(), components_.end(),
620  inRhs.components_.begin(), comparitor);
621  }
622 
623  //============================================================================
624  // Method Description:
632  bool operator!=(const Quaternion& inRhs) const noexcept
633  {
634  return !(*this == inRhs);
635  }
636 
637  //============================================================================
638  // Method Description:
646  Quaternion& operator+=(const Quaternion& inRhs) noexcept
647  {
648  stl_algorithms::transform(components_.begin(), components_.end(),
649  inRhs.components_.begin(), components_.begin(), std::plus<double>());
650 
651  normalize();
652 
653  return *this;
654  }
655 
656  //============================================================================
657  // Method Description:
665  Quaternion operator+(const Quaternion& inRhs) const noexcept
666  {
667  return Quaternion(*this) += inRhs;
668  }
669 
670  //============================================================================
671  // Method Description:
679  Quaternion& operator-=(const Quaternion& inRhs) noexcept
680  {
681  stl_algorithms::transform(components_.begin(), components_.end(),
682  inRhs.components_.begin(), components_.begin(), std::minus<double>());
683 
684  normalize();
685 
686  return *this;
687  }
688 
689  //============================================================================
690  // Method Description:
698  Quaternion operator-(const Quaternion& inRhs) const noexcept
699  {
700  return Quaternion(*this) -= inRhs;
701  }
702 
703  //============================================================================
704  // Method Description:
710  Quaternion operator-() const noexcept
711  {
712  return Quaternion(*this) *= -1.0;
713  }
714 
715  //============================================================================
716  // Method Description:
724  Quaternion& operator*=(const Quaternion& inRhs) noexcept
725  {
726  double q0 = inRhs.s() * i();
727  q0 += inRhs.i() * s();
728  q0 -= inRhs.j() * k();
729  q0 += inRhs.k() * j();
730 
731  double q1 = inRhs.s() * j();
732  q1 += inRhs.i() * k();
733  q1 += inRhs.j() * s();
734  q1 -= inRhs.k() * i();
735 
736  double q2 = inRhs.s() * k();
737  q2 -= inRhs.i() * j();
738  q2 += inRhs.j() * i();
739  q2 += inRhs.k() * s();
740 
741  double q3 = inRhs.s() * s();
742  q3 -= inRhs.i() * i();
743  q3 -= inRhs.j() * j();
744  q3 -= inRhs.k() * k();
745 
746  components_[0] = q0;
747  components_[1] = q1;
748  components_[2] = q2;
749  components_[3] = q3;
750 
751  normalize();
752 
753  return *this;
754  }
755 
756  //============================================================================
757  // Method Description:
766  Quaternion& operator*=(double inScalar) noexcept
767  {
768  stl_algorithms::for_each(components_.begin(), components_.end(),
769  [&inScalar](double& component)
770  {
771  component *= inScalar;
772  });
773 
774  normalize();
775 
776  return *this;
777  }
778 
779  //============================================================================
780  // Method Description:
788  Quaternion operator*(const Quaternion& inRhs) const noexcept
789  {
790  return Quaternion(*this) *= inRhs;
791  }
792 
793  //============================================================================
794  // Method Description:
803  Quaternion operator*(double inScalar) const noexcept
804  {
805  return Quaternion(*this) *= inScalar;
806  }
807 
808  //============================================================================
809  // Method Description:
818  {
819  if (inVec.size() != 3)
820  {
821  THROW_INVALID_ARGUMENT_ERROR("input vector must be a cartesion vector of length = 3.");
822  }
823 
824  const auto p = Quaternion(inVec[0], inVec[1], inVec[2], 0.0);
825  const auto pPrime = *this * p * this->inverse();
826 
827  NdArray<double> rotatedVec = { pPrime.i(), pPrime.j(), pPrime.k() };
828  rotatedVec *= norm(inVec).item();
829  return rotatedVec;
830  }
831 
832  //============================================================================
833  // Method Description:
841  Vec3 operator*(const Vec3& inVec3) const
842  {
843  return *this * inVec3.toNdArray();
844  }
845 
846  //============================================================================
847  // Method Description:
855  Quaternion& operator/=(const Quaternion& inRhs) noexcept
856  {
857  return *this *= inRhs.conjugate();
858  }
859 
860  //============================================================================
861  // Method Description:
869  Quaternion operator/(const Quaternion& inRhs) const noexcept
870  {
871  return Quaternion(*this) /= inRhs;
872  }
873 
874  //============================================================================
875  // Method Description:
883  friend std::ostream& operator<<(std::ostream& inOStream, const Quaternion& inQuat)
884  {
885  inOStream << inQuat.str();
886  return inOStream;
887  }
888 
889  private:
890  //====================================Attributes==============================
891  std::array<double, 4> components_{ {0.0, 0.0, 0.0, 1.0} };
892 
893  //============================================================================
894  // Method Description:
897  void normalize() noexcept
898  {
899  double sumOfSquares = 0.0;
900  stl_algorithms::for_each(components_.begin(), components_.end(),
901  [&sumOfSquares](double component) noexcept -> void
902  {
903  sumOfSquares += utils::sqr(component);
904  });
905 
906  const double norm = std::sqrt(sumOfSquares);
907  stl_algorithms::for_each(components_.begin(), components_.end(),
908  [&norm](double& component) noexcept -> void
909  {
910  component /= norm;
911  });
912  }
913 
914  //============================================================================
915  // Method Description:
922  void eulerToQuat(double roll, double pitch, double yaw) noexcept
923  {
924  const double halfPhi = roll / 2.0;
925  const double halfTheta = pitch / 2.0;
926  const double halfPsi = yaw / 2.0;
927 
928  components_[0] = std::sin(halfPhi) * std::cos(halfTheta) * std::cos(halfPsi);
929  components_[0] -= std::cos(halfPhi) * std::sin(halfTheta) * std::sin(halfPsi);
930 
931  components_[1] = std::cos(halfPhi) * std::sin(halfTheta) * std::cos(halfPsi);
932  components_[1] += std::sin(halfPhi) * std::cos(halfTheta) * std::sin(halfPsi);
933 
934  components_[2] = std::cos(halfPhi) * std::cos(halfTheta) * std::sin(halfPsi);
935  components_[2] -= std::sin(halfPhi) * std::sin(halfTheta) * std::cos(halfPsi);
936 
937  components_[3] = std::cos(halfPhi) * std::cos(halfTheta) * std::cos(halfPsi);
938  components_[3] += std::sin(halfPhi) * std::sin(halfTheta) * std::sin(halfPsi);
939  }
940 
941  //============================================================================
942  // Method Description:
947  void dcmToQuat(const NdArray<double>& dcm)
948  {
949  const Shape inShape = dcm.shape();
950  if (!(inShape.rows == 3 && inShape.cols == 3))
951  {
952  THROW_INVALID_ARGUMENT_ERROR("input direction cosine matrix must have shape = (3,3).");
953  }
954 
955  NdArray<double> checks(1, 4);
956  checks[0] = 1 + dcm(0, 0) + dcm(1, 1) + dcm(2, 2);
957  checks[1] = 1 + dcm(0, 0) - dcm(1, 1) - dcm(2, 2);
958  checks[2] = 1 - dcm(0, 0) + dcm(1, 1) - dcm(2, 2);
959  checks[3] = 1 - dcm(0, 0) - dcm(1, 1) + dcm(2, 2);
960 
961  const uint32 maxIdx = argmax(checks).item();
962 
963  switch (maxIdx)
964  {
965  case 0:
966  {
967  components_[3] = 0.5 * std::sqrt(1 + dcm(0, 0) + dcm(1, 1) + dcm(2, 2));
968  components_[0] = (dcm(2, 1) - dcm(1, 2)) / (4 * components_[3]);
969  components_[1] = (dcm(0, 2) - dcm(2, 0)) / (4 * components_[3]);
970  components_[2] = (dcm(1, 0) - dcm(0, 1)) / (4 * components_[3]);
971 
972  break;
973  }
974  case 1:
975  {
976  components_[0] = 0.5 * std::sqrt(1 + dcm(0, 0) - dcm(1, 1) - dcm(2, 2));
977  components_[1] = (dcm(1, 0) + dcm(0, 1)) / (4 * components_[0]);
978  components_[2] = (dcm(2, 0) + dcm(0, 2)) / (4 * components_[0]);
979  components_[3] = (dcm(2, 1) - dcm(1, 2)) / (4 * components_[0]);
980 
981  break;
982  }
983  case 2:
984  {
985  components_[1] = 0.5 * std::sqrt(1 - dcm(0, 0) + dcm(1, 1) - dcm(2, 2));
986  components_[0] = (dcm(1, 0) + dcm(0, 1)) / (4 * components_[1]);
987  components_[2] = (dcm(2, 1) + dcm(1, 2)) / (4 * components_[1]);
988  components_[3] = (dcm(0, 2) - dcm(2, 0)) / (4 * components_[1]);
989 
990  break;
991  }
992  case 3:
993  {
994  components_[2] = 0.5 * std::sqrt(1 - dcm(0, 0) - dcm(1, 1) + dcm(2, 2));
995  components_[0] = (dcm(2, 0) + dcm(0, 2)) / (4 * components_[2]);
996  components_[1] = (dcm(2, 1) + dcm(1, 2)) / (4 * components_[2]);
997  components_[3] = (dcm(1, 0) - dcm(0, 1)) / (4 * components_[2]);
998 
999  break;
1000  }
1001  }
1002  }
1003  };
1004  } // namespace rotations
1005 } // namespace nc
nc::rotations::Quaternion::operator+=
Quaternion & operator+=(const Quaternion &inRhs) noexcept
Definition: Quaternion.hpp:646
nc::NdArray::item
value_type item() const
Definition: NdArrayCore.hpp:2958
nc::rotations::Quaternion::operator!=
bool operator!=(const Quaternion &inRhs) const noexcept
Definition: Quaternion.hpp:632
nc::rotations::Quaternion::Quaternion
Quaternion(double inI, double inJ, double inK, double inS) noexcept
Definition: Quaternion.hpp:89
nc::rotations::Quaternion::operator*
Vec3 operator*(const Vec3 &inVec3) const
Definition: Quaternion.hpp:841
nc::rotations::Quaternion::slerp
static Quaternion slerp(const Quaternion &inQuat1, const Quaternion &inQuat2, double inPercent)
Definition: Quaternion.hpp:424
nc::rotations::Quaternion
Holds a unit quaternion.
Definition: Quaternion.hpp:58
nc::Vec3::y
double y
Definition: Vec3.hpp:55
nc::rotations::Quaternion::operator-=
Quaternion & operator-=(const Quaternion &inRhs) noexcept
Definition: Quaternion.hpp:679
Error.hpp
nc::NdArray::dot
NdArray< dtype > dot(const NdArray< dtype > &inOtherArray) const
Definition: NdArrayCore.hpp:2644
nc::rotations::Quaternion::identity
static Quaternion identity() noexcept
Definition: Quaternion.hpp:242
nc::sqrt
auto sqrt(dtype inValue) noexcept
Definition: sqrt.hpp:51
nc::rotations::Quaternion::pitch
double pitch() const noexcept
Definition: Quaternion.hpp:343
nc::rotations::Quaternion::operator*=
Quaternion & operator*=(const Quaternion &inRhs) noexcept
Definition: Quaternion.hpp:724
nc::rotations::Quaternion::toDCM
NdArray< double > toDCM() const
Definition: Quaternion.hpp:506
nc::rotations::Quaternion::s
double s() const noexcept
Definition: Quaternion.hpp:409
square.hpp
nc::clip
dtype clip(dtype inValue, dtype inMinValue, dtype inMaxValue)
Definition: clip.hpp:51
nc::utils::essentiallyEqual
bool essentiallyEqual(dtype inValue1, dtype inValue2) noexcept
Definition: essentiallyEqual.hpp:53
clip.hpp
nc::rotations::Quaternion::nlerp
static Quaternion nlerp(const Quaternion &inQuat1, const Quaternion &inQuat2, double inPercent)
Definition: Quaternion.hpp:294
nc::utils::num2str
std::string num2str(dtype inNumber)
Definition: num2str.hpp:47
nc::rotations::Quaternion::yaw
double yaw() const noexcept
Definition: Quaternion.hpp:567
nc::rotations::Quaternion::operator/
Quaternion operator/(const Quaternion &inRhs) const noexcept
Definition: Quaternion.hpp:869
nc::rotations::Quaternion::inverse
Quaternion inverse() const noexcept
Definition: Quaternion.hpp:254
nc::rotations::Quaternion::xRotation
static Quaternion xRotation(double inAngle) noexcept
Definition: Quaternion.hpp:555
nc::Vec3::z
double z
Definition: Vec3.hpp:56
nc::rotations::Quaternion::roll
double roll() const noexcept
Definition: Quaternion.hpp:363
nc::NdArray::transpose
NdArray< dtype > transpose() const
Definition: NdArrayCore.hpp:4608
nc::NdArray< double >
nc::cos
auto cos(dtype inValue) noexcept
Definition: cos.hpp:52
nc::stl_algorithms::transform
OutputIt transform(InputIt first, InputIt last, OutputIt destination, UnaryOperation unaryFunction)
Definition: StlAlgorithms.hpp:703
nc::stl_algorithms::for_each
void for_each(InputIt first, InputIt last, UnaryFunction f)
Definition: StlAlgorithms.hpp:214
nc::uint32
std::uint32_t uint32
Definition: Types.hpp:41
nc::rotations::Quaternion::zRotation
static Quaternion zRotation(double inAngle) noexcept
Definition: Quaternion.hpp:597
nc::rotations::Quaternion::operator-
Quaternion operator-(const Quaternion &inRhs) const noexcept
Definition: Quaternion.hpp:698
NdArray.hpp
num2str.hpp
dot.hpp
Vec3.hpp
nc::rotations::Quaternion::operator*
Quaternion operator*(const Quaternion &inRhs) const noexcept
Definition: Quaternion.hpp:788
nc::NdArray::put
NdArray< dtype > & put(int32 inIndex, value_type inValue)
Definition: NdArrayCore.hpp:3685
nc::rotations::Quaternion::Quaternion
Quaternion(const NdArray< double > &inArray)
Definition: Quaternion.hpp:103
nc::rotations::Quaternion::toNdArray
NdArray< double > toNdArray() const
Definition: Quaternion.hpp:540
nc::stl_algorithms::copy
OutputIt copy(InputIt first, InputIt last, OutputIt destination) noexcept
Definition: StlAlgorithms.hpp:96
nc::NdArray::size
size_type size() const noexcept
Definition: NdArrayCore.hpp:4326
nc::rotations::Quaternion::angularVelocity
NdArray< double > angularVelocity(const Quaternion &inQuat2, double inTime) const
Definition: Quaternion.hpp:206
nc::rotations::Quaternion::operator==
bool operator==(const Quaternion &inRhs) const noexcept
Definition: Quaternion.hpp:612
nc::rotations::Quaternion::print
void print() const
Definition: Quaternion.hpp:352
nc::rotations::Quaternion::rotate
Vec3 rotate(const Vec3 &inVec3) const
Definition: Quaternion.hpp:397
nc::sin
auto sin(dtype inValue) noexcept
Definition: sin.hpp:52
nc::NdArray::zeros
NdArray< dtype > & zeros() noexcept
Definition: NdArrayCore.hpp:4626
nc::rotations::Quaternion::k
double k() const noexcept
Definition: Quaternion.hpp:279
hat.hpp
nc::rotations::Quaternion::yRotation
static Quaternion yRotation(double inAngle) noexcept
Definition: Quaternion.hpp:582
nc
Definition: Coordinate.hpp:45
nc::rotations::Quaternion::operator<<
friend std::ostream & operator<<(std::ostream &inOStream, const Quaternion &inQuat)
Definition: Quaternion.hpp:883
nc::rotations::Quaternion::Quaternion
Quaternion()=default
nc::rotations::Quaternion::j
double j() const noexcept
Definition: Quaternion.hpp:267
nc::rotations::Quaternion::Quaternion
Quaternion(const Vec3 &inAxis, double inAngle) noexcept
Definition: Quaternion.hpp:135
nc::rotations::Quaternion::operator*=
Quaternion & operator*=(double inScalar) noexcept
Definition: Quaternion.hpp:766
sqr.hpp
nc::rotations::Quaternion::operator*
Quaternion operator*(double inScalar) const noexcept
Definition: Quaternion.hpp:803
nc::rotations::Quaternion::rotate
NdArray< double > rotate(const NdArray< double > &inVector) const
Definition: Quaternion.hpp:378
essentiallyEqual.hpp
argmax.hpp
nc::Vec3::toNdArray
NdArray< double > toNdArray() const
Definition: Vec3.hpp:324
nc::rotations::Quaternion::str
std::string str() const
Definition: Quaternion.hpp:491
THROW_INVALID_ARGUMENT_ERROR
#define THROW_INVALID_ARGUMENT_ERROR(msg)
Definition: Error.hpp:37
nc::Vec3::x
double x
Definition: Vec3.hpp:54
nc::rotations::Quaternion::i
double i() const noexcept
Definition: Quaternion.hpp:230
nc::rotations::Quaternion::operator+
Quaternion operator+(const Quaternion &inRhs) const noexcept
Definition: Quaternion.hpp:665
nc::utils::sqr
constexpr dtype sqr(dtype inValue) noexcept
Definition: sqr.hpp:45
StlAlgorithms.hpp
nc::rotations::Quaternion::slerp
Quaternion slerp(const Quaternion &inQuat2, double inPercent) const
Definition: Quaternion.hpp:479
nc::rotations::Quaternion::Quaternion
Quaternion(double roll, double pitch, double yaw) noexcept
Definition: Quaternion.hpp:75
nc::stl_algorithms::equal
bool equal(InputIt1 first1, InputIt1 last1, InputIt2 first2) noexcept
Definition: StlAlgorithms.hpp:136
nc::rotations::Quaternion::conjugate
Quaternion conjugate() const noexcept
Definition: Quaternion.hpp:218
Types.hpp
nc::Slice
A Class for slicing into NdArrays.
Definition: Slice.hpp:44
nc::Vec3
Holds a 3D vector.
Definition: Vec3.hpp:50
nc::Vec3::normalize
Vec3 normalize() const noexcept
Definition: Vec3.hpp:276
nc::rotations::Quaternion::operator/=
Quaternion & operator/=(const Quaternion &inRhs) noexcept
Definition: Quaternion.hpp:855
norm.hpp
nc::norm
NdArray< double > norm(const NdArray< dtype > &inArray, Axis inAxis=Axis::NONE)
Definition: norm.hpp:53
nc::argmax
NdArray< uint32 > argmax(const NdArray< dtype > &inArray, Axis inAxis=Axis::NONE)
Definition: argmax.hpp:48
nc::rotations::Quaternion::Quaternion
Quaternion(const NdArray< double > &inAxis, double inAngle)
Definition: Quaternion.hpp:156
nc::rotations::Quaternion::angularVelocity
static NdArray< double > angularVelocity(const Quaternion &inQuat1, const Quaternion &inQuat2, double inTime)
Definition: Quaternion.hpp:171
nc::rotations::Quaternion::operator-
Quaternion operator-() const noexcept
Definition: Quaternion.hpp:710
nc::rotations::Quaternion::operator*
NdArray< double > operator*(const NdArray< double > &inVec) const
Definition: Quaternion.hpp:817
nc::rotations::Quaternion::nlerp
Quaternion nlerp(const Quaternion &inQuat2, double inPercent) const
Definition: Quaternion.hpp:332