jaulib v1.3.0
Jau Support Library (C++, Java, ..)
test_math_vec.cpp
Go to the documentation of this file.
1/*
2 * Author: Sven Gothel <sgothel@jausoft.com>
3 * Copyright (c) 2024 Gothel Software e.K.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24#include <thread>
25#include <cassert>
26#include <cinttypes>
27#include <cstring>
28
30
31#include <jau/math/vec2f.hpp>
32#include <jau/math/vec2i.hpp>
33#include <jau/math/vec3f.hpp>
34#include <jau/math/vec4f.hpp>
35#include <jau/math/mat4f.hpp>
36
37using namespace jau;
38using namespace jau::math;
39
40template<class T, class U>
41void test_vec(std::ostream& out, const char* prefix) {
42 out << "Test: " << std::string(prefix) << ", sizeof(U) = " << sizeof(U) << std::endl;
43 T a( U(1) ), b( U(2) );
44 out << "- a: " << a << ", len = " << std::to_string(a.length()) << ", len(normal(a)) = " << std::to_string(T(a).normalize().length()) << std::endl;
45 out << "- b: " << b << ", len = " << std::to_string(b.length()) << ", len(normal(b)) = " << std::to_string(T(b).normalize().length()) << std::endl;
46
47 REQUIRE( T(U(2)) == a * U(2) );
48 REQUIRE( T(U(1)) == b / U(2) );
49
50 a.normalize();
51 b.normalize();
52
53 REQUIRE( jau::equals(U(1), a.length() ) );
54 REQUIRE( jau::equals(U(1), b.length() ) );
55}
56
57template<class T>
58void dump_align_props(std::ostream& out, const char* prefix) {
59 out << std::string(prefix) << "{size " << std::to_string( sizeof(T) ) << ", alignment " << std::to_string( alignof(T) )
60 << " }" << std::endl;
61}
62
63TEST_CASE( "Math Vec Test 00", "[vec][linear_algebra][math]" ) {
64 static_assert(alignof(int) == alignof(Vec2i));
65 static_assert(alignof(float) == alignof(Vec2f));
66 static_assert(alignof(float) == alignof(Vec3f));
67 static_assert(alignof(float) == alignof(Vec4f));
68 static_assert(alignof(float) == alignof(Mat4f));
69
70 dump_align_props<int>(std::cout, "int");
71 dump_align_props<float>(std::cout, "float");
72 dump_align_props<Vec2i>(std::cout, "Vec2i");
73 dump_align_props<Vec2f>(std::cout, "Vec2f");
74 dump_align_props<Vec3f>(std::cout, "Vec3f");
75 dump_align_props<Vec4f>(std::cout, "Vec4f");
76 dump_align_props<Mat4f>(std::cout, "Mat4f");
77
78 std::cout << "A v2 " << Vec2f(1, 2) << std::endl;
79 std::cout << "A v3 " << Vec3f(1, 2, 3) << std::endl;
80 std::cout << "A v4 " << Vec4f(1, 2, 3, 4) << std::endl;
81 {
82 const float mf[] = { 1.0f, 2.0f, 3.0f, 4.0f, // column 0
83 5.0f, 6.0f, 7.0f, 8.0f, // column 1
84 9.0f, 10.0f, 11.0f, 12.0f, // column 2
85 13.0f, 14.0f, 15.0f, 16.0f // column 3
86 };
87 std::cout << "A mat4 " << Mat4f(mf) << std::endl;
88 }
89
90 REQUIRE( Vec2f() == Vec2f(0, 0) );
91 REQUIRE( Vec3f() == Vec3f(0, 0, 0) );
92 REQUIRE( 0.0f == Vec2f().length() );
93 REQUIRE( 0.0f == Vec3f().length() );
94
95 test_vec<Vector2I<int>, int>(std::cout, "Vector2I<int>");
96 test_vec<Vector2I<long>, long>(std::cout, "Vector2I<long>");
97
98 test_vec<Vector2F<float>, float>(std::cout, "Vector2F<float>");
99 test_vec<Vector2F<double>, double>(std::cout, "Vector2F<double>");
100
101 test_vec<Vector3F<float>, float>(std::cout, "Vector3F<float>");
102 test_vec<Vector3F<double>, double>(std::cout, "Vector3F<double>");
103
104 test_vec<Vector4F<float>, float>(std::cout, "Vector4F<float>");
105 test_vec<Vector4F<double>, double>(std::cout, "Vector4F<double>");
106}
107
108TEST_CASE( "Math Vec Normalize Test 01", "[vec][linear_algebra][math]" ) {
109 const Vec3f v0(1, 0, 0);
110 Vec3f v1(1, 2, 3);
111 REQUIRE( true == jau::equals( 1.0f, v0.length() ) );
112 REQUIRE( 1 < v1.length() );
113 REQUIRE( true == jau::equals( 1.0f, v1.normalize().length() ) );
114}
115
116TEST_CASE( "Math Vec Angle Test 02", "[vec][linear_algebra][math]" ) {
117 // test 0 deg
118 {
119 std::cout << "Test 0-deg, UNIT_X vecs" << std::endl;
120 Vec3f v0(1, 0, 0);
121 Vec3f v1(1, 0, 0);
122 std::cout << "v0 " << v0 << std::endl;
123 std::cout << "v1 " << v1 << std::endl;
124
125 const float a0_v0_v1 = v0.angle(v1);
126 std::cout << "a0(v0, v1) = " << a0_v0_v1 << " rad, " << jau::rad_to_adeg(a0_v0_v1) << " deg, via dot, acos" << std::endl;
127 REQUIRE(true == jau::equals(0.0f, a0_v0_v1));
128 }
129 // test 0 deg
130 {
131 std::cout << "Test 0-deg, free vecs" << std::endl;
132 const Vec3f v0(0.14f, 0.07f, 0.0f);
133 const Vec3f v1(0.33f, 0.07f, 0.0f);
134 const Vec3f v0_1 = v1 - v0;
135 std::cout << "v0 " << v0 << std::endl;
136 std::cout << "v1 " << v1 << std::endl;
137 std::cout << "v0_1 " << v0_1 << std::endl;
138
139 const float a0_x_v0_1 = Vec3f(1, 0, 0).angle(v0_1);
140 std::cout << "a0(X, v0_1) = " << a0_x_v0_1 << " rad, " << jau::rad_to_adeg(a0_x_v0_1) << " deg, via dot, acos" << std::endl;
141 REQUIRE(true == jau::equals(0.0f, a0_x_v0_1));
142 }
143 // test 180 deg
144 {
145 std::cout << "Test 180-deg, free vecs" << std::endl;
146 const Vec3f v0(0.33f, 0.07f, 0.0f);
147 const Vec3f v1(0.14f, 0.07f, 0.0f);
148 const Vec3f v0_1 = v1 - v0;
149 std::cout << "v0 " << v0 << std::endl;
150 std::cout << "v1 " << v1 << std::endl;
151 std::cout << "v0_1 " << v0_1 << std::endl;
152
153 const float a0_x_v0_1 = Vec3f(1, 0, 0).angle(v0_1);
154 std::cout << "a0(X, v0_1) = " << a0_x_v0_1 << " rad, " << jau::rad_to_adeg(a0_x_v0_1) << " deg, via dot, acos" << std::endl;
155 REQUIRE(true == jau::equals((float)M_PI, a0_x_v0_1));
156 }
157 // test 90 deg
158 {
159 std::cout << "Test 90-deg, UNIT_X, UNIT_Y vecs" << std::endl;
160 const Vec3f v0(1, 0, 0);
161 const Vec3f v1(0, 1, 0);
162 std::cout << "v0 " << v0 << std::endl;
163 std::cout << "v1 " << v1 << std::endl;
164 const float a0_v0_v1 = v0.angle(v1);
165 std::cout << "a0(v0, v1) = " << a0_v0_v1 << " rad, " << jau::rad_to_adeg(a0_v0_v1) << " deg, via dot, acos" << std::endl;
166 REQUIRE(true == jau::equals((float)M_PI_2, a0_v0_v1));
167 }
168 // test 180 deg
169 {
170 std::cout << "Test 180-deg, UNIT_X, UNIT_X_NEG vecs" << std::endl;
171 const Vec3f v0(1, 0, 0);
172 const Vec3f v1(-1, 0, 0);
173 std::cout << "v0 " << v0 << std::endl;
174 std::cout << "v1 " << v1 << std::endl;
175 const float a0_v0_v1 = v0.angle(v1);
176 std::cout << "a0(v0, v1) = " << a0_v0_v1 << " rad, " << jau::rad_to_adeg(a0_v0_v1) << " deg, via dot, acos" << std::endl;
177 REQUIRE(true == jau::equals((float)M_PI, a0_v0_v1));
178 }
179}
180
Basic 4x4 value_type matrix implementation using fields for intensive use-cases (host operations).
Definition: mat4f.hpp:112
constexpr_cxx26 value_type angle(const Vector3F &o) const noexcept
Return the angle between to vectors in radians.
Definition: vec3f.hpp:316
constexpr Vector3F & normalize() noexcept
Normalize this vector in place.
Definition: vec3f.hpp:237
constexpr value_type length() const noexcept
Return the length of a vector, a.k.a the norm or magnitude
Definition: vec3f.hpp:230
4D vector using four value_type components.
Definition: vec4f.hpp:51
std::string to_string(const alphabet &v) noexcept
Definition: base_codec.hpp:97
std::enable_if< std::is_floating_point_v< T >, bool >::type constexpr equals(const T &a, const T &b, const T &epsilon=std::numeric_limits< T >::epsilon()) noexcept
Returns true if both values are equal, i.e.
Definition: float_math.hpp:394
constexpr T rad_to_adeg(const T rad) noexcept
Converts radians to arc-degree.
Definition: float_math.hpp:489
Matrix4< float > Mat4f
Definition: mat4f.hpp:1881
Vector4F< float > Vec4f
Definition: vec4f.hpp:323
Vector2F< float > Vec2f
Definition: vec2f.hpp:356
Vector3F< float > Vec3f
Definition: vec3f.hpp:371
__pack(...): Produces MSVC, clang and gcc compatible lead-in and -out macros.
Definition: backtrace.hpp:32
2D vector using two integer components.
Definition: vec2i.hpp:49
TEST_CASE("Math Vec Test 00", "[vec][linear_algebra][math]")
void dump_align_props(std::ostream &out, const char *prefix)
void test_vec(std::ostream &out, const char *prefix)