| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238 |
- //
- // common_test.cxx
- // math-test
- //
- // Created by Sam Jaffe on 5/5/19.
- // Copyright © 2019 Sam Jaffe. All rights reserved.
- //
- #include <cmath>
- #include <gmock/gmock.h>
- #include "game/math/angle.hpp"
- #include "game/math/common.hpp"
- #include "game/math/shape.hpp"
- #include "test_printers.h"
- using namespace math::dim2;
- using namespace testing;
- template <typename T, typename G>
- decltype(auto) generate(T min, T max, T step, G && generator) {
- std::vector<decltype(generator(min))> out;
- for (T val = min; val < max; val += step) {
- out.emplace_back(generator(val));
- }
- return out;
- }
- template <typename T> decltype(auto) generate(T min, T max, T step) {
- auto identity = [](T const & val) { return val; };
- return generate(min, max, step, identity);
- }
- struct LineTest : TestWithParam<std::tuple<point, int>> {};
- TEST_P(LineTest, ExistsOnOriginLine) {
- point const end = std::get<0>(GetParam());
- line const ln{{{0, 0}}, end};
- point const pt = end * std::get<1>(GetParam()) / 100.f;
- EXPECT_TRUE(math::contains(ln, pt));
- }
- TEST_P(LineTest, ColinearOutsideDoesNotContain) {
- point const end = std::get<0>(GetParam());
- line const ln{end, end * 2};
- point const pt = end * std::get<1>(GetParam()) / 100.f;
- EXPECT_FALSE(math::contains(ln, pt));
- }
- std::vector<point> const line_ends{{{1, 1}}, {{0, 1}}, {{1, 0}},
- {{-1, -1}}, {{0, -1}}, {{-1, 0}}};
- INSTANTIATE_TEST_CASE_P(Contains, LineTest,
- Combine(ValuesIn(line_ends),
- ValuesIn(generate(0, 100, 10))));
- struct UnitCircleTest : TestWithParam<point> {};
- TEST_P(UnitCircleTest, ExistsInCircle) {
- circle unit{{{0, 0}}, 1};
- EXPECT_TRUE(math::contains(unit, GetParam()));
- }
- TEST_P(UnitCircleTest, OutsideSmallerCircle) {
- circle subunit{{{0, 0}}, 0.9999};
- EXPECT_FALSE(math::contains(subunit, GetParam()));
- }
- point unit_circle_angle(math::degree degs) {
- return point(make_vector(math::sin(degs), math::cos(degs)));
- }
- INSTANTIATE_TEST_CASE_P(Contains, UnitCircleTest,
- ValuesIn(generate(0.0, 360.0, 5.0, unit_circle_angle)));
- struct UnitSquareTest : TestWithParam<std::tuple<float, float>> {};
- TEST_P(UnitSquareTest, PointInSquare) {
- square unit{{{0, 0}}, 1};
- point pt{{std::get<0>(GetParam()), std::get<1>(GetParam())}};
- EXPECT_TRUE(math::contains(unit, pt));
- }
- TEST_F(UnitSquareTest, PointOutsideSquare) {
- square unit{{{0, 0}}, 1};
- EXPECT_FALSE(math::contains(unit, {{0.f, 1.1f}}));
- EXPECT_FALSE(math::contains(unit, {{0.f, -0.1f}}));
- EXPECT_FALSE(math::contains(unit, {{-0.1f, 0.0f}}));
- EXPECT_FALSE(math::contains(unit, {{1.1f, 0.0f}}));
- }
- INSTANTIATE_TEST_CASE_P(Contains, UnitSquareTest,
- Combine(ValuesIn(generate(0.f, 1.f, 0.25f)),
- ValuesIn(generate(0.f, 1.f, 0.25f))));
- struct LineQuadTest : TestWithParam<point> {};
- TEST_P(LineQuadTest, OriginLineIntersectsUnitSquare) {
- square const unit{{{0, 0}}, 1};
- line const ln{{{0, 0}}, GetParam()};
- EXPECT_TRUE(math::intersects(ln, unit));
- EXPECT_TRUE(math::intersects(unit, ln));
- }
- TEST_P(LineQuadTest, CrossingLineIntersectsUnitSquare) {
- square const unit{{{0, 0}}, 1};
- line const ln{{{0.5, 0.5}}, GetParam()};
- EXPECT_TRUE(math::intersects(ln, unit));
- EXPECT_TRUE(math::intersects(unit, ln));
- }
- TEST_P(LineQuadTest, CrossingLineIntersectsSquare) {
- square const unit{{{0, 0}}, 0.9};
- line const ln{{{0.5, 0.5}}, GetParam()};
- EXPECT_TRUE(math::intersects(ln, unit));
- EXPECT_TRUE(math::intersects(unit, ln));
- }
- TEST_F(LineQuadTest, JustPointIntersection) {
- square const unit{{{0, 0}}, 1};
- line const ln{{{1, 1}}, {{2, 1}}};
- EXPECT_TRUE(math::intersects(ln, unit));
- EXPECT_TRUE(math::intersects(unit, ln));
- }
- TEST_F(LineQuadTest, EntirelyEncasedIntersection) {
- square const unit{{{0, 0}}, 1};
- line const ln{{{0.5, 0.5}}, {{0.75, 0.75}}};
- EXPECT_TRUE(math::intersects(ln, unit));
- EXPECT_TRUE(math::intersects(unit, ln));
- }
- TEST_F(LineQuadTest, OutsideByAnInch) {
- square const unit{{{0, 0}}, 1};
- line const ln{{{1.001, 1}}, {{2, 1}}};
- math::intersects(ln, unit);
- EXPECT_FALSE(math::intersects(ln, unit));
- EXPECT_FALSE(math::intersects(unit, ln));
- }
- INSTANTIATE_TEST_CASE_P(Intersects, LineQuadTest, ValuesIn(line_ends));
- TEST(CircleTest, CircleIntersectsSelf) {
- circle const c1{{{0, 0}}, 1};
- circle const c2{{{0, 0}}, 1};
- EXPECT_TRUE(math::intersects(c1, c2));
- }
- TEST(CircleTest, CircleIntersectsAtOnePoint) {
- circle const c1{{{0, 0}}, 1};
- circle const c2{{{0, 2}}, 1};
- EXPECT_TRUE(math::intersects(c1, c2));
- }
- TEST(CircleTest, CircleIntersectsWithChord) {
- circle const c1{{{0, 0}}, 0.5};
- circle const c2{{{0, 1}}, 0.5};
- EXPECT_TRUE(math::intersects(c1, c2));
- }
- TEST(CircleTest, CircleContainedWithin) {
- circle const c1{{{0, 0}}, 2};
- circle const c2{{{0, 1}}, 0.5};
- EXPECT_TRUE(math::intersects(c1, c2));
- }
- TEST(CircleTest, CircleOutsideDoesNotIntersect) {
- circle const c1{{{0, 0}}, 1};
- circle const c2{{{1.5, 1.5}}, 1};
- EXPECT_FALSE(math::intersects(c1, c2));
- }
- TEST(CircleTest, LineIntersectsFromWithin) {
- circle const c1{{{0, 0}}, 1};
- line const ln{{{0.5, 0.5}}, {{1, 1}}};
- EXPECT_TRUE(math::intersects(c1, ln));
- }
- TEST(CircleTest, LineIntersectsOnEdge) {
- circle const c1{{{0, 0}}, 1};
- line const ln{{{-1, 1}}, {{1, 1}}};
- EXPECT_TRUE(math::intersects(c1, ln));
- }
- TEST(CircleTest, LineIntersectsWhenContained) {
- circle const c1{{{0, 0}}, 1};
- line const ln{{{0.5, 0.5}}, {{-0.5, -0.5}}};
- EXPECT_TRUE(math::intersects(c1, ln));
- }
- TEST(CircleTest, ChordLineIntersects) {
- circle const c1{{{0, 0}}, 1};
- line const ln{{{1, 1}}, {{-1, 0.5}}};
- EXPECT_TRUE(math::intersects(c1, ln));
- }
- TEST(CircleTest, OutsideLineDoesntIntersect) {
- circle const c1{{{0, 0}}, 1};
- line const ln{{{1, 1}}, {{0, 1.5}}};
- EXPECT_FALSE(math::intersects(c1, ln));
- }
- TEST(CircleTest, OverlappingQuad) {
- circle const c1{{{0, 0}}, 1};
- square const sq{{{1, 1}}, 0.5};
- EXPECT_TRUE(math::intersects(c1, sq));
- }
- TEST(CircleTest, IntersectsAtEdge) {
- circle const c1{{{0, 0}}, 1};
- square const sq{{{-1, 1}}, 2};
- EXPECT_TRUE(math::intersects(c1, sq));
- }
- TEST(CircleTest, IntersectsAtCorner) {
- circle const c1{{{0, 0}}, 1};
- square const sq{{{0, 1}}, 1};
- EXPECT_TRUE(math::intersects(c1, sq));
- }
- TEST(CircleTest, ContainingQuad) {
- circle const c1{{{0, 0}}, 1};
- square const sq{{{0, 0}}, 0.5};
- EXPECT_TRUE(math::intersects(c1, sq));
- }
- TEST(CircleTest, ContainedInQuad) {
- circle const c1{{{0, 0}}, 0.5};
- square const sq{{{-1, -1}}, 2};
- EXPECT_TRUE(math::intersects(c1, sq));
- }
- TEST(CircleTest, NonIntersecting) {
- circle const c1{{{0, 0}}, 1};
- square const sq{{{1, 1}}, 1};
- EXPECT_FALSE(math::intersects(c1, sq));
- }
|