diff --git a/src/mobility/model/rectangle.cc b/src/mobility/model/rectangle.cc index 36e27de19..06a35eed5 100644 --- a/src/mobility/model/rectangle.cc +++ b/src/mobility/model/rectangle.cc @@ -52,12 +52,28 @@ Rectangle::IsOnTheBorder(const Vector& position) const Rectangle::Side Rectangle::GetClosestSideOrCorner(const Vector& position) const { - std::array distanceFromBorders{ - std::abs(position.x - this->xMin), // left border - std::abs(this->xMax - position.x), // right border - std::abs(position.y - this->yMin), // bottom border - std::abs(this->yMax - position.y), // top border - }; + std::array distanceFromBorders; + + if (IsInside(position)) + { + distanceFromBorders = { + std::abs(position.x - this->xMin), // left border + std::abs(this->xMax - position.x), // right border + std::abs(position.y - this->yMin), // bottom border + std::abs(this->yMax - position.y) // top border + }; + } + else + { + const auto yMid = (yMax + yMin) / 2; + const auto xMid = (xMax + xMin) / 2; + distanceFromBorders = { + CalculateDistance(position, Vector(xMin, yMid, position.z)), // left border + CalculateDistance(position, Vector(xMax, yMid, position.z)), // right border + CalculateDistance(position, Vector(xMid, yMin, position.z)), // bottom border + CalculateDistance(position, Vector(xMid, yMax, position.z)) // top border + }; + } uint8_t flags = 0; double minDist = std::numeric_limits::max(); for (int i = 0; i < 4; i++) @@ -85,22 +101,12 @@ Rectangle::GetClosestSideOrCorner(const Vector& position) const side = TOPSIDE; break; case 0b0011: - // Opposing sides are equally distant, so we need to check the other two - // We also need to check if we're inside or outside. + // Opposing sides are equally distant, so we choose top side = TOPSIDE; - if (!IsInside(position)) - { - side = (distanceFromBorders[0] > distanceFromBorders[1]) ? RIGHTSIDE : LEFTSIDE; - } break; case 0b1100: - // Opposing sides are equally distant, so we need to check the other two - // We also need to check if we're inside or outside. + // Opposing sides are equally distant, so choose right side = RIGHTSIDE; - if (!IsInside(position)) - { - side = (distanceFromBorders[2] > distanceFromBorders[3]) ? TOPSIDE : BOTTOMSIDE; - } break; case 0b0001: case 0b1101: diff --git a/src/mobility/test/rectangle-closest-border-test.cc b/src/mobility/test/rectangle-closest-border-test.cc index 93b7d7b99..07d1ab981 100644 --- a/src/mobility/test/rectangle-closest-border-test.cc +++ b/src/mobility/test/rectangle-closest-border-test.cc @@ -87,22 +87,29 @@ RectangleClosestBorderTestSuite::RectangleClosestBorderTestSuite() // Rectangle in the positive x-plane to check the intersection with. Rectangle rectangle = Rectangle(0.0, 10.0, 0.0, 10.0); - /* 2 3 4 - * +----------------------------+ (10,10) - * | 11 16 12 | - * | | - * | | - * 1 | 15 18 17 | 5 - * | | - * | | - * | 10 14 13 | - * +----------------------------+ - * 9 7 - * (0,0) + /* 23 24 + * 20 + * : + * : + * 2 3 4 + * +----------------------------+ (10,10) + * | 11 16 12 | + * | | + * | | + * 19 .... 1 | 15 18 17 | 5 .... 21 + * | | + * | | + * | 10 14 13 | + * +----------------------------+ + * 9 7 + * (0,0) * * * - * 8 + * 8 + * : + * : + * 26 22 25 */ // Left side (1 and 15) AddTestCase(new RectangleClosestBorderTestCase(-5, 5, rectangle, Rectangle::LEFTSIDE), @@ -147,6 +154,26 @@ RectangleClosestBorderTestSuite::RectangleClosestBorderTestSuite() // Central position (18) AddTestCase(new RectangleClosestBorderTestCase(5, 5, rectangle, Rectangle::TOPSIDE), TestCase::Duration::QUICK); + // For coordinates to left, top, right, bottom (19, 20, 21, 22) + AddTestCase(new RectangleClosestBorderTestCase(-30, 5, rectangle, Rectangle::LEFTSIDE), + TestCase::Duration::QUICK); + AddTestCase(new RectangleClosestBorderTestCase(5, 30, rectangle, Rectangle::TOPSIDE), + TestCase::Duration::QUICK); + AddTestCase(new RectangleClosestBorderTestCase(30, 5, rectangle, Rectangle::RIGHTSIDE), + TestCase::Duration::QUICK); + AddTestCase(new RectangleClosestBorderTestCase(5, -30, rectangle, Rectangle::BOTTOMSIDE), + TestCase::Duration::QUICK); + // For coordinates to left-top, right-top, right-bottom, left-bottom diagonals (23, 24, 25, 26) + AddTestCase(new RectangleClosestBorderTestCase(-30, 40, rectangle, Rectangle::TOPLEFTCORNER), + TestCase::Duration::QUICK); + AddTestCase(new RectangleClosestBorderTestCase(40, 40, rectangle, Rectangle::TOPRIGHTCORNER), + TestCase::Duration::QUICK); + AddTestCase( + new RectangleClosestBorderTestCase(40, -30, rectangle, Rectangle::BOTTOMRIGHTCORNER), + TestCase::Duration::QUICK); + AddTestCase( + new RectangleClosestBorderTestCase(-30, -30, rectangle, Rectangle::BOTTOMLEFTCORNER), + TestCase::Duration::QUICK); } /**