blob: 7f3f8b2e2d92cd519f1fb1239f0e83ef070333aa [file] [log] [blame]
James Kuszmaul0af658b2019-01-25 18:36:29 -08001#include "aos/util/math.h"
2
Stephan Pleinesb1177672024-05-27 17:48:32 -07003#include <memory>
4
James Kuszmaul0af658b2019-01-25 18:36:29 -08005#include "gtest/gtest.h"
6
Stephan Pleinesf63bde82024-01-13 15:59:33 -08007namespace aos::math::testing {
James Kuszmaul0af658b2019-01-25 18:36:29 -08008
9bool AngleEqual(double a1, double a2) {
10 double diff = a1 - a2;
11 return ::std::fmod(diff, 2 * M_PI) == 0.0;
12}
13
14bool AngleInBounds(double a) { return a <= M_PI && a > -M_PI; }
15
16// Check that something
17void ExpectNormalizesCorrectly(double a) {
18 double b = NormalizeAngle(a);
19 EXPECT_PRED2(AngleEqual, a, b);
20 EXPECT_PRED1(AngleInBounds, b);
21}
22
23void ExpectDiffsCorrectly(double a, double b) {
24 double diff = DiffAngle(a, b);
25
26 EXPECT_PRED1(AngleInBounds, diff) << "a: " << a << " b: " << b;
27 EXPECT_PRED2(AngleEqual, a, b + diff);
28}
29
30// Checks that normalizing positive and negative angles in and out of bounds
31// works correctly.
32TEST(MathTest, NormalizeAngleTest) {
33 ExpectNormalizesCorrectly(0.0);
34 ExpectNormalizesCorrectly(1.0);
35 ExpectNormalizesCorrectly(-1.0);
36 ExpectNormalizesCorrectly(M_PI);
37 ExpectNormalizesCorrectly(2.0 * M_PI);
38 ExpectNormalizesCorrectly(-2.0 * M_PI);
39 ExpectNormalizesCorrectly(100.0);
40 ExpectNormalizesCorrectly(-100.0);
41}
42
43// Checks that subtracting one angle from another works for various combinations
44// of angles.
45TEST(MathTest, DiffAngleTest) {
46 ExpectDiffsCorrectly(0.0, 0.0);
47 ExpectDiffsCorrectly(1.0, 0.0);
48 ExpectDiffsCorrectly(0.0, 1.0);
49 ExpectDiffsCorrectly(-1.0, 1.0);
50 ExpectDiffsCorrectly(100.0, 1.0);
51 ExpectDiffsCorrectly(-100.0, 1.0);
52 ExpectDiffsCorrectly(M_PI, M_PI);
53}
54
55// Check that points that are really counter-clockwise show up as
56// counter-clockwise, and that invalid orderings don't show up as CCW.
57TEST(MathTest, PointsAreCCWTest) {
58 Eigen::Vector2d a, b, c;
59 a << 0.0, 0.0;
60 b << 1.0, 0.0;
61 c << 0.0, 1.0;
62 // Because there are only six orderings we can just enumerate them all.
63 EXPECT_TRUE(PointsAreCCW<double>(a, b, c));
64 EXPECT_FALSE(PointsAreCCW<double>(a, c, b));
65 EXPECT_FALSE(PointsAreCCW<double>(b, a, c));
66 EXPECT_TRUE(PointsAreCCW<double>(b, c, a));
67 EXPECT_TRUE(PointsAreCCW<double>(c, a, b));
68 EXPECT_FALSE(PointsAreCCW<double>(c, b, a));
69}
70
71// Collinear points should always appear as non-counter-clockwise.
72TEST(MathTest, CollinearPointsAreCCWTest) {
73 // Create three collinear points along the X-axis and check that every
74 // combination is not CCW.
75 Eigen::Vector2d a, b, c;
76 a << 0.0, 0.0;
77 b << 1.0, 0.0;
78 c << 2.0, 0.0;
79 EXPECT_FALSE(PointsAreCCW<double>(a, b, c));
80 EXPECT_FALSE(PointsAreCCW<double>(a, c, b));
81 EXPECT_FALSE(PointsAreCCW<double>(b, a, c));
82 EXPECT_FALSE(PointsAreCCW<double>(b, c, a));
83 EXPECT_FALSE(PointsAreCCW<double>(c, a, b));
84 EXPECT_FALSE(PointsAreCCW<double>(c, b, a));
85}
86
Stephan Pleinesf63bde82024-01-13 15:59:33 -080087} // namespace aos::math::testing