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