./
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
20 / 35
57.1%
Branches:
17 / 46
37.0%
Functions:
7 / 8
87.5%

libs/base/src/eu/base/axisangle.cc
Line Branch Exec Source
1 #include "eu/base/axisangle.h"
2
3 #include <algorithm>
4
5 #include "eu/assert/assert.h"
6
7 #include "eu/base/quat.h"
8
9 namespace eu
10 {
11 1606 AA::AA(const n3 &ax, const An &ang)
12 1606 : axis(ax), angle(ang)
13 {
14
1/6
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 10 taken 1606 times.
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 10 not taken.
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 11 not taken.
1606 ASSERT(ax.is_valid());
15 1606 }
16
17 [[nodiscard]] AA
18 4 AA::from(const Q& q)
19 {
20 4 const float cos_a = std::ranges::clamp(q.w , -1.0f, 1.0f); // todo(Gustav): is this needed?
21
2/4
✓ Branch 3 → 4 taken 4 times.
✗ Branch 3 → 19 not taken.
✓ Branch 4 → 5 taken 4 times.
✗ Branch 4 → 19 not taken.
4 const auto angle = acos(cos_a) * 2;
22 4 const auto sin_a = clamp_zero(std::sqrt(1.0f - cos_a * cos_a), 1, 0.0005f);
23 // todo(Gustav): do we need to normalize here?
24
3/6
✓ Branch 7 → 8 taken 4 times.
✗ Branch 7 → 20 not taken.
✓ Branch 8 → 9 taken 4 times.
✗ Branch 8 → 20 not taken.
✓ Branch 9 → 10 taken 4 times.
✗ Branch 9 → 20 not taken.
4 const auto axis = (q.get_vec_part() / sin_a).get_normalized();
25
1/2
✗ Branch 11 → 12 not taken.
✓ Branch 11 → 14 taken 4 times.
4 if (!axis)
26 {
27 // a "zero" rotation so any axis works
28
0/2
✗ Branch 12 → 13 not taken.
✗ Branch 12 → 22 not taken.
✗ return rha(kk::up, no_rotation);
29 }
30
1/2
✓ Branch 15 → 16 taken 4 times.
✗ Branch 15 → 22 not taken.
4 return rha(*axis, angle);
31 }
32
33 [[nodiscard]] Ypr
34 ✗ Ypr::from(const Q& q)
35 {
36 // Protect against small floating-point errors.
37 ✗ const auto sin_pitch = std::clamp(
38 ✗ 2.0f * (q.y * q.z - q.w * q.x),
39 ✗ -1.0f,
40
0/2
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 11 not taken.
✗ 1.0f
41 ✗ );
42
43 return
44 {
45 ✗ .yaw = An::from_radians(std::atan2(
46 ✗ -2.0f * (q.w * q.y + q.x * q.z),
47 ✗ 1.0f - 2.0f * (q.x * q.x + q.y * q.y)
48 )),
49 ✗ .pitch = An::from_radians(std::asin(sin_pitch)),
50 ✗ .roll = An::from_radians(std::atan2(
51 ✗ 2.0f * (q.w * q.z + q.x * q.y),
52 ✗ 1.0f - 2.0f * (q.x * q.x + q.z * q.z)
53 ))
54 ✗ };
55 }
56
57 AA
58 65 rha(const n3 &axis, const An &angle)
59 {
60
1/6
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 10 taken 65 times.
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 10 not taken.
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 16 not taken.
65 ASSERT(axis.is_valid());
61
2/4
✓ Branch 11 → 12 taken 65 times.
✗ Branch 11 → 19 not taken.
✓ Branch 12 → 13 taken 65 times.
✗ Branch 12 → 19 not taken.
65 return {axis, An::from_radians(angle.as_radians())};
62 }
63
64 std::string
65 4 string_from(const AA &aa)
66 {
67
1/2
✓ Branch 2 → 3 taken 4 times.
✗ Branch 2 → 5 not taken.
4 return fmt::format("({} {})", aa.axis, aa.angle);
68 }
69
70 std::string
71 514 string_from(const Ypr& x)
72 {
73
1/2
✓ Branch 2 → 3 taken 514 times.
✗ Branch 2 → 5 not taken.
514 return fmt::format("({}, {}, {})", x.yaw, x.pitch, x.roll);
74 }
75
76
2/4
✓ Branch 2 → 3 taken 2 times.
✗ Branch 2 → 10 not taken.
✓ Branch 3 → 4 taken 2 times.
✗ Branch 3 → 8 not taken.
2 ADD_CATCH_FORMATTER_IMPL(AA)
77
2/4
✓ Branch 2 → 3 taken 1 time.
✗ Branch 2 → 10 not taken.
✓ Branch 3 → 4 taken 1 time.
✗ Branch 3 → 8 not taken.
1 ADD_CATCH_FORMATTER_IMPL(Ypr)
78 }
79