00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "VAPoints.h"
00011
00012 #include "Tools/Debugging/Debugging.h"
00013
00014
00015
00016
00017 const double GAUSS0 = 1.0, GAUSS1 = .63, GAUSS2 = .16, GAUSS4 = .40, GAUSS5 = .10;
00018
00019
00020 VAPoints::VAPoints(int numberOfVAPoints, int numberOfMaxima)
00021 {
00022 this->numberOfVAPoints = numberOfVAPoints;
00023 this->numberOfMaxima = numberOfMaxima;
00024
00025 points = new VAPoint[numberOfVAPoints];
00026 maxima = new Maximum[numberOfMaxima];
00027
00028 for(int i = 0; i < numberOfVAPoints; i++)
00029 {
00030 points[i].relevance = 0;
00031 }
00032
00033 int gridX = 0, gridY = 0;
00034
00035 for (gridX = 0; gridX < NUMBER_OF_GRID_POINTS_X; gridX++)
00036 {
00037 for (gridY = 0; gridY < NUMBER_OF_GRID_POINTS_Y; gridY++)
00038 {
00039 field[gridX][gridY] = 0;
00040 }
00041 }
00042
00043 timeOfLastMaximaSearch = SystemCall::getCurrentSystemTime();
00044 }
00045
00046 VAPoints::~VAPoints()
00047 {
00048 delete points;
00049 delete maxima;
00050 }
00051
00052 void VAPoints::addPoint(int x, int y, double validity, unsigned long timestamp)
00053 {
00054 double relevance;
00055 double age = SystemCall::getTimeSince(timestamp);
00056 if (age < validity * FADE_OUT_TIME2)
00057 {
00058 relevance = validity - (age / FADE_OUT_TIME2);
00059 }
00060 else
00061 {
00062 relevance = 0;
00063 }
00064
00065 updateGridByPoint(x, y, relevance);
00066
00067
00068
00069
00070
00071
00072
00073 }
00074
00075 int VAPoints::findInsertPos()
00076 {
00077 double minRelevance = 10;
00078 int insertPos = 0;
00079 double currRelevance;
00080 for(int i = 0; i < numberOfVAPoints; i++)
00081 {
00082 currRelevance = points[i].getRelevance();
00083 if (currRelevance < minRelevance)
00084 {
00085 minRelevance = currRelevance;
00086 insertPos = i;
00087 if (minRelevance == 0) break;
00088 }
00089 }
00090 return insertPos;
00091 }
00092
00093 void VAPoints::searchMaxima()
00094 {
00095 int gridX = 0, gridY = 0, maximum1 = 0, maximum2 = 0, temp = 0;
00096 bool isNear = false;
00097
00098 for (int i=0; i < this->numberOfMaxima; i++)
00099 {
00100 maxima[i].x = -10;
00101 maxima[i].y = -10;
00102 maxima[i].height = 0;
00103 }
00104
00105 double timeSinceLastSearch = SystemCall::getTimeSince(timeOfLastMaximaSearch);
00106 timeOfLastMaximaSearch = SystemCall::getCurrentSystemTime();
00107
00108 double decrement = MIN_HEIGHT_FOR_MAX_VALIDITY * (timeSinceLastSearch / FADE_OUT_TIME2);
00109
00110 for (gridX = 0; gridX < NUMBER_OF_GRID_POINTS_X; gridX++)
00111 {
00112 for (gridY = 0; gridY < NUMBER_OF_GRID_POINTS_Y; gridY++)
00113 {
00114 if (field[gridX][gridY] > MIN_HEIGHT_FOR_MAX_VALIDITY)
00115 {
00116 field[gridX][gridY] -= 2 * decrement;
00117 }
00118 else
00119 {
00120 if (field[gridX][gridY] > decrement)
00121 {
00122 field[gridX][gridY] -= decrement;
00123 }
00124 else
00125 {
00126 field[gridX][gridY] = 0;
00127 }
00128 }
00129 }
00130 }
00131
00132
00133
00134
00135 for (gridX = 0; gridX < NUMBER_OF_GRID_POINTS_X; gridX++)
00136 {
00137 for (gridY = 0; gridY < NUMBER_OF_GRID_POINTS_Y; gridY++)
00138 {
00139 for (maximum1 = 0; maximum1 < this->numberOfMaxima; maximum1++)
00140 {
00141 if (field[gridX][gridY] > maxima[maximum1].height) if (isLokMax(gridX, gridY))
00142 {
00143 isNear = false;
00144 for (maximum2 = 0; maximum2 < this->numberOfMaxima; maximum2++)
00145 {
00146 if ((abs(gridX - maxima[maximum2].x) <= 2) && (abs(gridY - maxima[maximum2].y) <= 2))
00147 {
00148 isNear = true;
00149 if (field[gridX][gridY] > maxima[maximum2].height)
00150 {
00151 for (temp = maximum2; temp > maximum1; temp--)
00152 {
00153 maxima[temp] = maxima[temp - 1];
00154 }
00155 maxima[maximum1].x = gridX;
00156 maxima[maximum1].y = gridY;
00157 maxima[maximum1].height = field[gridX][gridY];
00158 }
00159 break;
00160 }
00161 }
00162
00163 if (isNear) break;
00164
00165 for (temp = this->numberOfMaxima - 1; temp > maximum1; temp--)
00166 {
00167 maxima[temp] = maxima[temp - 1];
00168 }
00169 maxima[maximum1].x = gridX;
00170 maxima[maximum1].y = gridY;
00171 maxima[maximum1].height = field[gridX][gridY];
00172 break;
00173 }
00174 }
00175 }
00176 }
00177 }
00178
00179 bool VAPoints::getMaximum(int index, int& x_position, int& y_position, double& validity)
00180 {
00181 if((index < 0) || (index > this->numberOfMaxima) || (maxima[index].height == 0)) return false;
00182
00183 int fieldX = 0, fieldY = 0;
00184 getFieldPoints(maxima[index].x, maxima[index].y, fieldX, fieldY);
00185
00186 x_position = fieldX;
00187 y_position = fieldY;
00188
00189 if (maxima[index].height > MIN_HEIGHT_FOR_MAX_VALIDITY)
00190 validity = 1.0;
00191 else
00192 validity = maxima[index].height / MIN_HEIGHT_FOR_MAX_VALIDITY;
00193
00194
00195
00196
00197
00198
00199 return true;
00200 }
00201
00202 void VAPoints::pointsToField()
00203 {
00204
00205 int gridX = 0, gridY = 0;
00206
00207 for (gridX = 0; gridX < NUMBER_OF_GRID_POINTS_X; gridX++)
00208 {
00209 for (gridY = 0; gridY < NUMBER_OF_GRID_POINTS_Y; gridY++)
00210 {
00211 field[gridX][gridY] = 0;
00212 }
00213 }
00214
00215 for (int i = 0; i < numberOfVAPoints; i++)
00216 {
00217 updateGridByPoint(points[i].x, points[i].y,points[i].getRelevance());
00218 }
00219 }
00220
00221 void VAPoints::updateGridByPoint(int xPos, int yPos, double relevance)
00222 {
00223 int gridX = 0, gridY = 0;
00224
00225 if (relevance > 0)
00226 {
00227 getGridIndices(xPos, yPos, gridX, gridY);
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282 incrementGridPoint(gridX-1, gridY-2, GAUSS5 * relevance);
00283 incrementGridPoint(gridX, gridY-2, GAUSS2 * relevance);
00284 incrementGridPoint(gridX+1, gridY-2, GAUSS5 * relevance);
00285
00286 incrementGridPoint(gridX-2, gridY-1, GAUSS5 * relevance);
00287 incrementGridPoint(gridX-1, gridY-1, GAUSS4 * relevance);
00288 incrementGridPoint(gridX, gridY-1, GAUSS1 * relevance);
00289 incrementGridPoint(gridX+1, gridY-1, GAUSS4 * relevance);
00290 incrementGridPoint(gridX+2, gridY-1, GAUSS5 * relevance);
00291
00292 incrementGridPoint(gridX-2, gridY, GAUSS2 * relevance);
00293 incrementGridPoint(gridX-1, gridY, GAUSS1 * relevance);
00294 incrementGridPoint(gridX, gridY, GAUSS0 * relevance);
00295 incrementGridPoint(gridX+1, gridY, GAUSS1 * relevance);
00296 incrementGridPoint(gridX+2, gridY, GAUSS2 * relevance);
00297
00298 incrementGridPoint(gridX-2, gridY+1, GAUSS5 * relevance);
00299 incrementGridPoint(gridX-1, gridY+1, GAUSS4 * relevance);
00300 incrementGridPoint(gridX, gridY+1, GAUSS1 * relevance);
00301 incrementGridPoint(gridX+1, gridY+1, GAUSS4 * relevance);
00302 incrementGridPoint(gridX+2, gridY+1, GAUSS5 * relevance);
00303
00304 incrementGridPoint(gridX-1, gridY+2, GAUSS5 * relevance);
00305 incrementGridPoint(gridX, gridY+2, GAUSS2 * relevance);
00306 incrementGridPoint(gridX+1, gridY+2, GAUSS5 * relevance);
00307 }
00308 }
00309
00310 void VAPoints::incrementGridPoint(int xIndex, int yIndex, double increment)
00311 {
00312 if ((xIndex >= 1) && (xIndex <= NUMBER_OF_GRID_POINTS_X - 1) && (yIndex >= 1) && (yIndex <= NUMBER_OF_GRID_POINTS_Y - 1))
00313 {
00314 double fieldHeight = field[xIndex][yIndex];
00315 double realHeight = (MIN_HEIGHT_FOR_MAX_VALIDITY * fieldHeight) / ((2 * MIN_HEIGHT_FOR_MAX_VALIDITY) - fieldHeight);
00316
00317 field[xIndex][yIndex] = (2 * MIN_HEIGHT_FOR_MAX_VALIDITY) - ((2 * MIN_HEIGHT_FOR_MAX_VALIDITY * MIN_HEIGHT_FOR_MAX_VALIDITY) / (realHeight + increment + MIN_HEIGHT_FOR_MAX_VALIDITY));
00318
00319 }
00320 }
00321
00322 void VAPoints::getGridIndices(int xPos, int yPos, int& xIndex, int& yIndex)
00323 {
00324 xIndex = (int)((xPos - xPosBackFlags) / GRID_SPACING);
00325
00326 if(xIndex < 1)
00327 xIndex = 1;
00328 if(xIndex >= NUMBER_OF_GRID_POINTS_X - 1)
00329 xIndex = NUMBER_OF_GRID_POINTS_X - 1;
00330
00331 yIndex = (int)((yPos - yPosRightFlags) / GRID_SPACING);
00332
00333 if(yIndex < 1)
00334 yIndex = 1;
00335 if(yIndex >= NUMBER_OF_GRID_POINTS_Y - 1)
00336 yIndex = NUMBER_OF_GRID_POINTS_Y - 1;
00337 }
00338
00339 void VAPoints::getFieldPoints(int xIndex, int yIndex, int& xPos, int& yPos)
00340 {
00341 xPos = xIndex * GRID_SPACING + xPosBackFlags;
00342 yPos = yIndex * GRID_SPACING + yPosRightFlags;
00343 }
00344
00345 bool VAPoints::isLokMax(int xIndex, int yIndex)
00346 {
00347 bool result = true;
00348
00349 for (int gridX = xIndex-1; gridX <= xIndex+1; gridX++)
00350 {
00351 for (int gridY = yIndex-1; gridY <= yIndex+1; gridY++)
00352 {
00353 if ((gridX == xIndex) && (gridY == yIndex)) break;
00354 if ((xIndex >= 2) && (xIndex <= NUMBER_OF_GRID_POINTS_X - 2) && (yIndex >= 2) && (yIndex <= NUMBER_OF_GRID_POINTS_Y - 2))
00355 result &= (field[xIndex][yIndex] > field[gridX][gridY]);
00356 }
00357 }
00358 return result;
00359 }
00360
00361
00362
00363 In& operator>>(In& stream,VAPoints& VAPoints)
00364 {
00365 stream >> VAPoints.numberOfVAPoints;
00366 stream.read(&VAPoints.points,sizeof(VAPoints.points));
00367 return stream;
00368 }
00369
00370 Out& operator<<(Out& stream, const VAPoints& vaPoints)
00371 {
00372 stream << vaPoints.numberOfVAPoints;
00373 stream.write(&vaPoints.points, sizeof(vaPoints.points));
00374 return stream;
00375 }
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430