double PST_Edge::closest_on_edge( const CubitVector& p ) { double t = closest_on_line( p ); if( t < 0.0 ) t = 0.0; else if( t > 1.0 ) t = 1.0; return t; }
static D3DXVECTOR3 closest_on_poly ( const D3DXVECTOR3& p, D3DXVECTOR3* line_dir ) { D3DXVECTOR3 v [ 32 ]; float d [ 32 ]; for ( int i = 0; i < cache.count - 1; i++ ) { v [ i ] = closest_on_line ( cache.vertex [ i ], cache.vertex [ i + 1 ], p ); D3DXVECTOR3 t = p - v [ i ]; d [ i ] = D3DXVec3Length ( &t ); } i = cache.count-1; v [ i ] = closest_on_line ( cache.vertex [ i ], cache.vertex [ 0 ], p ); D3DXVECTOR3 t = p - v [ i ]; d [ i ] = D3DXVec3Length ( &t ); float min = d [ 0 ]; D3DXVECTOR3 r = v [ 0 ]; int cl_line = 0; for ( i = 1; i < cache.count; i++ ) { if ( d [ i ] < min ) { min = d [ i ]; r = v [ i ]; cl_line = i; } } // calculate direction vector of closest line if ( cl_line < cache.count - 1) *line_dir = cache.vertex [ cl_line + 1 ] - cache.vertex [ cl_line ]; else *line_dir = cache.vertex [ 0 ] - cache.vertex [ cl_line ]; return r; }
double PST_Edge::closest_on_line( const CubitVector& B2, const CubitVector& M2 ) { CubitVector B1 = start_coord(); CubitVector M1 = direction(); if( M1.length_squared() < RESABS_SQR ) return 0.0; if( M2.length_squared() < RESABS_SQR ) return closest_on_line( B2 ); CubitVector cross = M2 * M1; if( cross.length_squared() < CUBIT_RESABS ) //parallel return 0.0; CubitVector N = M2 * cross; double D = -( N % B2 ); return -( N % B1 + D ) / ( N % M1 ); }