cgma
|
00001 //------------------------------------------------------------------------- 00002 // Filename : CylinderEvaluator.cpp 00003 // 00004 // Purpose : 00005 // 00006 // Special Notes : 00007 // 00008 // Creator : Matt Staten 00009 // 00010 // Creation Date : 09/15/04 00011 // 00012 // Owner : Matt Staten 00013 //------------------------------------------------------------------------- 00014 00015 #include "CylinderEvaluator.hpp" 00016 #include "CubitMessage.hpp" 00017 #include "CubitBox.hpp" 00018 #include "CubitVector.hpp" 00019 00020 // ********** END CUBIT INCLUDES ********** 00021 00022 // ********** BEGIN STATIC DECLARATIONS ********** 00023 // ********** END STATIC DECLARATIONS ********** 00024 00025 // ********** BEGIN PUBLIC FUNCTIONS ********** 00026 00027 //------------------------------------------------------------------------- 00028 // Purpose : Construct a CylinderEvaluator object given a structure 00029 // containing the radius, center, etc. for the desired 00030 // Cylinder. 00031 // 00032 // Special Notes : 00033 // 00034 //------------------------------------------------------------------------- 00035 CylinderEvaluator::CylinderEvaluator( const CylinderEvaluatorData *data ) 00036 { 00037 mEvalData = *data; 00038 00039 mTmatrix.scale_about_origin( 1.0, mEvalData.base_radius_y/mEvalData.base_radius_x, 1.0 ); 00040 } 00041 00042 //------------------------------------------------------------------------- 00043 // Purpose : Compute and return the bounding box for this cylinder. 00044 // 00045 // Special Notes : 00046 // 00047 //------------------------------------------------------------------------- 00048 CubitBox CylinderEvaluator::bounding_box( void ) const 00049 { 00050 int ipt = 0; 00051 CubitVector pts[8]; 00052 CubitVector axis( 0.0, 0.0, 1.0 ); 00053 CubitVector base_pt = base(); 00054 CubitVector top_pt = base() + mEvalData.height * axis; 00055 CubitVector x_dir( 1.0, 0.0, 0.0 ); 00056 CubitVector y_dir( 0.0, 1.0, 0.0 ); 00057 double scale = mEvalData.base_radius_y * mEvalData.base_radius_x; 00058 00059 pts[0] = base_pt + ( x_dir * mEvalData.base_radius_x ); 00060 pts[1] = base_pt - ( x_dir * mEvalData.base_radius_x ); 00061 pts[2] = base_pt + ( y_dir * mEvalData.base_radius_y ); 00062 pts[3] = base_pt - ( y_dir * mEvalData.base_radius_y ); 00063 pts[4] = top_pt + ( x_dir * mEvalData.top_radius ); 00064 pts[5] = top_pt - ( x_dir * mEvalData.top_radius ); 00065 pts[6] = top_pt + ( y_dir * mEvalData.top_radius * scale ); 00066 pts[7] = top_pt - ( y_dir * mEvalData.top_radius * scale ); 00067 00068 for ( ipt = 0; ipt < 8; ipt++ ) 00069 { 00070 pts[ipt] = mTmatrix * pts[ipt]; 00071 } 00072 00073 CubitVector min( pts[0] ), 00074 max( pts[0] ); 00075 for ( ipt = 1; ipt < 8; ipt++ ) 00076 { 00077 CubitVector *pt = &(pts[ipt]); 00078 if ( min.x() > pt->x() ) min.x( pt->x() ); 00079 if ( min.y() > pt->y() ) min.y( pt->y() ); 00080 if ( min.z() > pt->z() ) min.z( pt->z() ); 00081 if ( max.x() < pt->x() ) max.x( pt->x() ); 00082 if ( max.y() < pt->y() ) max.y( pt->y() ); 00083 if ( max.z() < pt->z() ) max.z( pt->z() ); 00084 } 00085 00086 CubitBox thebbox( min, max ); 00087 00088 return thebbox; 00089 } 00090 00091 //------------------------------------------------------------------------- 00092 // Purpose : This functions computes the point on the surface that is 00093 // closest to the input location and then calculates the 00094 // magnitudes of the principal curvatures at this (possibly, 00095 // new) point on the surface. 00096 // 00097 // Special Notes : 00098 // 00099 //------------------------------------------------------------------------- 00100 CubitStatus CylinderEvaluator::principal_curvatures( 00101 CubitVector const& location, 00102 double& curvature_1, 00103 double& curvature_2, 00104 CubitVector* closest_location ) 00105 { 00106 PRINT_ERROR("principles_curvatures not implemented for cylinders yet.\n"); 00107 return CUBIT_FAILURE; 00108 00109 // if ( closest_location ) 00110 // { 00111 // return closest_point( location, closest_location ); 00112 // } 00113 // return CUBIT_SUCCESS; 00114 } 00115 00116 //------------------------------------------------------------------------- 00117 // Purpose : Computes the closest_point on the surface to the input 00118 // location. Optionally, it also computes and returns 00119 // the normal to the surface and the principal curvatures 00120 // at closest_location. 00121 // 00122 //------------------------------------------------------------------------- 00123 CubitStatus CylinderEvaluator::closest_point( CubitVector const& location, 00124 CubitVector* closest_location, 00125 CubitVector* unit_normal_ptr, 00126 CubitVector* curvature1_ptr, 00127 CubitVector* curvature2_ptr) const 00128 { 00129 CubitTransformMatrix inverse_Tmatrix = mTmatrix; 00130 inverse_Tmatrix.inverse(); 00131 CubitVector new_pt = inverse_Tmatrix * location; 00132 CubitVector normal; 00133 double dist = sqrt( ( new_pt.x() * new_pt.x() ) + ( new_pt.y() * new_pt.y() ) ); 00134 if ( dist < GEOMETRY_RESABS ) 00135 { 00136 normal.set( 1.0, 0.0, 0.0 ); 00137 } 00138 else 00139 { 00140 normal.set( new_pt.x(), new_pt.y(), 0.0 ); 00141 } 00142 normal.normalize(); 00143 if ( unit_normal_ptr ) 00144 { 00145 CubitVector origin( 0.0, 0.0, 0.0 ); 00146 CubitVector endpt( normal ); 00147 00148 origin = mTmatrix * origin;; 00149 endpt = mTmatrix * endpt; 00150 00151 *unit_normal_ptr = endpt - origin; 00152 unit_normal_ptr->normalize(); 00153 } 00154 if ( closest_location != NULL ) 00155 { 00156 CubitVector axis_pt( 0.0, 0.0, new_pt.z() ); 00157 double v = axis_pt.z() - base().z(); 00158 double radius = v * ( ( mEvalData.top_radius - mEvalData.base_radius_x ) / mEvalData.height ) + mEvalData.base_radius_x; 00159 00160 *closest_location = axis_pt + ( radius * normal ); 00161 *closest_location = mTmatrix * (*closest_location); 00162 } 00163 return CUBIT_SUCCESS; 00164 } 00165 00166 //------------------------------------------------------------------------- 00167 // Purpose : Given a UV parametric location, return the cooresponding 00168 // XYZ location. 00169 //------------------------------------------------------------------------- 00170 CubitVector CylinderEvaluator::position_from_u_v( double u, double v ) const 00171 { 00172 double radius = v * ( ( mEvalData.top_radius - mEvalData.base_radius_x ) / mEvalData.height ) + mEvalData.base_radius_x; 00173 CubitVector base_pt = base(); 00174 double two_pi = 2.0 * CUBIT_PI; 00175 00176 while ( u > two_pi ) u -= two_pi; 00177 while ( u < 0.0 ) u += two_pi; 00178 00179 double x = radius * sin( u ); 00180 double y = radius * cos( u ); 00181 double z = base_pt.z() + v; 00182 00183 CubitVector position( x, y, z ); 00184 position = mTmatrix * position; 00185 00186 return position; 00187 } 00188 00189 //------------------------------------------------------------------------- 00190 // Purpose : Project a given XYZ position to a surface and return 00191 // the UV and XYZ locations on the surface. 00192 //------------------------------------------------------------------------- 00193 CubitStatus CylinderEvaluator::u_v_from_position 00194 ( 00195 CubitVector const& location, 00196 double& u, 00197 double& v, 00198 CubitVector* closest_location 00199 ) const 00200 { 00201 CubitTransformMatrix inverse_Tmatrix = mTmatrix; 00202 inverse_Tmatrix.inverse(); 00203 CubitVector transformed_pt = inverse_Tmatrix * location; 00204 CubitVector base_pt = base(); 00205 CubitVector dir( transformed_pt.x(), transformed_pt.y(), 0.0 ); 00206 dir.normalize(); 00207 00208 v = transformed_pt.z() - base_pt.z(); 00209 u = acos( dir.y() ); 00210 if ( dir.x() < 0.0 ) 00211 u = 2*CUBIT_PI - u; 00212 00213 while ( u < 0.0 ) u += 2*CUBIT_PI; 00214 while ( u >= 2*CUBIT_PI ) u -= 2*CUBIT_PI; 00215 00216 if ( closest_location ) 00217 closest_point( location, closest_location ); 00218 return CUBIT_SUCCESS; 00219 } 00220 00221 //------------------------------------------------------------------------- 00222 // Purpose : return the dimension parameters of this cylinder. 00223 // 00224 //------------------------------------------------------------------------- 00225 const CubitEvaluatorData* CylinderEvaluator::evaluator_data( void ) const 00226 { 00227 return &mEvalData; 00228 } 00229 00230 //------------------------------------------------------------------------- 00231 // Purpose : return parametric extremes in the U direction 00232 // 00233 //------------------------------------------------------------------------- 00234 CubitBoolean CylinderEvaluator::get_param_range_U 00235 ( 00236 double& lower_bound, 00237 double& upper_bound 00238 ) const 00239 { 00240 lower_bound = 0.0; 00241 upper_bound = 2*CUBIT_PI; 00242 return CUBIT_TRUE; 00243 } 00244 00245 //------------------------------------------------------------------------- 00246 // Purpose : return parametric extremes in the V direction 00247 // 00248 //------------------------------------------------------------------------- 00249 CubitBoolean CylinderEvaluator::get_param_range_V 00250 ( 00251 double& lower_bound, 00252 double& upper_bound 00253 ) const 00254 { 00255 lower_bound = 0.0; 00256 upper_bound = mEvalData.height; 00257 return CUBIT_TRUE; 00258 } 00259 00260 // ********** END PUBLIC FUNCTIONS ********** 00261 00262 CubitVector CylinderEvaluator::base() const 00263 { 00264 return CubitVector( 0.0, 0.0, -0.5*mEvalData.height ); 00265 } 00266 00267 // ********** END PROTECTED FUNCTIONS ********** 00268 00269 // ********** BEGIN PRIVATE FUNCTIONS ********** 00270 // ********** END PRIVATE FUNCTIONS ********** 00271 00272 // ********** BEGIN HELPER CLASSES ********** 00273 // ********** END HELPER CLASSES ********** 00274 00275 // ********** BEGIN EXTERN FUNCTIONS ********** 00276 // ********** END EXTERN FUNCTIONS ********** 00277 00278 // ********** BEGIN STATIC FUNCTIONS ********** 00279 // ********** END STATIC FUNCTIONS **********