cgma
Curve.cpp
Go to the documentation of this file.
00001 //-------------------------------------------------------------------------
00002 // Filename      : Curve.cc
00003 //
00004 // Purpose       : 
00005 //
00006 // Special Notes :
00007 //
00008 // Creator       : Xuechen Liu
00009 //
00010 // Creation Date : 08/02/96
00011 //
00012 // Owner         : Malcolm J. Panthaki
00013 //-------------------------------------------------------------------------
00014 
00015 // ********** BEGIN STANDARD INCLUDES      **********
00016 // ********** END STANDARD INCLUDES        **********
00017 
00018 // ********** BEGIN CUBIT INCLUDES         **********
00019 #include "Curve.hpp"
00020 #include "Point.hpp"
00021 #include "GeometryQueryTool.hpp"
00022 
00023 #include "CastTo.hpp"
00024 #include "CubitMessage.hpp"
00025 // ********** END CUBIT INCLUDES           **********
00026 
00027 // ********** BEGIN STATIC DECLARATIONS    **********
00028 // ********** END STATIC DECLARATIONS      **********
00029 
00030 // ********** BEGIN PUBLIC FUNCTIONS       **********
00031 
00032 //-------------------------------------------------------------------------
00033 // Purpose       : The default constructor. Does not do anything right now.
00034 //
00035 // Special Notes :
00036 //
00037 // Creator       : Xuechen Liu
00038 //
00039 // Creation Date : 08/02/96
00040 //-------------------------------------------------------------------------
00041 
00042 Curve::Curve()
00043 {}
00044 
00045 //-------------------------------------------------------------------------
00046 // Purpose       : The destructor. Does not do anything right now.
00047 //
00048 // Special Notes :
00049 //
00050 // Creator       : Raikanta Sahu
00051 //
00052 // Creation Date : 09/06/96
00053 //-------------------------------------------------------------------------
00054 
00055 Curve::~Curve()
00056 {}
00057 
00058 CubitSense Curve::relative_sense(Curve *other_curve)
00059 {
00060   CubitVector center, junk, this_tangent, other_tangent;
00061   double start, end;
00062   
00063   if (!get_param_range(start,end)                 ||
00064       !position_from_u(0.5*(start+end), center)   ||
00065       !closest_point(center, junk, &this_tangent) ||
00066       !other_curve->closest_point(center, junk, &other_tangent))
00067     return CUBIT_UNKNOWN;
00068   
00069   double dot = this_tangent % other_tangent;
00070   return dot == 0.0 ? CUBIT_UNKNOWN : dot > 0. ? CUBIT_FORWARD : CUBIT_REVERSED;
00071 }
00072 
00073 //- When this is implemented in VirtualGeometryEngine it should be a pure vitual
00074 CubitStatus Curve::get_point_direction( CubitVector& , CubitVector&  )
00075 {
00076    return CUBIT_FAILURE;
00077 }
00078 
00079 //- default implementation
00080 CubitStatus Curve::get_center_radius( CubitVector& c, double& r)
00081 {
00082   CubitVector start_pos, closest_pos;
00083   if ( position_from_u(start_param(), start_pos) &&
00084        closest_point(start_pos, closest_pos, 0, &c) ) 
00085   {
00086     r = c.length();
00087     if (r > CUBIT_RESABS) 
00088     {
00089       r = 1.0 / r;
00090       c *= r * r;
00091       c += closest_pos;
00092       return CUBIT_SUCCESS;
00093     }
00094   }
00095   return CUBIT_FAILURE; 
00096 }
00097 
00098 //-------------------------------------------------------------------------
00099 // Purpose       : This function returns the point that is a distance
00100 //                 arc length from the root_point.
00101 //
00102 // Special Notes : If the root point is on a periodic curve, it may
00103 //                 accidentaly get the wrong parameter.  There is
00104 //                 a special test here to make sure root point does
00105 //                 not get set as the end parameter...
00106 //                 If root point is at the end, we will assert later on..
00107 //
00108 // Creator       : David White
00109 //
00110 // Creation Date : 03/24/97
00111 //-------------------------------------------------------------------------
00112 CubitStatus Curve::point_from_arc_length ( const CubitVector &root_point,
00113                                            double const arc_length,
00114                                            CubitVector& new_point )
00115 {
00116     // Get the parameter value of the root point
00117   double root_param = u_from_position( root_point );
00118   return point_from_arc_length(root_param, arc_length, new_point);
00119 }
00120 
00121 //-------------------------------------------------------------------------
00122 // Purpose       : This function returns the point that is a distance
00123 //                 arc length from the point corresponding to root_param
00124 //
00125 // Special Notes : The original point_from_arc_length was split up
00126 //                 to allow the starting parameter to be specified directly.
00127 //                 This helps with periodic curves, where the start_param of the
00128 //                 curve can be passed in so we're sure its starting from the
00129 //                 start vertex.
00130 //
00131 // Creator       : David White (modified by Ved Vyas)
00132 //
00133 // Creation Date : 5/21/2006
00134 //-------------------------------------------------------------------------
00135 
00136 CubitStatus Curve::point_from_arc_length( double root_param,
00137                                           const double arc_length,
00138                                           CubitVector &new_point )
00139 {
00140   double low_param = start_param();
00141   double high_param = end_param();
00142 
00143   if (high_param < low_param)
00144   {
00145     double temp = high_param;
00146     high_param = low_param;
00147     low_param = temp;
00148   }
00149 
00150     // Comment: The way we handle points not on the bounded curve is
00151     //          different for periodic and non-periodic curves!
00152     //          Periodic curves leave the parameter off of the curve,
00153     //          while non-periodic curves move the point to the closest
00154     //          endpoint.  Just an observation!
00155   
00156   
00157     // Adjust the parameter for periodic curves
00158   double periodic_param;
00159 
00160   if ( is_periodic( periodic_param ))
00161   {
00162     while (root_param < low_param)
00163       root_param += periodic_param;
00164     while (root_param > high_param)
00165       root_param -= periodic_param;
00166       // If you're moving in the positive direction and
00167       // you're almost at the start point...
00168     if (fabs( this->end_param() - root_param ) <= CUBIT_RESABS &&
00169         arc_length > 0.0 )
00170     {
00171         //the root param should be switched with the start param.
00172       root_param = this->start_param();
00173     }
00174       // If you're moving in the negative direction and
00175       // you're almost at the end point...
00176     else if (fabs( this->start_param() - root_param ) <= CUBIT_RESABS &&
00177              arc_length < 0.0 )
00178     {
00179       root_param = this->end_param();
00180     }
00181   }
00182   else if ( root_param < (low_param + CUBIT_RESABS) )
00183     root_param = low_param;
00184   else if ( root_param > (high_param - CUBIT_RESABS) )
00185     root_param = high_param;
00186  
00187     // Get the parameter value of the new point
00188   double new_param = this->u_from_arc_length( root_param,
00189                                               arc_length );
00190   
00191     // Now get the coordinates (in world space) representing this parameter
00192     // value
00193   return this->position_from_u(new_param, new_point);
00194 }
00195 
00196 //-------------------------------------------------------------------------
00197 // Purpose       : Find the closest point on a BOUNDED curve.
00198 //
00199 // Creator       : Jason Kraftcheck 
00200 //
00201 // Creation Date : 07/17/98
00202 //-------------------------------------------------------------------------
00203 CubitStatus Curve::closest_point_trimmed( CubitVector const& from_pt,
00204                                           CubitVector& result )
00205 {
00206     // Get the untrimmed point
00207   double param;
00208   if ( !closest_point(from_pt, result, NULL, NULL, &param) )
00209     return CUBIT_FAILURE;  
00210   
00211   double param_range = 0.0;
00212   double period, start_param, end_param;
00213   
00214     // Get whether periodic
00215   CubitBoolean is_per = this->is_periodic(period);
00216     // Get the parameter range
00217   get_param_range( start_param, end_param );
00218   
00219     // Make sure the start_param is lower than end_param.
00220   if (start_param > end_param)
00221   {
00222       // use param_range as temp
00223     param_range = start_param;
00224     start_param = end_param;
00225     end_param = param_range;
00226   }
00227   param_range = end_param - start_param;
00228   
00229     // If the Curve does not loop onto itself...
00230   if(  is_per == CUBIT_FALSE  ||
00231        param_range < period)
00232   {
00233       // If not within parameter range, return
00234       // the the closest endpoint
00235     CubitVector start, end;
00236     position_from_u( start_param, start );
00237     position_from_u( end_param, end );
00238 
00239     if( (param < start_param) || (param > end_param) )
00240     {
00241       result = ( (start - result).length_squared() < 
00242                  (end - result).length_squared() ) ? start : end ;
00243     }
00244     else
00245     {
00246       double tmp_dist_sq = (from_pt - result).length_squared();
00247       if( (start-from_pt).length_squared() < tmp_dist_sq )
00248         result = start;
00249       else if( (end-from_pt).length_squared() < tmp_dist_sq )
00250         result = end;
00251     }
00252   }
00253 
00254   
00255   return CUBIT_SUCCESS;
00256 }
00257 
00258 //-------------------------------------------------------------------------
00259 // Purpose       : Check for discontinuity in the tangents of a curve
00260 //
00261 // Special Notes : 
00262 //
00263 // Creator       : Jason Kraftcheck
00264 //
00265 // Creation Date : 05/01/00
00266 //-------------------------------------------------------------------------
00267 CubitBoolean Curve::G1_discontinuous( double u,
00268     CubitVector* minus_tangent_r, CubitVector* plus_tangent_r )
00269 {
00270     double start_param, end_param;
00271     if( ! get_param_range( start_param, end_param ) ) return CUBIT_FALSE;
00272     //if the curve is not parametric, just return false.
00273     if( start_param > end_param )
00274     {
00275         double tmp = start_param;
00276         start_param = end_param;
00277         end_param = tmp;
00278     }
00279     
00280     double u_minus = (2 * CUBIT_RESABS);
00281     double u_plus = u_minus;
00282     
00283     //can't be C1 discontinous at an end point!
00284     if( ((u - u_minus) < start_param) || ((u + u_plus) > end_param) )
00285         return CUBIT_FALSE;
00286 
00287     CubitVector position;
00288     position_from_u( u, position );
00289     const double res_abs_sqr = CUBIT_RESABS * CUBIT_RESABS;
00290 
00291     CubitVector minus_position, minus_tangent;
00292     position_from_u( u - u_minus, minus_position );
00293     double u_minus2 = u_from_position( minus_position );
00294     minus_tangent = position - minus_position;
00295 
00296     while( ((u - u_minus2) > (u - CUBIT_RESABS)) || 
00297            (minus_tangent.length_squared() < res_abs_sqr) )
00298     {
00299         u_minus *= 10.;
00300         //can't be C1 discontinous at an end point!
00301         if( (u - u_minus) < start_param ) return CUBIT_FALSE;
00302         position_from_u( u - u_minus, minus_position );
00303         u_minus2 = u_from_position( minus_position );
00304         minus_tangent = position - minus_position;
00305     }
00306     
00307     CubitVector plus_position, plus_tangent;
00308     position_from_u( u + u_plus, plus_position );
00309     double u_plus2 = u_from_position( plus_position );
00310     plus_tangent = plus_position - position;
00311     
00312     while( ((u + u_plus2) < (u + CUBIT_RESABS)) ||
00313            ((position - plus_position).length_squared() < res_abs_sqr) )
00314     {
00315         u_plus *= 10.;
00316         //can't be C1 discontinous at an end point!
00317         if( (u + u_plus) > end_param ) return CUBIT_FALSE;
00318         position_from_u( u + u_plus, plus_position );
00319         u_plus2 = u_from_position( plus_position );
00320         plus_tangent = plus_position - position;
00321     }
00322     
00323     plus_tangent.normalize();
00324     minus_tangent.normalize();
00325     if( (plus_tangent * minus_tangent).length_squared() > (2 * res_abs_sqr) )
00326     {
00327         if( plus_tangent_r ) *plus_tangent_r = plus_tangent;
00328         if( minus_tangent_r ) * minus_tangent_r = minus_tangent;
00329         return CUBIT_TRUE;
00330     }
00331     
00332     return CUBIT_FALSE; 
00333 }
00334     
00335 // ********** END PUBLIC FUNCTIONS         **********
00336 
00337 // ********** BEGIN PROTECTED FUNCTIONS    **********
00338 // ********** END PROTECTED FUNCTIONS      **********
00339 
00340 // ********** BEGIN PRIVATE FUNCTIONS      **********
00341 // ********** END PRIVATE FUNCTIONS        **********
00342 
00343 // ********** BEGIN HELPER CLASSES         **********
00344 // ********** END HELPER CLASSES           **********
00345 
00346 // ********** BEGIN EXTERN FUNCTIONS       **********
00347 // ********** END EXTERN FUNCTIONS         **********
00348 
00349 // ********** BEGIN STATIC FUNCTIONS       **********
00350 // ********** END STATIC FUNCTIONS         **********
00351 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines