GaitGeneration by Graph Search
読み取り中…
検索中…
一致する文字列を見つけられません
math_util_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_UTIL_TEST_H_
9#define DESIGNLAB_MATH_UTIL_TEST_H_
10
11#include <doctest.h>
12
13#include <numbers>
14
15#include "math_util.h"
16
17
18TEST_SUITE("math_util::IsEqual")
19{
22
23 TEST_CASE_TEMPLATE("値が等しい時,trueを返すべき", T, float, double)
24 {
25 CHECK(IsEqual(T(0.0), T(0.0)));
26 CHECK(IsEqual(T(1.0), T(1.0)));
27 CHECK(IsEqual(T(-1.0), T(-1.0)));
28 CHECK(IsEqual(T(325.1), T(325.1)));
29
30 SUBCASE("誤差の範囲内で等しい時,trueを返すべき")
31 {
32 CHECK(IsEqual(T(0.0), T(0.0) + MathConst<T>::kAllowableError / 2));
33 CHECK(IsEqual(T(0.0), T(0.0) - MathConst<T>::kAllowableError / 2));
34 CHECK(IsEqual(T(1.0), T(1.0) + MathConst<T>::kAllowableError / 2));
35 CHECK(IsEqual(T(1.0), T(1.0) - MathConst<T>::kAllowableError / 2));
36 CHECK(IsEqual(T(-1.0), T(-1.0) + MathConst<T>::kAllowableError / 2));
37 CHECK(IsEqual(T(-1.0), T(-1.0) - MathConst<T>::kAllowableError / 2));
38 }
39 }
40
41 TEST_CASE_TEMPLATE("値が等しくない時,falseを返すべき", T, float, double)
42 {
43 CHECK_FALSE(IsEqual(T(0.0), T(1.0)));
44 CHECK_FALSE(IsEqual(T(1.0), T(0.0)));
45 CHECK_FALSE(IsEqual(T(-1.0), T(1.0)));
46 CHECK_FALSE(IsEqual(T(325.1), T(325.2)));
47
48 SUBCASE("誤差の範囲を上回っている時,falseを返すべき")
49 {
50 CHECK_FALSE(IsEqual(T(0.0), T(0.0) + MathConst<T>::kAllowableError * 2));
51 CHECK_FALSE(IsEqual(T(0.0), T(0.0) - MathConst<T>::kAllowableError * 2));
52 CHECK_FALSE(IsEqual(T(1.0), T(1.0) + MathConst<T>::kAllowableError * 2));
53 CHECK_FALSE(IsEqual(T(1.0), T(1.0) - MathConst<T>::kAllowableError * 2));
54 CHECK_FALSE(IsEqual(T(-1.0), T(-1.0) + MathConst<T>::kAllowableError * 2));
55 CHECK_FALSE(IsEqual(T(-1.0), T(-1.0) - MathConst<T>::kAllowableError * 2));
56 }
57 }
58}
59
60TEST_SUITE("math_util::Squared")
61{
63
64 TEST_CASE_TEMPLATE("値の2乗を返すべき", T, int, float, double)
65 {
66 CHECK(Squared(T(0.0)) == T(0.0));
67 CHECK(Squared(T(1.0)) == T(1.0));
68 CHECK(Squared(T(-1.0)) == T(1.0));
69 CHECK(Squared(T(5)) == T(25));
70 CHECK(Squared(T(-5)) == T(25));
71 CHECK(Squared(T(15)) == T(225));
72 CHECK(Squared(T(-1462)) == T(2137444));
73 }
74}
75
76TEST_SUITE("math_util::CanMakeTriangle")
77{
79
80 TEST_CASE_TEMPLATE("3角形を作ることが可能な時,trueを返すべき", T, int, float, double)
81 {
82 CHECK(CanMakeTriangle(T(1.0), T(1.0), T(1.0)));
83 CHECK(CanMakeTriangle(T(2.0), T(2.0), T(3.0)));
84 CHECK(CanMakeTriangle(T(2.0), T(3.0), T(2.0)));
85 CHECK(CanMakeTriangle(T(3.0), T(2.0), T(2.0)));
86 CHECK(CanMakeTriangle(T(3.0), T(4.0), T(5.0)));
87 CHECK(CanMakeTriangle(T(3.0), T(5.0), T(4.0)));
88 CHECK(CanMakeTriangle(T(4.0), T(3.0), T(5.0)));
89 CHECK(CanMakeTriangle(T(4.0), T(5.0), T(3.0)));
90 CHECK(CanMakeTriangle(T(5.0), T(3.0), T(4.0)));
91 CHECK(CanMakeTriangle(T(5.0), T(4.0), T(3.0)));
92 }
93
94 TEST_CASE_TEMPLATE("3角形を作ることが不可能な時,falseを返すべき", T, int, float, double)
95 {
96 CHECK_FALSE(CanMakeTriangle(T(1.0), T(1.0), T(3.0)));
97 CHECK_FALSE(CanMakeTriangle(T(1.0), T(3.0), T(1.0)));
98 CHECK_FALSE(CanMakeTriangle(T(3.0), T(1.0), T(1.0)));
99 CHECK_FALSE(CanMakeTriangle(T(1.0), T(2.0), T(3.0)));
100 CHECK_FALSE(CanMakeTriangle(T(1.0), T(3.0), T(2.0)));
101 CHECK_FALSE(CanMakeTriangle(T(2.0), T(1.0), T(3.0)));
102 CHECK_FALSE(CanMakeTriangle(T(2.0), T(3.0), T(1.0)));
103 CHECK_FALSE(CanMakeTriangle(T(3.0), T(1.0), T(2.0)));
104 CHECK_FALSE(CanMakeTriangle(T(3.0), T(2.0), T(1.0)));
105 CHECK_FALSE(CanMakeTriangle(T(1.0), T(1.0), T(2.0)));
106 CHECK_FALSE(CanMakeTriangle(T(1.0), T(2.0), T(1.0)));
107 CHECK_FALSE(CanMakeTriangle(T(2.0), T(1.0), T(1.0)));
108 CHECK_FALSE(CanMakeTriangle(T(1.0), T(1.0), T(4.0)));
109 CHECK_FALSE(CanMakeTriangle(T(1.0), T(4.0), T(1.0)));
110 CHECK_FALSE(CanMakeTriangle(T(4.0), T(1.0), T(1.0)));
111 CHECK_FALSE(CanMakeTriangle(T(1.0), T(2.0), T(4.0)));
112 CHECK_FALSE(CanMakeTriangle(T(1.0), T(4.0), T(2.0)));
113 CHECK_FALSE(CanMakeTriangle(T(2.0), T(1.0), T(4.0)));
114 }
115}
116
117TEST_SUITE("math_util::ConvertRadToDeg")
118{
121
122 TEST_CASE_TEMPLATE("0 [rad]が渡された時,0 [deg]を返すべき", T, float, double)
123 {
124 CHECK(ConvertRadToDeg(T(0.0)) == T(0.0));
125 }
126
127 TEST_CASE_TEMPLATE("0 [rad] ~ 3.14 [rad]の範囲の値が渡された時,0 [deg] ~ 360 [deg]の範囲で変換すべき", T, float, double)
128 {
129 T rad1 = T(std::numbers::pi_v<float> / 6);
130 T expected_deg1 = T(30.0);
131 CHECK(ConvertRadToDeg(rad1) == doctest::Approx(expected_deg1));
132
133 T rad2 = T(std::numbers::pi_v<float> / 4);
134 T expected_deg2 = T(45.0);
135 CHECK(ConvertRadToDeg(rad2) == doctest::Approx(expected_deg2));
136
137 T rad3 = T(std::numbers::pi_v<float> / 3);
138 T expected_deg3 = T(60.0);
139 CHECK(ConvertRadToDeg(rad3) == doctest::Approx(expected_deg3));
140
141 T rad4 = T(std::numbers::pi_v<float> / 2);
142 T expected_deg4 = T(90.0);
143 CHECK(ConvertRadToDeg(rad4) == doctest::Approx(expected_deg4));
144
145 T rad5 = T(std::numbers::pi_v<float>);
146 T expected_deg5 = T(180.0);
147 CHECK(ConvertRadToDeg(rad5) == doctest::Approx(expected_deg5));
148
149 T rad6 = T(std::numbers::pi_v<float> *2);
150 T expected_deg6 = T(360.0);
151 CHECK(ConvertRadToDeg(rad6) == doctest::Approx(expected_deg6));
152 }
153}
154
155TEST_SUITE("math_util::ConvertDegToRad")
156{
158
159 TEST_CASE_TEMPLATE("", T, float, double)
160 {
161 CHECK(ConvertDegToRad(T(0.0)) == T(0.0));
162 CHECK(ConvertDegToRad(T(1.0)) == doctest::Approx(T(0.0174532925)));
163 CHECK(ConvertDegToRad(T(-1.0)) == doctest::Approx(T(-0.0174532925)));
164 CHECK(ConvertDegToRad(T(180.0)) == doctest::Approx(T(3.1415926)));
165 CHECK(ConvertDegToRad(T(-180.0)) == doctest::Approx(T(-3.1415926)));
166 CHECK(ConvertDegToRad(T(360.0)) == doctest::Approx(T(6.2831853)));
167 CHECK(ConvertDegToRad(T(-360.0)) == doctest::Approx(T(-6.2831853)));
168 CHECK(ConvertDegToRad(T(28.647889)) == doctest::Approx(T(0.5)));
169 CHECK(ConvertDegToRad(T(-28.647889)) == doctest::Approx(T(-0.5)));
170 CHECK(ConvertDegToRad(T(14.323944)) == doctest::Approx(T(0.25)));
171 CHECK(ConvertDegToRad(T(-14.323944)) == doctest::Approx(T(-0.25)));
172 CHECK(ConvertDegToRad(T(7.161972)) == doctest::Approx(T(0.125)));
173 CHECK(ConvertDegToRad(T(-7.161972)) == doctest::Approx(T(-0.125)));
174 CHECK(ConvertDegToRad(T(3.580986)) == doctest::Approx(T(0.0625)));
175 }
176}
177
178TEST_SUITE("math_util::LimitRangeAngleDeg")
179{
181
182 TEST_CASE_TEMPLATE("[-180 [deg], 180 [deg] )の範囲の値が渡された時,そのまま返すべき", T, float, double)
183 {
184 CHECK(LimitRangeAngleDeg(T(-180.0)) == T(-180.0));
185 CHECK(LimitRangeAngleDeg(T(-179.0)) == T(-179.0));
186 CHECK(LimitRangeAngleDeg(T(-90.0)) == T(-90.0));
187 CHECK(LimitRangeAngleDeg(T(-1.0)) == T(-1.0));
188 CHECK(LimitRangeAngleDeg(T(0.0)) == T(0.0));
189 CHECK(LimitRangeAngleDeg(T(1.0)) == T(1.0));
190 CHECK(LimitRangeAngleDeg(T(90.0)) == T(90.0));
191 CHECK(LimitRangeAngleDeg(T(179.0)) == T(179.0));
192 }
193
194 TEST_CASE_TEMPLATE("-180 [deg]未満の値が渡された時,[-180 [deg], 180 [deg] )の範囲に変換して返すべき", T, float, double)
195 {
196 CHECK(LimitRangeAngleDeg(T(-181.0)) == T(179.0));
197 CHECK(LimitRangeAngleDeg(T(-270.0)) == T(90.0));
198 CHECK(LimitRangeAngleDeg(T(-360.0)) == T(0.0));
199 CHECK(LimitRangeAngleDeg(T(-361.0)) == T(-1.0));
200 CHECK(LimitRangeAngleDeg(T(-450.0)) == T(-90.0));
201 CHECK(LimitRangeAngleDeg(T(-540.0)) == T(-180.0));
202 CHECK(LimitRangeAngleDeg(T(-541.0)) == T(179.0));
203 CHECK(LimitRangeAngleDeg(T(-630.0)) == T(90.0));
204 CHECK(LimitRangeAngleDeg(T(-720.0)) == T(0.0));
205 CHECK(LimitRangeAngleDeg(T(-721.0)) == T(-1.0));
206 CHECK(LimitRangeAngleDeg(T(-810.0)) == T(-90.0));
207 CHECK(LimitRangeAngleDeg(T(-900.0)) == T(-180.0));
208 CHECK(LimitRangeAngleDeg(T(-901.0)) == T(179.0));
209 CHECK(LimitRangeAngleDeg(T(-990.0)) == T(90.0));
210 CHECK(LimitRangeAngleDeg(T(-1080.0)) == T(0.0));
211 }
212
213 TEST_CASE_TEMPLATE("180 [deg]以上の値が渡された時,[-180 [deg], 180 [deg] )の範囲に変換して返すべき", T, float, double)
214 {
215 CHECK(LimitRangeAngleDeg(T(180.0)) == T(-180.0));
216 CHECK(LimitRangeAngleDeg(T(181.0)) == T(-179.0));
217 CHECK(LimitRangeAngleDeg(T(270.0)) == T(-90.0));
218 CHECK(LimitRangeAngleDeg(T(360.0)) == T(0.0));
219 CHECK(LimitRangeAngleDeg(T(361.0)) == T(1.0));
220 CHECK(LimitRangeAngleDeg(T(450.0)) == T(90.0));
221 CHECK(LimitRangeAngleDeg(T(540.0)) == T(-180.0));
222 CHECK(LimitRangeAngleDeg(T(541.0)) == T(-179.0));
223 CHECK(LimitRangeAngleDeg(T(630.0)) == T(-90.0));
224 CHECK(LimitRangeAngleDeg(T(720.0)) == T(0.0));
225 CHECK(LimitRangeAngleDeg(T(721.0)) == T(1.0));
226 CHECK(LimitRangeAngleDeg(T(810.0)) == T(90.0));
227 CHECK(LimitRangeAngleDeg(T(900.0)) == T(-180.0));
228 CHECK(LimitRangeAngleDeg(T(901.0)) == T(-179.0));
229 CHECK(LimitRangeAngleDeg(T(990.0)) == T(-90.0));
230 CHECK(LimitRangeAngleDeg(T(1080.0)) == T(0.0));
231 }
232}
233
234
235#endif // DESIGNLAB_MATH_UTIL_TEST_H_
TEST_SUITE("math_util::IsEqual")
T LimitRangeAngleDeg(T angle)
角度を -180° ~ 180° の範囲に収める関数.
Definition math_util.h:135
constexpr bool CanMakeTriangle(const T a, const T b, const T c) noexcept
3辺で三角形が作れるか調べる関数.
Definition math_util.h:68
constexpr T ConvertRadToDeg(const T rad) noexcept
角度を [rad]から [deg] に変換する関数.
Definition math_util.h:117
constexpr T ConvertDegToRad(const T deg) noexcept
角度を [deg] から [rad] に変換する関数.
Definition math_util.h:126
constexpr bool IsEqual(const T num1, const T num2) noexcept
C++において,小数同士の計算は誤差が出てしまう. 誤差込みで値が等しいか調べる.
Definition math_util.h:45
constexpr T Squared(const T num) noexcept
2乗した値を返す関数.
Definition math_util.h:59
float 型と double 型の定数を提供するクラス.
Definition math_const.h:25