1 package cz.cuni.amis.pogamut.defcon.communication.worldview.modules.grid.basic;
2
3 import java.util.LinkedList;
4 import java.util.List;
5
6 import cz.cuni.amis.pogamut.base3d.worldview.object.Location;
7 import cz.cuni.amis.pogamut.defcon.communication.worldview.modules.grid.IGridIterator;
8 import cz.cuni.amis.pogamut.defcon.communication.worldview.modules.grid.basic.BasicGrid.CellIndices;
9
10
11
12
13
14
15
16 public class BasicGridIterator implements
17 IGridIterator<SymmetricGridCell, SymmetricGridCellId> {
18
19 private Location cellLocation;
20 private CellIndices indices;
21 private BasicGrid grid;
22
23 private SymmetricGridCell cell;
24
25 public BasicGridIterator(SymmetricGridCellId cellId, BasicGrid grid) {
26 this.grid = grid;
27 this.cell = grid.getCell(cellId);
28 this.cellLocation = cellId.getLocation();
29 this.indices = grid.getCellIndices(cellId);
30 }
31
32 @Override
33 public SymmetricGridCell getCell() {
34 return cell;
35 }
36
37 @Override
38 public SymmetricGridCell getBottomNeighbourCell() {
39 return grid.getCell(indices.getX(), indices.getY() + grid.getGridStep());
40 }
41
42 @Override
43 public SymmetricGridCell getLeftNeighbourCell() {
44 return grid.getCell(indices.getX() - grid.getGridStep(), indices.getY());
45 }
46
47 @Override
48 public SymmetricGridCell getRightNeighbourCell() {
49 return grid.getCell(indices.getX() + grid.getGridStep(), indices.getY());
50 }
51
52 @Override
53 public SymmetricGridCell getTopNeighbourCell() {
54 return grid.getCell(indices.getX(), indices.getY() - grid.getGridStep());
55 }
56
57 @Override
58 public SymmetricGridCell getBottomLeftNeighbourCell() {
59 return grid.getCell(indices.getX() - grid.getGridStep(), indices.getY() + grid.getGridStep());
60 }
61
62 @Override
63 public SymmetricGridCell getBottomRightNeighbourCell() {
64 return grid.getCell(indices.getX() + grid.getGridStep(), indices.getY() + grid.getGridStep());
65 }
66
67 @Override
68 public SymmetricGridCell getTopLeftNeighbourCell() {
69 return grid.getCell(indices.getX() - grid.getGridStep(), indices.getY() - grid.getGridStep());
70 }
71
72 @Override
73 public SymmetricGridCell getTopRightNeighbourCell() {
74 return grid.getCell(indices.getX() + grid.getGridStep(), indices.getY() - grid.getGridStep());
75 }
76
77 @Override
78 public List<SymmetricGridCell> getListOfNeighbouringCells() {
79 LinkedList<SymmetricGridCell> cells = new LinkedList<SymmetricGridCell>();
80 cells.add(getBottomNeighbourCell());
81 cells.add(getLeftNeighbourCell());
82 cells.add(getRightNeighbourCell());
83 cells.add(getTopNeighbourCell());
84 cells.add(getBottomLeftNeighbourCell());
85 cells.add(getBottomRightNeighbourCell());
86 cells.add(getTopLeftNeighbourCell());
87 cells.add(getTopRightNeighbourCell());
88 return cells;
89 }
90
91 private enum Direction {
92 TOP(0, -1), TOP_RIGHT(1, -1), RIGHT(1, 0), BOTTOM_RIGHT(1, 1), BOTTOM(
93 0, 1), BOTTOM_LEFT(-1, 1), LEFT(-1, 0), TOP_LEFT(-1, -1);
94
95 private Direction(int x, int y) {
96 this.x = x;
97 this.y = y;
98 }
99
100 public final int x;
101 public final int y;
102 };
103
104 @Override
105 public SymmetricGridCell getNeighbourCellInDirection(Location direction) {
106 Location tested_direction = new Location(1, 0);
107 double maximal_dot = direction.dot(tested_direction);
108 double current_dot;
109 Direction dir = Direction.RIGHT;
110
111 tested_direction = tested_direction.setY(1);
112 if ((current_dot = direction.dot(tested_direction)) > maximal_dot) {
113 dir = Direction.BOTTOM_RIGHT;
114 maximal_dot = current_dot;
115 }
116
117 tested_direction = tested_direction.setX(0);
118 if ((current_dot = direction.dot(tested_direction)) > maximal_dot) {
119 dir = Direction.BOTTOM;
120 maximal_dot = current_dot;
121 }
122
123 tested_direction = tested_direction.setX(-1);
124 if ((current_dot = direction.dot(tested_direction)) > maximal_dot) {
125 dir = Direction.BOTTOM_LEFT;
126 maximal_dot = current_dot;
127 }
128
129 tested_direction = tested_direction.setY(0);
130 if ((current_dot = direction.dot(tested_direction)) > maximal_dot) {
131 dir = Direction.BOTTOM_RIGHT;
132 maximal_dot = current_dot;
133 }
134
135 tested_direction = tested_direction.setY(-1);
136 if ((current_dot = direction.dot(tested_direction)) > maximal_dot) {
137 dir = Direction.LEFT;
138 maximal_dot = current_dot;
139 }
140
141 tested_direction = tested_direction.setX(0);
142 if ((current_dot = direction.dot(tested_direction)) > maximal_dot) {
143 dir = Direction.TOP;
144 maximal_dot = current_dot;
145 }
146
147 switch (dir) {
148 case TOP:
149 return getTopNeighbourCell();
150 case TOP_RIGHT:
151 return getTopRightNeighbourCell();
152 case RIGHT:
153 return getRightNeighbourCell();
154 case BOTTOM_RIGHT:
155 return getBottomRightNeighbourCell();
156 case BOTTOM:
157 return getBottomNeighbourCell();
158 case BOTTOM_LEFT:
159 return getBottomLeftNeighbourCell();
160 case LEFT:
161 return getLeftNeighbourCell();
162 case TOP_LEFT:
163 return getTopLeftNeighbourCell();
164 default:
165 return null;
166 }
167 }
168
169 @Override
170 public LinkedList<SymmetricGridCellId> getCellsInRadiusOf(float radius) {
171
172 LinkedList<SymmetricGridCellId> list = new LinkedList<SymmetricGridCellId>();
173 int normed_radius = (int) Math.floor(radius/grid.getGridStep());
174 int y_base = (int) cellLocation.getY();
175
176 double x = cellLocation.getX() - normed_radius;
177 double y = cellLocation.getY();
178
179 for (;
180 x <= (int) (cellLocation.getX() + normed_radius);
181 ++x) {
182
183 y = y_base;
184
185 while (new Location(x, y).sub(cellLocation).getLength() < radius) {
186 ++y;
187 }
188
189 int y_diff = (int) (y - y_base - grid.getGridStep());
190
191 for (y = y_base - y_diff; y <= y_base + y_diff; ++y) {
192 list.add(new SymmetricGridCellId(new Location(x,y)));
193 }
194 }
195
196 return list;
197 }
198
199 @Override
200 public SymmetricGridCell moveToBottomLeftNeighbourCell() {
201 cell = getBottomLeftNeighbourCell();
202 cellLocation = cell.getCellId().getLocation();
203 indices = grid.getCellIndices((SymmetricGridCellId) cell.getCellId());
204 return cell;
205 }
206
207 @Override
208 public SymmetricGridCell moveToBottomNeighbourCell() {
209 cell = getBottomNeighbourCell();
210 cellLocation = cell.getCellId().getLocation();
211 indices = grid.getCellIndices((SymmetricGridCellId) cell.getCellId());
212 return cell;
213 }
214
215 @Override
216 public SymmetricGridCell moveToBottomRightNeighbourCell() {
217 cell = getBottomRightNeighbourCell();
218 cellLocation = cell.getCellId().getLocation();
219 indices = grid.getCellIndices((SymmetricGridCellId) cell.getCellId());
220 return cell;
221 }
222
223 @Override
224 public SymmetricGridCell moveToLeftNeighbourCell() {
225 cell = getLeftNeighbourCell();
226 cellLocation = cell.getCellId().getLocation();
227 indices = grid.getCellIndices((SymmetricGridCellId) cell.getCellId());
228 return cell;
229 }
230
231 @Override
232 public SymmetricGridCell moveToNeighbourCellInDirection(Location direction) {
233 cell = moveToNeighbourCellInDirection(direction);
234 cellLocation = cell.getCellId().getLocation();
235 indices = grid.getCellIndices((SymmetricGridCellId) cell.getCellId());
236 return cell;
237 }
238
239 @Override
240 public SymmetricGridCell moveToRightNeighbourCell() {
241 cell = getRightNeighbourCell();
242 cellLocation = cell.getCellId().getLocation();
243 indices = grid.getCellIndices((SymmetricGridCellId) cell.getCellId());
244 return cell;
245 }
246
247 @Override
248 public SymmetricGridCell moveToTopLeftNeighbourCell() {
249 cell = getTopLeftNeighbourCell();
250 cellLocation = cell.getCellId().getLocation();
251 indices = grid.getCellIndices((SymmetricGridCellId) cell.getCellId());
252 return cell;
253 }
254
255 @Override
256 public SymmetricGridCell moveToTopNeighbourCell() {
257 cell = getTopNeighbourCell();
258 cellLocation = cell.getCellId().getLocation();
259 indices = grid.getCellIndices((SymmetricGridCellId) cell.getCellId());
260 return cell;
261 }
262
263 @Override
264 public SymmetricGridCell moveToTopRightNeighbourCell() {
265 cell = getTopRightNeighbourCell();
266 cellLocation = cell.getCellId().getLocation();
267 indices = grid.getCellIndices((SymmetricGridCellId) cell.getCellId());
268 return cell;
269 }
270 }