xcal
基于 C++23 的现代图形渲染引擎
载入中...
搜索中...
未找到
quaternion.cc
浏览该文件的文档.
1#include <gtest/gtest.h>
2
3#include <xcmath/xcmath.hpp>
4using namespace xcmath;
5TEST(Quaternion, Constructors) {
6 // 测试标量构造函数
8 EXPECT_DOUBLE_EQ(q1.r(), 1.0);
9 EXPECT_DOUBLE_EQ(q1.i(), 0.0);
10 EXPECT_DOUBLE_EQ(q1.j(), 0.0);
11 EXPECT_DOUBLE_EQ(q1.k(), 0.0);
12
13 // 测试轴角构造函数
14 xcmath::vec3<double> axis(0, 0, 1);
15 double angle = PI / 2;
16 xcmath::quaternion<double> q2(axis, angle);
17 double expected_r = cos(angle / 2);
18 double expected_i = axis.x() * sin(angle / 2);
19 double expected_j = axis.y() * sin(angle / 2);
20 double expected_k = axis.z() * sin(angle / 2);
21 EXPECT_DOUBLE_EQ(q2.r(), expected_r);
22 EXPECT_DOUBLE_EQ(q2.i(), expected_i);
23 EXPECT_DOUBLE_EQ(q2.j(), expected_j);
24 EXPECT_DOUBLE_EQ(q2.k(), expected_k);
25}
26TEST(Quaternion, Multiplication) {
27 xcmath::quaternion<double> q1(1.0, 0.0, 0.0, 0.0);
28 xcmath::quaternion<double> q2(0.0, 1.0, 0.0, 0.0);
29 xcmath::quaternion<double> result = q1 * q2;
30 EXPECT_DOUBLE_EQ(result.r(), 0.0);
31 EXPECT_DOUBLE_EQ(result.i(), 1.0);
32 EXPECT_DOUBLE_EQ(result.j(), 0.0);
33 EXPECT_DOUBLE_EQ(result.k(), 0.0);
34
35 xcmath::quaternion<double> q3(0.0, 0.0, 1.0, 0.0);
36 xcmath::quaternion<double> q4(0.0, 0.0, 0.0, 1.0);
37 xcmath::quaternion<double> result2 = q3 * q4;
38 EXPECT_DOUBLE_EQ(result2.r(), 0.0);
39 EXPECT_DOUBLE_EQ(result2.i(), 1.0);
40 EXPECT_DOUBLE_EQ(result2.j(), 0.0);
41 EXPECT_DOUBLE_EQ(result2.k(), 0.0);
42}
43TEST(Quaternion, Division) {
44 xcmath::quaternion<double> q1(1.0, 0.0, 0.0, 0.0);
45 xcmath::quaternion<double> q2(1.0, 0.0, 0.0, 0.0);
46 xcmath::quaternion<double> result = q1 / q2;
47 EXPECT_DOUBLE_EQ(result.r(), 1.0);
48 EXPECT_DOUBLE_EQ(result.i(), 0.0);
49 EXPECT_DOUBLE_EQ(result.j(), 0.0);
50 EXPECT_DOUBLE_EQ(result.k(), 0.0);
51
52 xcmath::quaternion<double> q3(2.0, 0.0, 0.0, 0.0);
53 xcmath::quaternion<double> q4(1.0, 0.0, 0.0, 0.0);
54 xcmath::quaternion<double> result2 = q3 / q4;
55 EXPECT_DOUBLE_EQ(result2.r(), 2.0);
56 EXPECT_DOUBLE_EQ(result2.i(), 0.0);
57 EXPECT_DOUBLE_EQ(result2.j(), 0.0);
58 EXPECT_DOUBLE_EQ(result2.k(), 0.0);
59}
60TEST(Quaternion, Norm) {
61 xcmath::quaternion<double> q1(1.0, 0.0, 0.0, 0.0);
62 EXPECT_DOUBLE_EQ(q1.norm(), 1.0);
63
64 xcmath::quaternion<double> q2(1.0, 1.0, 1.0, 1.0);
65 EXPECT_DOUBLE_EQ(q2.norm(), 4.0);
66}
67
68TEST(Quaternion, Inverse) {
69 xcmath::quaternion<double> q1(1.0, 0.0, 0.0, 0.0);
70 xcmath::quaternion<double> inverse_q1 = q1.inverse();
71 EXPECT_DOUBLE_EQ(inverse_q1.r(), 1.0);
72 EXPECT_DOUBLE_EQ(inverse_q1.i(), 0.0);
73 EXPECT_DOUBLE_EQ(inverse_q1.j(), 0.0);
74 EXPECT_DOUBLE_EQ(inverse_q1.k(), 0.0);
75
76 xcmath::quaternion<double> q2(2.0, 1.0, 1.0, 1.0);
77 xcmath::quaternion<double> inverse_q2 = q2.inverse();
78 double norm = q2.norm();
79 EXPECT_DOUBLE_EQ(inverse_q2.r(), 2.0 / norm);
80 EXPECT_DOUBLE_EQ(inverse_q2.i(), -1.0 / norm);
81 EXPECT_DOUBLE_EQ(inverse_q2.j(), -1.0 / norm);
82 EXPECT_DOUBLE_EQ(inverse_q2.k(), -1.0 / norm);
83}
84
85TEST(Quaternion, ToMat) {
86 xcmath::quaternion<double> q(0.0, 0.0, 0.0, 1.0);
88 xcmath::mat<double, 3, 3> expected_mat{xcmath::vec3<double>{-1.0, 0.0, 0.0},
89 xcmath::vec3<double>{0.0, -1.0, 0.0},
90 xcmath::vec3<double>{0.0, 0.0, 1.0}};
91 for (size_t i = 0; i < 3; ++i) {
92 for (size_t j = 0; j < 3; ++j) {
93 EXPECT_DOUBLE_EQ(mat[i][j], expected_mat[i][j]);
94 }
95 }
96}
97
98TEST(Quaternion, FromMat) {
100 xcmath::vec3<double>{0.0, -1.0, 0.0},
101 xcmath::vec3<double>{0.0, 0.0, 1.0}};
103 xcmath::quaternion<double> expected_q(0.0, 0.0, 0.0, 1.0);
104 EXPECT_DOUBLE_EQ(q.r(), expected_q.r());
105 EXPECT_DOUBLE_EQ(q.i(), expected_q.i());
106 EXPECT_DOUBLE_EQ(q.j(), expected_q.j());
107 EXPECT_DOUBLE_EQ(q.k(), expected_q.k());
108}
109
110TEST(Quaternion, ScalarAdditionAndSubtraction) {
111 xcmath::quaternion<double> q(1.0, 0.0, 0.0, 0.0);
112 auto result = 2.0 + q;
113 EXPECT_DOUBLE_EQ(result.r(), 3.0);
114 EXPECT_DOUBLE_EQ(result.i(), 0.0);
115 EXPECT_DOUBLE_EQ(result.j(), 0.0);
116 EXPECT_DOUBLE_EQ(result.k(), 0.0);
117
118 auto result2 = q + 2.0;
119 EXPECT_DOUBLE_EQ(result2.r(), 3.0);
120 EXPECT_DOUBLE_EQ(result2.i(), 0.0);
121 EXPECT_DOUBLE_EQ(result2.j(), 0.0);
122 EXPECT_DOUBLE_EQ(result2.k(), 0.0);
123
124 auto result3 = 2.0 - q;
125 EXPECT_DOUBLE_EQ(result3.r(), 1.0);
126 EXPECT_DOUBLE_EQ(result3.i(), 0.0);
127 EXPECT_DOUBLE_EQ(result3.j(), 0.0);
128 EXPECT_DOUBLE_EQ(result3.k(), 0.0);
129
130 auto result4 = q - 2.0;
131 EXPECT_DOUBLE_EQ(result4.r(), -1.0);
132 EXPECT_DOUBLE_EQ(result4.i(), 0.0);
133 EXPECT_DOUBLE_EQ(result4.j(), 0.0);
134 EXPECT_DOUBLE_EQ(result4.k(), 0.0);
135 auto q33 = 1 + 2_qi;
136 auto q32 = 2_qi + 2_qk;
137}
138
139TEST(Quaternion, ConvertToOtherTypeQuaternion) {
140 using namespace xcmath;
141 quaternion<float> v1{1, 2, 3, 4};
142 auto v2 = (quaternion<double>)v1;
143
144 EXPECT_EQ(v2.r(), 1);
145 EXPECT_EQ(v2.i(), 2);
146 EXPECT_EQ(v2.j(), 3);
147 EXPECT_EQ(v2.k(), 4);
148}
Matrix class template
Definition mat.hpp:27
Quaternion class template
constexpr _Tp & r()
Get scalar part of the quaternion
constexpr quaternion< _Tp > inverse()
Compute inverse of the quaternion
constexpr mat< _Tp, 3, 3 > to_mat() const
Convert quaternion to rotation matrix
constexpr _Tp & i()
Get i-component of the quaternion
constexpr _Tp & k()
Get k-component of the quaternion
constexpr _Tp norm() const
Compute norm of the quaternion
static constexpr quaternion< _Tp > from_mat(const mat< _Tp, 3, 3 > &mat)
Create quaternion from rotation matrix
constexpr _Tp & j()
Get j-component of the quaternion
Vector class template
Definition vec.hpp:206
constexpr _Tp & x()
Get the item at index 0
Definition vec.hpp:454
constexpr _Tp & y()
Get the item at index 1
Definition vec.hpp:465
constexpr _Tp & z()
Get the item at index 2
Definition vec.hpp:476
Compiler-specific type information handling for MSVC
Definition complex.hpp:12
constexpr long double PI
Pi constant
TEST(Quaternion, Constructors)
Definition quaternion.cc:5