From 6e3c1ba5233fbd9fefa7295231c342bd887d82d7 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Tue, 23 Feb 2021 10:24:49 +0700 Subject: [PATCH] rlength and rlength2 functions --- README.md | 18 ++++++++++++++++++ headers/vmath.hpp/vmath_ext.hpp | 2 +- headers/vmath.hpp/vmath_fun.hpp | 14 +++++++++++++- headers/vmath.hpp/vmath_qua_fun.hpp | 12 +++++++++++- headers/vmath.hpp/vmath_vec_fun.hpp | 12 +++++++++++- untests/vmath_fix_tests.cpp | 4 ++++ untests/vmath_fun_tests.cpp | 6 ++++++ untests/vmath_qua_fun_tests.cpp | 6 ++++++ untests/vmath_vec_fun_tests.cpp | 6 ++++++ 9 files changed, 76 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 6c284cc..107f751 100644 --- a/README.md +++ b/README.md @@ -1302,9 +1302,15 @@ constexpr T dot(T x, T y) noexcept; template < arithmetic T > constexpr T length(T x) noexcept; +template < arithmetic T > +constexpr T rlength(T x) noexcept; + template < arithmetic T > constexpr T length2(T x) noexcept; +template < arithmetic T > +constexpr T rlength2(T x) noexcept; + template < arithmetic T > constexpr T distance(T x, T y) noexcept; @@ -1324,9 +1330,15 @@ constexpr T dot(const vec& xs, const vec& ys); template < typename T, size_t Size > T length(const vec& xs); +template < typename T, size_t Size > +T rlength(const vec& xs); + template < typename T, size_t Size > constexpr T length2(const vec& xs); +template < typename T, size_t Size > +constexpr T rlength2(const vec& xs); + template < typename T, size_t Size > T distance(const vec& xs, const vec& ys); @@ -1352,9 +1364,15 @@ constexpr T dot(const qua& xs, const qua& ys); template < typename T > T length(const qua& xs); +template < typename T > +T rlength(const qua& xs); + template < typename T > constexpr T length2(const qua& xs); +template < typename T > +constexpr T rlength2(const qua& xs); + template < typename T > T distance(const qua& xs, const qua& ys); diff --git a/headers/vmath.hpp/vmath_ext.hpp b/headers/vmath.hpp/vmath_ext.hpp index e67a9ea..47e0a37 100644 --- a/headers/vmath.hpp/vmath_ext.hpp +++ b/headers/vmath.hpp/vmath_ext.hpp @@ -877,7 +877,7 @@ namespace vmath_hpp template < typename T, std::size_t Size > [[nodiscard]] constexpr vec project(const vec& v, const vec& normal) { - return dot(v, normal) * rcp(length2(normal)) * normal; + return dot(v, normal) * rlength2(normal) * normal; } // perpendicular diff --git a/headers/vmath.hpp/vmath_fun.hpp b/headers/vmath.hpp/vmath_fun.hpp index e2ba837..d0500e1 100644 --- a/headers/vmath.hpp/vmath_fun.hpp +++ b/headers/vmath.hpp/vmath_fun.hpp @@ -317,12 +317,24 @@ namespace vmath_hpp return abs(x); } + template < typename T > + [[nodiscard]] std::enable_if_t, T> + constexpr rlength(T x) noexcept { + return rcp(abs(x)); + } + template < typename T > [[nodiscard]] std::enable_if_t, T> constexpr length2(T x) noexcept { return dot(x, x); } + template < typename T > + [[nodiscard]] std::enable_if_t, T> + constexpr rlength2(T x) noexcept { + return rcp(dot(x, x)); + } + template < typename T > [[nodiscard]] std::enable_if_t, T> constexpr distance(T x, T y) noexcept { @@ -338,7 +350,7 @@ namespace vmath_hpp template < typename T > [[nodiscard]] std::enable_if_t, T> normalize(T x) noexcept { - return x * rsqrt(length2(x)); + return x * rlength(x); } } diff --git a/headers/vmath.hpp/vmath_qua_fun.hpp b/headers/vmath.hpp/vmath_qua_fun.hpp index fac296d..e96896a 100644 --- a/headers/vmath.hpp/vmath_qua_fun.hpp +++ b/headers/vmath.hpp/vmath_qua_fun.hpp @@ -259,11 +259,21 @@ namespace vmath_hpp return length(vec{xs}); } + template < typename T > + [[nodiscard]] T rlength(const qua& xs) { + return rlength(vec{xs}); + } + template < typename T > [[nodiscard]] constexpr T length2(const qua& xs) { return length2(vec{xs}); } + template < typename T > + [[nodiscard]] constexpr T rlength2(const qua& xs) { + return rlength2(vec{xs}); + } + template < typename T > [[nodiscard]] T distance(const qua& xs, const qua& ys) { const qua zs = xs * conjugate(ys); @@ -377,6 +387,6 @@ namespace vmath_hpp template < typename T > [[nodiscard]] constexpr qua inverse(const qua& q) { - return conjugate(q) * rcp(length2(q)); + return conjugate(q) * rlength2(q); } } diff --git a/headers/vmath.hpp/vmath_vec_fun.hpp b/headers/vmath.hpp/vmath_vec_fun.hpp index 951634e..8b66c28 100644 --- a/headers/vmath.hpp/vmath_vec_fun.hpp +++ b/headers/vmath.hpp/vmath_vec_fun.hpp @@ -778,11 +778,21 @@ namespace vmath_hpp return sqrt(dot(xs, xs)); } + template < typename T, std::size_t Size > + [[nodiscard]] T rlength(const vec& xs) { + return rsqrt(dot(xs, xs)); + } + template < typename T, std::size_t Size > [[nodiscard]] constexpr T length2(const vec& xs) { return dot(xs, xs); } + template < typename T, std::size_t Size > + [[nodiscard]] constexpr T rlength2(const vec& xs) { + return rcp(dot(xs, xs)); + } + template < typename T, std::size_t Size > [[nodiscard]] T distance(const vec& xs, const vec& ys) { return length(ys - xs); @@ -808,7 +818,7 @@ namespace vmath_hpp template < typename T, std::size_t Size > [[nodiscard]] vec normalize(const vec& xs) { - return xs * rsqrt(length2(xs)); + return xs * rlength(xs); } } diff --git a/untests/vmath_fix_tests.cpp b/untests/vmath_fix_tests.cpp index 5baa823..12f03df 100644 --- a/untests/vmath_fix_tests.cpp +++ b/untests/vmath_fix_tests.cpp @@ -256,7 +256,9 @@ namespace vmath_hpp { template fix dot(const fix2f&, const fix2f&); template fix length(const fix2f&); + template fix rlength(const fix2f&); template fix length2(const fix2f&); + template fix rlength2(const fix2f&); template fix distance(const fix2f&, const fix2f&); template fix distance2(const fix2f&, const fix2f&); template fix cross(const fix2f&, const fix2f&); @@ -268,7 +270,9 @@ namespace vmath_hpp { template fix dot(const qfix&, const qfix&); template fix length(const qfix&); + template fix rlength(const qfix&); template fix length2(const qfix&); + template fix rlength2(const qfix&); template fix distance(const qfix&, const qfix&); template qfix normalize(const qfix&); } diff --git a/untests/vmath_fun_tests.cpp b/untests/vmath_fun_tests.cpp index 8de5f9a..484afa7 100644 --- a/untests/vmath_fun_tests.cpp +++ b/untests/vmath_fun_tests.cpp @@ -107,9 +107,15 @@ TEST_CASE("vmath/fun") { STATIC_CHECK(length(10.f) == uapprox(10.f)); STATIC_CHECK(length(-10.f) == uapprox(10.f)); + STATIC_CHECK(rlength(10.f) == uapprox(0.1f)); + STATIC_CHECK(rlength(-10.f) == uapprox(0.1f)); + STATIC_CHECK(length2(10.f) == uapprox(100.f)); STATIC_CHECK(length2(-10.f) == uapprox(100.f)); + STATIC_CHECK(rlength2(10.f) == uapprox(0.01f)); + STATIC_CHECK(rlength2(-10.f) == uapprox(0.01f)); + STATIC_CHECK(distance(5.f, 10.f) == uapprox(5.f)); STATIC_CHECK(distance(-5.f, -10.f) == uapprox(5.f)); diff --git a/untests/vmath_qua_fun_tests.cpp b/untests/vmath_qua_fun_tests.cpp index 0c71cc3..80bb33e 100644 --- a/untests/vmath_qua_fun_tests.cpp +++ b/untests/vmath_qua_fun_tests.cpp @@ -136,9 +136,15 @@ TEST_CASE("vmath/qua_fun") { CHECK(length(qfloat(10.f,0.f,0.f,0.f)) == uapprox(10.f)); CHECK(length(qfloat(-10.f,0.f,0.f,0.f)) == uapprox(10.f)); + CHECK(rlength(qfloat(10.f,0.f,0.f,0.f)) == uapprox(0.1f)); + CHECK(rlength(qfloat(-10.f,0.f,0.f,0.f)) == uapprox(0.1f)); + STATIC_CHECK(length2(qfloat(10.f,0.f,0.f,0.f)) == uapprox(100.f)); STATIC_CHECK(length2(qfloat(-10.f,0.f,0.f,0.f)) == uapprox(100.f)); + STATIC_CHECK(rlength2(qfloat(10.f,0.f,0.f,0.f)) == uapprox(0.01f)); + STATIC_CHECK(rlength2(qfloat(-10.f,0.f,0.f,0.f)) == uapprox(0.01f)); + CHECK(distance(qrotate_z(radians(0.f)) * 2.f, qrotate_z(radians(0.f)) * 1.5f) == uapprox(radians(0.f))); CHECK(distance(qrotate_z(radians(0.f)) * 3.f, qrotate_z(radians(360.f)) * 2.5f) == uapprox(radians(0.f))); CHECK(distance(qrotate_z(radians(0.f)) * 4.f, qrotate_z(radians(180.f)) * 3.5f) == uapprox(radians(180.f))); diff --git a/untests/vmath_vec_fun_tests.cpp b/untests/vmath_vec_fun_tests.cpp index 8cee9a0..2919ed8 100644 --- a/untests/vmath_vec_fun_tests.cpp +++ b/untests/vmath_vec_fun_tests.cpp @@ -251,9 +251,15 @@ TEST_CASE("vmath/vec_fun") { CHECK(length(float2(10.f,0.f)) == uapprox(10.f)); CHECK(length(float2(-10.f,0.f)) == uapprox(10.f)); + CHECK(rlength(float2(10.f,0.f)) == uapprox(0.1f)); + CHECK(rlength(float2(-10.f,0.f)) == uapprox(0.1f)); + STATIC_CHECK(length2(float2(10.f,0.f)) == uapprox(100.f)); STATIC_CHECK(length2(float2(-10.f,0.f)) == uapprox(100.f)); + STATIC_CHECK(rlength2(float2(10.f,0.f)) == uapprox(0.01f)); + STATIC_CHECK(rlength2(float2(-10.f,0.f)) == uapprox(0.01f)); + CHECK(distance(float2(5.f,0.f), float2(10.f,0.f)) == uapprox(5.f)); CHECK(distance(float2(-5.f,0.f), float2(-10.f,0.f)) == uapprox(5.f));