86 Quaternion(
double inI,
double inJ,
double inK,
double inS) noexcept :
87 components_{ inI, inJ, inK, inS }
98 Quaternion(
const std::array<double, 4>& components) noexcept :
99 components_{ components }
113 components_{ 0., 0., 0., 0. }
115 if (inArray.
size() == 3)
118 eulerToQuat(inArray[0], inArray[1], inArray[2]);
120 else if (inArray.
size() == 4)
126 else if (inArray.
size() == 9)
149 const double halfAngle = inAngle / 2.;
150 const double sinHalfAngle =
std::sin(halfAngle);
152 components_[0] = normAxis.
x * sinHalfAngle;
153 components_[1] = normAxis.
y * sinHalfAngle;
154 components_[2] = normAxis.
z * sinHalfAngle;
155 components_[3] =
std::cos(halfAngle);
178 return 2. * std::acos(
s());
200 eyeTimesScalar.
zeros();
201 eyeTimesScalar(0, 0) = inQuat2.
s();
202 eyeTimesScalar(1, 1) = inQuat2.
s();
203 eyeTimesScalar(2, 2) = inQuat2.
s();
205 NdArray<double> epsilonHat = linalg::hat<double>(inQuat2.
i(), inQuat2.
j(), inQuat2.
k());
207 q.
put(
Slice(0, 3),
Slice(0, 3), eyeTimesScalar + epsilonHat);
208 q(3, 0) = -inQuat2.
i();
209 q(3, 1) = -inQuat2.
j();
210 q(3, 2) = -inQuat2.
k();
239 const auto sinHalfAngle =
std::sin(halfAngle);
240 auto axis =
Vec3(
i() / sinHalfAngle,
j() / sinHalfAngle,
k() / sinHalfAngle);
243 return axis.normalize();
254 return { -
i(), -
j(), -
k(),
s() };
263 [[nodiscard]]
double i() const noexcept
265 return components_[0];
297 [[nodiscard]]
double j() const noexcept
299 return components_[1];
308 [[nodiscard]]
double k() const noexcept
310 return components_[2];
324 if (inPercent < 0. || inPercent > 1.)
338 const double oneMinus = 1. - inPercent;
339 std::array<double, 4> newComponents{};
342 inQuat1.components_.end(),
343 inQuat2.components_.begin(),
344 newComponents.begin(),
345 [inPercent, oneMinus](
double component1,
double component2) ->
double
346 { return oneMinus * component1 + inPercent * component2; });
348 return { newComponents };
361 return nlerp(*
this, inQuat2, inPercent);
370 [[nodiscard]]
double pitch() const noexcept
372 return std::asin(2 * (
s() *
j() -
k() *
i()));
384 return { 0., inAngle, 0. };
402 [[nodiscard]]
double roll() const noexcept
416 return { inAngle, 0., 0. };
428 if (inVector.
size() != 3)
433 return *
this * inVector;
445 return *
this * inVec3;
454 [[nodiscard]]
double s() const noexcept
456 return components_[3];
470 if (inPercent < 0 || inPercent > 1)
496 constexpr double DOT_THRESHOLD = 0.9995;
497 if (dotProduct > DOT_THRESHOLD)
501 return nlerp(inQuat1, inQuat2, inPercent);
504 dotProduct =
clip(dotProduct, -1., 1.);
505 const double theta0 = std::acos(dotProduct);
506 const double theta = theta0 * inPercent;
526 return slerp(*
this, inQuat2, inPercent);
535 [[nodiscard]] std::string
str()
const
553 const double q0 =
i();
554 const double q1 =
j();
555 const double q2 =
k();
556 const double q3 =
s();
563 dcm(0, 0) = q3sqr + q0sqr - q1sqr - q2sqr;
564 dcm(0, 1) = 2. * (q0 * q1 - q3 * q2);
565 dcm(0, 2) = 2. * (q0 * q2 + q3 * q1);
566 dcm(1, 0) = 2. * (q0 * q1 + q3 * q2);
567 dcm(1, 1) = q3sqr + q1sqr - q0sqr - q2sqr;
568 dcm(1, 2) = 2. * (q1 * q2 - q3 * q0);
569 dcm(2, 0) = 2. * (q0 * q2 - q3 * q1);
570 dcm(2, 1) = 2. * (q1 * q2 + q3 * q0);
571 dcm(2, 2) = q3sqr + q2sqr - q0sqr - q1sqr;
584 auto componentsCopy = components_;
597 const Vec3 eulerAxis = { 1., 0., 0. };
607 [[nodiscard]]
double yaw() const noexcept
621 return { 0., 0., inAngle };
633 const Vec3 eulerAxis = { 0., 1., 0. };
646 const Vec3 eulerAxis = { 0., 0., 1. };
659 const auto comparitor = [](
double value1,
double value2)
noexcept ->
bool
662 return stl_algorithms::equal(components_.begin(), components_.end(), inRhs.components_.begin(), comparitor);
674 return !(*
this == inRhs);
688 inRhs.components_.begin(),
690 std::plus<double>());
720 inRhs.components_.begin(),
722 std::minus<double>());
761 double q0 = inRhs.
s() *
i();
762 q0 += inRhs.i() *
s();
763 q0 -= inRhs.j() *
k();
764 q0 += inRhs.k() *
j();
766 double q1 = inRhs.s() *
j();
767 q1 += inRhs.i() *
k();
768 q1 += inRhs.j() *
s();
769 q1 -= inRhs.k() *
i();
771 double q2 = inRhs.s() *
k();
772 q2 -= inRhs.i() *
j();
773 q2 += inRhs.j() *
i();
774 q2 += inRhs.k() *
s();
776 double q3 = inRhs.s() *
s();
777 q3 -= inRhs.i() *
i();
778 q3 -= inRhs.j() *
j();
779 q3 -= inRhs.k() *
k();
803 [inScalar](
double& component) { component *= inScalar; });
844 if (inVec.
size() != 3)
849 const auto vecNorm =
norm(inVec).
item();
855 const auto p =
Quaternion(inVec[0], inVec[1], inVec[2], 0.);
856 const auto pPrime = *
this * p * this->
inverse();
859 rotatedVec *= vecNorm;
909 inOStream << inQuat.
str();
915 std::array<double, 4> components_{ { 0., 0., 0., 1. } };
921 void normalize() noexcept
923 double sumOfSquares = 0.;
926 [&sumOfSquares](
double component) noexcept ->
void
927 { sumOfSquares += utils::sqr(component); });
932 [
norm](
double& component) noexcept ->
void { component /= norm; });
943 void eulerToQuat(
double roll,
double pitch,
double yaw)
noexcept
945 const auto halfPhi =
roll / 2.;
946 const auto halfTheta =
pitch / 2.;
947 const auto halfPsi =
yaw / 2.;
949 const auto sinHalfPhi =
std::sin(halfPhi);
950 const auto cosHalfPhi =
std::cos(halfPhi);
952 const auto sinHalfTheta =
std::sin(halfTheta);
953 const auto cosHalfTheta =
std::cos(halfTheta);
955 const auto sinHalfPsi =
std::sin(halfPsi);
956 const auto cosHalfPsi =
std::cos(halfPsi);
958 components_[0] = sinHalfPhi * cosHalfTheta * cosHalfPsi;
959 components_[0] -= cosHalfPhi * sinHalfTheta * sinHalfPsi;
961 components_[1] = cosHalfPhi * sinHalfTheta * cosHalfPsi;
962 components_[1] += sinHalfPhi * cosHalfTheta * sinHalfPsi;
964 components_[2] = cosHalfPhi * cosHalfTheta * sinHalfPsi;
965 components_[2] -= sinHalfPhi * sinHalfTheta * cosHalfPsi;
967 components_[3] = cosHalfPhi * cosHalfTheta * cosHalfPsi;
968 components_[3] += sinHalfPhi * sinHalfTheta * sinHalfPsi;
977 void dcmToQuat(
const NdArray<double>& dcm)
979 const Shape inShape = dcm.shape();
980 if (!(inShape.rows == 3 && inShape.cols == 3))
985 NdArray<double> checks(1, 4);
986 checks[0] = 1 + dcm(0, 0) + dcm(1, 1) + dcm(2, 2);
987 checks[1] = 1 + dcm(0, 0) - dcm(1, 1) - dcm(2, 2);
988 checks[2] = 1 - dcm(0, 0) + dcm(1, 1) - dcm(2, 2);
989 checks[3] = 1 - dcm(0, 0) - dcm(1, 1) + dcm(2, 2);
997 components_[3] = 0.5 *
std::sqrt(1 + dcm(0, 0) + dcm(1, 1) + dcm(2, 2));
998 components_[0] = (dcm(2, 1) - dcm(1, 2)) / (4 * components_[3]);
999 components_[1] = (dcm(0, 2) - dcm(2, 0)) / (4 * components_[3]);
1000 components_[2] = (dcm(1, 0) - dcm(0, 1)) / (4 * components_[3]);
1006 components_[0] = 0.5 *
std::sqrt(1 + dcm(0, 0) - dcm(1, 1) - dcm(2, 2));
1007 components_[1] = (dcm(1, 0) + dcm(0, 1)) / (4 * components_[0]);
1008 components_[2] = (dcm(2, 0) + dcm(0, 2)) / (4 * components_[0]);
1009 components_[3] = (dcm(2, 1) - dcm(1, 2)) / (4 * components_[0]);
1015 components_[1] = 0.5 *
std::sqrt(1 - dcm(0, 0) + dcm(1, 1) - dcm(2, 2));
1016 components_[0] = (dcm(1, 0) + dcm(0, 1)) / (4 * components_[1]);
1017 components_[2] = (dcm(2, 1) + dcm(1, 2)) / (4 * components_[1]);
1018 components_[3] = (dcm(0, 2) - dcm(2, 0)) / (4 * components_[1]);
1024 components_[2] = 0.5 *
std::sqrt(1 - dcm(0, 0) - dcm(1, 1) + dcm(2, 2));
1025 components_[0] = (dcm(2, 0) + dcm(0, 2)) / (4 * components_[2]);
1026 components_[1] = (dcm(2, 1) + dcm(1, 2)) / (4 * components_[2]);
1027 components_[3] = (dcm(1, 0) - dcm(0, 1)) / (4 * components_[2]);
#define THROW_INVALID_ARGUMENT_ERROR(msg)
Definition: Error.hpp:37
size_type size() const noexcept
Definition: NdArrayCore.hpp:4524
self_type & zeros() noexcept
Definition: NdArrayCore.hpp:4900
const_iterator cbegin() const noexcept
Definition: NdArrayCore.hpp:1365
self_type transpose() const
Definition: NdArrayCore.hpp:4882
self_type dot(const self_type &inOtherArray) const
Definition: NdArrayCore.hpp:2719
const_iterator cend() const noexcept
Definition: NdArrayCore.hpp:1673
value_type item() const
Definition: NdArrayCore.hpp:3022
self_type & put(index_type inIndex, const value_type &inValue)
Definition: NdArrayCore.hpp:3693
A Class for slicing into NdArrays.
Definition: Slice.hpp:45
Holds a 3D vector.
Definition: Vec3.hpp:51
double z
Definition: Vec3.hpp:56
Vec3 normalize() const noexcept
Definition: Vec3.hpp:289
double x
Definition: Vec3.hpp:54
double y
Definition: Vec3.hpp:55
NdArray< double > toNdArray() const
Definition: Vec3.hpp:337
Holds a unit quaternion.
Definition: Quaternion.hpp:56
double s() const noexcept
Definition: Quaternion.hpp:454
std::string str() const
Definition: Quaternion.hpp:535
double angleOfRotation() const noexcept
Definition: Quaternion.hpp:176
friend std::ostream & operator<<(std::ostream &inOStream, const Quaternion &inQuat)
Definition: Quaternion.hpp:907
double roll() const noexcept
Definition: Quaternion.hpp:402
static Quaternion xRotation(double inAngle) noexcept
Definition: Quaternion.hpp:595
static Quaternion nlerp(const Quaternion &inQuat1, const Quaternion &inQuat2, double inPercent)
Definition: Quaternion.hpp:322
static Quaternion rollRotation(double inAngle) noexcept
Definition: Quaternion.hpp:414
Vec3 rotate(const Vec3 &inVec3) const
Definition: Quaternion.hpp:443
Quaternion(double inI, double inJ, double inK, double inS) noexcept
Definition: Quaternion.hpp:86
NdArray< double > angularVelocity(const Quaternion &inQuat2, double inTime) const
Definition: Quaternion.hpp:225
Quaternion operator-() const noexcept
Definition: Quaternion.hpp:747
NdArray< double > operator*(const NdArray< double > &inVec) const
Definition: Quaternion.hpp:842
Quaternion(const std::array< double, 4 > &components) noexcept
Definition: Quaternion.hpp:98
Quaternion operator+(const Quaternion &inRhs) const noexcept
Definition: Quaternion.hpp:704
double i() const noexcept
Definition: Quaternion.hpp:263
double yaw() const noexcept
Definition: Quaternion.hpp:607
double pitch() const noexcept
Definition: Quaternion.hpp:370
Quaternion slerp(const Quaternion &inQuat2, double inPercent) const
Definition: Quaternion.hpp:524
NdArray< double > toNdArray() const
Definition: Quaternion.hpp:582
Quaternion & operator/=(const Quaternion &inRhs) noexcept
Definition: Quaternion.hpp:882
static Quaternion slerp(const Quaternion &inQuat1, const Quaternion &inQuat2, double inPercent)
Definition: Quaternion.hpp:468
static Quaternion yawRotation(double inAngle) noexcept
Definition: Quaternion.hpp:619
void print() const
Definition: Quaternion.hpp:391
Quaternion(const NdArray< double > &inAxis, double inAngle)
Definition: Quaternion.hpp:165
bool operator==(const Quaternion &inRhs) const noexcept
Definition: Quaternion.hpp:657
NdArray< double > rotate(const NdArray< double > &inVector) const
Definition: Quaternion.hpp:426
Quaternion(double roll, double pitch, double yaw) noexcept
Definition: Quaternion.hpp:72
Vec3 operator*(const Vec3 &inVec3) const
Definition: Quaternion.hpp:870
Quaternion inverse() const noexcept
Definition: Quaternion.hpp:285
double k() const noexcept
Definition: Quaternion.hpp:308
static Quaternion zRotation(double inAngle) noexcept
Definition: Quaternion.hpp:644
NdArray< double > toDCM() const
Definition: Quaternion.hpp:549
Quaternion operator/(const Quaternion &inRhs) const noexcept
Definition: Quaternion.hpp:894
Quaternion nlerp(const Quaternion &inQuat2, double inPercent) const
Definition: Quaternion.hpp:359
static Quaternion yRotation(double inAngle) noexcept
Definition: Quaternion.hpp:631
Quaternion(const Vec3 &inAxis, double inAngle) noexcept
Definition: Quaternion.hpp:144
Quaternion & operator*=(double inScalar) noexcept
Definition: Quaternion.hpp:799
double j() const noexcept
Definition: Quaternion.hpp:297
Quaternion & operator+=(const Quaternion &inRhs) noexcept
Definition: Quaternion.hpp:684
Quaternion operator*(double inScalar) const noexcept
Definition: Quaternion.hpp:830
Quaternion operator-(const Quaternion &inRhs) const noexcept
Definition: Quaternion.hpp:736
Quaternion operator*(const Quaternion &inRhs) const noexcept
Definition: Quaternion.hpp:817
bool operator!=(const Quaternion &inRhs) const noexcept
Definition: Quaternion.hpp:672
Quaternion(const NdArray< double > &inArray)
Definition: Quaternion.hpp:112
Quaternion conjugate() const noexcept
Definition: Quaternion.hpp:252
static Quaternion identity() noexcept
Definition: Quaternion.hpp:274
Vec3 axisOfRotation() const noexcept
Definition: Quaternion.hpp:236
static NdArray< double > angularVelocity(const Quaternion &inQuat1, const Quaternion &inQuat2, double inTime)
Definition: Quaternion.hpp:191
Quaternion & operator-=(const Quaternion &inRhs) noexcept
Definition: Quaternion.hpp:716
Quaternion & operator*=(const Quaternion &inRhs) noexcept
Definition: Quaternion.hpp:759
static Quaternion pitchRotation(double inAngle) noexcept
Definition: Quaternion.hpp:382
OutputIt transform(InputIt first, InputIt last, OutputIt destination, UnaryOperation unaryFunction)
Definition: StlAlgorithms.hpp:775
void for_each(InputIt first, InputIt last, UnaryFunction f)
Definition: StlAlgorithms.hpp:225
bool equal(InputIt1 first1, InputIt1 last1, InputIt2 first2) noexcept
Definition: StlAlgorithms.hpp:140
OutputIt copy(InputIt first, InputIt last, OutputIt destination) noexcept
Definition: StlAlgorithms.hpp:97
std::string num2str(dtype inNumber)
Definition: num2str.hpp:44
bool essentiallyEqual(dtype inValue1, dtype inValue2) noexcept
Definition: essentiallyEqual.hpp:49
constexpr dtype sqr(dtype inValue) noexcept
Definition: sqr.hpp:42
NdArray< double > norm(const NdArray< dtype > &inArray, Axis inAxis=Axis::NONE)
Definition: norm.hpp:51
auto sin(dtype inValue) noexcept
Definition: sin.hpp:49
dtype clip(dtype inValue, dtype inMinValue, dtype inMaxValue)
Definition: clip.hpp:50
auto cos(dtype inValue) noexcept
Definition: cos.hpp:49
auto sqrt(dtype inValue) noexcept
Definition: sqrt.hpp:48
NdArray< uint32 > argmax(const NdArray< dtype > &inArray, Axis inAxis=Axis::NONE)
Definition: argmax.hpp:46
std::uint32_t uint32
Definition: Types.hpp:40