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

Modules/ImageProcessor/RasterImageProcessor/BoxSpecialist.cpp

Go to the documentation of this file.
00001 /**
00002 * @file BoxSpecialist.cpp
00003 * 
00004 * This file contains the implementation of class BoxSpecialist.
00005 *
00006 * @author <a href="mailto:sadprofessor@web.de">Bernd Schmidt</a>
00007 */
00008 #include "BoxSpecialist.h"
00009 #include "Tools/ColorClasses.h"
00010 #include "Tools/Location.h"
00011 
00012 BoxSpecialist::SegmentInfo::SegmentInfo():
00013   lmValiditySkyblue(0),
00014   lmValidityYellow(0),
00015   goalValidity(0),
00016   pink(0),
00017   yellow(0),
00018   skyblue(0){
00019 }
00020 
00021 BoxSpecialist::BoxSpecialist(RasterImageProcessor &processor,RasterStrategy &strat):
00022   RasterSpecialist(processor),edgeScanner(processor)  {
00023 
00024   strategy = &strat;
00025   preScanNeeded = true;
00026   postScanNeeded = false;
00027 
00028   
00029   InBinaryFile stream1(getLocation().getFilename("flag.thr"));
00030 
00031   if(stream1.exists()) stream1 >> flagThreshold;
00032     else flagThreshold = 20;
00033 
00034   InBinaryFile stream2(getLocation().getFilename("goal.thr"));
00035 
00036   if(stream2.exists()) stream2 >> goalThreshold;
00037     else goalThreshold = 25;
00038 
00039 
00040   OUTPUT(idText,text,"goal-thr: " << goalThreshold);
00041   OUTPUT(idText,text,"flag-thr: " << flagThreshold);
00042 
00043 }
00044 
00045 
00046 BoxSpecialist::~BoxSpecialist(){}
00047 
00048 
00049 int BoxSpecialist::getType() {
00050   return __RBoxSpecialist;
00051 }
00052 
00053 void BoxSpecialist::init() {
00054     segments_img.clear();
00055     infos_img.clear();
00056     lst_pts.clear();
00057     bottomPoints.clear();
00058     //OUTPUT(idText,text,"init started");
00059     edgeScanner.threshold = 17;
00060 }
00061 
00062 //TODO: could be faster
00063 void BoxSpecialist::createBBox() {
00064 
00065   SVector::iterator sit;
00066   list<LinePair>::iterator l_it;
00067   
00068   double dist, p_dist;
00069 
00070 
00071   for (sit = segments_img.begin();sit != segments_img.end();sit++){
00072     if (sit->size() < 2) continue;
00073     
00074     //OUTPUT(idText,text,"size of Goal-Seg: "<<  sit->size());
00075     Geometry::Line top,bottom,left,right;
00076     Vector2<int> minHor,maxHor,minPHor,maxPHor;
00077     SegmentInfo si;
00078     double min_dist = 20000, max_dist = -20000, min_p_dist = 20000, max_p_dist = -20000;
00079     
00080     for (l_it = sit->begin();l_it!=sit->end();++l_it) {
00081 
00082       dist = getDistanceToLine(horizon,l_it->v1);
00083       p_dist = getDistanceToLine(pHorizon,l_it->v1);
00084 
00085       if (dist < min_dist) {
00086         min_dist = dist;
00087         minHor = l_it->v1;
00088 
00089       }
00090       if (dist > max_dist) {
00091         max_dist = dist;
00092         maxHor = l_it->v1;
00093       }
00094 
00095       if (p_dist < min_p_dist) {
00096         min_p_dist = p_dist;
00097         minPHor = l_it->v1;
00098       }
00099       if (p_dist > max_p_dist) {
00100         max_p_dist = p_dist;
00101         maxPHor = l_it->v1;
00102 
00103       }
00104 
00105       dist = getDistanceToLine(horizon,l_it->v2);
00106       p_dist = getDistanceToLine(pHorizon,l_it->v2);
00107 
00108       if (dist < min_dist) {
00109         min_dist = dist;
00110         minHor = l_it->v2;
00111 
00112       }
00113       if (dist > max_dist) {
00114         max_dist = dist;
00115         maxHor = l_it->v2;
00116       }
00117 
00118       if (p_dist < min_p_dist) {
00119         min_p_dist = p_dist;
00120         minPHor = l_it->v2;
00121       }
00122       if (p_dist > max_p_dist) {
00123         max_p_dist = p_dist;
00124         maxPHor = l_it->v2;
00125       }
00126     }
00127     top.base = Vector2<double>(
00128       (double)maxHor.x,
00129       (double)maxHor.y);
00130     top.direction = horizon.direction;
00131     
00132     bottom.base = Vector2<double>(
00133       (double)minHor.x,
00134       (double)minHor.y);
00135     bottom.direction = horizon.direction;
00136     
00137     left.base = Vector2<double>(
00138       (double)minPHor.x,
00139       (double)minPHor.y);
00140     left.direction = pHorizon.direction;
00141     
00142     right.base = Vector2<double>(
00143       (double)maxPHor.x,
00144       (double)maxPHor.y);
00145     right.direction = pHorizon.direction;
00146     
00147     Geometry::getIntersectionOfLines(top,left,si.rect.upperLeft);
00148     Geometry::getIntersectionOfLines(top,right,si.rect.upperRight);
00149     Geometry::getIntersectionOfLines(bottom,left,si.rect.bottomLeft);
00150     Geometry::getIntersectionOfLines(bottom,right,si.rect.bottomRight);
00151     si.rect.center = (si.rect.upperLeft + si.rect.bottomRight)/2;
00152     si.size = sit->size();
00153     si.segment = &(*sit);
00154     
00155     countColors(si,*(si.segment));
00156     si.bottomColor = getColor(minHor.x,minHor.y);
00157     si.topColor = getColor(maxHor.x,maxHor.y);
00158     createValidities(si);
00159     infos_img.push_back(si);
00160   }
00161 }
00162 
00163 
00164 
00165 void BoxSpecialist::invokeOnPreScan(int x, int y){
00166 
00167   Vector2 <int> cur_pt(x,y); //= getVecFromRaster(x,y);
00168 
00169   if (!strategy->insideBox) left_border = cur_pt;
00170   else {
00171     LinePair lp(left_border,cur_pt);
00172     lp.color = getColor(lp.v1.x,lp.v1.y);
00173 
00174     //search for edges to widen the pairs to the edges of the object
00175     edgeScanner.scanWest(lp.v1.x,lp.v2.y);
00176     edgeScanner.scanEast(lp.v2.x,lp.v2.y);
00177 
00178     if ((lp.v2.x-lp.v1.x)>1) {      
00179       lst_pts.push_back(lp);
00180         
00181       LINE(imageProcessor_general,
00182         lp.v1.x,lp.v1.y, 
00183         lp.v2.x,lp.v2.y, 
00184         0.5, Drawings::ps_solid, Drawings::red);
00185   
00186     }
00187   }
00188 }
00189 
00190 bool BoxSpecialist::missingData(bool ulc, bool urc, bool brc, bool blc, int i) {
00191   if (ulc && urc) return segments_img[i].size() >5;
00192   else if (blc && brc) return segments_img[i].size() >5;
00193 
00194   return false;
00195 }
00196 
00197 bool BoxSpecialist::searchGoal(BoxSpecialist::SegmentInfo& goal) {
00198   int i = 0;
00199   
00200   if ((goal.pink != 0) || (goal.yellow != 0) && (goal.skyblue != 0)) return false;
00201   if (!(goal.yellow > 20 || goal.skyblue > 20)) return false;
00202 
00203   double centerDistance = fabs(Geometry::getDistanceToLine(horizon,goal.rect.center));
00204   double colorCount = goal.yellow + goal.skyblue;
00205   
00206   if (centerDistance/colorCount > 2) return false;
00207   bool ownTeamColorIsBlue = getPlayer().getTeamColor() == Player::blue;
00208   bool opponentGoal = false;
00209   colorClass goalColor = (goal.yellow > goal.skyblue)? yellow : skyblue;
00210   
00211   if (ownTeamColorIsBlue){
00212     if(goalColor == yellow) opponentGoal = true;
00213     else opponentGoal = false;
00214   }
00215   else if (goalColor == skyblue) opponentGoal = true;
00216   
00217 
00218   Vector2<double> south = pHorizon.direction;
00219   Vector2<double> north(-pHorizon.direction.x,-pHorizon.direction.y);
00220   Vector2<double> east = horizon.direction;
00221   Vector2<double> west(-horizon.direction.x,-horizon.direction.y);
00222   
00223   int const cols = 12;
00224   int const rows = 8;
00225   
00226   vector<Vector2<int> > tops(cols);
00227   vector<Vector2<int> > bottoms(cols);
00228   vector<Vector2<int> > lefts(rows);
00229   vector<Vector2<int> > rights(rows);
00230 
00231 //  double topDists[cols],bottomDists[cols],leftDists[rows],rightDists[rows];
00232 
00233 
00234   bool bottomOnBorder = true;
00235   bool topOnBorder = true;
00236   bool leftOnBorder = true;
00237   bool rightOnBorder = true;
00238 
00239   Vector2<double> step = (goal.rect.upperRight - goal.rect.upperLeft)/(cols+2); // looks to right
00240   Vector2<double> vert = (goal.rect.upperRight - goal.rect.bottomRight)/(rows+2); // looks to bottom
00241   //Vector2<double> stepRight = step*-1;
00242   //Vector2<double> vertDown = vert*-1;
00243   
00244   
00245   if (step.abs() < 1) return false;
00246   if (vert.abs() < 1) return false;
00247   
00248   for (i = 0;i<cols;i++){
00249     Vector2<double> top = goal.rect.upperLeft + (step*(i+1)) - vert;
00250     Vector2<double> bottom = goal.rect.bottomLeft + (step*(i+1)) + vert;
00251     tops[i].x = (int)(top.x+0.5);
00252     tops[i].y = (int)(top.y+0.5);
00253     bottoms[i].x = (int)(bottom.x + 0.5);
00254     bottoms[i].y = (int)(bottom.y + 0.5);
00255     if (edgeScanner.scan(bottoms[i].x,bottoms[i].y,south)) bottomOnBorder = false;
00256     if (edgeScanner.scan(tops[i].x,tops[i].y,north)) topOnBorder = false;
00257 
00258     DOT(imageProcessor_flagsAndGoals, tops[i].x, tops[i].y,
00259       Drawings::white, Drawings::red);
00260     DOT(imageProcessor_flagsAndGoals, bottoms[i].x, bottoms[i].y,
00261       Drawings::white, Drawings::red);
00262   }
00263 
00264   for (i = 0;i<rows;i++){
00265     Vector2<double> left = goal.rect.bottomLeft + step + (vert*(i+1));
00266     Vector2<double> right = goal.rect.bottomRight - step + (vert*(i+1));
00267     lefts[i].x = (int)(left.x + 0.5);
00268     lefts[i].y = (int)(left.y + 0.5);
00269     rights[i].x = (int)(right.x + 0.5);
00270     rights[i].y = (int)(right.y + 0.5);
00271     if(edgeScanner.scan(lefts[i].x,lefts[i].y,west)) leftOnBorder = false;
00272     if(edgeScanner.scan(rights[i].x,rights[i].y,east)) rightOnBorder = false;
00273 
00274     DOT(imageProcessor_flagsAndGoals, lefts[i].x, lefts[i].y,
00275       Drawings::white, Drawings::blue);
00276     DOT(imageProcessor_flagsAndGoals, rights[i].x, rights[i].y,
00277       Drawings::white, Drawings::blue);
00278   }
00279 
00280   //now finding the edges
00281   Geometry::Line top;
00282   Geometry::Line bottom;
00283   Geometry::Line left;
00284   Geometry::Line right;
00285   Geometry::Line t1;
00286   Geometry::Line t2;
00287   int r1;
00288   int r2;
00289   float best1;
00290   float best2;
00291   float dist1;
00292   float dist2;
00293     
00294   for(i=0;i<10;i++){
00295     r1 = rand()%cols;
00296     do r2 = rand()%cols; while (r1==r2);
00297     t1.base.x += bottoms[r1].x;
00298     t1.base.y += bottoms[r1].y;
00299     t2.base.x += tops[r1].x;
00300     t2.base.y += tops[r1].y;
00301     t1.direction.x = t1.base.x - bottoms[r2].x; 
00302     t1.direction.y = t1.base.y - bottoms[r2].y;
00303     t2.direction.x = t1.base.x - tops[r2].x; 
00304     t2.direction.y = t1.base.y - tops[r2].y;
00305 
00306     dist1 = 0;
00307     dist2 = 0;
00308     best1 = 1000;
00309     best2 = 1000;
00310     
00311     for(int j=0;j<cols;j++){
00312       dist1 += getDistanceToLine(t1,bottoms[j]);
00313       dist2 += getDistanceToLine(t2,tops[j]);
00314     }
00315     dist1 = fabs(dist1);
00316     dist2 = fabs(dist2);
00317 
00318     if (dist1 < best1){
00319       best1 = dist1;
00320       bottom = t1;
00321     }
00322 
00323     if (dist2 < best2){
00324       best2 = dist2;
00325       top = t2;
00326     }
00327   }
00328 
00329   t1.direction = pHorizon.direction;
00330   t2.direction = pHorizon.direction;
00331 
00332   for(i = 0;i<10;i++){
00333     r1 = rand()%rows;
00334     do r2 = rand()%rows; while (r1==r2);
00335     right.base.x += rights[r1].x;
00336     right.base.y += rights[r1].y;
00337     left.base.x += lefts[r1].x;
00338     left.base.y += lefts[r1].y;
00339     t1.direction.x = t1.base.x - bottoms[r2].x; 
00340         t1.direction.y = t1.base.y - bottoms[r2].y;
00341     t2.direction.x = t1.base.x - tops[r2].x; 
00342         t2.direction.y = t1.base.y - tops[r2].y;
00343     
00344     dist1 = 0;
00345     dist2 = 0;
00346     best1 = 1000;
00347     best2 = 1000;
00348 
00349     for(int j=0;j<rows;j++){
00350       dist1 += getDistanceToLine(t1,rights[j]);
00351       dist2 += getDistanceToLine(t2,lefts[j]);
00352     }
00353     dist1 = fabs(dist1);
00354     dist2 = fabs(dist2);
00355 
00356     if (dist1 < best1){
00357       best1 = dist1;
00358       bottom = t1;
00359     }
00360     if (dist2 < best2){
00361       best2 = dist2;
00362       top = t2;
00363     }
00364   }
00365 
00366   //directions could be corrigated
00367 
00368   //top.direction = horizon.direction;
00369   //bottom.direction = horizon.direction;
00370   //left.direction = pHorizon.direction;
00371   //right.direction = pHorizon.direction;
00372 
00373   Rectangle& r = goal.rect;
00374   
00375   //calculating rectangle
00376   Geometry::getIntersectionOfLines(bottom,left,goal.rect.bottomLeft);
00377   Geometry::getIntersectionOfLines(bottom,right,goal.rect.bottomRight);
00378   Geometry::getIntersectionOfLines(top,left,goal.rect.upperLeft);
00379   Geometry::getIntersectionOfLines(top,right,goal.rect.upperRight);
00380   goal.rect.center = (goal.rect.upperLeft + goal.rect.bottomRight)/2;
00381 
00382   double size = (goal.rect.bottomLeft - goal.rect.bottomRight).abs();
00383   size*= (goal.rect.bottomLeft - goal.rect.bottomRight).abs();
00384 
00385   if ( !(size > 100 && Geometry::getDistanceToLine(horizon, goal.rect.center) < 25) 
00386     || Geometry::getDistanceToLine(horizon, goal.rect.center) < -10 )
00387     return false;
00388   
00389   RasterSpecialist::Box b(1,1,imageWidth-2,imageWidth-2);
00390   bool ulc = !b.inside((int)r.upperLeft.x,(int)r.upperLeft.y);
00391   bool urc = !b.inside((int)r.upperRight.x,(int)r.upperRight.y);
00392   bool brc = !b.inside((int)r.bottomRight.x,(int)r.bottomRight.y);
00393   bool blc = !b.inside((int)r.bottomLeft.x,(int)r.bottomLeft.y);
00394   
00395   ConditionalBoundary bound; 
00396   
00397 /*  
00398   obstaclesPercept.angleToFreePartOfGoalWasDetermined[ObstaclesPercept::opponentGoal] = true;
00399   obstaclesPercept.angleToFreePartOfGoal[ObstaclesPercept::opponentGoal] = firstDir + factor * (lastDir - firstDir);
00400   double distance = ((first2 + last2) / 2).abs();
00401   obstaclesPercept.distanceToFreePartOfGoal[ObstaclesPercept::opponentGoal] = distance;
00402   obstaclesPercept.widthOfFreePartOfGoal[ObstaclesPercept::opponentGoal] = distance ? 2 * atan((first - last).abs() / 2 / distance) : pi;
00403 */
00404   Vector2<double> a[4];
00405   Vector2<double> leftCenter = (r.upperLeft + r. bottomLeft)/2;
00406   Vector2<double> rightCenter = (r.upperRight + r. bottomRight)/2;
00407   Vector2<double> bottomCenter = (r.bottomRight + r. bottomLeft)/2;
00408   Vector2<double> topCenter = (r.upperRight + r. upperLeft)/2;
00409 
00410   calculateAnglesForPoint(leftCenter,rip->cameraMatrix,rip->image.cameraInfo,a[0]);
00411   calculateAnglesForPoint(rightCenter,rip->cameraMatrix,rip->image.cameraInfo,a[1]);
00412   calculateAnglesForPoint(bottomCenter,rip->cameraMatrix,rip->image.cameraInfo,a[2]);
00413   calculateAnglesForPoint(topCenter,rip->cameraMatrix,rip->image.cameraInfo,a[3]);
00414   
00415   bound.addX(a[0].x,blc);
00416   bound.addX(a[1].x,brc);
00417   bound.addX(a[2].x,ulc);
00418   bound.addX(a[3].x,urc);
00419 
00420   bound.addY(a[0].y,blc);
00421   bound.addY(a[1].y,brc);
00422   bound.addY(a[2].y,ulc);
00423   bound.addY(a[3].y,urc);
00424 
00425   rip->landmarksPercept.addGoal(goalColor, ownTeamColorIsBlue, bound);
00426   
00427   //calculate distance
00428 //  int distance = Geometry::getDistanceBySize(
00429 //      goalHeight, 
00430 //    (int)(topCenter - bottomCenter).abs(), 
00431 //       rip->image.cameraInfo.resolutionWidth,
00432 //       rip->image.cameraInfo.openingAngleWidth);
00433 
00434   //if(opponentGoal)
00435   //  rip->obstaclesPercept.distanceToFreePartOfGoal[ObstaclesPercept::opponentGoal] = distance;
00436   //else
00437   //  rip->obstaclesPercept.distanceToFreePartOfGoal[ObstaclesPercept::ownGoal] = distance;
00438   //if(goal.skyblue != 0) {
00439   //  OUTPUT(idText,text,"goal recognized : skyblue");
00440   //}
00441   //else OUTPUT(idText,text,"goal recognized : yellow");
00442   
00443   goal.goalValidity = 1;
00444   
00445   LINE(imageProcessor_flagsAndGoals,
00446     goal.rect.upperLeft.x,goal.rect.upperLeft.y,
00447     goal.rect.upperRight.x,goal.rect.upperRight.y,
00448     1.5, Drawings::ps_solid, Drawings::white);
00449 
00450   LINE(imageProcessor_flagsAndGoals,
00451     goal.rect.bottomLeft.x,goal.rect.bottomLeft.y,
00452     goal.rect.bottomRight.x,goal.rect.bottomRight.y,
00453     1.5, Drawings::ps_solid, Drawings::white);
00454 
00455   LINE(imageProcessor_flagsAndGoals,
00456     goal.rect.upperLeft.x,goal.rect.upperLeft.y,
00457     goal.rect.bottomLeft.x,goal.rect.bottomLeft.y,
00458     1.5, Drawings::ps_solid, Drawings::white);
00459 
00460   LINE(imageProcessor_flagsAndGoals,
00461     goal.rect.upperRight.x,goal.rect.upperRight.y,
00462     goal.rect.bottomRight.x,goal.rect.bottomRight.y,
00463     1.5, Drawings::ps_solid, Drawings::white);
00464   
00465 return true;
00466 
00467 }
00468 
00469 bool BoxSpecialist::searchLandmark(BoxSpecialist::SegmentInfo& flag){
00470 //  const CameraInfo& cameraInfo = rip->image.cameraInfo;
00471 //  const CameraMatrix& cameraMatrix = rip->cameraMatrix;
00472   if (flag.pink == 0) return false;
00473   if (flag.yellow == 0 && flag.skyblue == 0) return false;
00474   Vector2<double> south = pHorizon.direction;
00475   Vector2<double> north(-pHorizon.direction.x,-pHorizon.direction.y);
00476   Vector2<double> east = horizon.direction;
00477   Vector2<double> west(-horizon.direction.x,-horizon.direction.y);
00478   Rectangle &r = flag.rect;
00479   bool bottomOnBorder = false;
00480   bool topOnBorder = false;
00481 
00482   Vector2<int> borderCenter;
00483   Vector2<int> center((int)(r.center.x + 0.5),(int)(r.center.y + 0.5));
00484   Vector2<int> bottomCenter = center;
00485   Vector2<int> topCenter = center;
00486   
00487   DOT(imageProcessor_flagsAndGoals, center.x, center.y,
00488     Drawings::black, Drawings::white);
00489   
00490   colorClass col = noColor;
00491   colorClass bottomColor = noColor;
00492   colorClass topColor = noColor;
00493   
00494   DOT(imageProcessor_flagsAndGoals, bottomCenter.x, bottomCenter.y,
00495     Drawings::red, Drawings::black);
00496   DOT(imageProcessor_flagsAndGoals, topCenter.x, topCenter.y,
00497     Drawings::green, Drawings::black);
00498 
00499   int& bx = bottomCenter.x;
00500   int& by = bottomCenter.y;
00501 
00502   double space = (r.bottomLeft-r.upperLeft).abs()/4;
00503 
00504   if (space<3) space = 3;
00505 
00506   while (!bottomOnBorder){
00507     bottomOnBorder = !edgeScanner.scan(bx,by,south);
00508     if(abs(center.x - bx) < space && abs(center.y - by) < space)
00509       edgeScanner.skip(bx,by);
00510     else break;
00511   }
00512 
00513   int& tx = topCenter.x;
00514   int& ty = topCenter.y;
00515 
00516   while (!topOnBorder){
00517     topOnBorder = !edgeScanner.scan(tx,ty,north);
00518     if(abs(center.x - tx) < space && abs(center.y - ty) < space)
00519       edgeScanner.skip(tx,ty);
00520     else break;   
00521   }
00522   Vector2<int> quarter = (topCenter - bottomCenter)/4;
00523   if (quarter.abs() < 1) return false; //flag is to small
00524   Vector2<int> topStart(topCenter.x - quarter.x,topCenter.y - quarter.y);
00525   Vector2<int> bottomStart(bottomCenter.x + quarter.x,bottomCenter.y + quarter.y);
00526   bool found = false;
00527   
00528   //an good example for how to use the color-scan methods of the scanner
00529   //scan for top color
00530   Vector2<int> scan = topStart;
00531   edgeScanner.setDirection(west);
00532   while(edgeScanner.colorScan(scan.x,scan.y,west,col)){
00533     if (col == pink || col == yellow || col == skyblue){
00534       topColor = col;
00535       found = true;
00536       break;
00537     }
00538     edgeScanner.skip(scan.x,scan.y);
00539     if ((scan - topStart).abs() > 10) break;
00540   } 
00541   if (!found){
00542     //scan in other direction
00543     col = noColor;
00544     scan = topStart;
00545     
00546     while(edgeScanner.colorScan(scan.x,scan.y,east,col)){
00547       if (col == pink || col == yellow || col == skyblue){
00548         topColor = col;
00549         found = true;
00550         break;
00551       }
00552       edgeScanner.skip(scan.x,scan.y);
00553       if ((scan - topStart).abs() > 10) break; 
00554     }
00555   }
00556   if (!found) return false;//no topColor found
00557   else found = false;
00558   
00559   //scan for bottomColor
00560   scan = bottomStart; 
00561   while(edgeScanner.colorScan(scan.x,scan.y,west,col)){
00562     if (col == pink || col == yellow || col == skyblue){
00563       bottomColor = col;
00564       found = true;
00565       break;
00566     }
00567     edgeScanner.skip(scan.x,scan.y);
00568     if ((scan - bottomStart).abs() > 10) break;
00569   } 
00570   if (!found){
00571     //scan in other direction
00572     col = noColor;
00573     scan = bottomStart;
00574     
00575     while(edgeScanner.colorScan(scan.x,scan.y,east,col)){
00576       if (col == pink || col == yellow || col == skyblue){
00577         bottomColor = col;
00578         found = true;
00579         break;
00580       }
00581       edgeScanner.skip(scan.x,scan.y);
00582       if ((scan - bottomStart).abs() > 10) break; 
00583     }
00584   }
00585   if (!found) return false;
00586 
00587   Flag::FlagType ft= Flag::numberOfFlagTypes;
00588   if (topColor == pink) {
00589     switch (bottomColor) {
00590     case yellow :
00591       ft = Flag::pinkAboveYellow;
00592       break;
00593     case skyblue :
00594       ft = Flag::pinkAboveSkyblue;
00595       break;  
00596     default : break;
00597     }
00598   }
00599   else if(bottomColor == pink){
00600     switch (topColor) {
00601     case skyblue :
00602       ft = Flag::skyblueAbovePink;
00603       break;
00604     case yellow :
00605       ft = Flag::yellowAbovePink;
00606       break;
00607     default : break;
00608     }
00609   }
00610   
00611   //if (ft == Flag::numberOfFlagTypes) return false;
00612 
00613   DOT(imageProcessor_flagsAndGoals, bottomStart.x, bottomStart.y,
00614     Drawings::red, Drawings::black);
00615   
00616   DOT(imageProcessor_flagsAndGoals, topStart.x, topStart.y,
00617     Drawings::green, Drawings::black);
00618   
00619   Vector2<int> left1,left2,right1,right2;
00620   
00621   scan = topStart;
00622 
00623   edgeScanner.setDirection(west);
00624   edgeScanner.scan(scan.x,scan.y);
00625   left1 = scan;
00626   DOT(imageProcessor_flagsAndGoals, scan.x, scan.y,
00627     Drawings::green, Drawings::blue);
00628 
00629   scan = topStart;
00630 
00631   edgeScanner.setDirection(east);
00632   edgeScanner.scan(scan.x,scan.y);
00633   right1 = scan;  
00634   DOT(imageProcessor_flagsAndGoals, scan.x, scan.y,
00635     Drawings::green, Drawings::blue);
00636 
00637   scan = bottomStart;
00638 
00639   edgeScanner.setDirection(west);
00640   edgeScanner.scan(scan.x,scan.y);
00641   left2 = scan;
00642   DOT(imageProcessor_flagsAndGoals, scan.x, scan.y,
00643     Drawings::green, Drawings::blue);
00644 
00645   scan = bottomStart;
00646   right2 = scan;
00647   edgeScanner.setDirection(east);
00648   edgeScanner.scan(scan.x,scan.y);
00649 
00650   DOT(imageProcessor_flagsAndGoals, scan.x, scan.y,
00651     Drawings::green, Drawings::blue);
00652 
00653   /////////////////////////////////////////
00654   //adding Percept
00655   
00656   Vector2<double> left = (r.bottomLeft + r.upperLeft)/2;
00657   Vector2<double> right = (r.bottomRight + r.upperRight)/2;
00658   Vector2<double> top(topCenter.x,topCenter.y);
00659   Vector2<double> bottom(bottomCenter.x,bottomCenter.y);
00660   center = (bottomCenter + topCenter)/2;
00661 
00662   DOT(imageProcessor_flagsAndGoals, bottomCenter.x, bottomCenter.y,
00663     Drawings::red, Drawings::black);
00664   
00665   DOT(imageProcessor_flagsAndGoals, topCenter.x, topCenter.y,
00666     Drawings::green, Drawings::black);
00667 
00668   DOT(imageProcessor_flagsAndGoals, right.x, right.y,
00669     Drawings::red, Drawings::black);
00670   
00671   DOT(imageProcessor_flagsAndGoals, left.x, left.y,
00672     Drawings::green, Drawings::black);
00673   
00674   rip->addFlag(left,right,top,bottom,ft); 
00675   return true;
00676 }
00677 
00678 void BoxSpecialist::fitLandmark(BoxSpecialist::SegmentInfo &flag){
00679   Vector2<double> south = pHorizon.direction;
00680   Vector2<double> north(-pHorizon.direction.x,-pHorizon.direction.y);
00681   Vector2<double> east = horizon.direction;
00682   Vector2<double> west(-horizon.direction.x,-horizon.direction.y);
00683   
00684   Rectangle& r = flag.rect;
00685   bool bottomOnBorder = false;
00686   bool topOnBorder = false;
00687     
00688   Vector2<int> center((int)(r.center.x + 0.5),(int)(r.center.y + 0.5));
00689   Vector2<int> bottomCenter = center;
00690   Vector2<int> topCenter = center;
00691 
00692   DOT(imageProcessor_flagsAndGoals, center.x, center.y,
00693     Drawings::black, Drawings::white);
00694   
00695   DOT(imageProcessor_flagsAndGoals, bottomCenter.x, bottomCenter.y,
00696     Drawings::red, Drawings::black);
00697   DOT(imageProcessor_flagsAndGoals, topCenter.x, topCenter.y,
00698     Drawings::green, Drawings::black);
00699 
00700   int& bx = bottomCenter.x;
00701   int& by = bottomCenter.y;
00702 
00703   double space = (r.bottomLeft-r.upperLeft).abs()/4;
00704 
00705   if (space<3) space = 3;
00706 
00707   while (!bottomOnBorder){
00708     bottomOnBorder = !edgeScanner.scan(bx,by,south);
00709     if(abs(center.x - bx) < space && abs(center.y - by) < space)
00710       edgeScanner.skip(bx,by);
00711     else break;
00712   }
00713 
00714   int& tx = topCenter.x;
00715   int& ty = topCenter.y;
00716 
00717   while (!topOnBorder){
00718     topOnBorder = !edgeScanner.scan(tx,ty,north);
00719     if(abs(center.x - tx) < space && abs(center.y - ty) < space)
00720       edgeScanner.skip(tx,ty);
00721     else break;   
00722   }
00723 
00724 
00725 
00726 
00727 }
00728 
00729 void BoxSpecialist::invokeOnPostScan(int x,int y) {
00730   //invoved from the grid scan
00731   bottomPoints.push_back(Vector2<int>(x,y));
00732 }
00733 
00734 void BoxSpecialist::executePostProcessing() {
00735 
00736   if (lst_pts.size() < 2) return;
00737   
00738   int allowedXSpace = 2;
00739   int allowedYSpace = 4;
00740   
00741   horizon = rip->getHorizon();
00742 
00743   pHorizon.base = horizon.base;
00744   pHorizon.direction = horizon.direction;
00745   pHorizon.direction.rotateLeft();
00746 
00747   createSegmentsFromLines2(lst_pts,segments_img,allowedXSpace,allowedYSpace);
00748 
00749   sort<SVector::iterator>(segments_img.begin(),segments_img.end(),ListSizeOrder());
00750   createBBox();
00751   int size = infos_img.size();
00752 
00753   if (size == 0) return;
00754   
00755   edgeScanner.threshold = goalThreshold;
00756   
00757   vector<SegmentInfo>::iterator it = infos_img.end();
00758   int goalParts = 0;
00759   do{ 
00760     it--;
00761     if (searchGoal(*it)) goalParts++;
00762     if (goalParts == 1) break; //TODO: merge code 
00763   }while(it != infos_img.begin());
00764 
00765 
00766   
00767   edgeScanner.threshold = flagThreshold;
00768   //searchLandmark(size); 
00769     //paint debug-drawings
00770   it = infos_img.end();
00771   int foundLM = 0;
00772   do{ 
00773     it--;
00774     if (searchLandmark(*it)){
00775       foundLM++;
00776     }
00777     if (foundLM == 2) break;
00778   }while(it != infos_img.begin());
00779   Vector2<double> cameraOffset(
00780     rip->cameraMatrix.translation.x,
00781     rip->cameraMatrix.translation.y);
00782 
00783   if (foundLM>0) rip->landmarksPercept.estimateOffsetForFlags(cameraOffset);
00784   if (goalParts>0){
00785     //if (goalParts>1)fusionGoal();
00786     //detectFreePartOfGoal();
00787     rip->landmarksPercept.estimateOffsetForGoals(cameraOffset);
00788   };
00789     
00790   for(it = infos_img.begin();it!= infos_img.end();++it) {
00791     
00792     LINE(imageProcessor_general,
00793         it->rect.upperLeft.x,it->rect.upperLeft.y,it->rect.upperRight.x,it->rect.upperRight.y,
00794         0.6, Drawings::ps_solid, Drawings::white);
00795     LINE(imageProcessor_general,
00796         it->rect.bottomLeft.x,it->rect.bottomLeft.y,it->rect.bottomRight.x,it->rect.bottomRight.y,
00797         0.6, Drawings::ps_solid, Drawings::green);
00798     LINE(imageProcessor_general,
00799         it->rect.upperLeft.x,it->rect.upperLeft.y,it->rect.bottomLeft.x,it->rect.bottomLeft.y,
00800         0.6, Drawings::ps_solid, Drawings::yellow);
00801     LINE(imageProcessor_general,
00802         it->rect.upperRight.x,it->rect.upperRight.y,it->rect.bottomRight.x,it->rect.bottomRight.y,
00803         0.6, Drawings::ps_solid, Drawings::blue);
00804   }
00805 
00806 
00807 }
00808 
00809 void BoxSpecialist::mergeBoxes(BoxSpecialist::SegmentInfo& seg1,BoxSpecialist::SegmentInfo& seg2){
00810   Geometry::Line top,bottom,left,right;
00811 
00812 
00813 //  seg1.segment->merge(*(seg2.segment));
00814   if (Geometry::getDistanceToLine(horizon,seg1.rect.upperLeft) <
00815     Geometry::getDistanceToLine(horizon,seg2.rect.upperLeft))
00816     seg1.rect.upperLeft = seg2.rect.upperLeft;
00817 
00818   if (Geometry::getDistanceToLine(horizon,seg1.rect.bottomRight) >
00819     Geometry::getDistanceToLine(horizon,seg2.rect.bottomRight))
00820     seg1.rect.bottomRight = seg2.rect.bottomRight;
00821 
00822   if (Geometry::getDistanceToLine(pHorizon,seg1.rect.upperRight) <
00823     Geometry::getDistanceToLine(pHorizon,seg2.rect.upperRight))
00824     seg1.rect.upperRight = seg2.rect.upperRight;
00825 
00826   if (Geometry::getDistanceToLine(pHorizon,seg1.rect.bottomLeft) >
00827     Geometry::getDistanceToLine(pHorizon,seg2.rect.bottomLeft))
00828     seg1.rect.bottomLeft = seg2.rect.bottomLeft;
00829 
00830   top.direction = horizon.direction;
00831   bottom.direction = horizon.direction;
00832   left.direction = pHorizon.direction;
00833   right.direction = pHorizon.direction;
00834 
00835   top.base = seg1.rect.upperLeft;
00836   bottom.base = seg1.rect.bottomRight;
00837   right.base = seg1.rect.upperRight;
00838   left.base = seg1.rect.bottomLeft;
00839 
00840   Geometry::getIntersectionOfLines(bottom,left,seg1.rect.bottomLeft);
00841   Geometry::getIntersectionOfLines(top,left,seg1.rect.upperLeft);
00842   Geometry::getIntersectionOfLines(bottom,right,seg1.rect.bottomRight);
00843   Geometry::getIntersectionOfLines(top,right,seg1.rect.upperRight);
00844   seg1.rect.center = (seg1.rect.upperLeft + seg1.rect.bottomRight)/2;
00845   seg1.size += seg2.pink;
00846   seg1.pink += seg2.pink;
00847   seg1.yellow += seg2.yellow;
00848   seg1.skyblue += seg2.skyblue;
00849 }
00850 
00851 void BoxSpecialist::countColors(BoxSpecialist::SegmentInfo& si, list<LinePair>& segment){
00852   list<LinePair>::iterator lines;
00853   si.pink = 0;
00854   si.yellow =0;
00855   si.skyblue = 0;
00856   for(lines = segment.begin();lines != segment.end();++lines){
00857     LinePair& line = *lines;
00858     switch(line.color){ 
00859     case pink: 
00860       si.pink += line.v2.x - line.v1.x;
00861       break;
00862     case yellow: 
00863       si.yellow += line.v2.x - line.v1.x;
00864       break;
00865     case skyblue: 
00866       si.skyblue += line.v2.x - line.v1.x;
00867       break;
00868 
00869     }
00870   }
00871 
00872   int max = 0;
00873   int min = 0;
00874   si.pink > si.skyblue? max = si.pink : max = si.skyblue;
00875   if (si.yellow > max) max = si.yellow;
00876   
00877   min = max/8;
00878 
00879   if (si.pink < min) si.pink = 0;
00880   if (si.yellow < min) si.yellow = 0;
00881   if (si.skyblue < min) si.skyblue = 0;
00882 }
00883 
00884 // not completed
00885 void BoxSpecialist::fusionGoal(){
00886   //get the greatest segment in a goal-color and fusion it with other parts,
00887   //if the goal seems to be splitted
00888   vector<SegmentInfo>::iterator it;
00889   
00890   it = infos_img.begin();
00891   
00892   SegmentInfo& greatest = infos_img.back();
00893 
00894   int pos = infos_img.size()-1;
00895   
00896   if ((greatest.pink != 0) || (greatest.yellow != 0) && (greatest.skyblue != 0)) return;
00897   
00898   double radius = (greatest.rect.center - greatest.rect.bottomRight).abs();
00899   
00900   colorClass goalColor = greatest.yellow != 0 ? yellow : skyblue;
00901   searchGoal(greatest);
00902   //instead of circles around the boxes we could use rectangular-patterns 
00903   //to find the boxes that have to be merged
00904   
00905   for(++it;it != infos_img.end();++it){
00906     SegmentInfo& si = *it;
00907     if (si.pink > 0) continue;
00908     colorClass curColor = si.yellow > si.skyblue ? yellow : skyblue;
00909     if (curColor != goalColor) continue;
00910     //double  dist = fabs(Geometry::getDistanceToLine(horizon,si.rect.center))*0.01;
00911     //if(dist > 1) continue;
00912     double curRadius = (si.rect.center - si.rect.bottomRight).abs() + 4 /*+ 10 ) / (1-dist)*/ ;
00913     if ((si.rect.center - greatest.rect.center).abs() > curRadius + radius) continue;
00914     if (fabs(Geometry::getDistanceToLine(horizon,si.rect.center)) > 20)continue;
00915     mergeBoxes(greatest,si);
00916     si.goalValidity = 1;
00917   }
00918 
00919   if (!((greatest.yellow > 90 ||  greatest.skyblue > 90) && Geometry::getDistanceToLine(horizon, greatest.rect.center) < 20)) return;
00920   
00921   Rectangle& r = greatest.rect;
00922   RasterSpecialist::Box b(1,1,imageWidth-2,imageWidth-2);
00923   bool ulc = b.inside((int)r.upperLeft.x,(int)r.upperLeft.y);
00924   bool urc = b.inside((int)r.upperRight.x,(int)r.upperRight.y);
00925   bool brc = b.inside((int)r.bottomRight.x,(int)r.bottomRight.y);
00926   bool blc = b.inside((int)r.bottomLeft.x,(int)r.bottomLeft.y);
00927 
00928   if (missingData(ulc, urc, brc, blc,pos)) return;
00929 
00930   ConditionalBoundary bound; 
00931   bool ownTeamColorIsBlue = getPlayer().getTeamColor() == Player::blue;
00932 
00933   
00934 /*  
00935   obstaclesPercept.angleToFreePartOfGoalWasDetermined[ObstaclesPercept::opponentGoal] = true;
00936   obstaclesPercept.angleToFreePartOfGoal[ObstaclesPercept::opponentGoal] = firstDir + factor * (lastDir - firstDir);
00937   double distance = ((first2 + last2) / 2).abs();
00938   obstaclesPercept.distanceToFreePartOfGoal[ObstaclesPercept::opponentGoal] = distance;
00939   obstaclesPercept.widthOfFreePartOfGoal[ObstaclesPercept::opponentGoal] = distance ? 2 * atan((first - last).abs() / 2 / distance) : pi;
00940 */
00941   Vector2<double> a[4];
00942   calculateAnglesForPoint(r.bottomLeft,rip->cameraMatrix,rip->image.cameraInfo,a[0]);
00943   calculateAnglesForPoint(r.bottomRight,rip->cameraMatrix,rip->image.cameraInfo,a[1]);
00944   calculateAnglesForPoint(r.upperLeft,rip->cameraMatrix,rip->image.cameraInfo,a[2]);
00945   calculateAnglesForPoint(r.upperRight,rip->cameraMatrix,rip->image.cameraInfo,a[3]);
00946   
00947   bound.addX(a[0].x,blc);
00948   bound.addX(a[1].x,brc);
00949   bound.addX(a[2].x,ulc);
00950   bound.addX(a[3].x,urc);
00951 
00952   bound.addY(a[0].y,blc);
00953   bound.addY(a[1].y,brc);
00954   bound.addY(a[2].y,ulc);
00955   bound.addY(a[3].y,urc);
00956 
00957   rip->landmarksPercept.addGoal(greatest.bottomColor, ownTeamColorIsBlue, bound);
00958   
00959   //if(greatest.skyblue != 0) {
00960   //  OUTPUT(idText,text,"goal recognized : skyblue");
00961   //}
00962   //else OUTPUT(idText,text,"goal recognized : yellow");
00963 
00964   greatest.goalValidity = 1;
00965   
00966   LINE(imageProcessor_flagsAndGoals,
00967     greatest.rect.upperLeft.x,greatest.rect.upperLeft.y,
00968     greatest.rect.upperRight.x,greatest.rect.upperRight.y,
00969     1.5, Drawings::ps_solid, Drawings::white);
00970 
00971   LINE(imageProcessor_flagsAndGoals,
00972     greatest.rect.bottomLeft.x,greatest.rect.bottomLeft.y,
00973     greatest.rect.bottomRight.x,greatest.rect.bottomRight.y,
00974     1.5, Drawings::ps_solid, Drawings::white);
00975 
00976   LINE(imageProcessor_flagsAndGoals,
00977     greatest.rect.upperLeft.x,greatest.rect.upperLeft.y,
00978     greatest.rect.bottomLeft.x,greatest.rect.bottomLeft.y,
00979     1.5, Drawings::ps_solid, Drawings::white);
00980 
00981   LINE(imageProcessor_flagsAndGoals,
00982     greatest.rect.upperRight.x,greatest.rect.upperRight.y,
00983     greatest.rect.bottomRight.x,greatest.rect.bottomRight.y,
00984     1.5, Drawings::ps_solid, Drawings::white);
00985   
00986 }
00987 
00988 void BoxSpecialist::calculateAnglesForPoint
00989 (
00990   const Vector2<double>& point, 
00991   const CameraMatrix& cameraMatrix, 
00992   const CameraInfo& cameraInfo, 
00993   Vector2<double>& angles
00994  )
00995 {
00996   double factor = ((double)cameraInfo.resolutionWidth / 2.0) / tan(cameraInfo.openingAngleWidth / 2.0);
00997   
00998   Vector3<double> vectorToPoint(
00999     factor,
01000     cameraInfo.resolutionWidth / 2 - point.x,
01001     cameraInfo.resolutionHeight / 2 - point.y);
01002   
01003   Vector3<double> vectorToPointWorld = 
01004     cameraMatrix.rotation * vectorToPoint;
01005   
01006   angles.x =
01007     atan2(vectorToPointWorld.y,vectorToPointWorld.x);
01008   
01009   angles.y =
01010     atan2(
01011     vectorToPointWorld.z,
01012     sqrt(sqr(vectorToPointWorld.x) + sqr(vectorToPointWorld.y)) 
01013     );
01014 }
01015 
01016 bool BoxSpecialist::calculatePointOnField
01017 (
01018  const double x,
01019  const double y,
01020  const CameraMatrix& cameraMatrix,
01021  const CameraInfo& cameraInfo,
01022  Vector2<int>& pointOnField
01023  )
01024 {
01025 #ifndef _WIN32 // don't recalculate on real robot
01026   static 
01027 #endif
01028   double xFactor = tan(cameraInfo.openingAngleWidth / 2) / (cameraInfo.resolutionWidth / 2),
01029          yFactor = tan(cameraInfo.openingAngleHeight / 2) / (cameraInfo.resolutionHeight / 2);
01030 
01031   Vector3<double> 
01032     vectorToCenter(1, (cameraInfo.resolutionWidth / 2 - 0.5 - x) * xFactor, (cameraInfo.resolutionHeight / 2 - 0.5 - y) * yFactor);
01033   Vector3<double> 
01034     vectorToCenterWorld = cameraMatrix.rotation * vectorToCenter;
01035 
01036   //Is the point above the horizon ? - return
01037   if(vectorToCenterWorld.z > -5 * yFactor) return false;
01038   
01039   double a1 = cameraMatrix.translation.x,
01040          a2 = cameraMatrix.translation.y,
01041          a3 = cameraMatrix.translation.z,
01042          b1 = vectorToCenterWorld.x,
01043          b2 = vectorToCenterWorld.y,
01044          b3 = vectorToCenterWorld.z;
01045   
01046   pointOnField.x = int((a1 * b3 - a3 * b1) / b3 + 0.5);
01047   pointOnField.y = int((a2 * b3 - a3 * b2) / b3 + 0.5);
01048 
01049   return abs(pointOnField.x) < 10000 && abs(pointOnField.y) < 10000;
01050 }
01051 
01052 void BoxSpecialist::createValidities(BoxSpecialist::SegmentInfo& info){
01053   //only landmark validation done yet
01054   if (info.pink== 0 || info.yellow == 0) info.lmValidityYellow = 0;
01055   else info.lmValidityYellow = 1-  2 *  (fabs((double) info.yellow/(double)(info.yellow + info.pink) - 0.5)  );
01056 
01057   if (info.pink== 0 || info.skyblue == 0) info.lmValiditySkyblue = 0;
01058   else info.lmValiditySkyblue = 1-  2 *  (fabs((double) info.skyblue/(double)(info.skyblue + info.pink) - 0.5)  );  
01059 }
01060 
01061 /*void BoxSpecialist::detectFreePartOfGoal(SegmentInfo& goal){
01062   Rectangle& r = goal.rect;
01063   const int maxParts = 3;
01064   Vector2<double> south = pHorizon.direction;
01065   Vector2<double> north(-pHorizon.direction.x,-pHorizon.direction.y);
01066   Vector2<double> east = horizon.direction;
01067   Vector2<double> west(-horizon.direction.x,-horizon.direction.y);
01068 
01069   edgeScanner.threshold = 40;
01070   Vector2<int> bottomLeft((int) r.bottomLeft.x,(int)r.bottomLeft.y);
01071   Vector2<int> bottomRight((int) r.bottomRight.x,(int)r.bottomRight.y);
01072   Vector2<int> vecUp(
01073     (int)((r.upperLeft.x - r.bottomLeft.x)/4),
01074     (int)((r.upperLeft.y - r.bottomLeft.y)/4));
01075 
01076   Vector2<int> scan,finish,temp;
01077   Vector2<int> freeParts[maxParts][2];
01078   bool found;
01079   colorClass col = noColor;
01080   
01081   //scan for free part from the left side
01082   //edgeDetection and colorScanning are combined here again.
01083   finish = bottomRight + vecUp;
01084   temp = bottomLeft + vecUp;
01085   scan = temp;
01086   scan.x = (int)(scan.x + 3*east.x);
01087   scan.y = (int)(scan.y + 3*east.y);
01088 
01089   for(int i = 0;i<maxParts;i++){
01090     
01091     edgeScanner.scan(scan.x,scan.y,finish.x,finish.y);
01092     freeParts[i][0] = temp;
01093     freeParts[i][1] = scan;
01094     edgeScanner.skip(scan.x,scan.y);
01095       
01096     do{
01097       found = edgeScanner.colorScan(scan.x,scan.y,finish.x,finish.y,col);
01098       temp.x = scan.x;
01099       temp.y = scan.y;
01100       if (col == yellow){
01101         edgeScanner.scan(scan.x,scan.y,west);
01102         break;
01103       }
01104     }while (found && col != yellow);
01105   }
01106 }*/
01107 
01108 void BoxSpecialist::detectFreePartOfGoal(){
01109   vector<Vector2<int> >::iterator it = bottomPoints.begin();
01110   vector<Vector2<int> >::iterator lit = it;
01111   vector<Vector2<int> >::iterator last = it;
01112 
01113   vector<Vector2<int> >::iterator leftBorder = it;
01114   vector<Vector2<int> >::iterator rightBorder = it;
01115 
01116   int maxRange = 0;
01117   int clipRange = 5;
01118   int currentRange = 0;
01119   
01120   for(it++;it!=bottomPoints.end();it++){
01121     if ((*last - *it).abs() > clipRange){
01122       currentRange = (*last - *lit).abs();
01123       if (currentRange > maxRange){ 
01124         leftBorder = lit;
01125         rightBorder = last;
01126         maxRange = currentRange;
01127       }
01128       lit = it;
01129     }
01130   }
01131   
01132   //nothing found
01133   if (leftBorder==rightBorder)return;
01134 
01135   Vector2<double> leftAngle,rightAngle;
01136 
01137   LINE(imageProcessor_flagsAndGoals,
01138     leftBorder->x,leftBorder->y, 
01139     rightBorder->x,rightBorder->y, 
01140     2, Drawings::ps_solid, Drawings::green);
01141 
01142   Geometry::calculateAnglesForPoint(
01143     *leftBorder,rip->cameraMatrix,rip->image.cameraInfo,leftAngle);
01144   Geometry::calculateAnglesForPoint(
01145     *rightBorder,rip->cameraMatrix,rip->image.cameraInfo,rightAngle);
01146 
01147   Vector2<double> angles;
01148   Geometry::calculateAnglesForPoint(
01149     Vector2<int>(rip->image.cameraInfo.resolutionWidth / 2, rip->image.cameraInfo.resolutionHeight / 2),
01150     rip->cameraMatrix, rip->image.cameraInfo, angles);
01151 
01152   Pose2D camera(angles.x, Vector2<double>(
01153     rip->cameraMatrix.translation.x,
01154     rip->cameraMatrix.translation.y));
01155 
01156   Vector2<double> middleAngle = (leftAngle + rightAngle)/2;
01157 
01158   double midDir = atan2(middleAngle.x,middleAngle.y);
01159   Vector2<double> first2 = (camera + Pose2D(leftAngle)).translation,
01160                     last2 = (camera + Pose2D(rightAngle)).translation;
01161 
01162   rip->obstaclesPercept.angleToFreePartOfGoalWasDetermined[ObstaclesPercept::opponentGoal] = true;
01163   rip->obstaclesPercept.angleToFreePartOfGoal[ObstaclesPercept::opponentGoal] = midDir;
01164   double distance = ((first2 + last2) / 2).abs();
01165   rip->obstaclesPercept.distanceToFreePartOfGoal[ObstaclesPercept::opponentGoal] = distance;
01166   rip->obstaclesPercept.widthOfFreePartOfGoal[ObstaclesPercept::opponentGoal] = distance ? 2 * atan((leftAngle - rightAngle).abs() / 2 / distance) : pi;  
01167 }
01168   
01169 /*bool RFieldSpecialist::isValid(slist<figure>& lst, lstLineOnField& lines) {
01170 
01171   unsigned int size_t = 0, max_t = 3;
01172   unsigned int i;
01173 
01174   slist<figure>::iterator first(lst.front());
01175   slist<figure>::iterator next = first;
01176   
01177 
01178   if (!(next+=step_alpha)) return false;
01179 
01180   do {
01181     
01182     point p1 = first.get()->toConsider();
01183     point p2 = next.get()->toConsider();
01184 
01185     double angle = theta(p1,p2);
01186 
01187 
01188     next = ++first;
01189 
01190   } while (next+=step_alpha);
01191 
01192  
01193   bool valid = false;
01194   for (i = 0;i<=size_t;++i) {
01195     //OUTPUT(idText,text, "sous-seg " << i << " droit à " << tab_nb[i] << " elts : " << tab_angle[i]);
01196     if (tab_nb[i] >= max_t) {
01197       
01198       valid = true;
01199 
01200       lines.push_front(tab_line[i]);
01201     } 
01202   }
01203 
01204   return valid;
01205 
01206 }*/
01207 
01208 /*
01209 * Change log :
01210 * 
01211 * $Log: BoxSpecialist.cpp,v $
01212 * Revision 1.4  2004/09/06 12:02:26  schmidtb
01213 * commented almost all members, removed warnings in documentation
01214 
01215 * did further code clean up
01216 *
01217 * Revision 1.3  2004/09/02 07:59:29  schmidtb
01218 * Added RasterImageProcessor to repository, because we used it for the OpenChallenge.
01219 *
01220 * Revision 1.50  2004/06/03 13:53:50  schmidtb
01221 * returned to the previous version
01222 *
01223 * Revision 1.48  2004/05/25 13:27:33  schmidtb
01224 * modified version of rip for open-challenge
01225 *
01226 * Revision 1.48  2004/05/18 10:52:14  pg_besc
01227 * version of the last game at US-Open
01228 *
01229 * Revision 1.47  2004/04/15 19:09:01  pg_besc
01230 * merged code
01231 *
01232 * Revision 1.46  2004/03/25 15:20:58  pg_besc
01233 * made some changes
01234 *
01235 * Revision 1.45  2004/03/17 22:31:34  schmidtb
01236 * integrated RFieldStateMachine and horizonal grid scan
01237 *
01238 * Revision 1.44  2004/03/15 09:25:43  rossdeutscher
01239 * Commented out a bug.
01240 *
01241 * Revision 1.43  2004/03/11 20:54:14  schmidtb
01242 * *** empty log message ***
01243 *
01244 * Revision 1.42  2004/03/11 20:33:18  schmidtb
01245 * new version of rip
01246 *
01247 * Revision 1.41  2004/02/28 17:16:47  schmidtb
01248 * debugged and made some changes
01249 *
01250 * Revision 1.40  2004/02/26 14:31:32  schmidtb
01251 * comment some outputs
01252 *
01253 * Revision 1.39  2004/02/25 19:04:29  schmidtb
01254 * removed return statement
01255 *
01256 * Revision 1.38  2004/02/25 15:43:25  schmidtb
01257 * debugged search landmarks
01258 *
01259 * Revision 1.37  2004/02/25 13:30:52  schmidtb
01260 * debugged search landmarks
01261 *
01262 * Revision 1.36  2004/02/18 16:35:46  schmidtb
01263 * removed errors
01264 *
01265 * Revision 1.35  2004/02/18 14:56:19  neubach
01266 * new Segmentation established, code not cleared at all
01267 *
01268 * Revision 1.32  2004/02/05 11:51:17  schmidtb
01269 * now BoxSpecialist recognizes landmarks and goals
01270 *
01271 * Revision 1.31  2004/02/04 23:19:38  schmidtb
01272 * debugged and added calculation for angles to BoxSpecialist
01273 *
01274 * Revision 1.30  2004/02/04 19:09:32  schmidtb
01275 * *** empty log message ***
01276 *
01277 * Revision 1.29  2004/02/04 15:05:20  schmidtb
01278 * warnings removed
01279 *
01280 * Revision 1.28  2004/02/04 13:00:49  schmidtb
01281 * new version of BoxSpecialist
01282 *
01283 * Revision 1.27  2004/02/02 19:50:46  deom
01284 * some modifications,  in order to use the new fonctions added
01285 *
01286 * Revision 1.26  2004/02/02 16:56:52  roefer
01287 * Warnings removed
01288 *
01289 * Revision 1.25  2004/02/02 13:42:11  schmidtb
01290 * merged sources of RIP. added som functions.
01291 *
01292 * Revision 1.24  2004/02/01 13:33:40  deom
01293 * major improvements :
01294 * - validity analysis added
01295 * - bug fixed
01296 * - fonction calls restructurated
01297 * - no warnigs this time :)  dortmund won't suck anymore ...
01298 *
01299 * Revision 1.23  2004/01/29 09:16:19  schumann
01300 * unsucked.
01301 *
01302 * Revision 1.22  2004/01/29 00:14:07  deom
01303 * bug bixed
01304 *
01305 * Revision 1.20  2004/01/28 10:08:52  deom
01306 * added some code
01307 *
01308 * Revision 1.19  2004/01/27 21:30:34  kerdels
01309 * warnings removed...
01310 *
01311 * Revision 1.18  2004/01/27 21:26:34  deom
01312 * *** empty log message ***
01313 *
01314 * Revision 1.16  2004/01/27 21:05:34  schumann
01315 * added log
01316 *
01317 */

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