diff --git a/headers/vmath.hpp/vmath_qua_fun.hpp b/headers/vmath.hpp/vmath_qua_fun.hpp index f4ce40f..684734d 100644 --- a/headers/vmath.hpp/vmath_qua_fun.hpp +++ b/headers/vmath.hpp/vmath_qua_fun.hpp @@ -62,6 +62,67 @@ namespace vmath_hpp return (xs = (xs - ys)); } + // operator* + + template < typename T > + [[nodiscard]] constexpr qua operator*(const qua& xs, T y) { + return qua(vec{xs} * y); + } + + template < typename T > + [[nodiscard]] constexpr qua operator*(T x, const qua& ys) { + return qua(x * vec{ys}); + } + + template < typename T > + [[nodiscard]] constexpr vec operator*(const vec& xs, const qua& ys) { + const vec qv2 = cross(ys.v, xs) * T(2); + return xs + qv2 * ys.s + cross(ys.v, qv2); + } + + template < typename T > + [[nodiscard]] constexpr qua operator*(const qua& xs, const qua& ys) { + return { + cross(ys.v, xs.v) + ys.s * xs.v + xs.s * ys.v, + ys.s * xs.s - dot(ys.v, xs.v)}; + } + + // operator*= + + template < typename T > + constexpr qua& operator*=(qua& xs, T y) { + return (xs = (xs * y)); + } + + template < typename T > + constexpr vec& operator*=(vec& xs, const qua& ys) { + return (xs = (xs * ys)); + } + + template < typename T > + constexpr qua& operator*=(qua& xs, const qua& ys) { + return (xs = (xs * ys)); + } + + // operator/ + + template < typename T > + [[nodiscard]] constexpr qua operator/(const qua& xs, T y) { + return qua(vec{xs} / y); + } + + template < typename T > + [[nodiscard]] constexpr qua operator/(T x, const qua& ys) { + return qua(x / vec{ys}); + } + + // operator/= + + template < typename T > + constexpr qua& operator/=(qua& xs, T y) { + return (xs = (xs / y)); + } + // operator== template < typename T > diff --git a/untests/vmath_qua_fun_tests.cpp b/untests/vmath_qua_fun_tests.cpp index b3baf6c..fccd77c 100644 --- a/untests/vmath_qua_fun_tests.cpp +++ b/untests/vmath_qua_fun_tests.cpp @@ -32,5 +32,35 @@ TEST_CASE("vmath/qua_fun") { REQUIRE(&v == &(v -= qua{3,4,5,6})); REQUIRE(v == qua{-2,-2,-2,-2}); } + + STATIC_REQUIRE(qua(1,2,3,4) * 2 == qua(2,4,6,8)); + STATIC_REQUIRE(qua(2,4,6,8) / 2 == qua(1,2,3,4)); + + STATIC_REQUIRE(2 * qua(1,2,3,4) == qua(2,4,6,8)); + STATIC_REQUIRE(8 / qua(1,2,4,8) == qua(8,4,2,1)); + + { + qua v{1,2,3,4}; + REQUIRE(&v == &(v *= 2)); + REQUIRE(v == qua{2,4,6,8}); + REQUIRE(&v == &(v *= qua{})); + REQUIRE(v == qua{2,4,6,8}); + } + + { + qua v{2,4,6,8}; + REQUIRE(&v == &(v /= 2)); + REQUIRE(v == qua{1,2,3,4}); + } + + { + float3 v{1,0,0}; + REQUIRE(&v == &(v *= fqua{0,0,0.7071067812f,0.7071067812f})); + REQUIRE(v == uapprox3(0.f,1.f,0.f)); + } + + STATIC_REQUIRE(fqua{} * fqua{} == fqua{}); + STATIC_REQUIRE(float3{1,2,3} * fqua{} == uapprox3(1.f,2.f,3.f)); + STATIC_REQUIRE(float3{1,0,0} * fqua{0,0,0.7071067812f,0.7071067812f} == uapprox3(0.f,1.f,0.f)); } }