test_dense_grid.cpp
Go to the documentation of this file.
1 // Copyright 2023 Ekumen, Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include <gmock/gmock.h>
16 #include <gtest/gtest.h>
17 
18 #include <array>
19 #include <cstddef>
20 #include <cstdint>
21 #include <optional>
22 #include <utility>
23 #include <vector>
24 
25 #include <Eigen/Core>
26 
28 
29 namespace {
30 
31 template <std::size_t W, std::size_t H>
32 class Image : public beluga::BaseDenseGrid2<Image<W, H>> {
33  public:
34  using index_type = std::pair<std::size_t, std::size_t>;
35  using value_type = uint8_t;
36 
37  Image() = default;
38 
39  explicit Image(std::array<std::array<value_type, W>, H> data) : data_(std::move(data)) {}
40 
41  [[nodiscard]] index_type index_at(int xi, int yi) const {
42  return index_type{static_cast<std::size_t>(xi), static_cast<std::size_t>(yi)};
43  }
44 
45  [[nodiscard]] index_type index_at(const Eigen::Vector2i& pi) const { return index_at(pi.x(), pi.y()); }
46 
48 
49  [[nodiscard]] std::optional<value_type> data_at(const index_type& index) const {
50  return index.first < W && index.second < H ? std::make_optional(data_[index.first][index.second]) : std::nullopt;
51  }
52 
53  [[nodiscard]] std::size_t width() const { return W; }
54  [[nodiscard]] std::size_t height() const { return H; }
55  [[nodiscard]] double resolution() const { return 1.; }
56 
57  private:
58  std::array<std::array<value_type, W>, H> data_;
59 };
60 
61 TEST(DenseGrid2, Limits) {
62  const auto grid = Image<5, 5>{};
63 
64  EXPECT_TRUE(grid.contains(0, 0));
65  EXPECT_FALSE(grid.contains(-1, 0));
66  EXPECT_FALSE(grid.contains(0, -1));
67  EXPECT_TRUE(grid.contains(2, 2));
68  EXPECT_FALSE(grid.contains(5, 0));
69  EXPECT_FALSE(grid.contains(0, 5));
70 
71  EXPECT_TRUE(grid.contains(Eigen::Vector2i(0, 0)));
72  EXPECT_FALSE(grid.contains(Eigen::Vector2i(-1, 0)));
73  EXPECT_FALSE(grid.contains(Eigen::Vector2i(0, -1)));
74  EXPECT_TRUE(grid.contains(Eigen::Vector2i(2, 2)));
75  EXPECT_FALSE(grid.contains(Eigen::Vector2i(5, 0)));
76  EXPECT_FALSE(grid.contains(Eigen::Vector2i(0, 5)));
77 }
78 
79 TEST(DenseGrid2, Data) {
80  const auto grid =
81  Image<5, 5>({{{0, 0, 0, 0, 0}, {0, 1, 1, 1, 0}, {0, 1, 2, 1, 0}, {0, 1, 1, 1, 0}, {0, 0, 0, 0, 0}}});
82 
83  EXPECT_EQ(grid.data_at(Eigen::Vector2i(0, 0)), 0);
84  EXPECT_EQ(grid.data_at(Eigen::Vector2i(2, 2)), 2);
85  EXPECT_EQ(grid.data_at(Eigen::Vector2i(3, 1)), 1);
86  EXPECT_EQ(grid.data_at(Eigen::Vector2i(-1, 0)), std::nullopt);
87  EXPECT_EQ(grid.data_at(Eigen::Vector2i(0, -1)), std::nullopt);
88  EXPECT_EQ(grid.data_at(Eigen::Vector2i(5, 0)), std::nullopt);
89  EXPECT_EQ(grid.data_at(Eigen::Vector2i(0, 5)), std::nullopt);
90 }
91 
92 TEST(DenseGrid2, NearestData) {
93  const auto grid =
94  Image<5, 5>({{{0, 0, 0, 0, 0}, {0, 1, 1, 1, 0}, {0, 1, 2, 1, 0}, {0, 1, 1, 1, 0}, {0, 0, 0, 0, 0}}});
95 
96  EXPECT_EQ(grid.data_near(0.8, 0.2), 0);
97  EXPECT_EQ(grid.data_near(2.1, 2.9), 2);
98  EXPECT_EQ(grid.data_near(3.5, 1.5), 1);
99  EXPECT_EQ(grid.data_near(-0.1, 0), std::nullopt);
100  EXPECT_EQ(grid.data_near(0, -0.1), std::nullopt);
101  EXPECT_EQ(grid.data_near(5.25, 0), std::nullopt);
102  EXPECT_EQ(grid.data_near(0, 5.25), std::nullopt);
103 
104  EXPECT_EQ(grid.data_near(Eigen::Vector2d(0.8, 0.2)), 0);
105  EXPECT_EQ(grid.data_near(Eigen::Vector2d(2.1, 2.9)), 2);
106  EXPECT_EQ(grid.data_near(Eigen::Vector2d(3.5, 1.5)), 1);
107  EXPECT_EQ(grid.data_near(Eigen::Vector2d(-0.1, 0)), std::nullopt);
108  EXPECT_EQ(grid.data_near(Eigen::Vector2d(0, -0.1)), std::nullopt);
109  EXPECT_EQ(grid.data_near(Eigen::Vector2d(5.25, 0)), std::nullopt);
110  EXPECT_EQ(grid.data_near(Eigen::Vector2d(0, 5.25)), std::nullopt);
111 }
112 
113 TEST(DenseGrid2, Neighborhood4) {
114  const auto grid = Image<5, 5>{};
115 
116  {
117  const auto expected_neighborhood =
118  std::vector{Eigen::Vector2i{3, 2}, Eigen::Vector2i{2, 3}, Eigen::Vector2i{1, 2}, Eigen::Vector2i{2, 1}};
119  ASSERT_THAT(grid.neighborhood4(2, 2), testing::Pointwise(testing::Eq(), expected_neighborhood));
120  ASSERT_THAT(grid.neighborhood4(Eigen::Vector2i(2, 2)), testing::Pointwise(testing::Eq(), expected_neighborhood));
121  }
122 
123  {
124  const auto expected_neighborhood = std::vector{Eigen::Vector2i{1, 0}, Eigen::Vector2i{0, 1}};
125  ASSERT_THAT(grid.neighborhood4(0, 0), testing::Pointwise(testing::Eq(), expected_neighborhood));
126  ASSERT_THAT(grid.neighborhood4(Eigen::Vector2i(0, 0)), testing::Pointwise(testing::Eq(), expected_neighborhood));
127  }
128 
129  {
130  const auto expected_neighborhood = std::vector{Eigen::Vector2i{3, 4}, Eigen::Vector2i{4, 3}};
131  ASSERT_THAT(grid.neighborhood4(4, 4), testing::Pointwise(testing::Eq(), expected_neighborhood));
132  ASSERT_THAT(grid.neighborhood4(Eigen::Vector2i(4, 4)), testing::Pointwise(testing::Eq(), expected_neighborhood));
133  }
134 }
135 
136 } // namespace
beluga::BaseDenseGrid2
Dense 2D grid base type.
Definition: dense_grid.hpp:83
nullopt
constexpr nullopt_t nullopt
dense_grid.hpp
Concepts and abstract implementations of dense grids.
std
Definition: circular_array.hpp:529
beluga::BaseDenseGrid2::data_at
auto data_at(int xi, int yi) const
Gets cell data, if included.
Definition: dense_grid.hpp:108
beluga::TEST
TEST(Bresenham, MultiPassGuarantee)
Definition: test_bresenham.cpp:27


beluga
Author(s):
autogenerated on Tue Jul 16 2024 02:59:53