test/beluga/include/beluga/test/raycasting.hpp
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 #ifndef BELUGA_TEST_RAYCASTING_HPP
16 #define BELUGA_TEST_RAYCASTING_HPP
17 
18 #include <Eigen/Core>
19 
20 namespace beluga::testing {
21 
22 template <class Map>
23 std::optional<double> raycast(const Map& map, Eigen::Vector2i source, Eigen::Vector2i target) {
24  const bool steep = std::abs(target.y() - source.y()) > std::abs(target.x() - source.x());
25 
26  if (steep) {
27  std::swap(source.x(), source.y());
28  std::swap(target.x(), target.y());
29  }
30 
31  const auto delta = Eigen::Vector2i{
32  std::abs(target.x() - source.x()),
33  std::abs(target.y() - source.y()),
34  };
35 
36  int error = 0;
37 
38  const auto step = Eigen::Vector2i{
39  source.x() < target.x() ? 1 : -1,
40  source.y() < target.y() ? 1 : -1,
41  };
42 
43  auto current = source;
44 
45  do {
46  if (steep) {
47  if (auto opt = map.data_at(current.y(), current.x()); opt.has_value()) {
48  if (opt.value()) {
49  break;
50  }
51  } else {
52  return std::nullopt;
53  }
54  } else {
55  if (auto opt = map.data_at(current.x(), current.y()); opt.has_value()) {
56  if (opt.value()) {
57  break;
58  }
59  } else {
60  return std::nullopt;
61  }
62  }
63 
64  current.x() += step.x();
65  error += delta.y();
66  if (delta.x() <= 2 * error) {
67  current.y() += step.y();
68  error -= delta.x();
69  }
70 
71  if (current.x() == (target.x() + step.x())) {
72  return std::nullopt;
73  }
74  } while (true);
75 
76  return (current - source).cast<double>().norm() * map.resolution();
77 }
78 
79 } // namespace beluga::testing
80 
81 #endif
beluga::swap
constexpr void swap(CircularArray< T, N, F > &a, CircularArray< T, N, G > &b)
Swaps arrays a and b.
Definition: circular_array.hpp:523
beluga::testing::raycast
std::optional< double > raycast(const Map &map, Eigen::Vector2i source, Eigen::Vector2i target)
Definition: test/beluga/include/beluga/test/raycasting.hpp:23
beluga::testing
Definition: sophus_matchers.hpp:32


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