OSDLCircleBoundingBox.cc

Go to the documentation of this file.
00001 #include "OSDLCircleBoundingBox.h"
00002 
00003 
00004 using namespace Ceylan::Maths::Linear ;
00005 
00006 using namespace OSDL::Engine ;
00007 
00008 using std::string ;
00009 
00010 
00011 #ifdef OSDL_USES_CONFIG_H
00012 #include <OSDLConfig.h>               // for OSDL_DEBUG_BOUNDING_BOX and al
00013 #endif // OSDL_USES_CONFIG_H
00014 
00015 #if OSDL_DEBUG_BOUNDING_BOX
00016 
00017 using namespace Ceylan::Log ;
00018 #define OSDL_BOX_LOG(message) LogPlug::debug( message ) ;
00019 
00020 #else // OSDL_DEBUG_BOUNDING_BOX
00021 
00022 #define OSDL_BOX_LOG(message)
00023 
00024 #endif // OSDL_DEBUG_BOUNDING_BOX
00025 
00026 
00027 using Ceylan::Maths::Real ;
00028 
00029 
00030 CircleBoundingBox::CircleBoundingBox( Locatable2D & father, 
00031     const Bipoint & center, Real radius )
00032         throw() :
00033     BoundingBox2D( father, center ),
00034     _radius( radius )
00035 {
00036 
00037 }
00038 
00039 
00040 CircleBoundingBox::~CircleBoundingBox() throw()
00041 {
00042 
00043 }
00044 
00045 
00046 Real CircleBoundingBox::getRadius() const throw()
00047 {
00048     return _radius ;
00049 }
00050 
00051 
00052 void CircleBoundingBox::setRadius( Real newRadius ) throw()
00053 {
00054     _radius = newRadius ;
00055 }
00056 
00057 
00058 const string CircleBoundingBox::toString( Ceylan::VerbosityLevels level ) 
00059     const throw()
00060 {   
00061 
00062     string res = "Circular 2D bounding box, whose center is " 
00063         + getCenter().toString( level )
00064         + " and whose radius is " + Ceylan::toString( _radius ) ;
00065     
00066     if ( level == Ceylan::low )
00067         return res ;
00068     
00069     return res + " From a referential point of view, this is a(n) " 
00070         + Locatable2D::toString( level ) ;  
00071             
00072 }
00073 
00074 
00075 IntersectionResult CircleBoundingBox::doesIntersectWith( BoundingBox & other ) 
00076     throw( BoundingBoxException )
00077 {
00078     
00079     BoundingBox2D & other2D = BoundingBox2D::CheckIs2D( other ) ;
00080     
00081     // Here we know we have a 2D box.
00082     
00083     /*
00084      * For the moment, in the 2D boxes family, only the circle is supported :
00085      * (for example, a 2D square box would be rejected).
00086      *
00087      */
00088     CircleBoundingBox * circleBox = dynamic_cast<CircleBoundingBox *>( 
00089         & other2D ) ;
00090     
00091     if ( circleBox == 0 )
00092         throw BoundingBoxException( "CircleBoundingBox::doesIntersectWith : "
00093             "intersection with specified 2D box ("
00094             +other.toString() + ") is not implemented for the moment." ) ;
00095     
00096     return compareWith( * circleBox ) ;
00097 
00098 }
00099 
00100 
00101 IntersectionResult CircleBoundingBox::compareWith( CircleBoundingBox & other )
00102     throw() 
00103 {
00104     
00105     /*
00106      * The first concern is to have both boxes expressed in the same
00107      * referential.
00108      * One optimization could be to stop at the first common ancester in 
00109      * the referential tree, instead of evaluating everything in the root
00110      * referential.
00111      * However, thanks to referential caching, the overhead should be small.
00112      *
00113      */
00114             
00115     /*
00116      * Two circles, one case out of five to discriminate :
00117      * @see IntersectionResult
00118      * Let's first retrieve centers and radii.
00119      *
00120      */
00121      
00122     OSDL_BOX_LOG( "Comparing " + toString() + " to " + other.toString() ) ;
00123     
00124     Matrix3 & firstMatrix = * dynamic_cast<Matrix3*>( 
00125         & getGlobalReferential() ) ;    
00126         
00127     Bipoint firstCenter( firstMatrix.getElementAt( 2, 0 ),
00128         firstMatrix.getElementAt( 2, 1 ) ) ;    
00129         
00130     OSDL_BOX_LOG( "First matrix : " + firstMatrix.toString() ) ;
00131     
00132     Matrix3 & secondMatrix = * dynamic_cast<Matrix3*>( 
00133         & other.getGlobalReferential() ) ;
00134         
00135     Bipoint secondCenter( secondMatrix.getElementAt( 2, 0 ),
00136         secondMatrix.getElementAt( 2, 1 ) ) ;
00137         
00138     OSDL_BOX_LOG( "Second matrix : " + secondMatrix.toString() ) ;
00139     
00140     /*
00141      * Do not try to avoid square roots by comparing square distances, 
00142      * since (a+b)² >= a²+b²:
00143      *
00144      */
00145     
00146     Real centerDistance = Bipoint::Distance( firstCenter, secondCenter ) ;
00147     
00148     OSDL_BOX_LOG( "Distance between centers : " 
00149         + Ceylan::toString( centerDistance ) ) ;
00150            
00151     if ( centerDistance >= _radius + other.getRadius() )
00152         return isSeparate ;
00153     
00154     // We know they intersect.
00155     
00156     /*
00157      * Draw circles internally tangent to understand.
00158      *
00159      */ 
00160     if ( _radius > centerDistance + other.getRadius() )
00161         return contains ;
00162         
00163     if ( other.getRadius() > centerDistance + _radius )
00164         return isContained ;
00165     
00166     // Floating point values are almost never equal :
00167     if ( Ceylan::Maths::AreRelativelyEqual( centerDistance, 0.0f )
00168         && Ceylan::Maths::AreRelativelyEqual( _radius, other.getRadius() ) )    
00169         return isEqual ;
00170     
00171     // Last possible case :
00172     return intersects ;
00173     
00174 }
00175 
00176     
00177 CircleBoundingBox & CircleBoundingBox::CheckIsCircle( BoundingBox & box ) 
00178     throw( BoundingBoxException )
00179 {
00180 
00181     // Avoid calling CheckIs2D, it would be inefficient.
00182     
00183     CircleBoundingBox * circleBox = dynamic_cast<CircleBoundingBox *>( & box ) ;
00184     
00185     if ( circleBox == 0 )
00186         throw BoundingBoxException( 
00187             "CircleBoundingBox::CheckIsCircle : specified box ("
00188             + box.toString() + ") was not a circular (two dimensional) box." ) ;
00189     
00190     return * circleBox ;
00191         
00192 }
00193     

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