// L============================================================================= // L This software is distributed under the MIT license. // L Copyright 2021 Péter Kardos // L============================================================================= #pragma once #include "QuaternionImpl.hpp" namespace mathter { /// The euclidean length of the vector of the 4 elements of the quaternion. template T Abs(const Quaternion& q) { return Length(q.vec); } /// Negates the imaginary values of the quaternion. template Quaternion Conjugate(const Quaternion& q) { return Quaternion{ q.vec * Vector{ T(1), T(-1), T(-1), T(-1) } }; } /// Natural quaternion exponentiation, base e. template Quaternion Exp(const Quaternion& q) { auto a = q.ScalarPart(); auto v = q.VectorPart(); T mag = Length(v); T es = exp(a); Quaternion ret = { std::cos(mag), v * (std::sin(mag) / mag) }; ret *= es; return ret; } /// Natural quaternion logarithm, base e. template Quaternion Log(const Quaternion& q) { auto magq = Length(q); auto vn = Normalize(q.VectorPart()); Quaternion ret = { std::log(magq), vn * std::acos(q.s / magq) }; return ret; } /// Raises to the power of . template Quaternion Pow(const Quaternion& q, T a) { return Exp(a * Log(q)); } /// Returns the square of the absolute value. /// Just like complex numbers, it's the square of the length of the vector formed by the coefficients. /// This is much faster than . template T LengthSquared(const Quaternion& q) { return LengthSquared(q.vec); } /// Returns the absolute value of the quaternion. /// Just like complex numbers, it's the length of the vector formed by the coefficients. template T Length(const Quaternion& q) { return Abs(q); } /// Returns the unit quaternion of the same direction. Does not change this object. template Quaternion Normalize(const Quaternion& q) { return Quaternion{ Normalize(q.vec) }; } /// Returns the quaternion of opposite rotation. template Quaternion Inverse(const Quaternion& q) { return Conjugate(q); } /// Check if the quaternion is a unit quaternion, with some tolerance for floats. template bool IsNormalized(const Quaternion& q) { return IsNormalized(q.vec); } } // namespace mathter