cgma
CylinderEvaluator.cpp
Go to the documentation of this file.
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         **********
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines