orca-robotics INTRODUCTION Overview Download and Install Documentation REPOSITORY Interfaces Drivers Libraries Utilities Software Map DEVELOPER Dashboard PEOPLE Contributors Users Project Download Mailing lists
|
ograytracer.h00001 /* 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)