39 this->agentSize = agentSize;
40 int add_x, add_y, num = agentSize + 0.5 -
CN_EPS;
41 for(
int x = -num; x <= +num; x++)
42 for(
int y = -num; y <= +num; y++)
44 add_x = x != 0 ? 1 : 0;
45 add_y = y != 0 ? 1 : 0;
46 if((pow(2*abs(x) - add_x, 2) + pow(2*abs(y) - add_y, 2)) < pow(2*agentSize, 2))
47 cells.push_back({x, y});
50 cells.push_back({0,0});
59 this->agentSize = agentSize;
60 int add_x, add_y, num = agentSize + 0.5 -
CN_EPS;
62 for(
int x = -num; x <= +num; x++)
63 for(
int y = -num; y <= +num; y++)
65 add_x = x != 0 ? 1 : 0;
66 add_y = y != 0 ? 1 : 0;
67 if((pow(2*abs(x) - add_x, 2) + pow(2*abs(y) - add_y, 2)) < pow(2*agentSize, 2))
68 cells.push_back({x, y});
71 cells.push_back({0,0});
86 std::vector<std::pair<int, int>> lineCells(0);
87 if(x1 == x2 && y1 == y2)
90 lineCells.push_back({x1+cell.first, y1+cell.second});
93 int delta_x = std::abs(x1 - x2);
94 int delta_y = std::abs(y1 - y2);
95 if((delta_x >= delta_y && x1 > x2) || (delta_y > delta_x && y1 > y2))
100 int step_x = (x1 < x2 ? 1 : -1);
101 int step_y = (y1 < y2 ? 1 : -1);
102 int error = 0, x = x1, y = y1;
104 std::pair<int, int> add;
105 int gap = agentSize*sqrt(pow(delta_x, 2) + pow(delta_y, 2)) + double(delta_x + delta_y)/2 -
CN_EPS;
107 if(delta_x >= delta_y)
109 int extraCheck = agentSize*delta_y/sqrt(pow(delta_x, 2) + pow(delta_y, 2)) + 0.5 -
CN_EPS;
110 for(
int n = 1; n <= extraCheck; n++)
113 num = (gap - error)/delta_x;
114 for(k = 1; k <= num; k++)
115 lineCells.push_back({x1 - n*step_x, y1 + k*step_y});
116 for(k = 1; k <= num; k++)
117 lineCells.push_back({x2 + n*step_x, y2 - k*step_y});
120 for(x = x1; x != x2 + step_x; x+=step_x)
122 lineCells.push_back({x, y});
123 if(x < x2 - extraCheck)
125 num = (gap + error)/delta_x;
126 for(k = 1; k <= num; k++)
127 lineCells.push_back({x, y + k*step_y});
129 if(x > x1 + extraCheck)
131 num = (gap - error)/delta_x;
132 for(k = 1; k <= num; k++)
133 lineCells.push_back({x, y - k*step_y});
136 if((error<<1) > delta_x)
145 int extraCheck = agentSize*delta_x/sqrt(pow(delta_x, 2) + pow(delta_y, 2)) + 0.5 -
CN_EPS;
146 for(
int n = 1; n <= extraCheck; n++)
149 num = (gap - error)/delta_y;
150 for(k = 1; k <= num; k++)
151 lineCells.push_back({x1 + k*step_x, y1 - n*step_y});
152 for(k = 1; k <= num; k++)
153 lineCells.push_back({x2 - k*step_x, y2 + n*step_y});
156 for(y = y1; y != y2 + step_y; y += step_y)
158 lineCells.push_back({x, y});
159 if(y < y2 - extraCheck)
161 num = (gap + error)/delta_y;
162 for(k = 1; k <= num; k++)
163 lineCells.push_back({x + k*step_x, y});
165 if(y > y1 + extraCheck)
167 num = (gap - error)/delta_y;
168 for(k = 1; k <= num; k++)
169 lineCells.push_back({x - k*step_x, y});
172 if((error<<1) > delta_y)
179 for(k = 0; k < cells.size(); k++)
181 add = {x1 + cells[k].first, y1 + cells[k].second};
182 if(std::find(lineCells.begin(), lineCells.end(), add) == lineCells.end())
183 lineCells.push_back(add);
184 add = {x2 + cells[k].first, y2 + cells[k].second};
185 if(std::find(lineCells.begin(), lineCells.end(), add) == lineCells.end())
186 lineCells.push_back(add);
189 for(
auto it = lineCells.begin(); it != lineCells.end(); it++)
190 if(!map.CellOnGrid(it->first, it->second))
193 it = lineCells.begin();
208 for(
int k = 0; k < cells.size(); k++)
209 if(!map.CellOnGrid(x + cells[k].first, y + cells[k].second) || map.CellIsObstacle(x + cells[k].first, y + cells[k].second))
225 bool checkLine(
int x1,
int y1,
int x2,
int y2,
const T &map)
231 int delta_x = std::abs(x1 - x2);
232 int delta_y = std::abs(y1 - y2);
233 if((delta_x > delta_y && x1 > x2) || (delta_y >= delta_x && y1 > y2))
238 int step_x = (x1 < x2 ? 1 : -1);
239 int step_y = (y1 < y2 ? 1 : -1);
240 int error = 0, x = x1, y = y1;
241 int gap = agentSize*sqrt(pow(delta_x, 2) + pow(delta_y, 2)) + double(delta_x + delta_y)/2 -
CN_EPS;
244 if(delta_x > delta_y)
246 int extraCheck = agentSize*delta_y/sqrt(pow(delta_x, 2) + pow(delta_y, 2)) + 0.5 -
CN_EPS;
247 for(
int n = 1; n <= extraCheck; n++)
250 num = (gap - error)/delta_x;
251 for(k = 1; k <= num; k++)
252 if(map.CellOnGrid(x1 - n*step_x, y1 + k*step_y))
253 if(map.CellIsObstacle(x1 - n*step_x, y1 + k*step_y))
255 for(k = 1; k <= num; k++)
256 if(map.CellOnGrid(x2 + n*step_x, y2 - k*step_y))
257 if(map.CellIsObstacle(x2 + n*step_x, y2 - k*step_y))
261 for(x = x1; x != x2 + step_x; x+=step_x)
263 if(map.CellIsObstacle(x, y))
265 if(x < x2 - extraCheck)
267 num = (gap + error)/delta_x;
268 for(k = 1; k <= num; k++)
269 if(map.CellIsObstacle(x, y + k*step_y))
272 if(x > x1 + extraCheck)
274 num = (gap - error)/delta_x;
275 for(k = 1; k <= num; k++)
276 if(map.CellIsObstacle(x, y - k*step_y))
280 if((error<<1) > delta_x)
289 int extraCheck = agentSize*delta_x/sqrt(pow(delta_x, 2) + pow(delta_y, 2)) + 0.5 -
CN_EPS;
290 for(
int n = 1; n <= extraCheck; n++)
293 num = (gap - error)/delta_y;
294 for(k = 1; k <= num; k++)
295 if(map.CellOnGrid(x1 + k*step_x, y1 - n*step_y))
296 if(map.CellIsObstacle(x1 + k*step_x, y1 - n*step_y))
298 for(k = 1; k <= num; k++)
299 if(map.CellOnGrid(x2 - k*step_x, y2 + n*step_y))
300 if(map.CellIsObstacle(x2 - k*step_x, y2 + n*step_y))
304 for(y = y1; y != y2 + step_y; y += step_y)
306 if(map.CellIsObstacle(x, y))
308 if(y < y2 - extraCheck)
310 num = (gap + error)/delta_y;
311 for(k = 1; k <= num; k++)
312 if(map.CellIsObstacle(x + k*step_x, y))
315 if(y > y1 + extraCheck)
317 num = (gap - error)/delta_y;
318 for(k = 1; k <= num; k++)
319 if(map.CellIsObstacle(x - k*step_x, y))
323 if((error<<1) > delta_y)
340 std::vector<std::pair<int, int>>
getCells(
int i,
int j)
342 std::vector<std::pair<int, int>> cells;
343 for(
int k=0; k<this->cells.size(); k++)
344 cells.push_back({i+this->cells[k].first,j+this->cells[k].second});
350 std::vector<std::pair<int, int>> cells;
354 #endif // LINEOFSIGHT_H bool checkTraversability(int x, int y, const T &map)
Checks traversability of all cells on grid affected by agent's body.
LineOfSight(double agentSize=0.5)
LineOfSight constructor.
void setSize(double agentSize)
Set size of agent.
bool checkLine(int x1, int y1, int x2, int y2, const T &map)
Checks line-of-sight between two cells.
File contains main constants.
std::vector< std::pair< int, int > > getCells(int i, int j)
Returns all cells on grid that are affected by agent in position (i,j).
std::vector< std::pair< int, int > > getCellsCrossedByLine(int x1, int y1, int x2, int y2, const T &map)
Returns all cells on grid that are affected by agent during moving along a line.
This class implements line-of-sight function between two cells on the grid for a variable size of age...
#define CN_EPS
Epsilon for float number operations definition.