13#ifndef ML_QUATERNION_H
14#define ML_QUATERNION_H
104 template <
typename DT2>
107 qx =
static_cast<DT
>(q2.
qx);
108 qy =
static_cast<DT
>(q2.
qy);
109 qz =
static_cast<DT
>(q2.
qz);
110 qw =
static_cast<DT
>(q2.
qw);
210 inline void set(
const DT x,
const DT y,
const DT z,
const DT w)
231 printTemplateError(
"TQuaternion::getAsMat4() const, quaternion is not convertible to 4x4 matrix",
233 "Returning Quaterion");
236 *isConvertible =
false;
255 const DT qxqx =
qx*
qx;
256 const DT qyqy =
qy*
qy;
257 const DT qzqz =
qz*
qz;
259 const DT qxqy =
qx*
qy;
260 const DT qxqz =
qx*
qz;
261 const DT qxqw =
qx*
qw;
263 const DT qyqz =
qy*
qz;
264 const DT qyqw =
qy*
qw;
266 const DT qzqw =
qz*
qw;
268 const DT m11 = 1 - s * (qyqy + qzqz);
269 const DT m12 = s * (qxqy - qzqw);
270 const DT m13 = s * (qxqz + qyqw);
272 const DT m21 = s * (qxqy + qzqw);
273 const DT m22 = 1 - s * (qxqx + qzqz);
274 const DT m23 = s * (qyqz - qxqw);
276 const DT m31 = s * (qxqz - qyqw);
277 const DT m32 = s * (qyqz + qxqw);
278 const DT m33 = 1 - s * (qxqx + qyqy);
302 if (isConvertible){ *isConvertible =
true; }
402 *isError = (b.
qx == 0) ||
473 if (isError ==
nullptr){
477 "Returning unchanged quaternion");
487 if (isError !=
nullptr){ *isError =
false; }
535 if (isError ==
nullptr){
539 "Returning default quaternion");
548 if (isError){ *isError =
false; }
568 if (isError ==
nullptr){
572 "Returning default quaternion");
581 if (isError !=
nullptr){ *isError =
false; }
596 if (isError !=
nullptr){
604 retVal = *
this / absVal;
610 retVal = *
this / absVal;
626 if (isInvertible==
nullptr){
629 "Returning default quaternion");
632 *isInvertible =
false;
637 if (isInvertible !=
nullptr){ *isInvertible =
true; }
653 const DT n2 =
norm2();
654 const DT lqv =
qv().length();
657 if (isError ==
nullptr){
659 printTemplateError(
"TQuaternion::sqrt() const, sqrt of quaternion cannot be calculated",
661 "Returning default quaternion");
671 const DT sqrtSinF = sqrtSin*(1/lqv);
675 if (isError !=
nullptr){ *isError =
false; }
690 const DT len =
qv().length();
706 const DT n2 =
norm2();
707 const DT qvLen =
qv().length();
709 retVal.
set(0, 0, 0, log10(n2));
713 retVal.
set(
qv()/qvLen *
static_cast<DT
>(acos(
qw/n2)), log10(n2));
732 const DT len = v.
length();
736 static_cast<DT
>(
::cos(
qw)) * v / len *
static_cast<DT
>(
::sinh(len)) :
748 const DT len = v.
length();
752 static_cast<DT
>(-1)*
static_cast<DT
>(
::sin(
qw))*
qv()/len*
static_cast<DT
>(
::sinh(len)) :
776 const DT len = v.
length();
780 static_cast<DT
>(
::cosh(
qw))*v/len*
static_cast<DT
>(
::sin(len)) :
792 const DT len = v.
length();
796 static_cast<DT
>(
::sinh(
qw))*v/len*
static_cast<DT
>(
::sin(len)) :
840 #define _ML_QUATERNION_CALC_CHECKED(FUNC_NAME, CALC_EXPR) \
841 TQuaternion<DT> retVal; \
843 const Tvec3<DT> &v = qv(); \
844 const DT len = v.length(); \
845 if (MLValueIs0WOM(len)){ \
847 if (isError == NULL){ \
849 printTemplateError("TQuaternion::" FUNC_NAME "() const, " FUNC_NAME \
850 " of quaternion cannot be calculated", \
852 "Returning default quaternion"); \
861 if (isError != NULL){ *isError = false; } \
862 retVal = CALC_EXPR; \
870 #define _ML_QUAT_CALC_EXP TQuaternion<DT>(-v/len,0).mult(mult(TQuaternion<DT>(-v/len,0)).arcsinh());
880 #undef _ML_QUAT_CALC_EXP
885 #define _ML_QUAT_CALC_EXP TQuaternion<DT>(-v/len,0).mult(arccosh());
891 #undef _ML_QUAT_CALC_EXP
896 #define _ML_QUAT_CALC_EXP TQuaternion<DT>(-v/len,0).mult(mult(TQuaternion<DT>(-v/len,0)).arctanh());
902 #undef _ML_QUAT_CALC_EXP
906 #undef _ML_QUATERNION_CALC_CHECKED
941#ifdef _ML_IMPLEMENT_GLOBAL_QUATERNION_OPERATORS
942#ifndef _ML_IMPLEMENT_GLOBAL_QUATERNION_FUNCS_AND_OPS_IN_GLOBAL_NAMESPACE
950template <
typename DT>
951inline ML_LA_NAMESPACE::TQuaternion<DT>
operator+(DT d,
const ML_LA_NAMESPACE::TQuaternion<DT> &q){
952 return ML_LA_NAMESPACE::TQuaternion<DT>(q.qx, q.qy, q.qz, q.qw+d);
956template <
typename DT>
957inline ML_LA_NAMESPACE::TQuaternion<DT> operator+(
const ML_LA_NAMESPACE::TQuaternion<DT> &q, DT d){
958 return ML_LA_NAMESPACE::TQuaternion<DT>(q.qx, q.qy, q.qz, q.qw+d);
962template <
typename DT>
963inline ML_LA_NAMESPACE::TQuaternion<DT>
operator+(
const ML_LA_NAMESPACE::TQuaternion<DT> &qa,
964 const ML_LA_NAMESPACE::TQuaternion<DT> &qb){
965 return qa.operator+(qb);
974template <
typename DT>
975inline ML_LA_NAMESPACE::TQuaternion<DT>
operator-(DT d,
const ML_LA_NAMESPACE::TQuaternion<DT> &q){
976 return ML_LA_NAMESPACE::TQuaternion<DT>(-q.qx, -q.qy, -q.qz, d-q.qw);
980template <
typename DT>
981inline ML_LA_NAMESPACE::TQuaternion<DT>
operator-(
const ML_LA_NAMESPACE::TQuaternion<DT> &q, DT d){
982 return ML_LA_NAMESPACE::TQuaternion<DT>(q.qx, q.qy, q.qz, q.qw-d);
986template <
typename DT>
987inline ML_LA_NAMESPACE::TQuaternion<DT>
operator-(
const ML_LA_NAMESPACE::TQuaternion<DT> &qa,
988 const ML_LA_NAMESPACE::TQuaternion<DT> &qb){
989 return qa.operator-(qb);
994template <
typename DT>
995inline ML_LA_NAMESPACE::TQuaternion<DT>
operator*(DT d,
const ML_LA_NAMESPACE::TQuaternion<DT> &q){
1000template <
typename DT>
1001inline ML_LA_NAMESPACE::TQuaternion<DT>
operator*(
const ML_LA_NAMESPACE::TQuaternion<DT> &q, DT d){
1006template <
typename DT>
1007inline ML_LA_NAMESPACE::TQuaternion<DT>
operator*(
const ML_LA_NAMESPACE::TQuaternion<DT> &qa,
1008 const ML_LA_NAMESPACE::TQuaternion<DT> &qb){
1009 return qa.operator*(qb);
1013#ifndef _ML_IMPLEMENT_GLOBAL_QUATERNION_FUNCS_AND_OPS_IN_GLOBAL_NAMESPACE
1029#ifdef _ML_IMPLEMENT_GLOBAL_QUATERNION_FUNCTIONS
1030#ifndef _ML_IMPLEMENT_GLOBAL_QUATERNION_FUNCS_AND_OPS_IN_GLOBAL_NAMESPACE
1031ML_LA_START_NAMESPACE
1036#ifdef _ML_IMPLEMENT_QUATERNION_SQRT
1037template <
typename DT>
1038inline ML_LA_NAMESPACE::TQuaternion<DT>
sqrt (
const ML_LA_NAMESPACE::TQuaternion<DT> &q) {
return q.sqrt(); }
1042template <
typename DT>
1043inline ML_LA_NAMESPACE::TQuaternion<DT>
exp (
const ML_LA_NAMESPACE::TQuaternion<DT> &q) {
return q.exp(); }
1046template <
typename DT>
1047inline ML_LA_NAMESPACE::TQuaternion<DT> ln (
const ML_LA_NAMESPACE::TQuaternion<DT> &q) {
return q.ln(); }
1050template <
typename DT>
1051inline ML_LA_NAMESPACE::TQuaternion<DT> sin (
const ML_LA_NAMESPACE::TQuaternion<DT> &q) {
return q.sin(); }
1054template <
typename DT>
1055inline ML_LA_NAMESPACE::TQuaternion<DT> cos (
const ML_LA_NAMESPACE::TQuaternion<DT> &q) {
return q.cos(); }
1058template <
typename DT>
1059inline ML_LA_NAMESPACE::TQuaternion<DT> tan (
const ML_LA_NAMESPACE::TQuaternion<DT> &q) {
return q.tan(); }
1062template <
typename DT>
1063inline ML_LA_NAMESPACE::TQuaternion<DT> cotan (
const ML_LA_NAMESPACE::TQuaternion<DT> &q) {
return q.cotan(); }
1066template <
typename DT>
1067inline ML_LA_NAMESPACE::TQuaternion<DT> sinh (
const ML_LA_NAMESPACE::TQuaternion<DT> &q) {
return q.sinh(); }
1070template <
typename DT>
1071inline ML_LA_NAMESPACE::TQuaternion<DT> cosh (
const ML_LA_NAMESPACE::TQuaternion<DT> &q) {
return q.cosh(); }
1074template <
typename DT>
1075inline ML_LA_NAMESPACE::TQuaternion<DT> tanh (
const ML_LA_NAMESPACE::TQuaternion<DT> &q) {
return q.tanh(); }
1078template <
typename DT>
1079inline ML_LA_NAMESPACE::TQuaternion<DT> cotanh (
const ML_LA_NAMESPACE::TQuaternion<DT> &q) {
return q.cotanh(); }
1082template <
typename DT>
1083inline ML_LA_NAMESPACE::TQuaternion<DT> arcsinh(
const ML_LA_NAMESPACE::TQuaternion<DT> &q) {
return q.arcsinh(); }
1086template <
typename DT>
1087inline ML_LA_NAMESPACE::TQuaternion<DT> arccosh(
const ML_LA_NAMESPACE::TQuaternion<DT> &q) {
return q.arccosh(); }
1090template <
typename DT>
1091inline ML_LA_NAMESPACE::TQuaternion<DT> arctanh(
const ML_LA_NAMESPACE::TQuaternion<DT> &q) {
return q.arctanh(); }
1094template <
typename DT>
1095inline ML_LA_NAMESPACE::TQuaternion<DT> arcsin (
const ML_LA_NAMESPACE::TQuaternion<DT> &q) {
return q.arcsin(); }
1098template <
typename DT>
1099inline ML_LA_NAMESPACE::TQuaternion<DT> arccos (
const ML_LA_NAMESPACE::TQuaternion<DT> &q) {
return q.arccos(); }
1102template <
typename DT>
1103inline ML_LA_NAMESPACE::TQuaternion<DT> arctan (
const ML_LA_NAMESPACE::TQuaternion<DT> &q) {
return q.arctan(); }
1106#ifndef _ML_IMPLEMENT_GLOBAL_QUATERNION_FUNCS_AND_OPS_IN_GLOBAL_NAMESPACE
1120 template <
typename DT>
1121 inline ostream&
operator<<(ostream& s,
const ML_NAMESPACE::TQuaternion<DT> &v){
1122 return s <<
"(" << v.qx <<
"," << v.qy <<
"," << v.qz <<
"," << v.qw <<
")";
T length() const
Returns the length of the vector, i.e., norm2().
FloatingPointVector< T, 3, DataContainer > cross(const FloatingPointVector< T, 3, DataContainer > &b) const
Returns the cross product for elements, i.e., the returned vector is orthogonal to *this and b.
T dot(const FloatingPointVector< T, size, DataContainer > &buffer) const
Declaration of complex type traits.
TQuaternion< DT > arctan(bool *isError=nullptr) const
Inverse tangent; for error handling see _ML_QUATERNION_CALC_CHECKED.
TQuaternion< DT > arccos(bool *isError=nullptr) const
Inverse cosine; for error handling see _ML_QUATERNION_CALC_CHECKED.
TQuaternion< DT > euclideanMult(const TQuaternion< DT > &q) const
Euclidean product of this quaternion with another one (which is non-commutative).
DT dot(const TQuaternion< DT > &p) const
Dot product, equivalent to four component vector dot product.
TQuaternion< DT > arg(bool *isError=nullptr) const
TQuaternion< DT > ln() const
Computes the natural logarithm.
TQuaternion(DT x, DT y, DT z, DT w)
TQuaternion< DT > arccosh() const
Computes the inverse hyperbolic cosine.
TQuaternion< MLfloat > sinh() const
TQuaternion< DT > tan(bool *isError=nullptr) const
Computes the tangent; for error handling see _ML_QUATERNION_CALC_CHECKED.
TQuaternion< DT > add(const TQuaternion< DT > &b) const
Adds another quaternion b to this one and returns the sum.
TQuaternion< DT > tanh(bool *isError=nullptr) const
Computes the hyperbolic tangent; for error handling see _ML_QUATERNION_CALC_CHECKED.
FloatingPointVector< DT, 3, Vector3DataContainer< DT > > getImaginaryPart() const
TQuaternion< DT > sqrt(bool *isError=nullptr) const
void set(const FloatingPointVector< DT, 3, Vector3DataContainer< DT > > &v, const DT w)
TQuaternion< MLfloat > div(const TQuaternion< MLfloat > &d, bool *isError=nullptr) const
TQuaternion< DT > sgn(bool *isError=nullptr) const
const FloatingPointVector< MLfloat, 3, Vector3DataContainer< MLfloat > > & qv() const
TQuaternion< DT > cotan(bool *isError=nullptr) const
Computes the cotangent; for error handling see _ML_QUATERNION_CALC_CHECKED.
FloatingPointVector< DT, 3, Vector3DataContainer< DT > > & qv()
TQuaternion< MLfloat > sin() const
TQuaternion< MLfloat > cosh() const
TQuaternion< DT > arcsin(bool *isError=nullptr) const
Inverse sine, for error handling see _ML_QUATERNION_CALC_CHECKED.
bool operator==(const TQuaternion< MLfloat > &b) const
TQuaternion< DT > exp() const
Computes the natural exponential.
TQuaternion< DT > negate() const
Computes the negation.
TQuaternion< DT > arctanh() const
Computes the inverse hyperbolic tangent.
TQuaternion< DT > arcsinh() const
Computes the inverse hyperbolic sine.
TQuaternion< MLfloat > mult(const TQuaternion< MLfloat > &q) const
TQuaternion< DT > compDiv(const TQuaternion< DT > &b, bool *isError=nullptr) const
TQuaternion()
Standard constructor that is setting all elements to 0.
TQuaternion< DT > inverse(bool *isInvertible=nullptr) const
DT value_type
Scalar type used for qx, qy, qz, and qw.
DT & operator[](const size_t i)
Tmat4< DT > getAsMat4(bool *isConvertible=nullptr) const
TQuaternion< DT > & operator=(const TQuaternion< DT > &q)
Assignment operator.
TQuaternion< DT > add(DT s) const
Adds a scalar s to the quaternion and returns the sum. It is equivalent to a 'scalar add' of s to the...
void set(const DT x, const DT y, const DT z, const DT w)
TQuaternion< DT > odd(const TQuaternion< DT > &p) const
TQuaternion< DT > normalize(bool *isError=nullptr) const
TQuaternion(const TQuaternion< DT2 > &q2)
TQuaternion< MLfloat > conjugate() const
TQuaternion< DT > mult(DT s) const
Multiplies this quaternion with a scalar factor s.
TQuaternion(const FloatingPointVector< DT, 4 > &v)
TQuaternion< MLfloat > cos() const
DT operator[](const size_t i) const
TQuaternion< DT > cotanh(bool *isError=nullptr) const
Computes the hyperbolic cotangent; for error handling see _ML_QUATERNION_CALC_CHECKED.
TQuaternion< DT > pow(const TQuaternion< DT > &quat) const
Computes the power of a quaternion.
TQuaternion(const FloatingPointVector< DT, 3, Vector3DataContainer< DT > > &v, DT w)
TQuaternion(const TQuaternion &q2)=default
DT getRealPart() const
Returns a copy of the quaternion's real part, also called scalar() of a quaternion.
TQuaternion< DT > even(const TQuaternion< DT > &p) const
TQuaternion< DT > outer(const TQuaternion< DT > &q) const
Euclidean outer product of this quaternion with another one.
A 4x4 matrix class consisting of four row vectors.
void set(const DT val)
Sets all values to val.
static Tmat4< DT > getIdentity()
Returns the identity matrix.
Forward declarations to resolve header file dependencies.
Specialized base class for the FloatingPointVectorDataContainerBase.
bool MLValueIs0WOM(MLint8 a)
bool MLValuesAreEqualWOM(MLint8 a, MLint8 b)
#define ML_CHECK_FLOAT(x)
#define _ML_QUAT_CALC_EXP
Internal helper macro - do not use.
#define _ML_QUATERNION_CALC_CHECKED(FUNC_NAME, CALC_EXPR)
ScopeGuard< Functor > operator+(ScopeGuardOnExit, Functor &&fn)
void ML_UTILS_EXPORT printTemplateError(const char *location, MLErrorCode reason, const std::string_view &handling)
TQuaternion< MLdouble > Quaternion
Defines the default Quaternion type that is used by the ML; it uses double as component type.
TQuaternion< MLfloat > Quaternionf
A smaller Quaternion type as a specialization from TQuaternion.
T operator*(const FloatingPointVector< T, size, DataContainer > &a, const FloatingPointVector< T, size, DataContainer > &b)
FloatingPointVector< T, size, DataContainer > operator+(FloatingPointVector< T, size, DataContainer > lhs, const FloatingPointVector< T, size, DataContainer > &rhs)
TQuaternion< MLldouble > Quaternionld
A large Quaternion type for further extensions of the ML as a specialization from TQuaternion.
TQuaternion< MLdouble > Quaterniond
The default Quaternion type used in the ML as a specialization from TQuaternion.
FloatingPointVector< T, size, DataContainer > operator-(FloatingPointVector< T, size, DataContainer > lhs, const FloatingPointVector< T, size, DataContainer > &rhs)
MLEXPORT std::ostream & operator<<(std::ostream &s, const ml::Field &v)
Overloads the operator '<<' for stream output of Field objects.