orca-robotics


INTRODUCTION
Overview
Download and Install
Documentation

REPOSITORY
Interfaces
Drivers
Libraries
Utilities
Software Map

DEVELOPER
Dashboard

PEOPLE
Contributors
Users

SourceForge.net Logo
Project
Download
Mailing lists

 

         

ograytracer.h

00001 /*
00002  * Orca-Robotics Project: Components for robotics 
00003  *               http://orca-robotics.sf.net/
00004  * Copyright (c) 2004-2008 Alex Brooks, Alexei Makarenko, Tobias Kaupp, George Mathews
00005  *
00006  * This copy of Orca is licensed to you under the terms described in
00007  * the LICENSE file included in this distribution.
00008  *
00009  */
00010 #ifndef HYDROOGMAP_OGRAYTRACER_H
00011 #define HYDROOGMAP_OGRAYTRACER_H
00012 
00013 #include <hydroogmap/ogmap.h>
00014 #include <hydroportability/sharedlib.h>
00015 
00016 namespace hydroogmap {
00017 
00018 //
00019 // The OgRayTracer stuff's fast and general, but maybe a bit difficult to understand.
00020 // For a simple use case, see simpleograytrace.h
00021 //
00022 
00033 class SOEXPORT SafeLosCellTracer
00034 {
00035 public:
00036     SafeLosCellTracer( const hydroogmap::OgMap &theMap, 
00037                        unsigned char occupiedThreshold=hydroogmap::CELL_UNKNOWN )
00038         : theMap_(theMap),
00039           occupiedThreshold_(occupiedThreshold)
00040         {}
00041 
00044     inline bool traceCell(int x, int y)
00045         {
00046             if ( !theMap_.cellWithinMap( x, y )  ||
00047                  theMap_.gridCell(x,y) >= occupiedThreshold_ )
00048             {
00049                 // Occupied or outside the map: stop tracing.
00050                 lastEndX_ = x;
00051                 lastEndY_ = y;
00052                 return false;
00053             }
00054             // Keep tracing.
00055             return true;
00056         }
00057 
00058     inline void traceSucceeded( int x, int y )
00059         { lastEndX_ = x; lastEndY_ = y; }
00060 
00062     int lastEndX() const { return lastEndX_; }
00064     int lastEndY() const { return lastEndY_; }
00065 
00066 private:
00067 
00068     const hydroogmap::OgMap &theMap_;
00069     const unsigned char occupiedThreshold_;
00070 
00071     // The coordinates of the end of the last ray-trace.
00072     int lastEndX_;
00073     int lastEndY_;
00074 };
00075 
00085 class SOEXPORT UncheckedLosCellTracer
00086 {
00087 public:
00088     UncheckedLosCellTracer(const hydroogmap::OgMap &theMap,
00089                            unsigned char occupiedThreshold=hydroogmap::CELL_UNKNOWN )
00090         : theMap_(theMap),
00091           occupiedThreshold_(occupiedThreshold)
00092         {}
00093 
00095     inline bool traceCell(int x, int y)
00096         {
00097             if ( theMap_.gridCell(x,y) > occupiedThreshold_ )
00098             {
00099                 // Occupied: stop tracing.
00100                 lastEndX_ = x;
00101                 lastEndY_ = y;
00102                 return false;
00103             }
00104             // Keep tracing.
00105             return true;
00106         }
00107 
00108     inline void traceSucceeded( int x, int y )
00109         { lastEndX_ = x; lastEndY_ = y; }
00110 
00112     int lastEndX() const { return lastEndX_; }
00114     int lastEndY() const { return lastEndY_; }
00115 
00116 private:
00117 
00118     const hydroogmap::OgMap &theMap_;
00119     const unsigned char occupiedThreshold_;
00120 
00121     // The coordinates of the end of the last ray-trace.
00122     int lastEndX_;
00123     int lastEndY_;
00124 };
00125 
00133 template<class CellTracer=SafeLosCellTracer>
00134 class SOEXPORT OgRayTracer
00135 {
00136 
00137 public: 
00138 
00139     // non-const version
00140     OgRayTracer( CellTracer &cellTracer )
00141         : cellTracer_(cellTracer)
00142         {}
00143 
00158     bool trace( int x0, int y0, int x1, int y1 );
00159 
00160 private: 
00161 
00162     // These guys return:
00163     //  true:  we traced out to (x1,y1)
00164     //  false: the trace was short-circuited
00165     //
00166     bool rayTraceOct0( int x0, int y0, int x1, int y1 );
00167     bool rayTraceOct1( int x0, int y0, int x1, int y1 );
00168     bool rayTraceOct2( int x0, int y0, int x1, int y1 );
00169     bool rayTraceOct3( int x0, int y0, int x1, int y1 );
00170     bool rayTraceOct4( int x0, int y0, int x1, int y1 );
00171     bool rayTraceOct5( int x0, int y0, int x1, int y1 );
00172     bool rayTraceOct6( int x0, int y0, int x1, int y1 );
00173     bool rayTraceOct7( int x0, int y0, int x1, int y1 );
00174     bool rayTraceOct8( int x0, int y0, int x1, int y1 );
00175 
00176     CellTracer &cellTracer_;
00177 };
00178 
00179 template<class CellTracer>
00180 SOEXPORT bool
00181 OgRayTracer<CellTracer>::trace( int x0, int y0, int x1, int y1 )
00182 {
00183     /*
00184     *  Octants are defined as follows:
00185     *
00186     *   \2|1/ 
00187     *   3\|/0
00188     *   --x--
00189     *   4/|\7
00190     *   /5|6\ 
00191     *
00192     */
00193     float slope;
00194     if ( x0 == x1 )
00195         slope = 999999;
00196     else
00197         slope = (float)(y1-y0) / (float)(x1-x0);
00198 
00199     bool traceWentToEnd;
00200     if ( slope >= 0.0 && slope <= 1.0 )
00201     {
00202         if ( x1 > x0 )
00203         {
00204             // octant 0
00205             traceWentToEnd = rayTraceOct0( x0, y0, x1, y1 );
00206         }
00207         else
00208         {
00209             // octant 4
00210             traceWentToEnd = rayTraceOct4( x1, y1, x0, y0 );
00211         }
00212     }
00213     else if ( slope > 1.0 )
00214     {
00215         if ( y1 > y0 )
00216         {
00217             // octant 1
00218             traceWentToEnd = rayTraceOct1( x0, y0, x1, y1 );
00219         }
00220         else
00221         {
00222             // octant 5
00223             traceWentToEnd = rayTraceOct5( x1, y1, x0, y0 );
00224         }
00225     }
00226     else if ( slope <= -1.0 )
00227     {
00228         if ( y1 > y0 )
00229         {
00230             // octant 2
00231             traceWentToEnd = rayTraceOct2( x0, y0, x1, y1 );
00232         }
00233         else
00234         {
00235             // octant 6
00236             traceWentToEnd = rayTraceOct6( x1, y1, x0, y0 );
00237         }
00238     }
00239     else // ( slope < 0.0 && slope > -1.0 )
00240     {
00241         if ( x1 > x0 )
00242         {
00243             // octant 7
00244             traceWentToEnd = rayTraceOct7( x0, y0, x1, y1 );
00245         }
00246         else
00247         {
00248             // octant 3
00249             traceWentToEnd = rayTraceOct3( x1, y1, x0, y0 );
00250         }
00251     }
00252 
00253     if ( traceWentToEnd )
00254     {
00255         cellTracer_.traceSucceeded( x1, y1 );
00256     }
00257     return traceWentToEnd;
00258 }
00259 
00260 template<class CellTracer>
00261 SOEXPORT bool
00262 OgRayTracer<CellTracer>::rayTraceOct0( int x0, int y0, int x1, int y1 )
00263 {
00264     int y = y0; 
00265     int dx = 2*(x1-x0);
00266     int dy = 2*(y1-y0); 
00267     int dydx = dy-dx; 
00268     int F = (dy-dx)/2; 
00269 
00270     for (int x=x0; x<=x1; x++) 
00271     { 
00272         if ( !cellTracer_.traceCell( x, y ) )
00273         {
00274             return false;
00275         }
00276         if ( F<0 ) 
00277         {
00278             F += dy; 
00279         }
00280         else 
00281         {
00282             y++; 
00283             F += dydx;
00284         } 
00285     }
00286     return true;
00287 }
00288 
00289 template<class CellTracer>
00290 SOEXPORT bool
00291 OgRayTracer<CellTracer>::rayTraceOct4( int x0, int y0, int x1, int y1 )
00292 {
00293     int y = y1; 
00294     int dx = 2*(x1-x0);
00295     int dy = 2*(y1-y0); 
00296     int dydx = dy-dx; 
00297     int F = (dy-dx)/2; 
00298 
00299     for (int x=x1; x>=x0; x--) 
00300     { 
00301         if ( !cellTracer_.traceCell( x, y ) )
00302         {
00303             return false;
00304         }
00305         if ( F<0 ) 
00306         {
00307             F += dy; 
00308         }
00309         else 
00310         {
00311             y--;
00312             F += dydx;
00313         } 
00314     }
00315     return true;
00316 }
00317 
00318 
00319 template<class CellTracer>
00320 SOEXPORT bool
00321 OgRayTracer<CellTracer>::rayTraceOct1( int x0, int y0, int x1, int y1 )
00322 {
00323     int x = x0; 
00324     int dx = 2*(x1-x0);
00325     int dy = 2*(y1-y0); 
00326     int dxdy = dx-dy; 
00327     int F = (dx-dy)/2; 
00328 
00329     for (int y=y0; y<=y1; y++) 
00330     { 
00331         if ( !cellTracer_.traceCell( x, y ) )
00332         {
00333             return false;
00334         }
00335         if ( F<0 ) 
00336         {
00337             F += dx; 
00338         }
00339         else 
00340         {
00341             x++; 
00342             F += dxdy;
00343         } 
00344     }
00345     return true;
00346 }
00347 
00348 template<class CellTracer>
00349 SOEXPORT bool
00350 OgRayTracer<CellTracer>::rayTraceOct5( int x0, int y0, int x1, int y1 )
00351 {
00352     int x = x1; 
00353     int dx = 2*(x1-x0);
00354     int dy = 2*(y1-y0); 
00355     int dxdy = dx-dy; 
00356     int F = (dx-dy)/2; 
00357 
00358     for (int y=y1; y>=y0; y--) 
00359     { 
00360         if ( !cellTracer_.traceCell( x, y ) )
00361         {
00362             return false;
00363         }
00364         if ( F<0 ) 
00365         {
00366             F += dx; 
00367         }
00368         else 
00369         {
00370             x--; 
00371             F += dxdy;
00372         } 
00373     }
00374     return true;
00375 }
00376 
00377 template<class CellTracer>
00378 SOEXPORT bool
00379 OgRayTracer<CellTracer>::rayTraceOct2( int x0, int y0, int x1, int y1 )
00380 {
00381     int x = x0; 
00382     int dx = -2*(x1-x0);
00383     int dy = 2*(y1-y0); 
00384     int dxdy = dx-dy; 
00385     int F = (dx-dy)/2; 
00386 
00387     for (int y=y0; y<=y1; y++) 
00388     { 
00389         if ( !cellTracer_.traceCell( x, y ) )
00390         {
00391             return false;
00392         }
00393         if ( F<0 ) 
00394         {
00395             F += dx; 
00396         }
00397         else 
00398         {
00399             x--; 
00400             F += dxdy;
00401         } 
00402     }
00403     return true;
00404 }
00405 
00406 template<class CellTracer>
00407 SOEXPORT bool
00408 OgRayTracer<CellTracer>::rayTraceOct6( int x0, int y0, int x1, int y1 )
00409 {
00410     int x = x1; 
00411     int dx = -2*(x1-x0);
00412     int dy = 2*(y1-y0); 
00413     int dxdy = dx-dy; 
00414     int F = (dx-dy)/2; 
00415 
00416     for (int y=y1; y>=y0; y--) 
00417     { 
00418         if ( !cellTracer_.traceCell( x, y ) )
00419         {
00420             return false;
00421         }
00422         if ( F<0 ) 
00423         {
00424             F += dx; 
00425         }
00426         else 
00427         {
00428             x++; 
00429             F += dxdy;
00430         } 
00431     }
00432     return true;
00433 }
00434 
00435 template<class CellTracer>
00436 SOEXPORT bool
00437 OgRayTracer<CellTracer>::rayTraceOct7( int x0, int y0, int x1, int y1 )
00438 {
00439     int y = y0; 
00440     int dx = 2*(x1-x0);
00441     int dy = -2*(y1-y0); 
00442     int dydx = dy-dx; 
00443     int F = (dy-dx)/2; 
00444 
00445     for (int x=x0; x<=x1; x++) 
00446     { 
00447         if ( !cellTracer_.traceCell( x, y ) )
00448         {
00449             return false;
00450         }
00451         if ( F<0 ) 
00452         {
00453             F += dy; 
00454         }
00455         else 
00456         {
00457             y--; 
00458             F += dydx;
00459         } 
00460     }
00461     return true;
00462 }
00463 
00464 template<class CellTracer>
00465 SOEXPORT bool
00466 OgRayTracer<CellTracer>::rayTraceOct3( int x0, int y0, int x1, int y1 )
00467 {
00468     int y = y1; 
00469     int dx = 2*(x1-x0);
00470     int dy = -2*(y1-y0); 
00471     int dydx = dy-dx; 
00472     int F = (dy-dx)/2; 
00473 
00474     for (int x=x1; x>=x0; x--) 
00475     { 
00476         if ( !cellTracer_.traceCell( x, y ) )
00477         {
00478             return false;
00479         }
00480         if ( F<0 ) 
00481         {
00482             F += dy; 
00483         }
00484         else 
00485         {
00486             y++; 
00487             F += dydx;
00488         } 
00489     }
00490     return true;
00491 }
00492 
00493 }
00494 
00495 #endif
00496 
 

Webmaster: Tobias Kaupp (tobasco at users.sourceforge.net)


Generated for Orca Robotics by  doxygen 1.4.5