GaitGeneration by Graph Search
読み取り中…
検索中…
一致する文字列を見つけられません
math_vector3_test.h
[詳解]
1
3
4// Copyright(c) 2023-2025 Design Engineering Laboratory, Saitama University
5// Released under the MIT license
6// https://opensource.org/licenses/mit-license.php
7
8#ifndef DESIGNLAB_MATH_VECTOR3_TEST_H_
9#define DESIGNLAB_MATH_VECTOR3_TEST_H_
10
11#include <doctest.h>
12
13#include <format>
14#include <string>
15#include <tuple>
16#include <utility>
17#include <vector>
18
19#include "math_vector3.h"
20
21
22
23TEST_SUITE("Vector3")
24{
27
28 TEST_CASE("DefaultConstructorTest_ShouldBeZeroVector")
29 {
30 const auto v = Vector3();
31 const float expected = 0.0f;
32 CHECK(v.x == expected);
33 CHECK(v.y == expected);
34 CHECK(v.z == expected);
35 }
36
37 TEST_CASE("ConstructorTest")
38 {
39 const auto v = Vector3(1, 2, 3);
40 CHECK(v.x == 1);
41 CHECK(v.y == 2);
42 CHECK(v.z == 3);
43 }
44
45 TEST_CASE("CopyConstructorTest")
46 {
47 const auto v1 = Vector3(1, 2, 3);
48 const auto v2 = Vector3(v1);
49 CHECK(v2.x == v1.x);
50 CHECK(v2.y == v1.y);
51 CHECK(v2.z == v1.z);
52 }
53
54 TEST_CASE("MoveConstructorTest")
55 {
56 Vector3 v1 = Vector3(1, 2, 3);
57 const Vector3 v2 = Vector3(std::move(v1));
58 CHECK(v2.x == 1);
59 CHECK(v2.y == 2);
60 CHECK(v2.z == 3);
61 }
62
63 TEST_CASE("AssignmentOperatorTest")
64 {
65 auto v = Vector3(1, 2, 3);
66
67 CHECK(v.x == 1);
68 CHECK(v.y == 2);
69 CHECK(v.z == 3);
70 }
71
72 TEST_CASE("ArithmeticOperatorTest")
73 {
74 SUBCASE("Addition")
75 {
76 constexpr auto v1 = Vector3(1, 2, 3);
77 constexpr auto v2 = Vector3(4, 5, 6);
78 constexpr auto actual = v1 + v2;
79 constexpr auto expected = Vector3(5, 7, 9);
80
81 CHECK_EQ(actual, expected);
82 }
83
84 SUBCASE("Subtraction")
85 {
86 constexpr auto v1 = Vector3(1, 2, 3);
87 constexpr auto v2 = Vector3(4, 5, 6);
88 constexpr auto actual = v1 - v2;
89 constexpr auto expected = Vector3(-3, -3, -3);
90
91 CHECK_EQ(actual, expected);
92 }
93
94 SUBCASE("Multiplication_WhenScalarIsFirst")
95 {
96 constexpr auto v = Vector3(1, 2, 3);
97 constexpr auto s = 2.0f;
98 constexpr auto actual = s * v;
99 constexpr auto expected = Vector3(2, 4, 6);
100
101 CHECK_EQ(actual, expected);
102 }
103
104 SUBCASE("Multiplication_WhenScalarIsSecond")
105 {
106 constexpr auto v = Vector3(1, 2, 3);
107 constexpr auto s = 2.0f;
108 constexpr auto actual = v * s;
109 constexpr auto expected = Vector3(2, 4, 6);
110
111 CHECK_EQ(actual, expected);
112 }
113
114 SUBCASE("Division")
115 {
116 constexpr auto v1 = Vector3(1, 2, 3);
117 constexpr auto v2 = 2.0f;
118 constexpr auto actual = v1 / v2;
119 constexpr auto expected = Vector3(0.5f, 1.0f, 1.5f);
120
121 CHECK_EQ(actual, expected);
122 }
123 }
124
125 TEST_CASE("UnaryOperatorTest")
126 {
127 SUBCASE("Plus")
128 {
129 constexpr auto v = Vector3(1, 2, 3);
130 constexpr auto actual = +v;
131 constexpr auto expected = Vector3(1, 2, 3);
132
133 CHECK_EQ(actual, expected);
134 }
135
136 SUBCASE("Minus")
137 {
138 constexpr auto v = Vector3(1, 2, 3);
139 constexpr auto actual = -v;
140 constexpr auto expected = Vector3(-1, -2, -3);
141
142 CHECK_EQ(actual, expected);
143 }
144 }
145
146 TEST_CASE("CrossTest")
147 {
148 const struct { Vector3 v1; Vector3 v2; Vector3 expected; }
149 table[] = {
150 {Vector3(1, 0, 0), Vector3(0, 1, 0), Vector3(0, 0, 1)},
151 {Vector3(0, 1, 0), Vector3(0, 0, 1), Vector3(1, 0, 0)},
152 {Vector3(0, 0, 1), Vector3(1, 0, 0), Vector3(0, 1, 0)},
153 {Vector3(0, 0, 1), Vector3(0, 1, 0), Vector3(-1, 0, 0)},
154 };
155
156 for (auto [v1, v2, expected] : table)
157 {
158 const auto actual = v1.Cross(v2);
159
160 INFO(std::format("v1 = ({}, {}, {})", v1.x, v1.y, v1.z));
161 INFO(std::format("v2 = ({}, {}, {})", v2.x, v2.y, v2.z));
162 CHECK_EQ(actual, expected);
163 }
164 }
165
166 TEST_CASE("DotTest")
167 {
168 const struct { Vector3 v1; Vector3 v2; float expected; }
169 table[] = {
170 {Vector3(1, 0, 0), Vector3(1, 0, 0), 1.0f},
171 {Vector3(1, 0, 0), Vector3(0, 1, 0), 0.0f},
172 {Vector3(1, 0, 0), Vector3(0, 0, 1), 0.0f},
173 {Vector3(0, 1, 0), Vector3(1, 0, 0), 0.0f},
174 {Vector3(0, 1, 0), Vector3(0, 1, 0), 1.0f},
175 {Vector3(0, 1, 1), Vector3(0, 1, 1), 2.0f},
176 {Vector3(3, 7, 5), Vector3(2, 11, 13), 148.0f},
177 {Vector3(-2, 5, -7), Vector3(1, -11, 6), -99.0f},
178 };
179
180 for (auto [v1, v2, expected] : table)
181 {
182 const auto actual = v1.Dot(v2);
183
184 INFO(std::format("v1 = ({}, {}, {})", v1.x, v1.y, v1.z));
185 INFO(std::format("v2 = ({}, {}, {})", v2.x, v2.y, v2.z));
186 CHECK(actual == doctest::Approx(expected));
187 }
188 }
189
190 TEST_CASE("GetDistanceFromTest")
191 {
192 const struct { Vector3 v1; Vector3 v2; float expected; }
193 table[] = {
194 {Vector3(1, 0, 0), Vector3(0, 1, 0), 1.414214f},
195 {Vector3(0, 1, 0), Vector3(0, 0, 1), 1.414214f},
196 {Vector3(26.f, -30.f, 105.f), Vector3(10.f, 0, 5.f), 105.621967f},
197 {Vector3(10.f, 0, 5.f), Vector3(26.f, -30.f, 105.f), 105.621967f},
198 {Vector3(0.2f, 1.f, -3.f), Vector3(-4.4f, 1.4f, 31.6f), 34.906732f},
199 };
200
201 for (auto [v1, v2, expected] : table)
202 {
203 const auto actual = v1.GetDistanceFrom(v2);
204
205 INFO(std::format("v1 = ({}, {}, {})", v1.x, v1.y, v1.z));
206 INFO(std::format("v2 = ({}, {}, {})", v2.x, v2.y, v2.z));
207 CHECK(actual == doctest::Approx(expected));
208 }
209 }
210
211 TEST_CASE("GetLengthTest")
212 {
213 const struct { Vector3 v; float expected; }
214 table[] = {
215 {Vector3(1, 0, 0), 1.0f},
216 {Vector3(0, 1, 0), 1.0f},
217 {Vector3(0, 0, 1), 1.0f},
218 {Vector3(1, 1, 1), 1.732051f},
219 {Vector3(-1, -1, -1), 1.732051f},
220 };
221
222 for (auto [v, expected] : table)
223 {
224 const auto actual = v.GetLength();
225
226 INFO(std::format("v = ({}, {}, {})", v.x, v.y, v.z));
227 CHECK(actual == doctest::Approx(expected));
228 }
229 }
230
231 TEST_CASE("GetNormalizedTest_WhenZeroVectorIsPassed_ShouldBeZeroVector")
232 {
233 const auto v1 = Vector3(0, 0, 0);
234 const auto actual1 = v1.GetNormalized();
235 const auto expected1 = Vector3(0, 0, 0);
236
237 CHECK(actual1 == expected1);
238 CHECK(actual1.GetLength() == doctest::Approx(0.0f));
239
240 const auto v2 = Vector3::GetZeroVec();
241 const auto actual2 = v2.GetNormalized();
242 const auto expected2 = Vector3(0, 0, 0);
243
244 CHECK(actual2 == expected2);
245 CHECK(actual2.GetLength() == doctest::Approx(0.0f));
246 }
247
248 TEST_CASE("GetNormalizedTest_WhenNonZeroVectorIsPassed_ShouldBeNormalizedVector")
249 {
250 const struct { Vector3 v; Vector3 expected; }
251 table[] = {
252 {Vector3(1, 0, 0), Vector3(1, 0, 0)},
253 {Vector3(0, 1, 0), Vector3(0, 1, 0)},
254 {Vector3(0, 0, 1), Vector3(0, 0, 1)},
255 {Vector3(1, 1, 1), Vector3(0.577350f, 0.577350f, 0.577350f)},
256 {Vector3(-1, -1, -1), Vector3(-0.577350f, -0.577350f, -0.577350f)},
257 };
258
259 for (auto [v, expected] : table)
260 {
261 const auto actual = v.GetNormalized();
262
263 INFO(std::format("v = ({}, {}, {})", v.x, v.y, v.z));
264 CHECK(actual == expected);
265 CHECK(actual.GetLength() == doctest::Approx(1.0f));
266 }
267 }
268
269 TEST_CASE("GetSquaredLengthTest")
270 {
271 const struct { Vector3 v; float expected; }
272 table[] = {
273 {Vector3(1, 0, 0), 1.0f},
274 {Vector3(0, 1, 0), 1.0f},
275 {Vector3(0, 0, 1), 1.0f},
276 {Vector3(1, 1, 1), 3.0f},
277 {Vector3(-1, -1, -1), 3.0f},
278 };
279
280 for (auto [v, expected] : table)
281 {
282 const auto actual = v.GetSquaredLength();
283
284 INFO(std::format("v = ({}, {}, {})", v.x, v.y, v.z));
285 CHECK(actual == doctest::Approx(expected));
286 }
287 }
288
289 TEST_CASE("IsZeroTest_WhenZeroVectorIsPassed_ShouldBeTrue")
290 {
291 const auto v1 = Vector3(0, 0, 0);
292
293 CHECK(v1.IsZero());
294
295 const auto v2 = Vector3::GetZeroVec();
296
297 CHECK(v2.IsZero());
298 }
299
300 TEST_CASE("IsZeroTest_WhenNonZeroVectorIsPassed_ShouldBeFalse")
301 {
302 SUBCASE("When (1,0,0) is passed, should be false")
303 {
304 const auto v = Vector3(1, 0, 0);
305
306 CHECK_FALSE(v.IsZero());
307 }
308
309 SUBCASE("When (0,1,0) is passed, should be false")
310 {
311 const auto v = Vector3(0, 1, 0);
312
313 CHECK_FALSE(v.IsZero());
314 }
315
316 SUBCASE("When (0,0,1) is passed, should be false")
317 {
318 const auto v = Vector3(0, 0, 1);
319
320 CHECK_FALSE(v.IsZero());
321 }
322
323 SUBCASE("When (1,1,1) is passed, should be false")
324 {
325 const auto v = Vector3(1, 1, 1);
326
327 CHECK_FALSE(v.IsZero());
328 }
329
330 SUBCASE("When (-1,-1,-1) is passed, should be false")
331 {
332 const auto v = Vector3(-1, -1, -1);
333
334 CHECK_FALSE(v.IsZero());
335 }
336 }
337
338 TEST_CASE("IsZeroTest_WhenEpsilonIsPassed_ShouldBeTrue")
339 {
340 const auto v1 = Vector3(0.0000001f, 0.0000001f, 0.0000001f);
341
342 CHECK(v1.IsZero());
343 }
344
345 TEST_CASE("NormalizeTest_WhenZeroVectorIsPassed_ShouldBeZeroVector")
346 {
347 auto v1 = Vector3(0, 0, 0);
348 v1.Normalize();
349
350 CHECK(v1 == Vector3(0, 0, 0));
351 CHECK(v1.GetLength() == doctest::Approx(0.0f));
352
353 auto v2 = Vector3::GetZeroVec();
354 v2.Normalize();
355
356 CHECK(v2 == Vector3(0, 0, 0));
357 CHECK(v2.GetLength() == doctest::Approx(0.0f));
358 }
359
360 TEST_CASE("NormalizeTest_WhenNonZeroVectorIsPassed_ShouldBeNormalizedVector")
361 {
362 const struct { Vector3 v; Vector3 expected; }
363 table[] = {
364 {Vector3(1, 0, 0), Vector3(1, 0, 0)},
365 {Vector3(0, 1, 0), Vector3(0, 1, 0)},
366 {Vector3(0, 0, 1), Vector3(0, 0, 1)},
367 {Vector3(1, 1, 1), Vector3(0.577350f, 0.577350f, 0.577350f)},
368 {Vector3(-1, -1, -1), Vector3(-0.577350f, -0.577350f, -0.577350f)},
369 };
370
371 for (auto [v, expected] : table)
372 {
373 auto actual = v;
374 actual.Normalize();
375
376 INFO(std::format("v = ({}, {}, {})", v.x, v.y, v.z));
377 CHECK(actual == expected);
378 CHECK(actual.GetLength() == doctest::Approx(1.0f));
379 }
380 }
381
382 TEST_CASE("ProjectedXYTest")
383 {
384 const struct { Vector3 v; Vector2 expected; }
385 table[] = {
386 {Vector3(0, 0, 0), Vector2(0, 0)},
387 {Vector3(1, 2, 3), Vector2(1, 2)},
388 {Vector3(-1, -2, -3), Vector2(-1, -2)},
389 };
390
391 for (auto [v, expected] : table)
392 {
393 const auto actual = v.ProjectedXY();
394
395 INFO(std::format("v = ({}, {}, {})", v.x, v.y, v.z));
396 CHECK(actual == expected);
397 }
398 }
399}
400
401
402#endif // DESIGNLAB_MATH_VECTOR3_TEST_H_
TEST_SUITE("Vector3")
2次元の位置ベクトルを表す構造体.
3次元の位置ベクトルを表す構造体.