| 696 | } |
| 697 | |
| 698 | Position GridMap::getClosestPositionInMap(const Position& position) const { |
| 699 | if (getSize().x() < 1u || getSize().y() < 1u) { |
| 700 | return position_; |
| 701 | } |
| 702 | |
| 703 | if (isInside(position)) { |
| 704 | return position; |
| 705 | } |
| 706 | |
| 707 | Position positionInMap = position; |
| 708 | |
| 709 | // Find edges. |
| 710 | const double halfLengthX = length_.x() * 0.5; |
| 711 | const double halfLengthY = length_.y() * 0.5; |
| 712 | const Position3 topLeftCorner(position_.x() + halfLengthX, position_.y() + halfLengthY, 0.0); |
| 713 | const Position3 topRightCorner(position_.x() + halfLengthX, position_.y() - halfLengthY, 0.0); |
| 714 | const Position3 bottomLeftCorner(position_.x() - halfLengthX, position_.y() + halfLengthY, 0.0); |
| 715 | const Position3 bottomRightCorner(position_.x() - halfLengthX, position_.y() - halfLengthY, 0.0); |
| 716 | |
| 717 | // Find constraints. |
| 718 | const double maxX = topRightCorner.x(); |
| 719 | const double minX = bottomRightCorner.x(); |
| 720 | const double maxY = bottomLeftCorner.y(); |
| 721 | const double minY = bottomRightCorner.y(); |
| 722 | |
| 723 | // Clip to box constraints and correct for indexing precision. |
| 724 | // Points on the border can lead to invalid indices because the cells represent half open intervals, i.e. [...). |
| 725 | positionInMap.x() = std::fmin(positionInMap.x(), maxX - std::numeric_limits<double>::epsilon()); |
| 726 | positionInMap.y() = std::fmin(positionInMap.y(), maxY - std::numeric_limits<double>::epsilon()); |
| 727 | |
| 728 | positionInMap.x() = std::fmax(positionInMap.x(), minX + std::numeric_limits<double>::epsilon()); |
| 729 | positionInMap.y() = std::fmax(positionInMap.y(), minY + std::numeric_limits<double>::epsilon()); |
| 730 | |
| 731 | return positionInMap; |
| 732 | } |
| 733 | |
| 734 | void GridMap::clear(const std::string& layer) { |
| 735 | try { |