blob: 7f3f8b2e2d92cd519f1fb1239f0e83ef070333aa [file] [log] [blame]
#include "aos/util/math.h"
#include <memory>
#include "gtest/gtest.h"
namespace aos::math::testing {
bool AngleEqual(double a1, double a2) {
double diff = a1 - a2;
return ::std::fmod(diff, 2 * M_PI) == 0.0;
}
bool AngleInBounds(double a) { return a <= M_PI && a > -M_PI; }
// Check that something
void ExpectNormalizesCorrectly(double a) {
double b = NormalizeAngle(a);
EXPECT_PRED2(AngleEqual, a, b);
EXPECT_PRED1(AngleInBounds, b);
}
void ExpectDiffsCorrectly(double a, double b) {
double diff = DiffAngle(a, b);
EXPECT_PRED1(AngleInBounds, diff) << "a: " << a << " b: " << b;
EXPECT_PRED2(AngleEqual, a, b + diff);
}
// Checks that normalizing positive and negative angles in and out of bounds
// works correctly.
TEST(MathTest, NormalizeAngleTest) {
ExpectNormalizesCorrectly(0.0);
ExpectNormalizesCorrectly(1.0);
ExpectNormalizesCorrectly(-1.0);
ExpectNormalizesCorrectly(M_PI);
ExpectNormalizesCorrectly(2.0 * M_PI);
ExpectNormalizesCorrectly(-2.0 * M_PI);
ExpectNormalizesCorrectly(100.0);
ExpectNormalizesCorrectly(-100.0);
}
// Checks that subtracting one angle from another works for various combinations
// of angles.
TEST(MathTest, DiffAngleTest) {
ExpectDiffsCorrectly(0.0, 0.0);
ExpectDiffsCorrectly(1.0, 0.0);
ExpectDiffsCorrectly(0.0, 1.0);
ExpectDiffsCorrectly(-1.0, 1.0);
ExpectDiffsCorrectly(100.0, 1.0);
ExpectDiffsCorrectly(-100.0, 1.0);
ExpectDiffsCorrectly(M_PI, M_PI);
}
// Check that points that are really counter-clockwise show up as
// counter-clockwise, and that invalid orderings don't show up as CCW.
TEST(MathTest, PointsAreCCWTest) {
Eigen::Vector2d a, b, c;
a << 0.0, 0.0;
b << 1.0, 0.0;
c << 0.0, 1.0;
// Because there are only six orderings we can just enumerate them all.
EXPECT_TRUE(PointsAreCCW<double>(a, b, c));
EXPECT_FALSE(PointsAreCCW<double>(a, c, b));
EXPECT_FALSE(PointsAreCCW<double>(b, a, c));
EXPECT_TRUE(PointsAreCCW<double>(b, c, a));
EXPECT_TRUE(PointsAreCCW<double>(c, a, b));
EXPECT_FALSE(PointsAreCCW<double>(c, b, a));
}
// Collinear points should always appear as non-counter-clockwise.
TEST(MathTest, CollinearPointsAreCCWTest) {
// Create three collinear points along the X-axis and check that every
// combination is not CCW.
Eigen::Vector2d a, b, c;
a << 0.0, 0.0;
b << 1.0, 0.0;
c << 2.0, 0.0;
EXPECT_FALSE(PointsAreCCW<double>(a, b, c));
EXPECT_FALSE(PointsAreCCW<double>(a, c, b));
EXPECT_FALSE(PointsAreCCW<double>(b, a, c));
EXPECT_FALSE(PointsAreCCW<double>(b, c, a));
EXPECT_FALSE(PointsAreCCW<double>(c, a, b));
EXPECT_FALSE(PointsAreCCW<double>(c, b, a));
}
} // namespace aos::math::testing