Pogosim
Loading...
Searching...
No Matches
distances.h
Go to the documentation of this file.
1#ifndef DISTANCES_H
2#define DISTANCES_H
3
4#include <box2d/box2d.h>
5#include <unordered_map>
6#include <vector>
7#include <cmath>
8
9#include "utils.h"
10#include "spogobot.h"
11#include "robot.h"
12
23float euclidean_distance(const b2Vec2& a, const b2Vec2& b);
24
31struct GridCell {
32 int x, y;
33
41 bool operator==(const GridCell& other) const {
42 return x == other.x && y == other.y;
43 }
44};
45
61 std::size_t operator()(const GridCell& cell) const {
62 // Simple hash combining for x and y.
63 return std::hash<int>()(cell.x) ^ (std::hash<int>()(cell.y) << 1);
64 }
65};
66
73constexpr std::array<GridCell,9> precomputed_neighbor_cells{
74 GridCell{-1,-1}, GridCell{-1,0}, GridCell{-1,1},
75 GridCell{ 0,-1}, GridCell{ 0,0}, GridCell{ 0,1},
76 GridCell{ 1,-1}, GridCell{ 1,0}, GridCell{ 1,1}
77};
78
90inline GridCell get_grid_cell(float x, float y, float cell_size) {
91 return {static_cast<int>(std::floor(x / cell_size)),
92 static_cast<int>(std::floor(y / cell_size))};
93}
94
95
96
97
98struct Candidate {
99 std::size_t idx; /* index inside robots[] */
100 float dist_sq;
101 float angle; /* atan2(dy,dx) */
102 float half_ap; /* asin(r_body / dist) */
103};
104
105/* ------------------------------------------------------------------------ */
106/* Angular-interval utilities (LOS test) */
107/* ------------------------------------------------------------------------ */
108namespace angles {
109 inline float wrap(float a) {
110 while (a <= -M_PI) a += 2 * M_PI;
111 while (a > M_PI) a -= 2 * M_PI;
112 return a;
113 }
114
115 struct Interval { float a, b; }; /* half-open, assume a < b in (-π, π] */
116
117 /* insert [a,b) into sorted union without overlaps */
118 void add_interval(float a, float b, std::vector<Interval>& ivs);
119
120 /* true iff [a,b) completely covered by ivs */
121 bool fully_covered(float a, float b, const std::vector<Interval>& ivs);
122
123 inline bool in_fov(float bearing, /* atan2(dy,dx) */
124 float center, /* LED direction */
125 float half_ap) /* half-FOV (e.g. π/3) */
126 {
127 return std::fabs(wrap(bearing - center)) <= half_ap;
128 }
129} // namespace angles
130
131/* ------------------------------------------------------------------------ */
132/* Building blocks for find_neighbors */
133/* ------------------------------------------------------------------------ */
134
135/* Build a spatial hash of LED positions. */
136std::unordered_map<GridCell,std::vector<std::size_t>,GridCellHash>
138 span_t<float> ys,
139 float cell_size);
140
141/* Collect robots that lie *
142 * – in the 3×3 grid block around emitter i *
143 * – inside emitter i’s communication radius */
144std::vector<Candidate>
145collect_candidates(std::size_t i,
146 span_t<float> xs,
147 span_t<float> ys,
148 span_t<float> cx,
149 span_t<float> cy,
150 span_t<float> body_rad,
151 span_t<float> comm_rad,
152 span_t<float> led_dir,
153 const std::unordered_map<GridCell,
154 std::vector<std::size_t>,
155 GridCellHash>& hash,
156 float cell_size,
157 bool clip_fov);
158
159/* Given distance-sorted candidates, keep only those not shadowed. */
160std::vector<std::size_t>
161filter_visible(const std::vector<Candidate>& cand);
162
163
181void find_neighbors(ir_direction dir, std::vector<std::shared_ptr<PogobotObject>>& robots,
182 float maxDistance,
183 bool enable_occlusion = true);
184
185
199std::vector<float>
201 const std::vector<std::shared_ptr<PogobotObject>>& robots,
202 const arena_polygons_t& arena_polygons);
203
204
213void find_neighbors_to_pogowalls(std::vector<std::shared_ptr<Pogowall>>& pogowalls, ir_direction dir, std::vector<std::shared_ptr<PogobotObject>>& robots);
214
215
216
217/************************* Period boundary conditions *************************/
218
219inline float wrap01(float x, float L) {
220 float k = std::floor(x / L);
221 return x - k * L;
222}
223
224inline float delta_periodic(float d, float L) {
225 d = std::fmod(d, L);
226 if (d > L * 0.5f) d -= L;
227 if (d <= -L * 0.5f) d += L;
228 return d;
229}
230
231inline b2Vec2 torus_delta(b2Vec2 a, b2Vec2 b, b2Vec2 dom_min, float Lx, float Ly) {
232 float ax = a.x - dom_min.x, ay = a.y - dom_min.y;
233 float bx = b.x - dom_min.x, by = b.y - dom_min.y;
234 return { delta_periodic(bx - ax, Lx), delta_periodic(by - ay, Ly) };
235}
236
237// Periodic-boundary variant (toroidal domain).
239 ir_direction dir,
240 std::vector<std::shared_ptr<PogobotObject>>& robots,
241 float max_distance,
242 b2Vec2 domain_min,
243 float domain_w,
244 float domain_h,
245 bool enable_occlusion = true);
246
247
248// Build a spatial hash with ghost insertions across edges for PBC.
249std::unordered_map<GridCell,std::vector<std::size_t>,GridCellHash>
251 span_t<float> ys,
252 float cell_size,
253 b2Vec2 domain_min,
254 float domain_w,
255 float domain_h);
256
257
258#endif // DISTANCES_H
259
260// MODELINE "{{{1
261// vim:expandtab:softtabstop=4:shiftwidth=4:fileencoding=utf-8
262// vim:foldmethod=marker
void find_neighbors_to_pogowalls(std::vector< std::shared_ptr< Pogowall > > &pogowalls, ir_direction dir, std::vector< std::shared_ptr< PogobotObject > > &robots)
Finds robots that are close to given pogowalls.
Definition distances.cpp:243
std::vector< std::size_t > filter_visible(const std::vector< Candidate > &cand)
Definition distances.cpp:99
float wrap01(float x, float L)
Definition distances.h:219
std::unordered_map< GridCell, std::vector< std::size_t >, GridCellHash > build_spatial_hash_periodic(span_t< float > xs, span_t< float > ys, float cell_size, b2Vec2 domain_min, float domain_w, float domain_h)
Definition distances.cpp:270
b2Vec2 torus_delta(b2Vec2 a, b2Vec2 b, b2Vec2 dom_min, float Lx, float Ly)
Definition distances.h:231
std::vector< float > compute_wall_distances(ir_direction dir, const std::vector< std::shared_ptr< PogobotObject > > &robots, const arena_polygons_t &arena_polygons)
Compute, for every robot, the distance from its IR–emitter dir to the nearest arena wall.
Definition distances.cpp:209
constexpr std::array< GridCell, 9 > precomputed_neighbor_cells
Precomputed offsets for neighbor grid cells.
Definition distances.h:73
float euclidean_distance(const b2Vec2 &a, const b2Vec2 &b)
Computes the Euclidean distance between two 2D points.
Definition distances.cpp:11
void find_neighbors_periodic(ir_direction dir, std::vector< std::shared_ptr< PogobotObject > > &robots, float max_distance, b2Vec2 domain_min, float domain_w, float domain_h, bool enable_occlusion=true)
Definition distances.cpp:395
std::unordered_map< GridCell, std::vector< std::size_t >, GridCellHash > build_spatial_hash(span_t< float > xs, span_t< float > ys, float cell_size)
Definition distances.cpp:41
GridCell get_grid_cell(float x, float y, float cell_size)
Converts a 2D position to a grid cell index.
Definition distances.h:90
float delta_periodic(float d, float L)
Definition distances.h:224
std::vector< Candidate > collect_candidates(std::size_t i, span_t< float > xs, span_t< float > ys, span_t< float > cx, span_t< float > cy, span_t< float > body_rad, span_t< float > comm_rad, span_t< float > led_dir, const std::unordered_map< GridCell, std::vector< std::size_t >, GridCellHash > &hash, float cell_size, bool clip_fov)
Definition distances.cpp:52
void find_neighbors(ir_direction dir, std::vector< std::shared_ptr< PogobotObject > > &robots, float maxDistance, bool enable_occlusion=true)
Finds neighboring robots within a specified maximum distance.
Definition distances.cpp:129
std::vector< std::vector< b2Vec2 > > arena_polygons_t
Definition geometry.h:13
Definition distances.h:108
bool in_fov(float bearing, float center, float half_ap)
Definition distances.h:123
bool fully_covered(float a, float b, const std::vector< Interval > &ivs)
Definition distances.cpp:30
float wrap(float a)
Definition distances.h:109
void add_interval(float a, float b, std::vector< Interval > &ivs)
Definition distances.cpp:19
ir_direction
Definition spogobot.h:148
Definition distances.h:98
float half_ap
Definition distances.h:102
std::size_t idx
Definition distances.h:99
float angle
Definition distances.h:101
float dist_sq
Definition distances.h:100
Hash functor for GridCell.
Definition distances.h:52
std::size_t operator()(const GridCell &cell) const
Computes a hash value for a GridCell.
Definition distances.h:61
Represents a cell in a spatial grid.
Definition distances.h:31
int y
The x and y coordinates of the grid cell.
Definition distances.h:32
int x
Definition distances.h:32
bool operator==(const GridCell &other) const
Compares two GridCell objects for equality.
Definition distances.h:41
Definition distances.h:115
float b
Definition distances.h:115
float a
Definition distances.h:115
const std::vector< T > & span_t
Definition utils.h:23