Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

Modules/PlayersLocator/PointsWithValidityAndAge.cpp

Go to the documentation of this file.
00001 /**
00002  *  @file PointsWithValidityAndAge.cpp
00003  *
00004  *  Represents a set of points on the field. 
00005  *  It is used to determine the location of other players on the field.
00006  *  If a new point is added and there are as many points in the set as it can held,
00007  *  the oldest point is overwritten.
00008  *
00009  *  @author <A href=mailto:juengel@informatik.hu-berlin.de>Matthias Juengel</A>
00010  *  @author <A href=mailto:kspiess@informatik.uni-bremen.de>Kai Spiess</A>
00011  */
00012 
00013 #include "PointsWithValidityAndAge.h"
00014 
00015 #include <string.h>
00016 
00017 
00018 /*
00019 PointsWithValidityAndAge::PointsWithValidityAndAge()
00020 {
00021   this->numberOfPoints = 0;
00022   this->indexOfNextPoint = 0;
00023   this->sizeOfSet = 0;
00024 
00025   for(int k = 0; k < this->MAX_NUMBER_OF_POINTS_WITH_AGE; k++)
00026   {
00027     x[k] = 9999;
00028     y[k] = 9999;
00029     xDistribution[k] = 0;
00030     yDistribution[k] = 0;
00031   }
00032 }
00033 */
00034 
00035 /*
00036 PointsWithValidityAndAge::PointsWithValidityAndAge(short int sizeOfSet)
00037 {
00038   this->numberOfPoints = 0;
00039   this->indexOfNextPoint = 0;
00040   this->sizeOfSet = sizeOfSet;
00041 //  this->x = new short int[sizeOfSet];
00042 
00043   for(int k = 0; k < this->sizeOfSet; k++)
00044   {
00045     x[k] = 9999;
00046     y[k] = 9999;
00047     xDistribution[k] = 0;
00048     yDistribution[k] = 0;
00049   }
00050 }
00051 */
00052 
00053 PointsWithValidityAndAge::PointsWithValidityAndAge(short int sizeOfSet)
00054 {
00055   this->numberOfPoints = 0;
00056   this->indexOfNextPoint = 0;
00057   this->sizeOfSet = sizeOfSet;
00058 //  this->x = new short int[sizeOfSet];
00059 
00060   int k;
00061   for(k = 0; k < this->sizeOfSet; k++)
00062   {
00063     x[k] = 9999;
00064     y[k] = 9999;
00065   }
00066   for(k = 0; k < this->NUMBER_OF_GRID_POINTS_X; k++)
00067   {
00068     xDistribution[k] = 0;
00069   }
00070   for(k = 0; k < this->NUMBER_OF_GRID_POINTS_Y; k++)
00071   {
00072     yDistribution[k] = 0;
00073   }
00074 }
00075 
00076 PointsWithValidityAndAge::~PointsWithValidityAndAge()
00077 {
00078 }
00079 
00080 void PointsWithValidityAndAge::setSizeOfSet(int size)
00081 {
00082   this->sizeOfSet = size;
00083 }
00084 
00085 void PointsWithValidityAndAge::add(int x, int y)
00086 {
00087   short int index = getIndexOfNextPoint();
00088   short int x_position, y_position;
00089 
00090   // remove the old value from the distribution
00091   if(index < numberOfPoints && this->x[index] != 9999)
00092   {
00093     x_position = (int)((this->x[index] - xPosBackFlags) / GRID_SPACING);
00094     
00095     if(x_position < 1) x_position = 1;
00096     if(x_position >= NUMBER_OF_GRID_POINTS_X - 1) x_position = NUMBER_OF_GRID_POINTS_X - 1;
00097     
00098     xDistribution[x_position - 1] -= 1;
00099     xDistribution[x_position]     -= 2;
00100     xDistribution[x_position + 1] -= 1;
00101     
00102     y_position = (int)((this->y[index] - yPosRightFlags) / GRID_SPACING);
00103     
00104     if(y_position < 1) y_position = 1;
00105     if(y_position >= NUMBER_OF_GRID_POINTS_Y - 1) y_position = NUMBER_OF_GRID_POINTS_Y - 1;
00106     
00107     yDistribution[y_position - 1] -= 1;
00108     yDistribution[y_position]     -= 2;
00109     yDistribution[y_position + 1] -= 1;
00110   }
00111 
00112   //write the new value to the list
00113   this->x[index] = x;
00114   this->y[index] = y;
00115 
00116   // add the new value to the distribution
00117   if(this->x[index] != 9999)
00118   {
00119     x_position = (int)((this->x[index] - xPosBackFlags) / GRID_SPACING);
00120     
00121     if(x_position < 1) x_position = 1;
00122     if(x_position >= NUMBER_OF_GRID_POINTS_X - 1) x_position = NUMBER_OF_GRID_POINTS_X - 1;
00123     
00124     xDistribution[x_position - 1] += 1;
00125     xDistribution[x_position]     += 2;
00126     xDistribution[x_position + 1] += 1;
00127     
00128     y_position = (int)((this->y[index] - yPosRightFlags) / GRID_SPACING);
00129     
00130     if(y_position < 1) y_position = 1;
00131     if(y_position >= NUMBER_OF_GRID_POINTS_Y - 1) y_position = NUMBER_OF_GRID_POINTS_Y - 1;
00132     
00133     yDistribution[y_position - 1] += 1;
00134     yDistribution[y_position]     += 2;
00135     yDistribution[y_position + 1] += 1;
00136   }
00137 
00138   //calculate new number of points
00139   if(numberOfPoints < this->sizeOfSet)
00140     this->numberOfPoints++;
00141 }
00142 
00143 
00144 short int PointsWithValidityAndAge::getIndexOfNextPoint()
00145 {
00146   short int toReturn = this->indexOfNextPoint;
00147   indexOfNextPoint++;
00148   if (indexOfNextPoint >= this->sizeOfSet)
00149   {
00150     indexOfNextPoint = 0;
00151   }
00152   return toReturn;
00153 }
00154 
00155 
00156 void PointsWithValidityAndAge::calculateXYDistribution()
00157 {
00158   //reset distributions
00159   memset(xDistribution, 0, sizeof(xDistribution));
00160   memset(yDistribution, 0, sizeof(yDistribution));
00161   
00162   for(int i = 0; i < this->sizeOfSet; i++)
00163   {
00164     if(x[i] != 9999)
00165     {
00166       //calculate x position in grid an correct it
00167       short int x_position = (int)((x[i] - xPosBackFlags) / GRID_SPACING);
00168       if(x_position < 1) x_position = 1;
00169       if(x_position >= NUMBER_OF_GRID_POINTS_X - 1) x_position = NUMBER_OF_GRID_POINTS_X - 1;
00170 
00171       //add distribution for the point in x direction
00172       xDistribution[x_position - 1] += 1;
00173       xDistribution[x_position]     += 2;
00174       xDistribution[x_position + 1] += 1;
00175 
00176       //calculate y position in grid an correct it
00177       short int y_position = (int)((y[i] - yPosRightFlags) / GRID_SPACING);
00178       if(y_position < 1) y_position = 1;
00179       if(y_position >= NUMBER_OF_GRID_POINTS_Y - 1) y_position = NUMBER_OF_GRID_POINTS_Y - 1;
00180 
00181       //add distribution for the point in y direction
00182       yDistribution[y_position - 1] += 1;
00183       yDistribution[y_position]     += 2;
00184       yDistribution[y_position + 1] += 1;
00185     }
00186   }
00187 }
00188 
00189 
00190 void PointsWithValidityAndAge::findMaximaInXYDistribution()
00191 {
00192   int currentMaximum = 0;
00193   int indexOfCurrentMaximum = 0;
00194   int indexOfNextHill = 0;
00195   bool hereIsAHill = false;
00196   int i;
00197 
00198   for(i = 0; i < NUMBER_OF_GRID_POINTS_X; i++)
00199   {
00200     //update index of the maximum in the x distribution
00201     if(xDistribution[i] > currentMaximum)
00202     {
00203       currentMaximum = xDistribution[i];
00204       indexOfCurrentMaximum = i;
00205     }
00206     // detect hilll, if the value of the x distribution is higher than 4 
00207     // and higher thanmaximum * 0.5
00208     if(xDistribution[i] > 4 && xDistribution[i] > currentMaximum * 0.5)
00209     {
00210       if(!hereIsAHill)
00211       {
00212         hereIsAHill = true;
00213       }
00214     }
00215     else
00216     {
00217       if(hereIsAHill)
00218       {
00219         //store index of located maximum in x distribution in xHills
00220         xHills[indexOfNextHill] = indexOfCurrentMaximum;
00221         if(indexOfNextHill < 8)
00222           indexOfNextHill++;
00223         currentMaximum = 0;
00224         hereIsAHill = false;
00225       }
00226     }
00227   }
00228   // set number of hills in x distribution
00229   this->numberOf_xHills = indexOfNextHill;
00230 
00231   // find maxima for y distribution
00232   currentMaximum = 0;
00233   indexOfCurrentMaximum = 0;
00234   indexOfNextHill = 0;
00235   hereIsAHill = false;
00236   for(i = 0; i < NUMBER_OF_GRID_POINTS_Y; i++)
00237   {
00238     //update index of the maximum in the y distribution
00239     if(yDistribution[i] > currentMaximum)
00240     {
00241       currentMaximum = yDistribution[i];
00242       indexOfCurrentMaximum = i;
00243     }
00244     // detect hilll, if the value of the x distribution is higher than 4 
00245     // and higher thanmaximum * 0.5
00246     if(yDistribution[i] > 4 && yDistribution[i] > currentMaximum * 0.5)
00247     {
00248       if(!hereIsAHill)
00249       {
00250         hereIsAHill = true;
00251       }
00252     }
00253     else
00254     {
00255       if(hereIsAHill)
00256       {
00257         //store index of located maximum in x distribution in xHills
00258         yHills[indexOfNextHill] = indexOfCurrentMaximum;
00259         if(indexOfNextHill < 8)
00260           indexOfNextHill++;
00261         currentMaximum = 0;
00262         hereIsAHill = false;
00263       }
00264     }
00265   }
00266   // set number of hills in y distribution
00267   this->numberOf_yHills = indexOfNextHill;
00268 }
00269 
00270 
00271 void PointsWithValidityAndAge::voteForHills()
00272 {
00273   int xHill, yHill;
00274   // reset the votes for hills
00275   memset(voteHills, 0, sizeof(voteHills));
00276   // calculate for every point in the set the distance to all possible hills
00277   // the hill with the shortest distance gets a vote
00278   for(int i = 0; i < this->sizeOfSet; i++)
00279   {
00280     int smallestDistance = 999999;
00281     int currentDistance;
00282     int x_votum = 0;
00283     int y_votum = 0;
00284     if(x[i] != 9999)
00285     {
00286       for(int xHill = 0; xHill < numberOf_xHills; xHill++)
00287       {
00288         for(int yHill = 0; yHill < numberOf_yHills; yHill++)
00289         {
00290           currentDistance = 
00291             calculateDistance(
00292             x[i],
00293             y[i],
00294             xHills[xHill] * GRID_SPACING + xPosBackFlags,
00295             yHills[yHill] * GRID_SPACING + yPosRightFlags);
00296           if(currentDistance < smallestDistance)
00297           {
00298             x_votum = xHill; y_votum = yHill;
00299             smallestDistance = currentDistance;
00300           }
00301         }
00302       }
00303       voteHills[x_votum][y_votum] += 1;
00304     }
00305   }
00306 
00307 
00308   int topVote1 = 0;
00309   int topVote2 = 0;
00310   int topVote3 = 0;
00311   int topVote4 = 0;
00312   numberOfObstacles = 0;
00313   // make a ranking over all voted hills, best first;
00314   // the votes must lie over the vote threshold;
00315   // hills with better votings as the best four are sorted in the topvotes;
00316   // increase number of detected objects for each vote entered in the ranking;
00317   for(xHill = 0; xHill < numberOf_xHills; xHill++)
00318   {
00319     for(yHill = 0; yHill < numberOf_yHills; yHill++)
00320     {
00321       //insert vote at first position
00322       if(voteHills[xHill][yHill] > topVote1 
00323         && voteHills[xHill][yHill] > VOTE_THRESHOLD)
00324       {
00325         topVote4 = topVote3;
00326         topVote3 = topVote2;
00327         topVote2 = topVote1;
00328         topVote1 = voteHills[xHill][yHill];
00329         x_vote[3] = x_vote[2];
00330         y_vote[3] = y_vote[2];
00331         x_vote[2] = x_vote[1];
00332         y_vote[2] = y_vote[1];
00333         x_vote[1] = x_vote[0];
00334         y_vote[1] = y_vote[0];
00335         x_vote[0] = xHills[xHill] * GRID_SPACING + xPosBackFlags;
00336         y_vote[0] = yHills[yHill] * GRID_SPACING + yPosRightFlags;
00337         numberOfObstacles++;
00338       }
00339       //insert vote at second position
00340       else if(voteHills[xHill][yHill] > topVote2 
00341         && voteHills[xHill][yHill] > VOTE_THRESHOLD)
00342       {
00343         topVote4 = topVote3;
00344         topVote3 = topVote2;
00345         topVote2 = voteHills[xHill][yHill];
00346         x_vote[3] = x_vote[2];
00347         y_vote[3] = y_vote[2];
00348         x_vote[2] = x_vote[1];
00349         y_vote[2] = y_vote[1];
00350         x_vote[1] = xHills[xHill] * GRID_SPACING + xPosBackFlags;
00351         y_vote[1] = yHills[yHill] * GRID_SPACING + yPosRightFlags;
00352         numberOfObstacles++;
00353       }
00354       //insert vote at third position
00355       else if(voteHills[xHill][yHill] > topVote3
00356         && voteHills[xHill][yHill] > VOTE_THRESHOLD)
00357       {
00358         topVote4 = topVote3;
00359         topVote3 = voteHills[xHill][yHill];
00360         x_vote[3] = x_vote[2];
00361         y_vote[3] = y_vote[2];
00362         x_vote[2] = xHills[xHill] * GRID_SPACING + xPosBackFlags;
00363         y_vote[2] = yHills[yHill] * GRID_SPACING + yPosRightFlags;
00364         numberOfObstacles++;
00365       }
00366       //insert vote at fourth position
00367       else if(voteHills[xHill][yHill] > topVote4
00368         && voteHills[xHill][yHill] > VOTE_THRESHOLD)
00369       {
00370         topVote4 = voteHills[xHill][yHill];
00371         x_vote[3] = xHills[xHill] * GRID_SPACING + xPosBackFlags;
00372         y_vote[3] = yHills[yHill] * GRID_SPACING + yPosRightFlags;
00373         numberOfObstacles++;
00374       }
00375     }
00376   }
00377 }
00378 
00379 
00380 bool PointsWithValidityAndAge::getPositionOfObstacle
00381 (
00382  int index, int* x_position, int* y_position)
00383 {
00384   if(index < 0 || index > 3 || index > numberOfObstacles - 1) return false;
00385   *x_position = this->x_vote[index];
00386   *y_position = this->y_vote[index];
00387   return true;
00388 }
00389 
00390 
00391 int PointsWithValidityAndAge::calculateDistance(int x1, int y1, int x2, int y2)
00392 {
00393   return (int)sqrt((double)( ((x1-x2)*(x1-x2)) + ((y1-y2)*(y1-y2)) ));
00394 }
00395 
00396 
00397 // Streaming operators
00398 In& operator>>(In& stream,PointsWithValidityAndAge& pointsWithValidityAndAge)
00399 {
00400   stream >> pointsWithValidityAndAge.sizeOfSet;
00401   stream >> pointsWithValidityAndAge.numberOfPoints;
00402   stream >> pointsWithValidityAndAge.indexOfNextPoint;
00403   stream.read(&pointsWithValidityAndAge.x,sizeof(pointsWithValidityAndAge.x));
00404   stream.read(&pointsWithValidityAndAge.y,sizeof(pointsWithValidityAndAge.y));
00405   return stream;
00406 }
00407 
00408 Out& operator<<(Out& stream, const PointsWithValidityAndAge& pointsWithValidityAndAge)
00409 {
00410   stream << pointsWithValidityAndAge.sizeOfSet;
00411   stream << pointsWithValidityAndAge.numberOfPoints;
00412   stream << pointsWithValidityAndAge.indexOfNextPoint;
00413   stream.write(&pointsWithValidityAndAge.x, sizeof(pointsWithValidityAndAge.x));
00414   stream.write(&pointsWithValidityAndAge.y, sizeof(pointsWithValidityAndAge.y));
00415   return stream;
00416 }
00417 
00418 
00419 /*
00420  * Change log :
00421  * 
00422  * $Log: PointsWithValidityAndAge.cpp,v $
00423  * Revision 1.1.1.1  2004/05/22 17:20:40  cvsadm
00424  * created new repository GT2004_WM
00425  *
00426  * Revision 1.1  2003/10/06 14:10:15  cvsadm
00427  * Created GT2004 (M.J.)
00428  *
00429  * Revision 1.1  2003/09/26 11:38:52  juengel
00430  * - sorted tools
00431  * - clean-up in DataTypes
00432  *
00433  * Revision 1.1.1.1  2003/07/02 09:40:22  cvsadm
00434  * created new repository for the competitions in Padova from the 
00435  * tamara CVS (Tuesday 2:00 pm)
00436  *
00437  * removed unused solutions
00438  *
00439  * Revision 1.4  2003/04/15 15:52:12  risler
00440  * DDD GO 2003 code integrated
00441  *
00442  * Revision 1.4  2003/04/12 23:17:54  dthomas
00443  * bugfix: initialized with wrong array index
00444  *
00445  * Revision 1.3  2002/10/01 09:01:44  kspiess
00446  * notes removed
00447  *
00448  * Revision 1.2  2002/09/22 18:40:51  risler
00449  * added new math functions, removed GTMath library
00450  *
00451  * Revision 1.1  2002/09/10 15:26:39  cvsadm
00452  * Created new project GT2003 (M.L.)
00453  * - Cleaned up the /Src/DataTypes directory
00454  * - Removed Challenge Code
00455  * - Removed processing of incoming audio data
00456  * - Renamed AcousticMessage to SoundRequest
00457  *
00458  * Revision 1.2  2002/06/07 10:15:46  kspiess
00459  * constructor changed
00460  *
00461  * Revision 1.1.1.1  2002/05/10 12:40:13  cvsadm
00462  * Moved GT2002 Project from ute to tamara.
00463  *
00464  * Revision 1.5  2002/02/08 14:20:33  kspiess
00465  * Anpassung an die Namenskonventionen
00466  *
00467  * Revision 1.4  2002/02/04 13:47:09  kspiess
00468  * BremenBerlin2001PlayersLocator in GT2001PlayersLocator umbenannt
00469  * alte Aufrufe in neue geändert
00470  * DebugDrawing für GT2001PlayersLocator eingebaut
00471  *
00472  * Revision 1.3  2002/01/29 18:31:48  kspiess
00473  * activated
00474  *
00475  * Revision 1.2  2002/01/22 11:03:15  kspiess
00476  * Fehler im Default-Konstruktor behoben und
00477  * SetSizeOfSet-Methode eingebaut
00478  *
00479  * Revision 1.1  2002/01/21 23:18:30  kspiess
00480  * PointsWithValidityAndAge portiert;
00481  * wird vom BremenBerlin2001PlayersLocator verwendet
00482  *
00483  *
00484  */

Generated on Thu Sep 23 19:57:31 2004 for GT2004 by doxygen 1.3.6