basic/geometry/MPK_Segment.cpp

Go to the documentation of this file.
00001 #include <math.h>
00002 #include <math/math2.h>
00003 
00004 #include "geometry\MPK_Sphere.h"
00005 #include "geometry\MPK_Segment.h"
00006 
00007 namespace MPK
00008 {
00009 
00010 
00011 Segment::Segment (FrameManager* frameManager)
00012   //## begin Segment::Segment%926539291.hasinit preserve=no
00013   //## end Segment::Segment%926539291.hasinit
00014   //## begin Segment::Segment%926539291.initialization preserve=yes
00015   :ObjectBase( frameManager )
00016   //## end Segment::Segment%926539291.initialization
00017 {
00018   //## begin Segment::Segment%926539291.body preserve=yes
00019   //## end Segment::Segment%926539291.body
00020 }
00021 
00022 Segment::Segment (const Segment& right)
00023   //## begin Segment::Segment%926539292.hasinit preserve=no
00024   //## end Segment::Segment%926539292.hasinit
00025   //## begin Segment::Segment%926539292.initialization preserve=yes
00026   :ObjectBase( right ),
00027         startPos( right.startPos ),
00028         endPos( right.endPos )
00029 
00030   //## end Segment::Segment%926539292.initialization
00031 {
00032   //## begin Segment::Segment%926539292.body preserve=yes
00033   //## end Segment::Segment%926539292.body
00034 }
00035 
00036 
00037 Segment::~Segment()
00038 {
00039   //## begin Segment::~Segment%.body preserve=yes
00040   //## end Segment::~Segment%.body
00041 }
00042 
00043 
00044 
00045 //## Other Operations (implementation)
00046 Entity* Segment::Clone () const
00047 {
00048   //## begin Segment::Clone%926539287.body preserve=yes
00049         ObjectBase* returnme = new Segment( *this ) ;
00050         return returnme ;
00051   //## end Segment::Clone%926539287.body
00052 }
00053 
00054 bool Segment::IsInterfering (const Entity* entity) const
00055 {
00056   //## begin Segment::IsInterfering%926539288.body preserve=yes
00057         assert( CanCheckInterference( entity ) ) ;      //IMPROVE: this should be error handled
00058 
00059         //determine the type of the entity
00060         if( dynamic_cast< const Segment* >( entity ) != NULL )
00061         {
00062                 return( IsInterfering( dynamic_cast< const Segment* >( entity ) ) ) ;
00063         }
00064         else if( dynamic_cast< const MPK_Sphere* >( entity ) != NULL )
00065         {
00066                 return( IsInterfering( dynamic_cast< const MPK_Sphere* >( entity ) ) ) ; ;
00067         }
00068         else
00069         {
00070                 assert( false ) ;       //should never get to here due to the assert( CanCheckInterference )
00071                 //IMPROVE: this assertion needs to be here
00072         }
00073         return false ;
00074 
00075   //## end Segment::IsInterfering%926539288.body
00076 }
00077 
00078 bool Segment::CanCheckInterference (const Entity* entity) const
00079 {
00080   //## begin Segment::CanCheckInterference%926539289.body preserve=yes
00081         
00082         if( dynamic_cast< const Segment* >( entity ) != NULL )
00083         {
00084                 return true ;
00085         }
00086         if( dynamic_cast< const MPK_Sphere* >( entity ) != NULL )
00087         {
00088                 return true ;
00089         }
00090         return false ;
00091 
00092   //## end Segment::CanCheckInterference%926539289.body
00093 }
00094 
00095 bool Segment::IsInterfering (const Segment* entity) const
00096 {
00097   //## begin Segment::IsInterfering%926539290.body preserve=yes
00098         Matrix4x4 relative = frameManager->GetTransformRelative( baseFrame, entity->baseFrame );
00099         Vector4 p1 = startPos ;
00100         Vector4 v1 = endPos - startPos ;
00101         double& v1x = v1[ 0 ] ;
00102         double& v1y = v1[ 1 ] ;
00103         double& v1z = v1[ 2 ] ;
00104 
00105         Vector4 q1 = entity->startPos ;
00106         Vector4 q2 = entity->endPos ;
00107         q1 = relative * q1 ;
00108         q2 = relative * q2 ;
00109 
00110         Vector4 p2 = q1 ;
00111         Vector4 v2 = q2 - q1 ;
00112         double& v2x = v2[ 0 ] ;
00113         double& v2y = v2[ 1 ] ;
00114         double& v2z = v2[ 2 ] ;
00115 
00116         Vector4 p = p2 - p1 ;
00117         Vector4 d = v1.Cross( v2 ) ;
00118 
00119         double& px = p[ 0 ] ;
00120         double& py = p[ 1 ] ;
00121         double& pz = p[ 2 ] ;
00122         double& dx = d[ 0 ] ;
00123         double& dy = d[ 1 ] ;
00124         double& dz = d[ 2 ] ;
00125 
00126         double magSquared = d.MagSquared() ;
00127         if( magSquared == 0 ) 
00128         {
00129                 //lines are parallel
00130                 
00131                 //check for colinearity
00132                 Vector4 endPoints = startPos - entity->startPos ;
00133                 if( endPoints.Projection( v1 ).MagSquared() != v1.MagSquared() )
00134                 {
00135                         //not colinear
00136                         return false ;
00137                 }
00138                 //need to project all the points onto a line
00139                 double a1 = startPos.ProjectionMag( v1 ) ;
00140                 double a2 = endPos.ProjectionMag( v1 ) ;
00141                 double b1 = entity->startPos.ProjectionMag( v1 ) ;
00142                 double b2 = entity->endPos.ProjectionMag( v1 ) ;
00143 
00144                 //if either b1 or b2 is between a1 and a2 they overlap
00145                 if( Between( a1, b1, b2 ) )     { return true ; }
00146                 if( Between( a2, b1, b2 ) )     { return true ; }
00147 
00148                 //if either a1 or a2 is between b1 and b2 they overlap
00149                 if( Between( b1, a1, a2 ) )     { return true ; }
00150                 if( Between( b2, a1, a2 ) )     { return true ; }
00151                 return false ;
00152         }
00153 
00154         //lines are not parallel - they would intersect at a point
00155         double t =              ( px * v2y * dz ) + ( v2x * dy * pz ) + ( dx * py * v2z )
00156                                 -       ( dx * v2y * pz ) - ( dy * v2z * px ) - ( dz * v2x * py );
00157         t /= magSquared ;
00158         if( t < 0 ) 
00159         {
00160                 return false ;
00161         }
00162         if( t > 1 )
00163         {
00164                 return false ;
00165         }
00166 
00167         double s =              ( px * v1y * dz ) + ( v1x * dy * pz ) + ( dx * py * v1z )
00168                                 -       ( dx * v1y * pz ) - ( dy * v1z * px ) - ( dz * v1x * py );
00169         s /= magSquared ;
00170         if( s < 0 )
00171         {
00172                 return false ;
00173         }
00174         if( s > 1 )
00175         {
00176                 return false ;
00177         }
00178 
00179         assert( ( p1 + v1 * t ) == ( p2 + v2 * s ) ) ;
00180         return true ;
00181   //## end Segment::IsInterfering%926539290.body
00182 }
00183 
00184 void Segment::SetStart (const Vector4& start)
00185 {
00186   //## begin Segment::SetStart%926539296.body preserve=yes
00187         startPos = start ;
00188   //## end Segment::SetStart%926539296.body
00189 }
00190 
00191 void Segment::SetEnd (const Vector4& end)
00192 {
00193   //## begin Segment::SetEnd%926539297.body preserve=yes
00194         endPos = end ;
00195   //## end Segment::SetEnd%926539297.body
00196 }
00197 
00198 bool Segment::IsInterfering (const MPK_Sphere* entity) const
00199 {
00200   //## begin Segment::IsInterfering%926709625.body preserve=yes
00201         //transform the sphere
00202         Matrix4x4 r1 = frameManager->GetTransformRelative( baseFrame, 0 );
00203         Matrix4x4 r2 = frameManager->GetTransformRelative( entity->BaseFrame(), 0 );
00204         Matrix4x4 relative = r1.Inverse() * r2 ;
00205 
00206         Vector4 center = entity->Position() ;
00207         center = relative * center ;
00208         Vector4 g = startPos - center ;         //this is the stert point relative to the center of the sphere 
00209         Vector4 lv = endPos - startPos ;
00210         double a = lv.Dot( lv ) ;
00211         double b = 2 * ( lv.Dot( g ) ) ;
00212         double c = ( g.Dot( g ) - pow( entity->Radius(), 2 ) ) ;
00213         double d = pow( b, 2 ) - 4 * a * c ;
00214         if( d < 0 )
00215         {
00216                 return false ;
00217         }
00218 
00219         assert( ( 2 * a ) != 0 ) ;
00220         double p1 = ( -b + sqrt( d ) ) / ( 2 * a ) ;
00221         double p2 = ( -b - sqrt( d ) ) / ( 2 * a ) ;
00222         if( Between( p1, 0.0, 1.0 ) )
00223         {
00224                 return true ;
00225         }
00226         if( Between( p2, 0.0, 1.0 ) )
00227         {
00228                 return true ;
00229         }
00230         if( Between( 0.0, p1, p2 ) )
00231         {
00232                 return true ;
00233         }
00234         assert( !Between( 1.0, p1, p2 ) ) ;     //Shouldn't have to check this
00235         return false ;
00236   //## end Segment::IsInterfering%926709625.body
00237 }
00238 
00239 void Segment::Deserialize (istream& is)
00240 {
00241   //## begin Segment::Deserialize%934220968.body preserve=yes
00242         assert( false );
00243   //## end Segment::Deserialize%934220968.body
00244 }
00245 
00246 void Segment::Serialize (ostream& os) const
00247 {
00248   //## begin Segment::Serialize%934220969.body preserve=yes
00249         assert( false );
00250   //## end Segment::Serialize%934220969.body
00251 }
00252 
00253 
00254 bool Segment::Verify() const
00255 {
00256         return true;
00257 }
00258 // Additional Declarations
00259   //## begin Segment%3739DECC01C7.declarations preserve=yes
00260   //## end Segment%3739DECC01C7.declarations
00261 
00262 //## begin module%3739DECC01C7.epilog preserve=yes
00263 //## end module%3739DECC01C7.epilog
00264 }

Generated on Sat Apr 1 21:30:33 2006 for Motion Planning Kernel by  doxygen 1.4.6-NO