00001 #include <assert.h> 00002 #include "CollisionDetectors\CD_BasicStyle.h" 00003 #include "SM_Trisection.h" 00004 00005 //============================================================================= 00006 // Constructor 00007 // 00008 // Description: constructor 00009 //============================================================================= 00010 SM_Trisection::SM_Trisection() 00011 : 00012 SmootherBase() 00013 { 00014 } 00015 00016 //============================================================================= 00017 // Destructor 00018 // 00019 // Description: destructor 00020 //============================================================================= 00021 SM_Trisection::~SM_Trisection() 00022 { 00023 } 00024 00025 //============================================================================= 00026 // PathValid 00027 // 00028 // Description: tests the shortcut from start% to end% of the path 00029 //============================================================================= 00030 bool SM_Trisection::PathValid( const double start, const double end ) const 00031 { 00032 Configuration cs = m_PathToSmooth->GetConfiguration( start ); 00033 Configuration cg = m_PathToSmooth->GetConfiguration( end ); 00034 bool pathInterfering = m_CollisionDetector->IsInterferingLinear( cs, cg ); 00035 00036 return !pathInterfering; 00037 } 00038 00039 //============================================================================= 00040 // Smooth 00041 // 00042 // Description: performs the path smoothing operation 00043 //============================================================================= 00044 void SM_Trisection::Smooth() 00045 { 00046 if( !m_Percentages.empty() ) 00047 { 00048 m_Percentages.clear(); 00049 } 00050 m_Percentages.insert( 0.0 ); 00051 m_Percentages.insert( 1.0 ); 00052 00053 Validate( 0.0, 1.0 ); 00054 00055 //compose the output path 00056 this->m_SmoothedPath.Clear(); 00057 std::set< double >::iterator it; 00058 for( it = m_Percentages.begin(); it != m_Percentages.end(); it++ ) 00059 { 00060 double percentage = *it; 00061 Configuration c = this->m_PathToSmooth->GetConfiguration( percentage ); 00062 m_SmoothedPath.AppendPoint( c ); 00063 } 00064 } 00065 00066 //============================================================================= 00067 // Validate 00068 // 00069 // Description: makes sure this section of the path is valid 00070 //============================================================================= 00071 void SM_Trisection::Validate( const double start, const double end ) 00072 { 00073 bool pathValid = PathValid( start, end ); 00074 if( pathValid ) 00075 { 00076 return; 00077 } 00078 00079 //add the midpoint of this path to the set 00080 double m1 = 0.67 * start + 0.33 * end; 00081 double m2 = 0.33 * start + 0.67 * end; 00082 00083 //make sure the midpoint is a valid configuration 00084 Configuration c1 = this->m_PathToSmooth->GetConfiguration( m1 ); 00085 Configuration c2 = this->m_PathToSmooth->GetConfiguration( m2 ); 00086 00087 #ifndef NDEBUG 00088 bool interferingConfig = this->m_CollisionDetector->IsInterfering( c1 ); 00089 interferingConfig &= this->m_CollisionDetector->IsInterfering( c2 ); 00090 assert( interferingConfig == false ); 00091 if( interferingConfig != false ) 00092 { 00093 return; 00094 } 00095 #endif 00096 00097 this->m_Percentages.insert( m1 ); 00098 this->m_Percentages.insert( m2 ); 00099 Validate( start, m1 ); //IMPROVE: revursion is bad 00100 Validate( m1, m2 ); 00101 Validate( m2, end ); 00102 }