libnxter  0.1
Map.nxc
Go to the documentation of this file.
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3  Map.nxc
4  Copyright (C) 2008 Naba Kumar <naba@gnome.org>
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program; if not, write to the Free Software
18  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
25 #ifndef __MAP_H_
26 #define __MAP_H_
27 
28 #include "Screen.nxc"
29 #include "Angle.nxc"
30 #include "Vector.nxc"
31 
32 #define MAP_X(map, index) (map.landmarks[(index * 2)]);
33 #define MAP_Y(map, index) (map.landmarks[(index * 2) + 1]);
34 
38 struct Map
39 {
40  long landmarks[];
41 };
42 
47 void MapArrayLandmarks(Map &map, long &landmarks[])
48 {
49  ArrayBuild(map.landmarks, landmarks);
50 }
51 
55 void MapAddLandMark(Map &map, int x, int y)
56 {
57  ArrayBuild(map.landmarks, x, y);
58 }
59 
64 {
65  return ArrayLen(map.landmarks)/2;
66 }
67 
71 void MapGetLandmark(Map &map, int index, Vector &vec)
72 {
73  long x, y;
74 
75  x = MAP_X(map, index);
76  y = MAP_Y(map, index);
77  VectorInit(vec, x, y, 0);
78 }
79 
93 bool MapFindNearestLandmarkAtAngle(Map &map, Vector &reference, int minAngle,
94  int maxAngle, Vector &retLandmark)
95 {
96  long minDistance = 20000000;
97  long minIndex = -1;
98  int size;
99  int flipCheck = false;
100  int angleDiff = maxAngle;
101 
102  if (minAngle > maxAngle) flipCheck = true;
103 
104  size = MapGetNumLandmarks(map);
105  for (int i = 0; i < size; i++)
106  {
107  Vector landmark;
108  MapGetLandmark(map, i, landmark);
109  VectorSubtract(landmark, reference);
110  long distance = VectorGetDistanceVec(reference, landmark);
111  int angle = VectorGetAngleVec(reference, landmark);
112  if (flipCheck == false && (angle >= minAngle && angle <= maxAngle) &&
113  distance < minDistance)
114  {
115  minIndex = i;
116  minDistance = distance;
117  }
118  else if (flipCheck == true && (angle >= minAngle || angle <= maxAngle) &&
119  distance < minDistance)
120  {
121  minIndex = i;
122  minDistance = distance;
123  }
124  }
125  if (minIndex >= 0)
126  {
127  MapGetLandmark(map, minIndex, retLandmark);
128  return true;
129  }
130  return false;
131 }
132 
142  int minAngle, int maxAngle,
143  Vector &landmark1, Vector &landmark2)
144 {
145  bool found1 = false;
146  bool found2 = false;
147  int min, mid, max;
148  Vector lm1, lm2;
149 
150  min = minAngle;
151  max = maxAngle;
152 
153  while (true)
154  {
155  int angleDiff = maxAngle;
156  angleDiff = AngleAbsSub(angleDiff, minAngle);
157 
158  // Print("maxAngle= %d", maxAngle, 0);
159  // Print("minAngle = %d", minAngle, 0);
160  // Print("angleDiff = %d", angleDiff, 1000);
161 
162  /* Calculate mid of current min-max */
163  mid = min;
164  mid = AngleAbsAdd(mid, angleDiff/2);
165 
166  found1 = MapFindNearestLandmarkAtAngle(map, reference, min, mid, lm1);
167  found2 = MapFindNearestLandmarkAtAngle(map, reference, mid, max, lm2);
168 
169  if (found1 == false && found2 == false)
170  return false;
171  if (found1 == true && found2 == true)
172  {
173  landmark1 = lm1;
174  landmark2 = lm2;
175  return true;
176  }
177  if (angleDiff < 20) /* Angle too acute */
178  {
179  return false;
180  }
181  if (found1 == true) /* Only found in 1st half */
182  {
183  max = mid;
184  }
185  else /* Only found in 2nd half */
186  {
187  min = mid;
188  }
189  }
190 }
191 
198 bool MapFindNearestLandmark(Map &map, Vector &reference, Vector &retLandmark)
199 {
200  int size;
201  long minDistance = 2000000000;
202  long distance;
203 
204  size = MapGetNumLandmarks(map);
205  if (size <= 0) return false;
206 
207  for (int i = 0; i < size; i++)
208  {
209  Vector landmark;
210  MapGetLandmark(map, i, landmark);
211  VectorSubtract(landmark, reference);
212  distance = VectorGetDistance(landmark);
213  if (distance > minDistance)
214  {
215  minDistance = distance;
216  MapGetLandmark(map, i, retLandmark);
217  }
218  }
219  return true;
220 }
221 
222 #ifdef ENABLE_TEST
223 
224 long testLandmarks[4] = {250, 250, 250, -250, -250, 250, -250, -250};
225 void TestMap()
226 {
227  bool found;
228  Map map;
229  Vector reference, detectedObject, landmark1, landmark2;
230 
231  MapArrayLandmarks(map, testLandmarks);
232 
233  VectorInit(reference, 0, 0, 0);
234  found = MapFindNearestLandmarkAtAngle(map, reference, 350, 105,
235  detectedObject);
236  TEST((found == true), "No landmark at 45");
237  TEST((detectedObject.x == 250 && detectedObject.y == 250),
238  "No object 1");
239 
240  found = MapFindNearestLandmarkAtAngle(map, reference, 75, 195,
241  detectedObject);
242  TEST((found == true), "No landmark at 135");
243  TEST((detectedObject.x == -250 && detectedObject.y == 250),
244  "No object 2");
245 
246  found = MapFindNearestLandmarkAtAngle(map, reference, 165, 285,
247  detectedObject);
248  TEST((found == true), "No landmark at 225");
249  TEST((detectedObject.x == -250 && detectedObject.y == -250),
250  "No object 3");
251 
252  found = MapFindNearestLandmarkAtAngle(map, reference, 225, 375,
253  detectedObject);
254  TEST((found == true), "No landmark at 315");
255  TEST((detectedObject.x == 250 && detectedObject.y == -250),
256  "No object 4");
257 
258  found = MapFindTriangulationLandmarks(map, reference, 280, 80,
259  landmark1, landmark2);
260  TEST((found == true), "landmark tri at 0");
261  TEST((landmark1.x == 250 && landmark1.y == -250),
262  "No tri object 1");
263  TEST((landmark2.x == 250 && landmark2.y == 250),
264  "No tri object 2");
265 
266  found = MapFindTriangulationLandmarks(map, reference, 10, 170,
267  landmark1, landmark2);
268  TEST((found == true), "landmark tri at 90");
269  TEST((landmark1.x == 250 && landmark1.y == 250),
270  "No tri object 1");
271  TEST((landmark2.x == -250 && landmark2.y == 250),
272  "No tri object 2");
273 
274  found = MapFindTriangulationLandmarks(map, reference, 110, 260,
275  landmark1, landmark2);
276  TEST((found == true), "landmark tri at 90");
277  TEST((landmark1.x == -250 && landmark1.y == 250),
278  "No tri object 1");
279  TEST((landmark2.x == -250 && landmark2.y == -250),
280  "No tri object 2");
281 
282  found = MapFindTriangulationLandmarks(map, reference, 190, 350,
283  landmark1, landmark2);
284  TEST((found == true), "landmark tri at 90");
285  TEST((landmark1.x == -250 && landmark1.y == -250),
286  "No tri object 1");
287  TEST((landmark2.x == 250 && landmark2.y == -250),
288  "No tri object 2");
289 }
290 /*
291 task main()
292 {
293  TestMap();
294 }
295 */
296 #endif /* ENABLE_TEST */
297 #endif /* __MAP_H_ */
298 
void MapArrayLandmarks(Map &map, long &landmarks[])
Initializes the Map with an array of landmarks. The array has alternate x and y positions of the land...
Definition: Map.nxc:47
A vector that represents a 2D point by x-y coordinates and a direction angle.
Definition: Vector.nxc:43
void MapGetLandmark(Map &map, int index, Vector &vec)
Gets a landmark at the given index and returns it in the provide vector.
Definition: Map.nxc:71
void MapAddLandMark(Map &map, int x, int y)
Adds a landmark (x,y) to the map.
Definition: Map.nxc:55
long VectorGetDistanceVec(Vector &a, Vector &b)
Gets the distance between given two vectors.
Definition: Vector.nxc:100
long VectorGetDistance(Vector &a)
Gets the polar distance of the given vector. It's the distance of its x-y coordicate from origin...
Definition: Vector.nxc:76
int AngleAbsAdd(int absAngleA, int angle)
Adds angle to an absolute angle (0 .. 360) absAngleA. Returns an absolute angle properly truncated to...
Definition: Angle.nxc:65
A simple 3-components vector implementation (2D point + direction)
Map class to hold a collection of landmarks.
Definition: Map.nxc:38
void VectorSubtract(Vector &a, Vector &b)
Subtracts vector b from a. i.e. a -= b.
Definition: Vector.nxc:182
int MapGetNumLandmarks(Map &map)
Returns the number of landmarks currently present in the map.
Definition: Map.nxc:63
bool MapFindNearestLandmark(Map &map, Vector &reference, Vector &retLandmark)
Finds the nearest landmard around the reference vector.
Definition: Map.nxc:198
bool MapFindTriangulationLandmarks(Map &map, Vector &reference, int minAngle, int maxAngle, Vector &landmark1, Vector &landmark2)
Finds two nearest landmarks around the reference vector within the bounds of given minAngle and maxAn...
Definition: Map.nxc:141
Provides simple arithmetic for absolute and relative angles.
long y
Definition: Vector.nxc:46
bool MapFindNearestLandmarkAtAngle(Map &map, Vector &reference, int minAngle, int maxAngle, Vector &retLandmark)
Finds the nearest landmark around the reference vector within the bounds of given minAngle and maxAng...
Definition: Map.nxc:93
long x
Definition: Vector.nxc:45
int AngleAbsSub(int absAngleA, int angle)
Subtracts angle from an absolute angle (0 .. 360) absAngleA. Returns an absolute angle properly trunc...
Definition: Angle.nxc:76
Display functions for text and graphs.
long VectorGetAngleVec(Vector &a, Vector &b)
Gets the angle of the line formed by the given two vectors.
Definition: Vector.nxc:110
void VectorInit(Vector &a, long x, long y, long theta)
Initializes the vector with given x, y and theta components.
Definition: Vector.nxc:122