OSDLPolygon.cc

Go to the documentation of this file.
00001 #include "OSDLPolygon.h"
00002 
00003 #include "OSDLSurface.h"  // for Surface
00004 #include "OSDLPoint2D.h"  // for Point2D
00005 #include "OSDLVideo.h"    // for VideoModule
00006 
00007 
00008 #include "SDL_gfxPrimitives.h"  // for graphic primitives exported by SDL_gfx
00009 
00010 
00011 
00012 
00013 using std::string ;
00014 using std::list ;
00015 
00016 using namespace Ceylan::Maths ;
00017 using namespace OSDL::Video ;
00018 
00019 
00020 using Ceylan::Maths::Real ;
00021 
00022 
00023 // A return code of 0 for SDL_gfx functions means no error, contrary to -1.
00024 
00025 
00026 
00027 bool TwoDimensional::drawPie( Surface & targetSurface, 
00028     Coordinate xCenter, Coordinate yCenter, Length radius, 
00029     Ceylan::Maths::AngleInDegrees angleStart, 
00030     Ceylan::Maths::AngleInDegrees angleStop,
00031     Pixels::ColorElement red, Pixels::ColorElement green, 
00032     Pixels::ColorElement blue, Pixels::ColorElement alpha ) throw()
00033 {
00034 
00035     return ( ::filledPieRGBA( & targetSurface.getSDLSurface(), 
00036         xCenter, yCenter, radius, static_cast<Coordinate>( angleStart ),
00037         static_cast<Coordinate>( angleStop ), red, green, blue, alpha ) == 0 ) ;
00038         
00039 }
00040 
00041 
00042 
00043 bool TwoDimensional::drawPie( Surface & targetSurface, 
00044     Coordinate xCenter, Coordinate yCenter, Length radius, 
00045     Ceylan::Maths::AngleInDegrees angleStart, 
00046     Ceylan::Maths::AngleInDegrees angleStop, 
00047     Pixels::ColorDefinition colorDef ) throw()
00048 {
00049 
00050     return ( ::filledPieColor( & targetSurface.getSDLSurface(), 
00051         xCenter, yCenter, radius, 
00052         static_cast<Coordinate>( angleStart ),
00053         static_cast<Coordinate>( angleStop ),
00054         Pixels::convertColorDefinitionToRawPixelColor( colorDef ) ) == 0 ) ;
00055 
00056 }
00057 
00058 
00059 
00060 bool TwoDimensional::drawTriangle( Surface & targetSurface, 
00061     Coordinate x1, Coordinate y1, 
00062     Coordinate x2, Coordinate y2, 
00063     Coordinate x3, Coordinate y3, 
00064     Pixels::ColorElement red, Pixels::ColorElement green, 
00065     Pixels::ColorElement blue, Pixels::ColorElement alpha, bool filled ) throw()
00066 {
00067 
00068     if ( filled )
00069     {
00070                 
00071         return ( ::filledTrigonRGBA( & targetSurface.getSDLSurface(), 
00072             x1, y1, x2, y2, x3, y3, red, green, blue, alpha ) == 0 ) ;
00073             
00074     }
00075     else
00076     {
00077         
00078         if ( VideoModule::GetAntiAliasingState() )
00079         {
00080             return ( ::aatrigonRGBA( & targetSurface.getSDLSurface(), 
00081                 x1, y1, x2, y2, x3, y3, red, green, blue, alpha ) == 0 ) ;
00082             
00083         }
00084         else
00085         {
00086             return ( ::trigonRGBA( & targetSurface.getSDLSurface(), 
00087                 x1, y1, x2, y2, x3, y3, red, green, blue, alpha ) == 0 ) ;
00088         
00089         }
00090     
00091     }
00092 
00093 }
00094 
00095 
00096     
00097 bool TwoDimensional::drawTriangle( Surface & targetSurface, 
00098     Coordinate x1, Coordinate y1, 
00099     Coordinate x2, Coordinate y2, 
00100     Coordinate x3, Coordinate y3, 
00101     Pixels::ColorDefinition colorDef, bool filled ) throw()
00102 {
00103 
00104     if ( filled )
00105     {
00106                 
00107         return ( ::filledTrigonColor( & targetSurface.getSDLSurface(), 
00108             x1, y1, x2, y2, x3, y3,
00109             Pixels::convertColorDefinitionToRawPixelColor( colorDef ) ) == 0 ) ;
00110             
00111     }
00112     else
00113     {
00114         
00115         if ( VideoModule::GetAntiAliasingState() )
00116         {
00117         
00118             return ( ::aatrigonColor( & targetSurface.getSDLSurface(), 
00119                 x1, y1, x2, y2, x3, y3,
00120                 Pixels::convertColorDefinitionToRawPixelColor( colorDef ) 
00121                     ) == 0 ) ;
00122             
00123         }
00124         else
00125         {
00126         
00127             return ( ::trigonColor( & targetSurface.getSDLSurface(), 
00128                 x1, y1, x2, y2, x3, y3,
00129                 Pixels::convertColorDefinitionToRawPixelColor( colorDef ) 
00130                     ) == 0 ) ;
00131         
00132         }
00133     
00134     }
00135 
00136 }
00137 
00138     
00139 
00140 bool TwoDimensional::drawTriangle( Surface & targetSurface, 
00141     const Point2D & p1, const Point2D & p2, const Point2D & p3,
00142     Pixels::ColorElement red, Pixels::ColorElement green, 
00143     Pixels::ColorElement blue, Pixels::ColorElement alpha, 
00144     bool filled ) throw()
00145 {
00146 
00147     if ( filled )
00148     {
00149                 
00150         return ( ::filledTrigonRGBA( & targetSurface.getSDLSurface(), 
00151             p1.getX(), p1.getY(),p2.getX(),p2.getY(), p3.getX(),p3.getY(),
00152             red, green, blue, alpha ) == 0 ) ;
00153             
00154     }
00155     else
00156     {
00157         
00158         if ( VideoModule::GetAntiAliasingState() )
00159         {
00160             return ( ::aatrigonRGBA( & targetSurface.getSDLSurface(),           
00161                 p1.getX(), p1.getY(),p2.getX(),p2.getY(), p3.getX(),p3.getY(),
00162                 red, green, blue, alpha ) == 0 ) ;
00163             
00164         }
00165         else
00166         {
00167             return ( ::trigonRGBA( & targetSurface.getSDLSurface(), 
00168                 p1.getX(), p1.getY(),p2.getX(),p2.getY(), p3.getX(),p3.getY(),
00169                 red, green, blue, alpha ) == 0 ) ;
00170         
00171         }
00172     
00173     }
00174 
00175 }
00176 
00177 
00178     
00179 bool TwoDimensional::drawTriangle( Surface & targetSurface, 
00180     const Point2D & p1, const Point2D & p2, const Point2D & p3, 
00181     Pixels::ColorDefinition colorDef, bool filled ) throw()
00182 {
00183 
00184     if ( filled )
00185     {
00186                 
00187         return ( ::filledTrigonColor( & targetSurface.getSDLSurface(), 
00188             p1.getX(), p1.getY(),p2.getX(),p2.getY(), p3.getX(),p3.getY(),
00189             Pixels::convertColorDefinitionToRawPixelColor( colorDef ) ) 
00190                 == 0 ) ;
00191             
00192     }
00193     else
00194     {
00195         
00196         if ( VideoModule::GetAntiAliasingState() )
00197         {
00198         
00199             return ( ::aatrigonColor( & targetSurface.getSDLSurface(), 
00200                 p1.getX(), p1.getY(),p2.getX(),p2.getY(), p3.getX(),p3.getY(),
00201                 Pixels::convertColorDefinitionToRawPixelColor( colorDef ) ) 
00202                     == 0 ) ;
00203             
00204         }
00205         else
00206         {
00207         
00208             return ( ::trigonColor( & targetSurface.getSDLSurface(),
00209                 p1.getX(), p1.getY(),p2.getX(),p2.getY(), p3.getX(),p3.getY(),
00210                 Pixels::convertColorDefinitionToRawPixelColor( colorDef ) ) 
00211                     == 0 ) ;
00212         
00213         }
00214     
00215     }
00216 
00217 }
00218 
00219 
00220 
00221 bool TwoDimensional::drawPolygon( Surface & targetSurface, 
00222     const listPoint2D & summits, Coordinate x, Coordinate y,
00223     Pixels::ColorElement red, Pixels::ColorElement green, 
00224     Pixels::ColorElement blue, Pixels::ColorElement alpha, bool filled ) throw()
00225 {
00226     
00227     
00228     // First, prepare data structure.
00229     
00230     
00231     /*
00232      * If a large number of summits waq to be used, dynamic allocation
00233      * (new/delete) would be better.
00234      *
00235      */
00236     Ceylan::System::Size vertexCount = summits.size() ;
00237      
00238     Coordinate * abscissaArray = new Coordinate[ vertexCount ] ;
00239     Coordinate * ordinateArray = new Coordinate[ vertexCount ] ;
00240     
00241     vertexCount = 0 ;
00242     
00243     for ( listPoint2D::const_iterator it = summits.begin(); 
00244         it != summits.end(); it++ )
00245     {
00246     
00247         abscissaArray[ vertexCount ] = (*it)->getX() + x ;
00248         ordinateArray[ vertexCount ] = (*it)->getY() + y ;
00249         
00250         vertexCount++ ;
00251         
00252     }
00253     
00254         
00255     // Then, draws it.
00256     
00257     if ( filled )
00258     {
00259         
00260         int res = ::filledPolygonRGBA( & targetSurface.getSDLSurface(), 
00261             abscissaArray, ordinateArray, vertexCount, 
00262             red, green, blue, alpha ) ;
00263         
00264         delete [] abscissaArray ;
00265         delete [] ordinateArray ;
00266                     
00267         return ( res == 0 ) ;
00268             
00269     }
00270     else
00271     {
00272         
00273         if ( VideoModule::GetAntiAliasingState() )
00274         {
00275         
00276             int res = ::aapolygonRGBA( & targetSurface.getSDLSurface(), 
00277                 abscissaArray, ordinateArray, vertexCount, 
00278                 red, green, blue, alpha ) ;
00279 
00280             delete [] abscissaArray ;
00281             delete [] ordinateArray ;
00282                 
00283             return ( res == 0 ) ;
00284             
00285         }
00286         else
00287         {
00288         
00289             int res = ::polygonRGBA( & targetSurface.getSDLSurface(),
00290                 abscissaArray, ordinateArray, vertexCount, 
00291                 red, green, blue, alpha ) ;
00292                 
00293             return ( res == 0 ) ;
00294         
00295         }
00296     
00297     }
00298 
00299 }   
00300 
00301     
00302     
00303 bool TwoDimensional::drawPolygon( Surface & targetSurface, 
00304     const listPoint2D & summits, Coordinate x, Coordinate y,
00305     Pixels::ColorDefinition colorDef, bool filled ) throw()
00306 {
00307 
00308 
00309     /*
00310      * If a large number of summits is to be used, dynamic allocation
00311      * (new/delete) would be better.
00312      *
00313      */
00314     Ceylan::System::Size vertexCount = summits.size() ;
00315      
00316     Coordinate * abscissaArray = new Coordinate[ vertexCount ] ;
00317     Coordinate * ordinateArray = new Coordinate[ vertexCount ] ;
00318     
00319     vertexCount = 0 ;
00320     
00321     for ( listPoint2D::const_iterator it = summits.begin(); 
00322         it != summits.end(); it++ )
00323     {
00324     
00325         abscissaArray[ vertexCount ] = (*it)->getX() + x ;
00326         ordinateArray[ vertexCount ] = (*it)->getY() + y ;
00327         
00328         vertexCount++ ;
00329         
00330     }
00331     
00332             
00333     // Then, draws it.
00334     
00335     if ( filled )
00336     {
00337         
00338         int res = ::filledPolygonColor( & targetSurface.getSDLSurface(), 
00339             abscissaArray, ordinateArray, vertexCount,
00340             Pixels::convertColorDefinitionToRawPixelColor( colorDef ) ) ;
00341         
00342         delete [] abscissaArray ;           
00343         delete [] ordinateArray ;   
00344                 
00345         return ( res == 0 ) ;
00346             
00347     }
00348     else
00349     {
00350         
00351         if ( VideoModule::GetAntiAliasingState() )
00352         {
00353         
00354             int res = ::aapolygonColor( & targetSurface.getSDLSurface(), 
00355                 abscissaArray, ordinateArray, vertexCount,
00356                 Pixels::convertColorDefinitionToRawPixelColor( colorDef ) ) ;
00357 
00358             delete [] abscissaArray ;           
00359             delete [] ordinateArray ;   
00360                     
00361             return ( res == 0 ) ;
00362             
00363         }
00364         else
00365         {
00366         
00367             int res = ::polygonColor( & targetSurface.getSDLSurface(),
00368                 abscissaArray, ordinateArray, vertexCount,
00369                 Pixels::convertColorDefinitionToRawPixelColor( colorDef ) ) ;
00370                  
00371             delete [] abscissaArray ;           
00372             delete [] ordinateArray ;   
00373             
00374             return ( res == 0 ) ;
00375         
00376         }
00377     
00378     }
00379     
00380 }
00381 
00382 
00383 
00384 
00385     
00386 using namespace OSDL::Video::TwoDimensional ;
00387 
00388 
00389 
00390 Polygon::Polygon( listPoint2D & summits, bool listOwner ) throw() :
00391     Locatable2D(),
00392     _summits( & summits ),
00393     _listOwner( listOwner )
00394 {
00395 
00396 }
00397 
00398 
00399 
00400 Polygon::~Polygon() throw()
00401 {
00402         
00403         
00404     if ( _summits != 0 )
00405     {
00406     
00407         if ( _listOwner )
00408         {
00409          
00410             for ( listPoint2D::iterator it = _summits->begin(); 
00411                 it != _summits->end(); it++ )
00412             {
00413                 delete *it ;
00414             }
00415 
00416             /*
00417              * Even the list should be deallocated, <b>only</b> if list 
00418              * owner  :
00419              *
00420              */
00421             delete _summits ;
00422             
00423         }
00424                 
00425         
00426     }   
00427     
00428 }
00429 
00430 
00431 
00432 bool Polygon::draw( Surface & targetSurface, 
00433     Pixels::ColorDefinition colorDef, bool filled ) const throw()
00434 {
00435 
00436      /*
00437       * Could be added to the API :
00438       *
00439       * @param transform tells whether the polygon should 
00440       * be transformed against referential matrix (if true) 
00441       * or drawn as is (if false). 
00442       * In all cases the internal summit list will not be
00443       * modified.
00444       *
00445       */
00446       
00447     listPoint2D * vertices = & Duplicate( *_summits ) ;
00448     Apply( getLocalMatrix(), * vertices ) ;
00449     
00450     
00451     /*
00452      * [0;0] origin specified since center must have been taken into 
00453      * account within the homogeneous matrix :
00454      *
00455      */
00456     return drawPolygon( targetSurface, * vertices, 0, 0, colorDef, filled ) ;
00457     
00458 }
00459 
00460 
00461 
00462 listPoint2D & Polygon::getPoints() const throw()
00463 {
00464 
00465     return * _summits ;
00466     
00467 }
00468 
00469 
00470 
00471 void Polygon::setPoints( listPoint2D & newList ) throw()
00472 {
00473 
00474     if ( _listOwner )
00475     {
00476     
00477         if ( _summits != 0 )
00478             Delete( * _summits ) ;
00479             
00480     }
00481 
00482     _summits = & newList ;  
00483         
00484 }
00485 
00486 
00487 
00488 bool Polygon::isListOwner() const throw()
00489 {
00490 
00491     return _listOwner ;
00492     
00493 }
00494 
00495 
00496     
00497 const string Polygon::toString( Ceylan::VerbosityLevels level ) const throw()
00498 {
00499 
00500     string res ;
00501 
00502     if ( _summits && ! _summits->empty() )
00503     {
00504 
00505         res = "Polygon defined by " + Ceylan::toString( _summits->size() ) 
00506             + " summits" ;
00507 
00508         if ( level == Ceylan::low )
00509             return res ;
00510         
00511         res += ". Its summits are : " ;
00512             
00513         list<string> summitsCoordinates ;
00514         
00515         Ceylan::Uint32 count = 0 ;
00516         
00517         for ( listPoint2D::const_iterator it = _summits->begin(); 
00518             it != _summits->end(); it++ )
00519         {
00520         
00521             count++ ;
00522             summitsCoordinates.push_back( "summit #" 
00523                 + Ceylan::toString( count ) + " : " 
00524                 + (*it)->toString( level ) ) ;              
00525         }
00526         
00527         res += Ceylan::formatStringList( summitsCoordinates ) ; 
00528         
00529         return res + "This polygon has for referential : " 
00530             + Locatable2D::toString( level ) ;
00531             
00532     }
00533     
00534     return "Void polygon (no summit registered)" ;
00535 
00536 }
00537 
00538 
00539 
00540 
00541 // Static section.
00542 
00543 
00544 Polygon & Polygon::CreateFlakeBranch( Length length, Length thickness,
00545         AngleInDegrees childAngle, Ratio branchingHeightRatio, Ratio scale ) 
00546     throw()
00547 {
00548 
00549     
00550     /*
00551      * Points will be created, put in a list that will have to be 
00552      * deallocated explicitly by the caller.
00553      *
00554      */
00555     
00556     AngleInRadians realAngle = Ceylan::Maths::DegreeToRadian( childAngle ) ;
00557     
00558     // Order of simpliest computation :
00559         
00560     Point2D * alpha = & Point2D::CreateFrom( 0, length ) ;
00561     Point2D * beta  = & Point2D::CreateFrom( thickness / 2, length ) ;
00562 
00563     Point2D * nu = & Point2D::CreateFrom( thickness / 2, 0 ) ;
00564     Point2D * mu = & Point2D::CreateFrom( thickness / 2, 
00565         length * branchingHeightRatio ) ;
00566         
00567     Point2D * omicron = & Point2D::CreateFrom( 0, 0 ) ;
00568         
00569     // gamma computed from the bottom :
00570     Point2D * gamma = & Point2D::CreateFrom( thickness / 2, 
00571         length * branchingHeightRatio + thickness * scale / Sin( realAngle ) ) ;
00572 
00573     // epsilon calculated from mu :
00574     Point2D * epsilon = & Point2D::CreateFrom( 
00575         thickness / 2 + length * scale * Sin( realAngle ),
00576         length * branchingHeightRatio  + scale * length * Cos( realAngle ) ) ;
00577         
00578     // delta calculated from epsilon :
00579     Point2D * delta = & Point2D::CreateFrom( 
00580         epsilon->getX() - thickness * scale * Cos( realAngle ), 
00581         epsilon->getY() + thickness * scale * Sin( realAngle )  ) ;
00582         
00583     listPoint2D * summits = new listPoint2D ;
00584         
00585     summits->push_back( alpha ) ;
00586     summits->push_back( beta ) ;
00587     summits->push_back( gamma ) ;
00588     summits->push_back( delta ) ;
00589     summits->push_back( epsilon ) ;
00590     summits->push_back( mu ) ;
00591     summits->push_back( nu ) ;
00592     summits->push_back( omicron ) ;
00593     
00594     
00595      /*
00596       * Useful for debugging purpose on a test application :
00597       *
00598       
00599      screen.drawCross( alpha,   Red ) ;
00600      screen.drawCross( beta,    Blue ) ;
00601      screen.drawCross( gamma,   Green ) ;
00602      screen.drawCross( delta,   White ) ;
00603      screen.drawCross( epsilon, Grey ) ;
00604      screen.drawCross( mu,      Violet ) ;
00605      screen.drawCross( nu,      Brown ) ;
00606      screen.drawCross( omicron, Cyan ) ;
00607      
00608       *
00609       */
00610         
00611         
00612     // Copy constructors :
00613         
00614     Point2D * alpha1 = new Point2D( * alpha ) ;
00615     alpha1->flipX() ;
00616         
00617     Point2D * beta1 = new Point2D( * beta ) ;
00618     beta1->flipX() ;
00619         
00620     Point2D * gamma1 = new Point2D( * gamma ) ;
00621     gamma1->flipX() ;
00622         
00623     Point2D * delta1 = new Point2D( * delta ) ;
00624     delta1->flipX() ;
00625         
00626     Point2D * epsilon1 = new Point2D( * epsilon ) ;
00627     epsilon1->flipX() ;
00628         
00629     Point2D * mu1 = new Point2D( * mu ) ;
00630     mu1->flipX() ;
00631         
00632     Point2D * nu1 = new Point2D( * nu ) ;
00633     nu1->flipX() ;
00634     
00635     /*
00636      * Mere copy to avoid double referenced points, since the polygon may 
00637      * own its points.
00638      *
00639      */
00640     Point2D * omicron1 = new Point2D( * omicron ) ;
00641 
00642     summits->push_back( alpha1 ) ;
00643     summits->push_back( beta1 ) ;
00644     summits->push_back( gamma1 ) ;
00645     summits->push_back( delta1 ) ;
00646     summits->push_back( epsilon1 ) ;
00647     summits->push_back( mu1 ) ;
00648     summits->push_back( nu1 ) ;
00649     summits->push_back( omicron1 ) ;
00650     
00651     // Neither the summit list nor its points are owned by this polygon :
00652     return * new Polygon( * summits, /* pointOwner */ false ) ;
00653 
00654 }
00655 
00656 
00657 
00658 listPoint2D & Polygon::Duplicate( const listPoint2D & source ) throw()
00659 {
00660 
00661     listPoint2D * newList = new listPoint2D ;
00662     
00663     for ( listPoint2D::const_iterator it = source.begin(); 
00664         it != source.end(); it++ )
00665     {
00666     
00667         newList->push_back( new Point2D( * (*it) ) ) ;
00668         
00669     }
00670     
00671     return * newList ;
00672     
00673 }
00674 
00675 
00676 
00677 void Polygon::Delete( listPoint2D & listToBeDeleted ) throw()
00678 {
00679 
00680     for ( listPoint2D::iterator it = listToBeDeleted.begin();
00681          it != listToBeDeleted.end(); it++ )
00682     {
00683     
00684         delete (*it) ;
00685         
00686     }
00687     
00688     delete & listToBeDeleted ;
00689 
00690 }
00691 
00692 
00693 
00694 listPoint2D & Polygon::Append( listPoint2D & toBeAugmented,
00695      const listPoint2D & toAppend ) throw()
00696 {
00697 
00698     for ( listPoint2D::const_iterator it = toAppend.begin(); 
00699         it != toAppend.end(); it++ )
00700     {
00701     
00702         toBeAugmented.push_back( (*it) ) ;
00703         
00704     }
00705     
00706     // Non-necessary but useful for chaining :
00707     
00708     return toBeAugmented ;
00709     
00710 }
00711 
00712 
00713 
00714 listPoint2D & Polygon::Apply( 
00715     const Linear::HomogeneousMatrix3 & transformation, 
00716     listPoint2D & sourceList ) throw()
00717 {
00718 
00719     for ( listPoint2D::iterator it = sourceList.begin(); 
00720         it != sourceList.end(); it++ )
00721     {
00722     
00723         /*
00724          * Linear operations performed on floating-point Vector2, 
00725          * not on integer Point2D :
00726          *
00727          */
00728         Linear::Vector2 temp( static_cast<Real>( (*it)->getX()), 
00729             static_cast<Real>( (*it)->getY()) ) ;
00730         (*it)->setFrom( transformation * temp ) ;
00731         
00732     }
00733 
00734     // Non-necessary but useful for chaining :
00735     
00736     return sourceList ;
00737 
00738 }
00739 
00740 
00741 
00742 
00743 // Polygon set.
00744                         
00745 
00746 PolygonSet::PolygonSet( bool listOwner ) throw() :
00747     Locatable2D(),
00748     _polygonList( 0 ),
00749     _listOwner( listOwner )
00750 {
00751 
00752 }
00753 
00754 
00755 
00756 PolygonSet::PolygonSet( std::list<listPoint2D *> & polygonList,
00757         bool listOwner ) throw():
00758     Locatable2D(),
00759     _polygonList( & polygonList ),
00760     _listOwner( listOwner )
00761 {
00762 
00763 }
00764 
00765 
00766 
00767 PolygonSet::~PolygonSet() throw()
00768 {
00769 
00770     if ( _polygonList != 0 )
00771     {
00772     
00773         if ( _listOwner )
00774         {
00775          
00776             // Deletes both lists and point in lists :
00777             for ( list<listPoint2D *>::iterator it = _polygonList->begin(); 
00778                 it != _polygonList->end(); it++ )
00779             {
00780             
00781                 Polygon::Delete( * (*it) ) ;
00782                 
00783             }
00784 
00785             delete _polygonList ;
00786     
00787         }
00788                 
00789     }   
00790     
00791 }
00792 
00793 
00794 
00795 void PolygonSet::addPointsOf( Polygon & newPolygon ) throw()
00796 {
00797 
00798     if ( newPolygon.isListOwner() )
00799         Ceylan::emergencyShutdown( "PolygonSet::addPointsOf : "
00800             "added polygon should not own its points." ) ;
00801     
00802     addPointList( newPolygon.getPoints() ) ;    
00803     
00804 }
00805 
00806 
00807 
00808 void PolygonSet::addPointList( listPoint2D & listToAdd ) throw()
00809 {
00810 
00811     if ( _polygonList == 0 )
00812         _polygonList = new list<listPoint2D *> ;
00813         
00814     _polygonList->push_back( & listToAdd ) ;
00815     
00816 }
00817 
00818 
00819 
00820 bool PolygonSet::draw( Surface & targetSurface, Coordinate x, Coordinate y,
00821     Pixels::ColorDefinition colorDef, bool filled ) const throw()
00822 {
00823 
00824     bool result = true ;
00825     
00826     for ( list<listPoint2D *>::const_iterator it = _polygonList->begin(); 
00827         it != _polygonList->end(); it++ )
00828     {
00829     
00830         /*
00831          * Avoid result = result 
00832          *    && (*it)->draw( targetSurface, x, y, colorDef,* (*it) ) ;
00833          * since if a drawing had to fail, next ones would not be attempted
00834          * (shortcut boolean evaluation).
00835          *
00836          */
00837          
00838         if ( drawPolygon( targetSurface, * (*it), x, y, colorDef, filled ) 
00839                 == false )
00840             result = false ; 
00841             
00842     }
00843     
00844     return result ;
00845     
00846 }
00847 
00848 
00849     
00850 const string PolygonSet::toString( Ceylan::VerbosityLevels level ) 
00851     const throw()
00852 {
00853 
00854     string res ;
00855 
00856     if ( _polygonList && ( ! _polygonList->empty() ) )
00857     {
00858 
00859         res = "Polygon set made of " 
00860             + Ceylan::toString( _polygonList->size() ) 
00861             + " separate polygons" ;
00862 
00863         if ( level == Ceylan::low )
00864             return res ;
00865         
00866         res += ". Its polygons are : " ;
00867             
00868         list<string> summitsCoordinates ;
00869         
00870         Ceylan::Uint32 polygonCount = 0 ;
00871         Ceylan::Uint32 summitCount ;
00872                 
00873         for ( list<listPoint2D *>::const_iterator itPolygonList 
00874                 = _polygonList->begin(); 
00875             itPolygonList != _polygonList->end(); itPolygonList++ )
00876         {   
00877             
00878             polygonCount++ ;
00879             
00880             res += "For polygon #" 
00881                 + Ceylan::toString( polygonCount ) + " : " ;
00882              
00883             summitCount = 0 ;
00884             summitsCoordinates.clear() ;
00885             
00886             for ( listPoint2D::iterator it = (*itPolygonList)->begin(); 
00887                 it != (*itPolygonList)->end(); it++ )
00888             {
00889             
00890                 summitCount++ ;
00891                 summitsCoordinates.push_back( "summit #" 
00892                     + Ceylan::toString( summitCount ) + " : " 
00893                     + (*it)->toString( level ) ) ;      
00894                             
00895             }
00896         
00897             res += Ceylan::formatStringList( summitsCoordinates ) ; 
00898         
00899         }   
00900         
00901         return res + "This polygon set has for referential : " 
00902             + Locatable2D::toString( level ) ;
00903     }
00904     
00905     return "Void set of polygons (no polygon registered)" ;
00906 
00907 }
00908 
00909 
00910 
00911 PolygonSet & PolygonSet::CreateFlake( 
00912     Ceylan::Uint8 branchCount, Length length, Length thickness, 
00913     Ceylan::Maths::AngleInDegrees childAngle, Ratio branchingHeightRatio, 
00914     Ratio scale ) throw()
00915 {
00916 
00917     if ( branchCount == 0 )
00918         Ceylan::emergencyShutdown( "PolygonSet::CreateFlake : "
00919             "snow flakes should have at least one branch." ) ;
00920             
00921     // Flake branches do not own their points.      
00922     Polygon & modelBranch = Polygon::CreateFlakeBranch( length, 
00923         thickness, childAngle, branchingHeightRatio, scale ) ;
00924     
00925     /*
00926      * List owner ensures all points and lists will be deleted when 
00927      * appropriate :
00928      *
00929      */
00930     PolygonSet & result = * new PolygonSet( /* listOwner */ true ) ;    
00931         
00932 
00933     /*
00934      * Creates the relevant transformation for branches 
00935      * (they are evenly placed) :
00936      *
00937      */
00938     Linear::HomogeneousMatrix3 transformation( 360 / branchCount,
00939         Linear::Vector2( 0, 0 ) ) ;
00940 
00941     // Creates first branch element :
00942     listPoint2D * lastlyCreatedBranchPoints = & modelBranch.getPoints() ;
00943     result.addPointList( * lastlyCreatedBranchPoints ) ;
00944     
00945     listPoint2D * newlyCreatedBranchPoints ;
00946     
00947     /*
00948      * Rotates in turn each of the other branches until a complete circle 
00949      * is made :    
00950      *
00951      */
00952     for ( Ceylan::Uint8 count = 1; count < branchCount; count++ )
00953     {
00954     
00955         newlyCreatedBranchPoints = & Polygon::Apply( transformation, 
00956             Polygon::Duplicate( * lastlyCreatedBranchPoints ) ) ;
00957             
00958         result.addPointList( * newlyCreatedBranchPoints ) ;
00959         lastlyCreatedBranchPoints = newlyCreatedBranchPoints ;
00960     
00961     }
00962     
00963     delete & modelBranch ;
00964     
00965     /*
00966      * All lists and points (either coming from 'modelBranch' or duplicated) 
00967      * are registered in the polygon set, that will deallocate each of 
00968      * them upon its own deallocation.
00969      *
00970      */
00971     return result ;
00972     
00973 }
00974 

Generated on Fri Mar 30 14:46:59 2007 for OSDL by  doxygen 1.5.1