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

geo_utils.cpp

Go to the documentation of this file.
00001 /*------------------------------------ Includes ---------------------------------------------*/ 00002 #include "geo_utils.h" 00003 00004 #include <math.h> 00005 #include <assert.h> 00006 00007 using namespace std; 00008 00009 /*--------------------------------------------------------------------------------------------------*/ 00010 float Get_Distance( cPoint2D& p1 , cPoint2D& p2 ) 00011 { 00012 return (float)sqrt( ( p1.X-p2.X ) * ( p1.X-p2.X ) 00013 +( p1.Y-p2.Y ) * ( p1.Y-p2.Y ) ); 00014 00015 } 00016 00017 /*--------------------------------------------------------------------------------------------------*/ 00018 unsigned int Get_Square_Distance( cPoint2D& p1 , cPoint2D& p2 ) 00019 { 00020 return ( ( p1.X-p2.X ) * ( p1.X-p2.X ) + ( p1.Y-p2.Y ) * ( p1.Y-p2.Y ) ); 00021 } 00022 00023 00024 00025 /****************************************************************************************************/ 00026 // class cRectangle 00027 /****************************************************************************************************/ 00028 void cRectangle::Get_Centre(cPoint2D & p) 00029 { 00030 p.Set( (p0.X + p1.X)/2 , (p0.Y + p1.Y)/2 ); 00031 } 00032 00033 00034 00035 00036 00037 /****************************************************************************************************/ 00038 // class cPositive_Rectangle 00039 /****************************************************************************************************/ 00040 cPositive_Rectangle::cPositive_Rectangle(cPoint2D &pA , cPoint2D &pB):cRectangle() 00041 { 00042 int xmin,xmax,ymin,ymax; 00043 if( pA.X <= pB.X) 00044 { 00045 xmin=pA.X; 00046 xmax=pB.X; 00047 } 00048 else 00049 { 00050 xmin=pB.X; 00051 xmax=pA.X; 00052 } 00053 00054 if( pA.Y <= pB.Y) 00055 { 00056 ymin=pA.Y; 00057 ymax=pB.Y; 00058 } 00059 else 00060 { 00061 ymin=pB.Y; 00062 ymax=pA.Y; 00063 } 00064 00065 p0.X = xmin; 00066 p0.Y = ymin; 00067 p1.X = xmax; 00068 p1.Y = ymax; 00069 } 00070 00071 /*--------------------------------------------------------------------------------------------------*/ 00072 void cPositive_Rectangle::Get_Nord_Seg( cHV_Seg & seg ) 00073 { 00074 cPoint2D pA,pB; 00075 pA = p0; 00076 pB.Set( p1.X , p0.Y ); 00077 seg.Set( pA , pB); 00078 } 00079 00080 /*--------------------------------------------------------------------------------------------------*/ 00081 void cPositive_Rectangle::Get_Ouest_Seg( cHV_Seg & seg ) 00082 { 00083 cPoint2D pA,pB; 00084 pA = p0; 00085 pB.Set( p0.X , p1.Y ); 00086 seg.Set( pA , pB); 00087 00088 } 00089 00090 /*--------------------------------------------------------------------------------------------------*/ 00091 void cPositive_Rectangle::Get_Est_Seg( cHV_Seg & seg ) 00092 { 00093 cPoint2D pA,pB; 00094 pA.Set( p1.X , p0.Y ); 00095 pB =p1; 00096 seg.Set( pA , pB); 00097 } 00098 00099 /*--------------------------------------------------------------------------------------------------*/ 00100 void cPositive_Rectangle::Get_Sud_Seg( cHV_Seg & seg ) 00101 { 00102 cPoint2D pA,pB; 00103 pA.Set( p0.X , p1.Y ); 00104 pB = p1; 00105 seg.Set( pA , pB); 00106 } 00107 00108 00109 00110 /*--------------------------------------------------------------------------------------------------*/ 00111 bool cPositive_Rectangle::In( cPoint2D &pA ) 00112 { 00113 return ( pA.Get_X()>=p0.X && pA.Get_X() <=p1.X && pA.Get_Y()>=p0.Y && pA.Get_Y() <=p1.Y ); 00114 }; 00115 00116 00117 00118 00119 /****************************************************************************************************/ 00120 // class cSeg 00121 /****************************************************************************************************/ 00122 float cSeg::Get_Square_Distance_From_Point( cPoint2D & C ) 00123 { 00124 float AB[2]; // represente le segment 00125 float AC[2]; 00126 float AC_sur_AB; 00127 float AE_2; // E : projete de C sur AB, dist carrée 00128 float AB_2; // E : projete de C sur AB, dist carrée 00129 float AC_2; // E : projete de C sur AB, dist carrée 00130 float BC_2; // E : projete de C sur AB, dist carrée 00131 00132 AB[0] = p1.Get_X() - p0.Get_X(); 00133 AB[1] = p1.Get_Y() - p0.Get_Y(); 00134 AC[0] = C.Get_X() - p0.Get_X(); 00135 AC[1] = C.Get_Y() - p0.Get_Y(); 00136 00137 AC_sur_AB = AB[0] * AC[0] + AB[1] * AC[1]; 00138 00139 00140 00141 if( AC_sur_AB <0) // le point le plus pres de C sur le segment est le point A 00142 { 00143 00144 return AC[0]*AC[0]+AC[1]*AC[1]; // AC² 00145 } 00146 else // le projet de de C est a droite de A 00147 { 00148 AB_2 = AB[0]*AB[0]+AB[1]*AB[1]; 00149 AE_2 = AC_sur_AB * AC_sur_AB / AB_2; 00150 00151 00152 if( AE_2 < AB_2) // le projete est sur le segment, on retourne CE² 00153 { 00154 00155 AC_2 = AC[0]*AC[0]+AC[1]*AC[1]; 00156 return AC_2 - AE_2; 00157 } 00158 else // le projete est a droite de B, on retourne BC² 00159 { 00160 00161 BC_2 = ( C.Get_X() - p1.Get_X())*( C.Get_X() - p1.Get_X() ) // BC² 00162 + ( C.Get_Y() - p1.Get_Y())*( C.Get_Y() - p1.Get_Y() ) ; 00163 return BC_2; 00164 } 00165 } 00166 00167 00168 } 00169 00170 /*--------------------------------------------------------------------------------------------------*/ 00171 void cSeg::Get_Middle(cPoint2D& p) 00172 { 00173 p.Set( (p0.Get_X() + p1.Get_X())/2 , (p0.Get_Y() + p1.Get_Y())/2 ) ; 00174 } 00175 00176 /*--------------------------------------------------------------------------------------------------*/ 00177 bool cSeg::operator==(cSeg& seg2) 00178 { 00179 return ( (p0==seg2.Get_p0() && p1==seg2.Get_p1()) || 00180 (p0==seg2.Get_p1() && p1==seg2.Get_p0()) ); 00181 } 00182 00183 /*--------------------------------------------------------------------------------------------------*/ 00184 unsigned int cSeg::Get_Square_Length() 00185 { 00186 return (p0.Get_X()-p1.Get_X()) * (p0.Get_X()-p1.Get_X()) 00187 + (p0.Get_Y()-p1.Get_Y()) * (p0.Get_Y()-p1.Get_Y()) ; 00188 } 00189 00190 00191 00192 00193 00194 00195 00196 /****************************************************************************************************/ 00197 // class cHV_Seg 00198 /****************************************************************************************************/ 00199 cHV_Seg::cHV_Seg(cPoint2D &pA , cPoint2D &pB):cSeg(pA , pB) 00200 { 00201 int xmin,xmax,ymin,ymax; 00202 00203 if( pA.Get_X() <= pB.Get_X() ) 00204 { 00205 xmin = pA.Get_X(); 00206 xmax = pB.Get_X(); 00207 } 00208 else 00209 { 00210 xmin = pB.Get_X(); 00211 xmax = pA.Get_X(); 00212 } 00213 00214 if( pA.Get_Y() <= pB.Get_Y() ) 00215 { 00216 ymin = pA.Get_Y(); 00217 ymax = pB.Get_Y(); 00218 } 00219 else 00220 { 00221 ymin = pB.Get_Y(); 00222 ymax = pA.Get_Y(); 00223 } 00224 00225 if( ymin == ymax) 00226 { 00227 bHorizontal = true; 00228 p0.Set( xmin,ymin); 00229 p1.Set( xmax,ymin); 00230 } 00231 else if( xmin == xmax) 00232 { 00233 bHorizontal = false; 00234 p0.Set( xmin,ymin); 00235 p1.Set( xmin,ymax); 00236 } 00237 else 00238 std::cout << "cHV_Seg(cPoint2D &pA , cPoint2D &pB) : [" << pA << "-->" << pB << "] not a valid HV seg \n"; 00239 } 00240 00241 /*--------------------------------------------------------------------------------------------------*/ 00242 void cHV_Seg::Set( cPoint2D &pA , cPoint2D &pB ) 00243 { 00244 int xmin,xmax,ymin,ymax; 00245 00246 if( pA.Get_X() <= pB.Get_X() ) 00247 { 00248 xmin = pA.Get_X(); 00249 xmax = pB.Get_X(); 00250 } 00251 else 00252 { 00253 xmin = pB.Get_X(); 00254 xmax = pA.Get_X(); 00255 } 00256 00257 if( pA.Get_Y() <= pB.Get_Y() ) 00258 { 00259 ymin = pA.Get_Y(); 00260 ymax = pB.Get_Y(); 00261 } 00262 else 00263 { 00264 ymin = pB.Get_Y(); 00265 ymax = pA.Get_Y(); 00266 } 00267 00268 if( ymin == ymax) 00269 { 00270 bHorizontal = true; 00271 p0.Set( xmin,ymin); 00272 p1.Set( xmax,ymin); 00273 } 00274 else if( xmin == xmax) 00275 { 00276 bHorizontal = false; 00277 p0.Set( xmin,ymin); 00278 p1.Set( xmin,ymax); 00279 } 00280 else 00281 std::cout << "cHV_Seg(cPoint2D &pA , cPoint2D &pB) : [" << pA << "-->" << pB << "] not a valid HV seg \n"; 00282 } 00283 00284 00285 /*--------------------------------------------------------------------------------------------------*/ 00286 bool cHV_Seg::Get_Intersection( cHV_Seg& seg , cHV_Seg& result) 00287 { 00288 cPoint2D pA,pB; 00289 00290 if( bHorizontal) 00291 { 00292 if( seg.Is_Horizontal() ) // les deux sont horizontaux 00293 { 00294 if( p0.Get_Y() != seg.p0.Get_Y() ) // les murs ne sont pas a la meme hauteur 00295 return false; 00296 else 00297 { 00298 if( seg.p1.Get_X() < p0.Get_X() ) // seg tt a gauche 00299 return false; 00300 if( seg.p0.Get_X() > p1.Get_X() ) // seg tt a droite 00301 return false; 00302 else 00303 { 00304 // le seg inter commence au plus grd X des deux points initiaux 00305 if( seg.p0.Get_X() < p0.Get_X() ) 00306 pA = p0; 00307 else 00308 pA = seg.p0; 00309 00310 // le seg inter termine au plus petit X des deux points initiaux 00311 if( seg.p1.Get_X() < p1.Get_X() ) 00312 pB = seg.p1; 00313 else 00314 pB = p1; 00315 00316 result.Set(pA,pB); 00317 return true; 00318 } 00319 } 00320 } 00321 else // le premier mur est horizontal et le secon vertical 00322 { 00323 pA.X = seg.Get_p0().X; 00324 pA.Y = p0.Y; 00325 result.Set( pA , pA); 00326 return true; 00327 } 00328 00329 } 00330 else // mur vertical 00331 { 00332 if( ! seg.Is_Horizontal() ) // les deux sont verticaux 00333 { 00334 if( seg.p1.Get_X() != p0.Get_X() ) // seg pas a la meme abcisse 00335 return false; 00336 else 00337 { 00338 if( seg.p1.Get_Y() < p0.Get_Y() ) // seg tt dessous 00339 return false; 00340 if( seg.p0.Get_Y() > p1.Get_Y() ) // seg tt au dessus 00341 return false; 00342 else 00343 { 00344 if( seg.p0.Get_Y() < p0.Get_Y() ) 00345 pA = p0; 00346 else 00347 pA = seg.p0; 00348 00349 if( seg.p1.Get_Y() < p1.Get_Y() ) 00350 pB = seg.p1; 00351 else 00352 pB = p1; 00353 result.Set(pA,pB); 00354 return true; 00355 } 00356 } 00357 } 00358 else 00359 { 00360 pA.X = p0.X; 00361 pA.Y = seg.Get_p0().Y; 00362 result.Set( pA , pA); 00363 return true; 00364 00365 } 00366 } 00367 } 00368 00369 00370 bool cHV_Seg::Contient( cHV_Seg& seg ) 00371 { 00372 cHV_Seg inter; 00373 bool result; 00374 result = Get_Intersection( seg , inter); 00375 00376 if( !result) 00377 return false; 00378 00379 if( inter == seg) 00380 return true; 00381 else 00382 return false; 00383 00384 } 00385 00386 /* seg doit etre contenu dans ce segment !!!!!! 00387 return : 00388 * 0 -> pas d'intersection 00389 * 1 -> egalité entre les segments ( this == seg) 00390 * 2 -> seg est strictement contenu ds ce segment, comp1 et comp2 contiennent les segments complementaires 00391 * tq que complementaire1 soit au dessus de complementaire 2 ( abcisse inférieure, ou ord inférieure) 00392 * this = comp1<->inter<->comp2 00393 * 3 -> complementaire1 est valide, complementaire 2 est vide 00394 * this = comp1<->inter 00395 * 4 -> complementaire2 est valide, complementaire 1 est vide 00396 * this = inter<->comp2 00397 */ 00398 00399 int cHV_Seg::Get_Complementaires( cHV_Seg& seg , cHV_Seg& complementaire1, cHV_Seg& complementaire2) 00400 { 00401 00402 assert( Contient(seg) ); 00403 00404 bool result; 00405 cHV_Seg inter; 00406 result = Get_Intersection( seg , inter); 00407 00408 if( result) 00409 { 00410 if( (*this) == seg) 00411 return 1; 00412 else 00413 { 00414 if( inter.Get_p0() != Get_p0() ) // comp1 valide 00415 { 00416 complementaire1.Set( Get_p0() , inter.Get_p0()); 00417 if( inter.Get_p1() != Get_p1()) //comp2 valide 00418 { 00419 complementaire2.Set( inter.Get_p1(), Get_p1() ); 00420 return 2; 00421 } 00422 else 00423 { 00424 return 3; 00425 } 00426 } 00427 else if( inter.Get_p1() != Get_p1() ) // comp2 valide 00428 { 00429 complementaire2.Set( inter.Get_p1(), Get_p1() ); 00430 return 4; 00431 } 00432 else 00433 assert(0); 00434 } 00435 } 00436 else 00437 return 0; 00438 00439 return 0; 00440 } 00441 00442 00443 00444 /*--------------------------------------------------------------------------------------------------*/ 00445 bool cHV_Seg::Contient_Point(cPoint2D & A) 00446 { 00447 if( bHorizontal) 00448 { 00449 if( A.Get_Y() != Get_p0().Get_Y() ) 00450 return false; 00451 else if( A.Get_X() < Get_p0().Get_X() || A.Get_X() > Get_p1().Get_X() ) // fonctionne car le cHV_Seg est ordonné croissant 00452 return false; 00453 return true; 00454 } 00455 else 00456 { 00457 if( A.Get_X() != Get_p0().Get_X() ) 00458 return false; 00459 else if( A.Get_Y() < Get_p0().Get_Y() || A.Get_Y() > Get_p1().Get_Y() ) // fonctionne car le cHV_Seg est ordonné croissant 00460 return false; 00461 return true; 00462 } 00463 } 00464 00465 00466 00467 bool cHV_Seg::On_Same_Line( cHV_Seg& seg ) 00468 { 00469 if( bHorizontal) 00470 { 00471 if( seg.Is_Horizontal() ) 00472 { 00473 if( seg.Get_p0().Y == p0.Y) 00474 return true; 00475 else 00476 return false; 00477 } 00478 else 00479 { 00480 return false; 00481 } 00482 } 00483 else 00484 { 00485 if( seg.Is_Horizontal() ) 00486 { 00487 return false; 00488 } 00489 else 00490 { 00491 if( seg.Get_p0().X == p0.X) 00492 return true; 00493 else 00494 return false; 00495 } 00496 } 00497 }

Generated on Fri May 21 19:22:37 2004 for LIBELL by doxygen 1.3.7