summaryrefslogtreecommitdiff
path: root/test/test-maths.cpp
blob: 420b69ef847ba6e983ca8f0d16784df1a69f3f34 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#define BOOST_TEST_MODULE test_maths

#include <boost/test/data/test_case.hpp>
#include <boost/test/unit_test.hpp>
#include <glm/gtx/transform.hpp>
#include <stream_support.hpp>
#include <string_view>
#include <type_traits>

#include <glm/glm.hpp>
#include <maths.h>
#include <tuple>

using vecter_to_angle = std::tuple<glm::vec3, float>;
BOOST_DATA_TEST_CASE(test_vector_yaw,
		boost::unit_test::data::make<vecter_to_angle>(
				{{north, 0}, {south, pi}, {west, half_pi}, {east, -half_pi}, {north + east, -quarter_pi},
						{south + east, quarter_pi * -3}, {north + west, quarter_pi}, {south + west, quarter_pi * 3}}),
		v, a)
{
	BOOST_CHECK_CLOSE(vector_yaw(v), a, 1.F);
}

BOOST_DATA_TEST_CASE(test_vector_pitch,
		boost::unit_test::data::make<vecter_to_angle>({
				{north, 0},
				{east, 0},
				{south, 0},
				{west, 0},
				{north + up, quarter_pi},
				{east + up, quarter_pi},
				{south + up, quarter_pi},
				{west + up, quarter_pi},
				{north - up, -quarter_pi},
				{east - up, -quarter_pi},
				{south - up, -quarter_pi},
				{west - up, -quarter_pi},
				{north + west - up, -quarter_pi},
				{north + west + up, quarter_pi},
		}),
		v, a)
{
	BOOST_CHECK_CLOSE(vector_pitch(v), a, 1.F);
}

using normalize_angle = std::tuple<float, float>;
BOOST_DATA_TEST_CASE(test_angle_normalize,
		boost::unit_test::data::make<normalize_angle>({
				{0, 0},
				{two_pi, 0},
				{-two_pi, 0},
				{half_pi, half_pi},
				{-half_pi, -half_pi},
				{half_pi * 3, -half_pi},
				{-half_pi * 3, half_pi},
		}),
		in, exp)
{
	BOOST_CHECK_CLOSE(normalize(in), exp, 1);
}

using pos3_to_arc = std::tuple<glm::vec3, glm::vec3, glm::vec3, Arc>;
BOOST_DATA_TEST_CASE(test_create_arc,
		boost::unit_test::data::make<pos3_to_arc>({
				{{0, 0, 0}, north, east, {0, half_pi * 3}},
				{{0, 0, 0}, west, east, {half_pi, half_pi * 3}},
				{{0, 0, 0}, south, east, {pi, half_pi * 3}},
				{{0, 0, 0}, east, north, {-half_pi, 0}},
				{{0, 0, 0}, south, north, {pi, two_pi}},
				{{0, 0, 0}, east, south, {-half_pi, pi}},
		}),
		c, s, e, a)
{
	const Arc arc {c, s, e};
	BOOST_REQUIRE_LT(arc.first, arc.second);
	BOOST_CHECK_CLOSE(arc.first, a.first, 1.F);
	BOOST_CHECK_CLOSE(arc.second, a.second, 1.F);
}

using fac = std::tuple<glm::vec2, float, glm::vec2, float, glm::vec2, bool>;
BOOST_DATA_TEST_CASE(test_find_arc_centre,
		boost::unit_test::data::make<fac>({
				{{2, 2}, pi, {3, 3}, half_pi, {3, 2}, true},
				{{2, 2}, pi, {1, 3}, -half_pi, {1, 2}, false},
				{{-1100, -1000}, pi, {-900, -800}, half_pi, {-900, -1000}, true},
				{{1100, 1000}, 0, {1050, 900}, pi + 0.92, {973, 1000}, true},
				{{1050, 900}, 0.92, {1000, 800}, pi, {1127, 800}, false},
		}),
		s, es, e, ee, exp, lr)
{
	const auto c = find_arc_centre(s, es, e, ee);
	BOOST_CHECK_CLOSE(exp.x, c.first.x, 1);
	BOOST_CHECK_CLOSE(exp.y, c.first.y, 1);
	BOOST_CHECK_EQUAL(lr, c.second);
}

BOOST_AUTO_TEST_CASE(test_find_arcs_radius)
{
	BOOST_CHECK_CLOSE(find_arcs_radius({10.32, 26.71}, {0.4, .92}, {2.92, 22.41}, {-0.89, -0.45}), 2.29, 1);
}

static void
compare_rotations(float a, const glm::vec3 & axis, glm::mat4 (*rotate_func)(float), std::string_view n)
{
	BOOST_TEST_CONTEXT(n) {
		const auto g {glm::rotate(a, axis)}, ilt {rotate_func(a)};
		for (int c = 0; c < 4; c++) {
			BOOST_TEST_CONTEXT(c) {
				for (int r = 0; r < 4; r++) {
					BOOST_TEST_CONTEXT(r) {
						BOOST_CHECK_CLOSE(g[c][r], ilt[c][r], 0.0001);
					}
				}
			}
		}
	}
}

const auto angs = boost::unit_test::data::make({pi, half_pi, two_pi, quarter_pi, -pi, -half_pi, -quarter_pi, 0.F})
		* boost::unit_test::data::make(0);
const auto random_angs = boost::unit_test::data::random(-two_pi, two_pi) ^ boost::unit_test::data::xrange(1000);
const auto rots = boost::unit_test::data::make<std::tuple<glm::vec3, glm::mat4 (*)(float), std::string_view>>({
		{up, rotate_yaw, "yaw"},
		{west, rotate_pitch, "pitch"},
		{north, rotate_roll, "roll"},
});
BOOST_DATA_TEST_CASE(test_rotations, (angs + random_angs) * rots, a, ai, ax, func, n)
{
	(void)ai;
	compare_rotations(a, ax, func, n);
}