Loading [MathJax]/extensions/TeX/AMSmath.js
Radium Engine  1.5.29
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
algebra.cpp
1#include <Core/Math/LinearAlgebra.hpp>
2#include <Core/Math/Math.hpp>
3#include <Core/Types.hpp>
4
5#include <algorithm> // clamp
6#include <catch2/catch_test_macros.hpp>
7#include <cmath>
8
9TEST_CASE( "Core/Math/Algebra", "[unittests][Core][Core/Math][Algebra]" ) {
10 using namespace Ra::Core;
11 SECTION( "Test custom vector functions" ) {
12
13 Vector3 tests[] = { { 1.34f, 10.34567f, 4.8e5f },
14 { 0.f, -1.42f, -5.3e5f },
15 { 0.9999f, 1.99999f, -1.000001f } };
16
17 for ( uint i = 0; i < 3; ++i ) {
18 const Vector3& v = tests[i];
19 Vector3 fl( std::floor( v.x() ), std::floor( v.y() ), std::floor( v.z() ) );
20 Vector3 ce( std::ceil( v.x() ), std::ceil( v.y() ), std::ceil( v.z() ) );
21
22 REQUIRE( fl == Math::floor( v ) );
23 REQUIRE( ce == Math::ceil( v ) );
24 }
25 }
26
27 SECTION( "Test quaternion functions" ) {
28 Quaternion qr( 1.f, 2.f, 3.f, 4.f );
29 qr.normalize();
30 // Quaternion multiplication does not commute
31 REQUIRE( ( 3.14f * qr ).isApprox( qr * 3.14f ) );
32
33 Quaternion qt, qs;
34
35 Math::getSwingTwist( qr, qs, qt );
36
37 // Swing decomposition
38 REQUIRE( qr.isApprox( qs * qt ) );
39 // Twist should be around z
40 REQUIRE( AngleAxis( qt ).axis().isApprox( Vector3::UnitZ() ) );
41 // Swing should be in xy
42 REQUIRE( Math::areApproxEqual( AngleAxis( qs ).axis().dot( Vector3::UnitZ() ), 0_ra ) );
43 }
44
45 SECTION( "Test clamp" ) {
46 // using std::clamp;
47 // using Math::clamp;
48 Scalar min = -12_ra;
49 Scalar max = +27_ra;
50 Scalar s = 0.6_ra;
51
52 REQUIRE( Math::areApproxEqual( s, std::clamp( s, min, max ) ) );
53 REQUIRE( Math::areApproxEqual( min, std::clamp( min, min, max ) ) );
54 REQUIRE( Math::areApproxEqual( max, std::clamp( max, min, max ) ) );
55 REQUIRE( Math::areApproxEqual( max, std::clamp( max + s, min, max ) ) );
56 REQUIRE( Math::areApproxEqual( min, std::clamp( min - s, min, max ) ) );
57
58 Vector3 v { Scalar( 0.1 ), Scalar( 0.2 ), Scalar( 0.3 ) };
59 Vector3 v2 = Math::clamp( v, min, max );
60 REQUIRE( v2.isApprox( v ) );
61
62 v = Math::clamp( Vector3::Constant( s ), min, max );
63 v2 = Vector3::Constant( s );
64 REQUIRE( v2.isApprox( v ) );
65
66 REQUIRE( Vector3::Constant( min ).isApprox(
67 Math::clamp( Vector3::Constant( min ), min, max ) ) );
68
69 REQUIRE( Vector3::Constant( max ).isApprox(
70 Math::clamp( Vector3::Constant( max ), min, max ) ) );
71 REQUIRE( Vector3::Constant( max ).isApprox(
72 Math::clamp( Vector3::Constant( max + s ), min, max ) ) );
73 REQUIRE( Vector3::Constant( min ).isApprox(
74 Math::clamp( Vector3::Constant( min - s ), min, max ) ) );
75
76 REQUIRE( Vector3::Constant( min ).isApprox( Math::clamp(
77 Vector3::Constant( min ), Vector3::Constant( min ), Vector3::Constant( max ) ) ) );
78
79 REQUIRE( Vector3::Constant( max ).isApprox( Math::clamp(
80 Vector3::Constant( max ), Vector3::Constant( min ), Vector3::Constant( max ) ) ) );
81 REQUIRE( Vector3::Constant( max ).isApprox( Math::clamp(
82 Vector3::Constant( max + s ), Vector3::Constant( min ), Vector3::Constant( max ) ) ) );
83 REQUIRE( Vector3::Constant( min ).isApprox( Math::clamp(
84 Vector3::Constant( min - s ), Vector3::Constant( min ), Vector3::Constant( max ) ) ) );
85
86 REQUIRE( Vector3( min, max, s )
87 .isApprox( Math::clamp( Vector3( min - s, max + s, s ),
88 Vector3::Constant( min ),
89 Vector3::Constant( max ) ) ) );
90 }
91
92 SECTION( "smootsteop" ) {
93 using Math::smoothstep;
94 Scalar min = -12_ra;
95 Scalar max = +27_ra;
96 Scalar s = 0.6_ra;
97
98 REQUIRE( Math::areApproxEqual( 0_ra, smoothstep( min, max, min ) ) );
99 REQUIRE( Math::areApproxEqual( 1_ra, smoothstep( min, max, max ) ) );
100 REQUIRE( Math::areApproxEqual( 1_ra, smoothstep( min, max, max + s ) ) );
101 REQUIRE( Math::areApproxEqual( 0_ra, smoothstep( min, max, min - s ) ) );
102
103 REQUIRE( Math::areApproxEqual( 0.5f, smoothstep( -1.f, 1.f, 0.f ) ) );
104 REQUIRE( Math::areApproxEqual( 1.f, smoothstep( 0.f, 0.f, 1.f ) ) );
105 REQUIRE( Math::areApproxEqual( 0.f, smoothstep( 1.f, -1.f, 1.f ) ) );
106
107 REQUIRE( Math::areApproxEqual( 0.5f, smoothstep( -1.0f, 1.0f, 0.0f ) ) );
108 REQUIRE( Math::areApproxEqual( 1.0f, smoothstep( 0.0f, 0.0f, 1.0f ) ) );
109 REQUIRE( Math::areApproxEqual( 0.0f, smoothstep( 1.0f, -1.0f, 1.0f ) ) );
110
111 Vector3 v { 0_ra, 0_ra, 0_ra };
112 auto v2 = smoothstep( -1_ra, 1_ra, v );
113 REQUIRE( v2.isApprox( Vector3 { 0.5_ra, 0.5_ra, 0.5_ra } ) );
114
115 Matrix2 m;
116 m << 0_ra, 0_ra, 0_ra, 0_ra;
117 Matrix2 m2;
118 m2 << 0.5_ra, 0.5_ra, 0.5_ra, 0.5_ra;
119 auto m3 = smoothstep( -1_ra, 1_ra, m );
120 REQUIRE( m3.isApprox( m2 ) );
121 }
122}
T ceil(T... args)
T floor(T... args)
T max(T... args)
T min(T... args)
T smoothstep(T edge0, T edge1, T x)
As define by https://registry.khronos.org/OpenGL-Refpages/gl4/html/smoothstep.xhtml.
Definition Math.hpp:132
This namespace contains everything "low level", related to data, datastuctures, and computation.
Definition Cage.cpp:5