opennurbs_math.h
Go to the documentation of this file.
00001 /* $NoKeywords: $ */
00002 /*
00003 //
00004 // Copyright (c) 1993-2012 Robert McNeel & Associates. All rights reserved.
00005 // OpenNURBS, Rhinoceros, and Rhino3D are registered trademarks of Robert
00006 // McNeel & Associates.
00007 //
00008 // THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
00009 // ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF
00010 // MERCHANTABILITY ARE HEREBY DISCLAIMED.
00011 //                              
00012 // For complete openNURBS copyright information see <http://www.opennurbs.org>.
00013 //
00015 */
00016 
00017 #if !defined(ON_MATH_INC_)
00018 #define ON_MATH_INC_
00019 
00020 class ON_3dVector;
00021 class ON_Interval;
00022 class ON_Line;
00023 class ON_Arc;
00024 class ON_Plane;
00025 
00026 /*
00027 Description:
00028   Class for carefully adding long list of numbers.
00029 */
00030 class ON_CLASS ON_Sum
00031 {
00032 public:
00033 
00034   /*
00035   Description:
00036     Calls ON_Sum::Begin(x)
00037   */
00038   void operator=(double x);
00039 
00040   /*
00041   Description:
00042     Calls ON_Sum::Plus(x);
00043   */
00044   void operator+=(double x);
00045 
00046   /*
00047   Description:
00048     Calls ON_Sum::Plus(-x);
00049   */
00050   void operator-=(double x);
00051 
00052   /*
00053   Description:
00054     Creates a sum that is ready to be used.
00055   */
00056   ON_Sum();
00057 
00058   /*
00059   Description:
00060     If a sum is being used more than once, call Begin()
00061     before starting each sum.
00062   Parameters:
00063     starting_value - [in] Initial value of sum.
00064   */
00065   void Begin( double starting_value = 0.0 );
00066 
00067   /*
00068   Description:
00069     Add x to the current sum.
00070   Parameters:
00071     x - [in] value to add to the current sum.
00072   */
00073   void Plus( double x );
00074 
00075   /*
00076   Description:
00077     Calculates the total sum.   
00078   Parameters:
00079     error_estimate - [out] if not NULL, the returned value of
00080        *error_estimate is an estimate of the error in the sum.
00081   Returns:
00082     Total of the sum.
00083   Remarks:
00084     You can get subtotals by mixing calls to Plus() and Total().
00085     In delicate sums, some precision may be lost in the final
00086     total if you call Total() to calculate subtotals.
00087   */
00088   double Total( double* error_estimate = NULL );
00089 
00090   /*
00091   Returns:
00092     Number of summands.
00093   */
00094   int SummandCount() const;
00095 
00096 private:
00097   enum {
00098     sum1_max_count=256,
00099     sum2_max_count=512,
00100     sum3_max_count=1024
00101   };
00102   double m_sum_err;
00103   double m_pos_sum;     
00104   double m_neg_sum;  
00105   
00106   int m_zero_count; // number of zeros added
00107   int m_pos_count; // number of positive numbers added
00108   int m_neg_count; // number of negative numbers added
00109   
00110   int m_pos_sum1_count;
00111   int m_pos_sum2_count;
00112   int m_pos_sum3_count;
00113   double m_pos_sum1[sum1_max_count];
00114   double m_pos_sum2[sum2_max_count];
00115   double m_pos_sum3[sum3_max_count];
00116   
00117   int m_neg_sum1_count;
00118   int m_neg_sum2_count;
00119   int m_neg_sum3_count;
00120   double m_neg_sum1[sum1_max_count];
00121   double m_neg_sum2[sum2_max_count];
00122   double m_neg_sum3[sum3_max_count];
00123 
00124   double SortAndSum( int, double* );
00125 };
00126 
00127 /*
00128 Description:
00129   Abstract function with an arbitrary number of parameters
00130   and values.  ON_Evaluator is used to pass functions to
00131   local solvers.
00132 */
00133 class ON_CLASS ON_Evaluator
00134 {
00135 public:
00136 
00137   /*
00138   Description:
00139     Construction of the class for a function that takes
00140     parameter_count input functions and returns
00141     value_count values.  If the domain is infinite, pass
00142     a NULL for the domain[] and periodic[] arrays.  If
00143     the domain is finite, pass a domain[] array with
00144     parameter_count increasing intervals.  If one or more of
00145     the parameters is periodic, pass the fundamental domain
00146     in the domain[] array and a true in the periodic[] array.
00147   Parameters:
00148     parameter_count - [in] >= 1.  Number of input parameters
00149     value_count - [in] >= 1.  Number of output values.
00150     domain - [in] If not NULL, then this is an array
00151                   of parameter_count increasing intervals
00152                   that defines the domain of the function.
00153     periodic - [in] if not NULL, then this is an array of 
00154                 parameter_count bools where b[i] is true if
00155                 the i-th parameter is periodic.  Valid 
00156                 increasing finite domains must be specificed
00157                 when this parameter is not NULL.
00158   */
00159   ON_Evaluator( 
00160     int parameter_count,
00161     int value_count,
00162     const ON_Interval* domain,
00163     const bool* periodic
00164     );
00165 
00166   virtual ~ON_Evaluator();
00167   
00168   /*
00169   Description:
00170     Evaluate the function that takes m_parameter_count parameters
00171     and returns a m_value_count dimensional point.
00172   Parameters:
00173     parameters - [in] array of m_parameter_count evaluation parameters
00174     values - [out] array of m_value_count function values
00175     jacobian - [out] If NULL, simply evaluate the value of the function.
00176                      If not NULL, this is the jacobian of the function.
00177                      jacobian[i][j] = j-th partial of the i-th value
00178                      0 <= i < m_value_count,
00179                      0 <= j < m_parameter_count
00180                      If not NULL, then all the memory for the
00181                      jacobian is allocated, you just need to fill
00182                      in the answers.
00183   Example:
00184     If f(u,v) = square of the distance from a fixed point P to a 
00185     surface evaluated at (u,v), then
00186 
00187           values[0] = (S-P)o(S-P)
00188           jacobian[0] = ( 2*(Du o (S-P)), 2*(Dv o (S-P)) )
00189 
00190     where S, Du, Dv = surface point and first partials evaluated
00191     at u=parameters[0], v = parameters[1].
00192 
00193     If the function takes 3 parameters, say (x,y,z), and returns
00194     two values, say f(x,y,z) and g(z,y,z), then
00195 
00196           values[0] = f(x,y,z)
00197           values[1] = g(x,y,z)
00198 
00199           jacobian[0] = (DfDx, DfDy, DfDz)
00200           jacobian[1] = (DgDx, DgDy, DgDz)
00201 
00202     where dfx denotes the first partial of f with respect to x.
00203 
00204   Returns:
00205     0 = unable to evaluate
00206     1 = successful evaluation
00207     2 = found answer, terminate search
00208   */
00209   virtual int Evaluate(
00210        const double* parameters,
00211        double* values,
00212        double** jacobian
00213        ) = 0;
00214 
00215   /*
00216   Description:
00217     OPTIONAL ability to evaluate the hessian in the case when 
00218     m_value_count is one.  If your function has more that
00219     one value or it is not feasable to evaluate the hessian,
00220     then do not override this function.  The default implementation
00221     returns -1.
00222   Parameters:
00223     parameters - [in] array of m_parameter_count evaluation parameters
00224     value - [out] value of the function (one double)
00225     gradient - [out] The gradient of the function.  This is a vector
00226                      of length m_parameter_count; gradient[i] is
00227                      the first partial of the function with respect to
00228                      the i-th parameter.
00229     hessian - [out] The hessian of the function. This is an
00230                     m_parameter_count x m_parameter_count 
00231                     symmetric matrix: hessian[i][j] is the
00232                     second partial of the function with respect
00233                     to the i-th and j-th parameters.  The evaluator
00234                     is responsible for filling in both the upper
00235                     and lower triangles.  Since the matrix is
00236                     symmetrix, you should do something like evaluate
00237                     the upper triangle and copy the values to the
00238                     lower tiangle.
00239   Returns:
00240    -1 = Hessian evaluation not available.
00241     0 = unable to evaluate
00242     1 = successful evaluation
00243     2 = found answer, terminate search
00244   */
00245   virtual int EvaluateHessian(
00246        const double* parameters,
00247        double* value,
00248        double* gradient,
00249        double** hessian
00250        );
00251   
00252   // Number of the function's input parameters. This number
00253   // is >= 1 and is specified in the constructor.
00254   const int m_parameter_count;
00255 
00256   // Number of the function's output values. This number
00257   // is >= 1 and is specified in the constructor.
00258   const int m_value_count;
00259 
00260   /*
00261   Description:
00262     Functions can have finite or infinite domains. Finite domains
00263     are specified by passing the domain[] array to the constructor
00264     or filling in the m_domain[] member variable.  If
00265     m_domain.Count() == m_parameter_count > 0, then the function
00266     has finite domains.
00267   Returns:
00268     True if the domain of the function is finite.
00269   */
00270   bool FiniteDomain() const;
00271 
00272   /*
00273   Description:
00274     If a function has a periodic parameter, then the m_domain
00275     interval for that parameter is the fundamental domain and
00276     the m_bPeriodicParameter bool for that parameter is true.
00277     A parameter is periodic if, and only if, 
00278     m_domain.Count() == m_parameter_count, and 
00279     m_bPeriodicParameter.Count() == m_parameter_count, and
00280     m_bPeriodicParameter[parameter_index] is true.
00281   Returns:
00282     True if the function parameter is periodic.
00283   */
00284   bool Periodic(
00285     int parameter_index
00286     ) const;
00287 
00288   /*
00289   Description:
00290     If a function has a periodic parameter, then the m_domain
00291     interval for that parameter is the fundamental domain and
00292     the m_bPeriodicParameter bool for that parameter is true.
00293     A parameter is periodic if, and only if, 
00294     m_domain.Count() == m_parameter_count, and 
00295     m_bPeriodicParameter.Count() == m_parameter_count, and
00296     m_bPeriodicParameter[parameter_index] is true.
00297   Returns:
00298     The domain of the parameter.  If the domain is infinite,
00299     the (-1.0e300, +1.0e300) is returned.
00300   */
00301   ON_Interval Domain(
00302     int parameter_index
00303     ) const;
00304 
00305 
00306   // If the function has a finite domain or periodic
00307   // parameters, then m_domain[] is an array of 
00308   // m_parameter_count finite increasing intervals.
00309   ON_SimpleArray<ON_Interval> m_domain;
00310 
00311   // If the function has periodic parameters, then 
00312   // m_bPeriodicParameter[] is an array of m_parameter_count
00313   // bools.  If m_bPeriodicParameter[i] is true, then
00314   // the i-th parameter is periodic and m_domain[i] is 
00315   // the fundamental domain for that parameter.
00316   ON_SimpleArray<bool> m_bPeriodicParameter;
00317 
00318 private:
00319   ON_Evaluator(); // prohibit default constructor
00320   ON_Evaluator& operator=(const ON_Evaluator&); // prohibit operator= (can't copy const members)
00321 };
00322 
00323 /*
00324 Description:
00325   Test a double to make sure it is a valid number.
00326 Returns:
00327   True if x != ON_UNSET_VALUE and _finite(x) is true.
00328 */
00329 ON_DECL
00330 bool ON_IsValid( double x );
00331 
00332 ON_DECL
00333 bool ON_IsValidFloat( float x );
00334 
00335 /*
00336 class ON_CLASS ON_TimeLimit
00337 {
00338   ON_TimeLimit();
00339   ON_TimeLimit(ON__UINT64 time_limit_seconds);
00340   void SetTimeLimit(ON__UINT64 time_limit_seconds);
00341   bool Continue() const;
00342   bool IsSet() const;
00343 private:
00344   ON__UINT64 m_time_limit[2];
00345 };
00346 */
00347 
00348 // The ON_IS_FINITE and ON_IS_VALID defines are much faster
00349 // than calling ON_IsValid(), but need to be used when
00350 // the macro expansion works.
00351 
00352 #if   defined(ON_LITTLE_ENDIAN)
00353 
00354 // works on little endian CPUs with IEEE doubles
00355 #define ON_IS_FINITE(x) (0x7FF0 != (*((unsigned short*)(&x) + 3) & 0x7FF0))
00356 #define ON_IS_VALID(x)  (x != ON_UNSET_VALUE && 0x7FF0 != (*((unsigned short*)(&x) + 3) & 0x7FF0))
00357 #define ON_IS_VALID_FLOAT(x)  (x != ON_UNSET_FLOAT)
00358 //TODO - ADD FAST ugly bit check#define ON_IS_VALID_FLOAT(x)  (x != ON_UNSET_FLOAT && 0x7FF0 != (*((unsigned short*)(&x) + 3) & 0x7FF0))
00359 
00360 #elif defined(ON_BIG_ENDIAN)
00361 
00362 // works on big endian CPUs with IEEE doubles
00363 #define ON_IS_FINITE(x) (0x7FF0 != (*((unsigned short*)(&x)) & 0x7FF0))
00364 #define ON_IS_VALID(x)  (x != ON_UNSET_VALUE && 0x7FF0 != (*((unsigned short*)(&x)) & 0x7FF0))
00365 #define ON_IS_VALID_FLOAT(x)  (x != ON_UNSET_FLOAT)
00366 //TODO - ADD FAST ugly bit check#define ON_IS_VALID_FLOAT(x)  (x != ON_UNSET_FLOAT && 0x7FF0 != (*((unsigned short*)(&x) + 3) & 0x7FF0))
00367 
00368 #else
00369 
00370 // Returns true if x is a finite double.  Specifically,
00371 // _finite returns a nonzero value (true) if its argument x
00372 // is not infinite, that is, if -INF < x < +INF. 
00373 // It returns 0 (false) if the argument is infinite or a NaN.
00374 //
00375 // If you are trying to compile opennurbs on a platform
00376 // that does not support finite(), then see if you can
00377 // use _fpclass(), fpclass(), _isnan(), or isnan().  If
00378 // you can't find anything, then just set this
00379 // function to return true.
00380 
00381 #if defined(_GNU_SOURCE)
00382 // if you are using an older version of gcc, use finite()
00383 //#define ON_IS_FINITE(x) (finite(x)?true:false)
00384 #define ON_IS_FINITE(x) (isfinite(x)?true:false)
00385 #else
00386 #define ON_IS_FINITE(x) (_finite(x)?true:false)
00387 #endif
00388 
00389 #define ON_IS_VALID(x)  (x != ON_UNSET_VALUE && ON_IS_FINITE(x))
00390 #define ON_IS_VALID_FLOAT(x)  (x != ON_UNSET_FLOAT && ON_IS_FINITE(x))
00391 
00392 #endif
00393 
00394 
00395 ON_DECL
00396 float ON_ArrayDotProduct( // returns AoB
00397           int,           // size of arrays (can be zero)
00398           const float*, // A[]
00399           const float*  // B[]
00400           );
00401 
00402 ON_DECL
00403 void   ON_ArrayScale( 
00404           int,           // size of arrays (can be zero)
00405           float,        // a
00406           const float*, // A[]
00407           float*        // returns a*A[]
00408           );
00409 
00410 ON_DECL
00411 void   ON_Array_aA_plus_B( 
00412           int,           // size of arrays (can be zero)
00413           float,        // a
00414           const float*, // A[]
00415           const float*, // B[]
00416           float*        // returns a*A[] + B[]
00417           );
00418 
00419 ON_DECL
00420 double ON_ArrayDotProduct( // returns AoB
00421           int,           // size of arrays (can be zero)
00422           const double*, // A[]
00423           const double*  // B[]
00424           );
00425 
00426 ON_DECL
00427 double ON_ArrayDotDifference( // returns A o ( B - C )
00428           int,           // size of arrays (can be zero)
00429           const double*, // A[]
00430           const double*, // B[]
00431           const double*  // C[]
00432           );
00433 
00434 ON_DECL
00435 double ON_ArrayMagnitude( // returns sqrt(AoA)
00436           int,           // size of arrays (can be zero)
00437           const double*  // A[]
00438           );
00439 
00440 ON_DECL
00441 double ON_ArrayMagnitudeSquared( // returns AoA
00442           int,           // size of arrays (can be zero)
00443           const double*  // A[]
00444           );
00445 
00446 ON_DECL
00447 double ON_ArrayDistance( // returns sqrt((A-B)o(A-B))
00448           int,           // size of arrays (can be zero)
00449           const double*, // A[]
00450           const double*  // B[]
00451           );
00452 
00453 ON_DECL
00454 double ON_ArrayDistanceSquared( // returns (A-B)o(A-B)
00455           int,           // size of arrays (can be zero)
00456           const double*, // A[]
00457           const double*  // B[]
00458           );
00459 
00460 ON_DECL
00461 void   ON_ArrayScale( 
00462           int,           // size of arrays (can be zero)
00463           double,        // a
00464           const double*, // A[]
00465           double*        // returns a*A[]
00466           );
00467 
00468 ON_DECL
00469 void   ON_Array_aA_plus_B( 
00470           int,           // size of arrays (can be zero)
00471           double,        // a
00472           const double*, // A[]
00473           const double*, // B[]
00474           double*        // returns a*A[] + B[]
00475           );
00476 
00477 ON_DECL
00478 int    ON_SearchMonotoneArray( // find a value in an increasing array
00479           // returns  -1: t < array[0]
00480           //           i: array[i] <= t < array[i+1] ( 0 <= i < length-1 )
00481           //    length-1: t == array[length-1]
00482           //      length: t >= array[length-1]
00483           const double*, // array[]
00484           int,           // length of array
00485           double         // t = value to search for
00486           );
00487 
00488 
00489 /* 
00490 Description:
00491   Compute a binomial coefficient.
00492 Parameters:
00493   i - [in]
00494   j - [in]
00495 Returns:
00496   (i+j)!/(i!j!), if 0 <= i and 0 <= j, and 0 otherwise.
00497 See Also:
00498   ON_TrinomialCoefficient()
00499 Remarks:
00500   If (i+j) <= 52, this function is fast and returns the exact
00501   value of the binomial coefficient.  
00502 
00503   For (i+j) > 52, the coefficient is computed recursively using
00504   the formula  bc(i,j) = bc(i-1,j) + bc(i,j-1).
00505   For (i+j) much larger than 60, this is inefficient.
00506   If you need binomial coefficients for large i and j, then you
00507   should probably be using something like Stirling's Formula.  
00508   (Look up "Stirling" or "Gamma function" in a calculus book.)
00509 */
00510 ON_DECL
00511 double ON_BinomialCoefficient( 
00512           int i,
00513           int j
00514           );
00515 
00516 
00517 /* 
00518 Description:
00519   Compute a trinomial coefficient.
00520 Parameters:
00521   i - [in]
00522   j - [in]
00523   k - [in]
00524 Returns:
00525   (i+j+k)!/(i!j!k!), if 0 <= i, 0 <= j and 0<= k, and 0 otherwise.
00526 See Also:
00527   ON_BinomialCoefficient()
00528 Remarks:
00529   The trinomial coefficient is computed using the formula
00530 
00531           (i+j+k)!      (i+j+k)!       (j+k)!
00532           --------   =  --------   *  -------
00533           i! j! k!      i! (j+k)!      j! k!
00534 
00535                       = ON_BinomialCoefficient(i,j+k)*ON_BinomialCoefficient(j,k)
00536   
00537 */
00538 ON_DECL
00539 double ON_TrinomialCoefficient( 
00540           int i,
00541           int j,
00542           int k
00543           );
00544 
00545 
00546 ON_DECL
00547 ON_BOOL32 ON_GetParameterTolerance(
00548         double, double, // domain
00549         double,          // parameter in domain
00550         double*, double* // parameter tolerance (tminus, tplus) returned here
00551         );
00552 
00553 
00554 ON_DECL
00555 ON_BOOL32 ON_IsValidPointList(
00556         int,  // dim
00557         ON_BOOL32, // true for homogeneous rational points
00558         int,  // count
00559         int,  // stride
00560         const float*
00561         );
00562 
00563 ON_DECL
00564 ON_BOOL32 ON_IsValidPointList(
00565         int,  // dim
00566         ON_BOOL32, // true for homogeneous rational points
00567         int,  // count
00568         int,  // stride
00569         const double*
00570         );
00571 
00572 /*
00573 Description:
00574   Determine if a list of points is planar.
00575 Parameters:
00576   bRational - [in]
00577     false if the points are euclidean (x,y,z)
00578     true if the points are homogeneous rational (x,y,z,w)
00579   point_count - [in]
00580     number of points
00581   point_stride - [in]
00582     number of doubles between point x coordinates
00583     first point's x coordinate = points[0],
00584     second point's x coordinate = points[point_stride],...
00585   points - [in]
00586     point coordinates (3d or 4d homogeneous rational)
00587   boxMin - [in]
00588   boxMax - [in]
00589     optional 3d bounding box - pass nulls if not readily available
00590   tolerance - [in] >= 0.0
00591   plane_equation0 - [in]
00592     If you want to test for planarity in a specific plane,
00593     pass the plane equation in here.  If you want to find
00594     a plane containing the points, pass null here.
00595   plane_equation - [out]
00596     If this point is not null, then the equation of the plane
00597     containing the points is retuened here.
00598 Returns:
00599   0 - points are not coplanar to the specified tolerance
00600   1 - points are coplanar to the specified tolerance
00601   2 - points are colinear to the specified tolerance
00602       (in this case, plane_equation is not a unique answer)
00603   3 - points are coincident to the specified tolerance
00604       (in this case, plane_equation is not a unique answer)
00605 */
00606 ON_DECL
00607 int ON_IsPointListPlanar(
00608     bool bRational,
00609     int count,
00610     int stride,
00611     const double* points,
00612     const double* boxMin,
00613     const double* boxMax,
00614     double tolerance,
00615     ON_PlaneEquation* plane_equation
00616     );
00617 
00618 ON_DECL
00619 ON_BOOL32 ON_IsValidPointGrid(
00620         int,  // dim
00621         ON_BOOL32, // true for homogeneous rational points
00622         int, int, // point_count0, point_count1,
00623         int, int, // point_stride0, point_stride1,
00624         const double*
00625         );
00626 
00627 ON_DECL
00628 bool ON_ReversePointList(
00629         int,  // dim
00630         ON_BOOL32, // true for homogeneous rational points
00631         int,  // count
00632         int,  // stride
00633         double*
00634         );
00635 
00636 ON_DECL
00637 ON_BOOL32 ON_ReversePointGrid(
00638         int,  // dim
00639         ON_BOOL32, // true for homogeneous rational points
00640         int, int, // point_count0, point_count1,
00641         int, int, // point_stride0, point_stride1,
00642         double*,
00643         int       // dir = 0 or 1
00644         );
00645 
00646 ON_DECL
00647 bool ON_SwapPointListCoordinates( 
00648         int, // count
00649         int, // stride
00650         float*,
00651         int, int // coordinates to swap
00652         );
00653 
00654 ON_DECL
00655 bool ON_SwapPointListCoordinates( 
00656         int, // count
00657         int, // stride
00658         double*,
00659         int, int // coordinates to swap
00660         );
00661 
00662 ON_DECL
00663 ON_BOOL32 ON_SwapPointGridCoordinates(
00664         int, int, // point_count0, point_count1,
00665         int, int, // point_stride0, point_stride1,
00666         double*,
00667         int, int // coordinates to swap
00668         );
00669 
00670 ON_DECL
00671 bool ON_TransformPointList(
00672         int,  // dim
00673         ON_BOOL32, // true for homogeneous rational points
00674         int,  // count
00675         int,  // stride
00676         float*,
00677         const ON_Xform&
00678         );
00679 
00680 ON_DECL
00681 bool ON_TransformPointList(
00682         int,  // dim
00683         ON_BOOL32, // true for homogeneous rational points
00684         int,  // count
00685         int,  // stride
00686         double*,
00687         const ON_Xform&
00688         );
00689 
00690 ON_DECL
00691 ON_BOOL32 ON_TransformPointGrid(
00692         int,      // dim
00693         ON_BOOL32,     // true for homogeneous rational points
00694         int, int, // point_count0, point_count1,
00695         int, int, // point_stride0, point_stride1,
00696         double*,
00697         const ON_Xform&
00698         );
00699 
00700 ON_DECL
00701 ON_BOOL32 ON_TransformVectorList(
00702        int,  // dim
00703        int,  // count
00704        int,  // stride
00705        float*,
00706        const ON_Xform&
00707        );
00708 
00709 ON_DECL
00710 ON_BOOL32 ON_TransformVectorList(
00711        int,  // dim
00712        int,  // count
00713        int,  // stride
00714        double*,
00715        const ON_Xform&
00716        );
00717 
00718 /*
00719 Parameters:
00720   dim - [in]
00721     >= 1
00722   is_rat - [in]
00723     true if the points are rational and points[dim] is the "weight"
00724   pointA - [in]
00725   pointB - [in]
00726     point coordinates
00727 Returns:
00728   True if the input is valid and for each coordinate pair,
00729   |a-b| <= ON_ZERO_TOLERANCE 
00730   or |a-b| <= (fabs(a)+fabs(b))*ON_RELATIVE_TOLERANCE.
00731   False otherwise.
00732 */
00733 ON_DECL
00734 bool ON_PointsAreCoincident(
00735     int dim,
00736     int is_rat,
00737     const double* pointA,
00738     const double* pointB
00739     );
00740 
00741 /*
00742 Description
00743   See ON_PointsAreCoincident() for a description of when opennurbs
00744   considers two points to be conincident.
00745 Parameters:
00746   dim - [in]
00747     >= 1
00748   is_rat - [in]
00749     true if the points are rational and points[dim] is the "weight"
00750   point_count - [in]
00751     number of points >= 2
00752   point_stride - [in]
00753     >= (0 != is_rat) ? (dim+1) : dim
00754   points - [in]
00755     point coordinates
00756 Returns:
00757   True if the first and last points are coincident and all other
00758   points in the list are coincident with the previous point.
00759   False if there are points that are not coincident or
00760   point_count < 2 or other input parameters are invalid.
00761 */
00762 ON_DECL
00763 bool ON_PointsAreCoincident(
00764     int dim,
00765     int is_rat,
00766     int point_count,
00767     int point_stride,
00768     const double* points
00769     );
00770 
00771 ON_DECL
00772 int ON_ComparePoint( // returns 
00773                               // -1: first < second
00774                               //  0: first == second
00775                               // +1: first > second
00776           int dim,            // dim (>=0)
00777           ON_BOOL32 israt,    // true for rational CVs
00778           const double* cv0,  // first CV
00779           const double* cv1   // secont CV
00780           );
00781 
00782 ON_DECL
00783 int ON_ComparePointList( // returns 
00784                               // -1: first < second
00785                               //  0: first == second
00786                               // +1: first > second
00787           int,           // dim (>=0)
00788           ON_BOOL32,          // true for rational CVs
00789           int,           // count
00790           // first point list
00791           int,           // stride
00792           const double*, // point
00793           // second point list
00794           int,           // stride
00795           const double*  // point
00796           );
00797 
00798 ON_DECL
00799 ON_BOOL32 ON_IsPointListClosed(
00800        int,  // dim
00801        int,  // true for homogeneos rational points
00802        int,  // count
00803        int,  // stride
00804        const double*
00805        );
00806 
00807 ON_DECL
00808 ON_BOOL32 ON_IsPointGridClosed(
00809         int,  // dim
00810         ON_BOOL32, // true for homogeneous rational points
00811         int, int, // point_count0, point_count1,
00812         int, int, // point_stride0, point_stride1,
00813         const double*,
00814         int       // dir = 0 or 1
00815        );
00816 
00817 ON_DECL
00818 int ON_SolveQuadraticEquation( // solve a*X^2 + b*X + c = 0
00819         // returns 0: two distinct real roots (r0 < r1)
00820         //         1: one real root (r0 = r1)
00821         //         2: two complex conjugate roots (r0 +/- (r1)*sqrt(-1))
00822         //        -1: failure - a = 0, b != 0        (r0 = r1 = -c/b)
00823         //        -2: failure - a = 0, b  = 0 c != 0 (r0 = r1 = 0.0)
00824         //        -3: failure - a = 0, b  = 0 c  = 0 (r0 = r1 = 0.0)
00825        double, double, double, // a, b, c
00826        double*, double*        // roots r0 and r1 returned here
00827        );
00828 
00829 ON_DECL
00830 ON_BOOL32 ON_SolveTriDiagonal( // solve TriDiagMatrix( a,b,c )*X = d
00831         int,               // dimension of d and X (>=1)
00832         int,               // number of equations (>=2)
00833         double*,           // a[n-1] = sub-diagonal (a is modified)
00834         const double*,     // b[n] = diagonal
00835         double*,           // c[n-1] = supra-diagonal
00836         const double*,     // d[n*dim]
00837         double*            // X[n*dim] = unknowns
00838         );
00839 
00840 // returns rank - if rank != 2, system is under determined
00841 // If rank = 2, then solution to 
00842 //
00843 //          a00*x0 + a01*x1 = b0, 
00844 //          a10*x0 + a11*x1 = b1 
00845 //
00846 // is returned
00847 ON_DECL
00848 int ON_Solve2x2( 
00849         double, double,   // a00 a01 = first row of 2x2 matrix
00850         double, double,   // a10 a11 = second row of 2x2 matrix
00851         double, double,   // b0 b1
00852         double*, double*, // x0, x1 if not NULL, then solution is returned here
00853         double*           // if not NULL, then pivot_ratio returned here
00854         );
00855 
00856 // Description:
00857 //   Solves a system of 3 linear equations and 2 unknowns.
00858 //
00859 //          x*col0[0] + y*col1[0] = d0
00860 //          x*col0[1] + y*col1[1] = d0
00861 //          x*col0[2] + y*col1[2] = d0
00862 //
00863 // Parameters:
00864 //   col0 - [in] coefficents for "x" unknown
00865 //   col1 - [in] coefficents for "y" unknown
00866 //   d0 - [in] constants
00867 //   d1 - [in]
00868 //   d2 - [in]
00869 //   x - [out]
00870 //   y - [out]
00871 //   error - [out]
00872 //   pivot_ratio - [out]
00873 //
00874 // Returns:
00875 //   rank of the system.  
00876 //   If rank != 2, system is under determined
00877 //   If rank = 2, then the solution is
00878 //
00879 //         (*x)*[col0] + (*y)*[col1]
00880 //         + (*error)*((col0 X col1)/|col0 X col1|)
00881 //         = (d0,d1,d2).
00882 ON_DECL
00883 int ON_Solve3x2( 
00884         const double[3], // col0
00885         const double[3], // col1
00886         double,  // d0
00887         double,  // d1
00888         double,  // d2
00889         double*, // x
00890         double*, // y
00891         double*, // error
00892         double*  // pivot_ratio
00893         );
00894 
00895 /* 
00896 Description:
00897   Use Gauss-Jordan elimination with full pivoting to solve 
00898   a system of 3 linear equations and 3 unknowns(x,y,z)
00899 
00900         x*row0[0] + y*row0[1] + z*row0[2] = d0
00901         x*row1[0] + y*row1[1] + z*row1[2] = d1
00902         x*row2[0] + y*row2[1] + z*row2[2] = d2
00903 
00904 Parameters:
00905     row0 - [in] first row of 3x3 matrix
00906     row1 - [in] second row of 3x3 matrix
00907     row2 - [in] third row of 3x3 matrix
00908     d0 - [in] 
00909     d1 - [in] 
00910     d2 - [in] (d0,d1,d2) right hand column of system
00911     x_addr - [in] first unknown
00912     y_addr - [in] second unknown
00913     z_addr - [in] third unknown
00914     pivot_ratio - [out] if not NULL, the pivot ration is 
00915          returned here.  If the pivot ratio is "small",
00916          then the matrix may be singular or ill 
00917          conditioned. You should test the results 
00918          before you use them.  "Small" depends on the
00919          precision of the input coefficients and the
00920          use of the solution.  If you can't figure out
00921          what "small" means in your case, then you
00922          must check the solution before you use it.
00923 
00924 Returns:
00925     The rank of the 3x3 matrix (0,1,2, or 3)
00926     If ON_Solve3x3() is successful (returns 3), then
00927     the solution is returned in 
00928     (*x_addr, *y_addr, *z_addr)
00929     and *pivot_ratio = min(|pivots|)/max(|pivots|).
00930     If the return code is < 3, then (0,0,0) is returned
00931     as the "solution".
00932 
00933 See Also:
00934   ON_Solve2x2
00935   ON_Solve3x2
00936   ON_Solve4x4
00937 */
00938 ON_DECL
00939 int ON_Solve3x3( 
00940         const double row0[3], 
00941         const double row1[3], 
00942         const double row2[3],
00943         double d0, 
00944         double d1, 
00945         double d2,
00946         double* x_addr, 
00947         double* y_addr, 
00948         double* z_addr,
00949         double* pivot_ratio
00950         );
00951 
00952 /* 
00953 Description:
00954   Use Gauss-Jordan elimination with full pivoting to solve 
00955   a system of 4 linear equations and 4 unknowns(x,y,z,w)
00956 
00957         x*row0[0] + y*row0[1] + z*row0[2] + w*row0[3] = d0
00958         x*row1[0] + y*row1[1] + z*row1[2] + w*row1[3] = d1
00959         x*row2[0] + y*row2[1] + z*row2[2] + w*row2[3] = d2
00960         x*row3[0] + y*row3[1] + z*row3[2] + w*row3[2] = d3
00961 
00962 Parameters:
00963     row0 - [in] first row of 4x4 matrix
00964     row1 - [in] second row of 4x4 matrix
00965     row2 - [in] third row of 4x4 matrix
00966     row3 - [in] forth row of 4x4 matrix
00967     d0 - [in] 
00968     d1 - [in] 
00969     d2 - [in] 
00970     d3 - [in] (d0,d1,d2,d3) right hand column of system
00971     x_addr - [in] first unknown
00972     y_addr - [in] second unknown
00973     z_addr - [in] third unknown
00974     w_addr - [in] forth unknown
00975     pivot_ratio - [out] if not NULL, the pivot ration is 
00976          returned here.  If the pivot ratio is "small",
00977          then the matrix may be singular or ill 
00978          conditioned. You should test the results 
00979          before you use them.  "Small" depends on the
00980          precision of the input coefficients and the
00981          use of the solution.  If you can't figure out
00982          what "small" means in your case, then you
00983          must check the solution before you use it.
00984 
00985 Returns:
00986     The rank of the 4x4 matrix (0,1,2,3, or 4)
00987     If ON_Solve4x4() is successful (returns 4), then
00988     the solution is returned in 
00989     (*x_addr, *y_addr, *z_addr, *w_addr)
00990     and *pivot_ratio = min(|pivots|)/max(|pivots|).
00991     If the return code is < 4, then, it a solution exists,
00992     on is returned.  However YOU MUST CHECK THE SOLUTION
00993     IF THE RETURN CODE IS < 4.
00994 
00995 See Also:
00996   ON_Solve2x2
00997   ON_Solve3x2
00998   ON_Solve3x3
00999 */
01000 ON_DECL
01001 int
01002 ON_Solve4x4(
01003           const double row0[4], 
01004           const double row1[4], 
01005           const double row2[4],  
01006           const double row3[4],
01007           double d0, 
01008           double d1, 
01009           double d2, 
01010           double d3,
01011           double* x_addr, 
01012           double* y_addr, 
01013           double* z_addr, 
01014           double* w_addr,
01015           double* pivot_ratio
01016           );
01017 
01018 /*
01019 Description:
01020   Use Gauss-Jordan elimination to find a numerical 
01021   solution to M*X = B where M is a n x n matrix,
01022   B is a known n-dimensional vector and X is
01023   an unknown.
01024 Paramters:
01025   bFullPivot - [in] if true, full pivoting is used,
01026     otherwise partial pivoting is used.  In rare
01027     cases full pivoting can produce a more accurate
01028     answer and never produces a less accurate answer.
01029     However full pivoting is slower.  If speed is an
01030     issue, then experiement with bFullPivot=false
01031     and see if it makes a difference.  Otherwise,
01032     set it to true.
01033   bNormalize - [in]
01034     If bNormalize is true, then the rows of the
01035     matrix are scaled so the sum of their squares
01036     is one.  This doesn't make the solution more
01037     accurate but in some cases it makes the pivot
01038     ratio more meaningful.  Set bNormalize to
01039     false unless you have a reason for setting it
01040     to true.
01041   n - [in] size of the matrix and vectors.
01042   M - [in] n x n matrix.  The values in M are
01043     changed as the solution is calculated.
01044     If you need to preserve M for future use,
01045     pass in a copy.
01046   B - [in] n-dimensional vector.  The values in
01047     B are changed as the solution is calculated.
01048     If you need to preserve B for future use,
01049     pass in a copy.
01050   X - [out] solution to M*X = B.
01051 Returns:
01052   If the returned value is <= 0.0, the input matrix
01053   has rank < n and no solution is returned in X.
01054   If the returned value is > 0.0, then a solution is
01055   returned in X and the returned value is the ratio
01056   (minimum pivot)/(maximum pivot).  This value is
01057   called the pivot ratio and will be denoted "pr"
01058   the discussion below. If pr <= 1e-15, then
01059   M was nearly degenerate and the solution should be
01060   used with caution.  If an accurate solution is
01061   critcial, then check the solution anytime pr <= 1e-10
01062   In general, the difference between M*X and B will be
01063   reasonably small.  However, when the pr is small
01064   there tend to be vector E, substantually different
01065   from zero, such that M*(X+E) - B is also reasonably
01066   small.
01067 See Also:
01068   ON_Solve2x2
01069   ON_Solve3x3
01070   ON_Solve4x4
01071   ON_Solve3x2
01072 */
01073 ON_DECL
01074 double ON_SolveNxN(bool bFullPivot, bool bNormalize, int n, double* M[], double B[], double X[]);
01075 
01076 
01077 // return false if determinant is (nearly) singular
01078 ON_DECL
01079 ON_BOOL32 ON_EvJacobian( 
01080         double, // ds o ds
01081         double, // ds o dt
01082         double, // dt o dt
01083         double* // jacobian = determinant ( ds_o_ds dt_o_dt / ds_o_dt ds_o_dt )
01084         );
01085 
01086 /*
01087 Description:
01088   Finds scalars x and y so that the component of V in the plane
01089   of A and B is x*A + y*B.
01090 Parameters:
01091   V - [in]
01092   A - [in] nonzero and not parallel to B
01093   B - [in] nonzero and not parallel to A
01094   x - [out]
01095   y - [out]
01096 Returns:
01097   1 - The rank of the problem is 2.  The decomposition is unique.
01098         0 - The rank less than 2.  Either there is no solution or there
01099                         are infinitely many solutions.
01100 
01101 See Also:
01102   ON_Solve2x2
01103 */
01104 ON_DECL
01105 int ON_DecomposeVector(
01106         const ON_3dVector& V,
01107         const ON_3dVector& A,
01108         const ON_3dVector& B,
01109         double* x, double* y
01110         );
01111 
01112 
01113 /*
01114 Description:
01115    Evaluate partial derivatives of surface unit normal
01116 Parameters:
01117   ds - [in]
01118   dt - [in] surface first partial derivatives
01119   dss - [in]
01120   dst - [in]
01121   dtt - [in] surface second partial derivatives
01122   ns - [out]
01123   nt - [out] First partial derivatives of surface unit normal
01124              (If the Jacobian is degenerate, ns and nt are set to zero.)
01125 Returns:
01126   true if Jacobian is nondegenerate
01127   false if Jacobian is degenerate
01128 */
01129 ON_DECL
01130 ON_BOOL32 ON_EvNormalPartials(
01131         const ON_3dVector& ds,
01132         const ON_3dVector& dt,
01133         const ON_3dVector& dss,
01134         const ON_3dVector& dst,
01135         const ON_3dVector& dtt,
01136         ON_3dVector& ns,
01137         ON_3dVector& nt
01138         );
01139 
01140 ON_DECL
01141 ON_BOOL32 
01142 ON_Pullback3dVector( // use to pull 3d vector back to surface parameter space
01143       const ON_3dVector&,   // 3d vector
01144       double,              // signed distance from vector location to closet point on surface
01145                                     // < 0 if point is below with respect to Du x Dv
01146       const ON_3dVector&,     // ds      surface first partials
01147       const ON_3dVector&,     // dt
01148       const ON_3dVector&,     // dss     surface 2nd partials
01149       const ON_3dVector&,     // dst     (used only when dist != 0)
01150       const ON_3dVector&,     // dtt
01151       ON_2dVector&            // pullback
01152       );
01153 
01154 ON_DECL
01155 ON_BOOL32 
01156 ON_GetParameterTolerance(
01157         double,   // t0      domain
01158         double,   // t1 
01159         double,   // t       parameter in domain
01160         double*,  // tminus  parameter tolerance (tminus, tplus) returned here
01161         double*   // tplus
01162         );
01163 
01164 
01165 ON_DECL
01166 ON_BOOL32 ON_EvNormal(
01167         int, // limit_dir 0=default,1=from quadrant I, 2 = from quadrant II, ...
01168         const ON_3dVector&, const ON_3dVector&, // first partials (Du,Dv)
01169         const ON_3dVector&, const ON_3dVector&, const ON_3dVector&, // optional second partials (Duu, Duv, Dvv)
01170         ON_3dVector& // unit normal returned here
01171         );
01172 
01173 // returns false if first returned tangent is zero
01174 ON_DECL
01175 bool ON_EvTangent(
01176         const ON_3dVector&, // first derivative
01177         const ON_3dVector&, // second derivative
01178         ON_3dVector&        // Unit tangent returned here
01179         );
01180 
01181 // returns false if first derivtive is zero
01182 ON_DECL
01183 ON_BOOL32 ON_EvCurvature(
01184         const ON_3dVector&, // first derivative
01185         const ON_3dVector&, // second derivative
01186         ON_3dVector&,       // Unit tangent returned here
01187         ON_3dVector&        // Curvature returned here
01188         );
01189 
01190 ON_DECL
01191 ON_BOOL32 ON_EvPrincipalCurvatures( 
01192         const ON_3dVector&, // Ds,
01193         const ON_3dVector&, // Dt,
01194         const ON_3dVector&, // Dss,
01195         const ON_3dVector&, // Dst,
01196         const ON_3dVector&, // Dtt,
01197         const ON_3dVector&, // N,   // unit normal to surface (use ON_EvNormal())
01198         double*, // gauss,  // = Gaussian curvature = kappa1*kappa2
01199         double*, // mean,   // = mean curvature = (kappa1+kappa2)/2
01200         double*, // kappa1, // = largest principal curvature value (may be negative)
01201         double*, // kappa2, // = smallest principal curvature value (may be negative)
01202         ON_3dVector&, // K1,     // kappa1 unit principal curvature direction
01203         ON_3dVector&  // K2      // kappa2 unit principal curvature direction
01204                         // output K1,K2,N is right handed frame
01205         );
01206 
01207 ON_DECL
01208 ON_BOOL32 ON_EvPrincipalCurvatures( 
01209         const ON_3dVector&, // Ds,
01210         const ON_3dVector&, // Dt,
01211         double l, // Dss*N Second fundamental form coefficients
01212         double m, // Dst*N,
01213         double n, // Dtt*N,
01214         const ON_3dVector&, // N,   // unit normal to surface (use ON_EvNormal())
01215         double*, // gauss,  // = Gaussian curvature = kappa1*kappa2
01216         double*, // mean,   // = mean curvature = (kappa1+kappa2)/2
01217         double*, // kappa1, // = largest principal curvature value (may be negative)
01218         double*, // kappa2, // = smallest principal curvature value (may be negative)
01219         ON_3dVector&, // K1,     // kappa1 unit principal curvature direction
01220         ON_3dVector&  // K2      // kappa2 unit principal curvature direction
01221                         // output K1,K2,N is right handed frame
01222         );
01223 
01224 /*
01225 Description:
01226   Evaluate sectional curvature from surface derivatives and 
01227   section plane normal.
01228 Parameters:
01229   S10, S01 - [in]
01230     surface 1st partial derivatives
01231   S20, S11, S02 - [in]
01232     surface 2nd partial derivatives
01233   planeNormal - [in]
01234     unit normal to section plane
01235   K - [out] Sectional curvature
01236     Curvature of the intersection curve of the surface
01237     and plane through the surface point where the partial
01238     derivatives were evaluationed.
01239 Returns:
01240   True if successful.
01241   False if first partials are not linearly independent, in
01242   which case the K is set to zero.
01243 */
01244 ON_DECL
01245 bool ON_EvSectionalCurvature( 
01246     const ON_3dVector& S10, 
01247     const ON_3dVector& S01,
01248     const ON_3dVector& S20, 
01249     const ON_3dVector& S11, 
01250     const ON_3dVector& S02,
01251     const ON_3dVector& planeNormal,
01252     ON_3dVector& K 
01253     );
01254 
01255 
01256 ON_DECL
01257 ON_3dVector ON_NormalCurvature( 
01258         const ON_3dVector&, // surface 1rst partial (Ds)
01259         const ON_3dVector&, // surface 1rst partial (Dt)
01260         const ON_3dVector&, // surface 1rst partial (Dss)
01261         const ON_3dVector&, // surface 1rst partial (Dst)
01262         const ON_3dVector&, // surface 1rst partial (Dtt)
01263         const ON_3dVector&, // surface unit normal
01264         const ON_3dVector&  // unit tangent direction
01265         );
01266 
01267 /*
01268 Description:
01269   Determing if two curvatrues are different enough
01270   to qualify as a curvature discontinuity.
01271 Parameters:
01272   Km - [in]
01273   Kp - [in]
01274     Km and Kp should be curvatures evaluated at the same
01275     parameters using limits from below (minus) and above (plus).
01276     The assumption is that you have already compared the
01277     points and tangents and consider to curve to be G1 at the
01278     point in question.
01279   cos_angle_tolerance - [in]
01280     If the inut value of cos_angle_tolerance >= -1.0
01281     and cos_angle_tolerance <= 1.0 and
01282     Km o Kp < cos_angle_tolerance*|Km|*|Kp|, then
01283     true is returned.  Otherwise it is assumed Km and Kp
01284     are parallel. If the curve being tested is nonplanar,
01285     then use something like cos(2*tangent angle tolerance)
01286     for this parameter. If the curve being tested is planar,
01287     then 0.0 will work fine.
01288   curvature_tolerance - [in]
01289     If |Kp-Km| <= curvature_tolerance,
01290     then false is returned, otherwise other tests are used
01291     to determing continuity.
01292   zero_curvature - [in] (ignored if < 2^-110 = 7.7037197787136e-34)
01293     If |K| <= zero_curvature, then K is treated as zero.
01294     When in doubt, use ON_ZERO_CURVATURE_TOLERANCE.
01295   radius_tolerance - [in]
01296     If radius_tolerance >= 0.0 and the difference between the
01297     radii of curvature is >= radius_tolerance, then true 
01298     is returned.
01299   relative_tolerance - [in]
01300     If relative_tolerance > 0 and
01301     |(|Km| - |Kp|)|/max(|Km|,|Kp|) > relative_tolerance,
01302     then true is returned.  Note that if the curvatures are
01303     nonzero and rm and rp are the radii of curvature, then
01304     |(|Km| - |Kp|)|/max(|Km|,|Kp|) = |rm-rp|/max(rm,rp).
01305     This means the relative_tolerance insures both the scalar
01306     curvature and the radii of curvature agree to the specified
01307     number of decimal places.
01308     When in double use ON_RELATIVE_CURVATURE_TOLERANCE, which
01309     is currently 0.05.
01310 Returns:
01311   False if the curvatures should be considered G2.
01312   True if the curvatures are different enough that the curve should be
01313   considered not G2.  
01314   In addition to the tests described under the curvature_tolerance and 
01315   radius_tolerance checks, other hurestic tests are used.
01316 */
01317 ON_DECL
01318 bool ON_IsCurvatureDiscontinuity( 
01319   const ON_3dVector Km, 
01320   const ON_3dVector Kp,
01321   double cos_angle_tolerance,
01322   double curvature_tolerance,
01323   double zero_curvature,
01324   double radius_tolerance,
01325   double relative_tolerance
01326   );
01327 
01328 ON_DECL
01329 bool ON_IsCurvatureDiscontinuity( 
01330   const ON_3dVector Km, 
01331   const ON_3dVector Kp,
01332   double cos_angle_tolerance,
01333   double curvature_tolerance,
01334   double zero_curvature,
01335   double radius_tolerance
01336   );
01337 
01338 
01339 /*
01340 Description:
01341   This function is used to test curvature continuity
01342   in IsContinuous and GetNextDiscontinuity functions
01343   when the continuity parameter is ON::G2_continuous.
01344 Parameters:
01345   Km - [in]
01346     Curve's vector curvature evaluated from below
01347   Kp - [in]
01348     Curve's vector curvature evaluated from below
01349 Returns:
01350   True if the change from Km to Kp should be considered
01351   G2 continuous.
01352 */
01353 ON_DECL
01354 bool ON_IsG2CurvatureContinuous(
01355   const ON_3dVector Km, 
01356   const ON_3dVector Kp,
01357   double cos_angle_tolerance,
01358   double curvature_tolerance
01359   );
01360 
01361 /*
01362 Description:
01363   This function is used to test curvature continuity
01364   in IsContinuous and GetNextDiscontinuity functions
01365   when the continuity parameter is ON::Gsmooth_continuous.
01366 Parameters:
01367   Km - [in]
01368     Curve's vector curvature evaluated from below
01369   Kp - [in]
01370     Curve's vector curvature evaluated from below
01371 Returns:
01372   True if the change from Km to Kp should be considered
01373   Gsmooth continuous.
01374 */
01375 ON_DECL
01376 bool ON_IsGsmoothCurvatureContinuous(
01377   const ON_3dVector Km, 
01378   const ON_3dVector Kp,
01379   double cos_angle_tolerance,
01380   double curvature_tolerance
01381   );
01382 
01383 /*
01384 Description:
01385   Test curve continuity from derivative values.
01386 Parameters:
01387   c - [in] type of continuity to test for. Read ON::continuity
01388            comments for details.
01389   Pa - [in] point on curve A.
01390   D1a - [in] first derviative of curve A.
01391   D2a - [in] second derviative of curve A.
01392   Pb - [in] point on curve B.
01393   D1b - [in] first derviative of curve B.
01394   D3b - [in] second derviative of curve B.
01395   point_tolerance - [in] if the distance between two points is
01396       greater than point_tolerance, then the curve is not C0.
01397   d1_tolerance - [in] if the difference between two first derivatives is
01398       greater than d1_tolerance, then the curve is not C1.
01399   d2_tolerance - [in] if the difference between two second derivatives is
01400       greater than d2_tolerance, then the curve is not C2.
01401   cos_angle_tolerance - [in] default = cos(1 degree) Used only when
01402       c is ON::G1_continuous or ON::G2_continuous.  If the cosine
01403       of the angle between two tangent vectors 
01404       is <= cos_angle_tolerance, then a G1 discontinuity is reported.
01405   curvature_tolerance - [in] (default = ON_SQRT_EPSILON) Used only when
01406       c is ON::G2_continuous.  If K0 and K1 are curvatures evaluated
01407       from above and below and |K0 - K1| > curvature_tolerance,
01408       then a curvature discontinuity is reported.
01409 Returns:
01410   true if the curve has at least the c type continuity at 
01411   the parameter t.
01412 */
01413 ON_DECL
01414 ON_BOOL32 ON_IsContinuous(
01415   ON::continuity c,
01416   ON_3dPoint Pa,
01417   ON_3dVector D1a,
01418   ON_3dVector D2a,
01419   ON_3dPoint Pb,
01420   ON_3dVector D1b,
01421   ON_3dVector D2b,
01422   double point_tolerance=ON_ZERO_TOLERANCE,
01423   double d1_tolerance=ON_ZERO_TOLERANCE,
01424   double d2_tolerance=ON_ZERO_TOLERANCE,
01425   double cos_angle_tolerance=ON_DEFAULT_ANGLE_TOLERANCE_COSINE,
01426   double curvature_tolerance=ON_SQRT_EPSILON
01427   );
01428 
01429 
01430 ON_DECL
01431 bool ON_TuneupEvaluationParameter( 
01432    int side,
01433    double s0, double s1, // segment domain
01434    double *s             // segment parameter
01435    );
01436 
01437 
01438 ON_DECL
01439 int ON_Compare2dex( const ON_2dex* a, const ON_2dex* b);
01440 
01441 ON_DECL
01442 int ON_Compare3dex( const ON_3dex* a, const ON_3dex* b);
01443 
01444 ON_DECL
01445 int ON_Compare4dex( const ON_4dex* a, const ON_4dex* b);
01446 
01447 ON_DECL
01448 const ON_2dex* ON_BinarySearch2dexArray( 
01449           int key_i, 
01450           const ON_2dex* base, 
01451           size_t nel
01452           );
01453 
01454 // These simple intersectors are fast and detect transverse intersections.
01455 // If the intersection is not a simple transverse case, then they
01456 // return false and you will have to use one of the slower but fancier
01457 // models.
01458 
01459 // returns closest points between the two infinite lines
01460 ON_DECL
01461 bool ON_Intersect( 
01462           const ON_Line&, 
01463           const ON_Line&, 
01464           double*, // parameter on first line
01465           double*  // parameter on second line
01466           );
01467 
01468 // Returns false unless intersection is a single point
01469 // If returned parameter is < 0 or > 1, then the line
01470 // segment between line.m_point[0] and line.m_point[1]
01471 // does not intersect the plane
01472 ON_DECL
01473 bool ON_Intersect( 
01474           const ON_Line&, 
01475           const ON_Plane&, 
01476           double* // parameter on line
01477           );
01478 
01479 ON_DECL
01480 bool ON_Intersect( 
01481         const ON_Plane&, 
01482         const ON_Plane&, 
01483         ON_Line& // intersection line is returned here
01484         );
01485 
01486 ON_DECL
01487 bool ON_Intersect( 
01488         const ON_Plane&, 
01489         const ON_Plane&, 
01490         const ON_Plane&,
01491         ON_3dPoint& // intersection point is returned here
01492         );
01493 
01494 // returns 0 = no intersections, 
01495 // 1 = intersection = single point, 
01496 // 2 = intersection = circle
01497 // If 0 is returned, returned circle has radius=0
01498 // and center = point on sphere closest to plane.
01499 // If 1 is returned, intersection is a single
01500 // point and returned circle has radius=0
01501 // and center = intersection point on sphere.
01502 ON_DECL
01503 int ON_Intersect( 
01504                  const ON_Plane&, const ON_Sphere&, ON_Circle&
01505                   );
01506 
01507 // Intersects an infinte line and sphere and returns 
01508 // 0 = no intersections, 
01509 // 1 = one intersection, 
01510 // 2 = 2 intersections
01511 // If 0 is returned, first point is point 
01512 // on line closest to sphere and 2nd point is the point
01513 // on the sphere closest to the line.
01514 // If 1 is returned, first point is obtained by evaluating
01515 // the line and the second point is obtained by evaluating
01516 // the sphere.
01517 ON_DECL
01518 int ON_Intersect(                  
01519         const ON_Line&, 
01520         const ON_Sphere&,
01521         ON_3dPoint&, 
01522         ON_3dPoint& // intersection point(s) returned here
01523         );
01524 
01525 
01526 // Intersects an infinte line and cylinder and returns 
01527 // 0 = no intersections, 
01528 // 1 = one intersection, 
01529 // 2 = 2 intersections
01530 // 3 = line lies on cylinder
01531 //
01532 // If 0 is returned, first point is point 
01533 // on line closest to cylinder and 2nd point is the point
01534 // on the cylinder closest to the line.
01535 // If 1 is returned, first point is obtained by evaluating
01536 // the line and the second point is obtained by evaluating
01537 // the cylinder.
01538 //
01539 // The value of cylinder.IsFinite() determines if the
01540 // intersection is performed on the finite or infinite cylinder.
01541 ON_DECL
01542 int ON_Intersect( 
01543       const ON_Line&, // [in]
01544       const ON_Cylinder&, // [in]
01545       ON_3dPoint&, // [out] first intersection point
01546       ON_3dPoint& // [out] second intersection point
01547       );
01548 
01549 // Description:
01550 //   Intersect an infinte line and circle.
01551 // Parameters:
01552 //   line - [in]
01553 //   circle - [in]
01554 //   line_t0 - [out] line parameter of first intersection point
01555 //   circle_point0 - [out] first intersection point on circle
01556 //   line_t1 - [out] line parameter of second intersection point
01557 //   circle_point1 - [out] second intersection point on circle
01558 // Returns:
01559 //   0     No intersection
01560 //   1     One intersection at line.PointAt(*line_t0)
01561 //   2     Two intersections at line.PointAt(*line_t0)
01562 //         and line.PointAt(*line_t1).
01563 ON_DECL
01564 int ON_Intersect( 
01565                   const ON_Line& line, 
01566                   const ON_Circle& circle,
01567                   double* line_t0,
01568                   ON_3dPoint& circle_point0,
01569                   double* line_t1,
01570                   ON_3dPoint& circle_point1
01571                   );
01572 
01573 
01574 
01575 // Description:
01576 //   Intersect a infinte line and arc.
01577 // Parameters:
01578 //   line - [in]
01579 //   arc - [in]
01580 //   line_t0 - [out] line parameter of first intersection point
01581 //   arc_point0 - [out] first intersection point on arc
01582 //   line_t1 - [out] line parameter of second intersection point
01583 //   arc_point1 - [out] second intersection point on arc
01584 // Returns:
01585 //   0     No intersection
01586 //   1     One intersection at line.PointAt(*line_t0)
01587 //   2     Two intersections at line.PointAt(*line_t0)
01588 //         and line.PointAt(*line_t1).
01589 ON_DECL
01590 int ON_Intersect( 
01591                   const ON_Line& line, 
01592                   const ON_Arc& arc,
01593                   double* line_t0,
01594                   ON_3dPoint& arc_point0,
01595                   double* line_t1,
01596                   ON_3dPoint& arc_point1
01597                   );
01598 
01599 // Description:
01600 //   Intersect a plane and a circle.
01601 // Parameters:
01602 //   plane - [in]
01603 //   circle - [in]
01604 //   point0 - [out] first intersection point 
01605 //   point1 - [out] second intersection point
01606 // Returns:
01607 //   0     No intersection
01608 //   1     One intersection at point0
01609 //   2     Two intersections at point0
01610 //         and point1.
01611 //       3               Circle lies on plane
01612 ON_DECL
01613 int ON_Intersect( 
01614                   const ON_Plane& plane, 
01615                   const ON_Circle& circle,
01616                   ON_3dPoint& point0,
01617                   ON_3dPoint& point1
01618                   );
01619 
01620 // Description:
01621 //   Intersect a plane and an arc.
01622 // Parameters:
01623 //   plane - [in]
01624 //   arc - [in]
01625 //   point0 - [out] first intersection point 
01626 //   point1 - [out] second intersection point
01627 // Returns:
01628 //   0     No intersection
01629 //   1     One intersection at point0
01630 //   2     Two intersections at point0
01631 //         and point1.
01632 //       3               Arc lies on plane
01633 ON_DECL
01634 int ON_Intersect( 
01635                   const ON_Plane& plane, 
01636                   const ON_Arc& arc,
01637                   ON_3dPoint& point0,
01638                   ON_3dPoint& point1
01639                   );
01640 
01641 
01642 // returns 0 = no, 1 = yes, 2 = points are coincident and on line
01643 ON_DECL
01644 int ON_ArePointsOnLine(
01645         int, // dimension of points
01646         int, // is_rat = true if homogeneous rational
01647         int, // count = number of points
01648         int, // stride ( >= is_rat?(dim+1) :dim)
01649         const double*, // point array
01650         const ON_BoundingBox&, // if needed, use ON_GetBoundingBox(dim,is_rat,count,stride,point)
01651         const ON_Line&,
01652         double         // tolerance (if 0.0, a tolerance based on bounding box size is used)
01653         );
01654 
01655 // returns 0 = no, 1 = yes, 2 = points are coincident and on line
01656 ON_DECL
01657 int ON_ArePointsOnPlane(
01658         int, // dimension of points
01659         int, // is_rat = true if homogeneous rational
01660         int, // count = number of points
01661         int, // stride ( >= is_rat?(dim+1) :dim)
01662         const double*, // point array
01663         const ON_BoundingBox&, // if needed, use ON_GetBoundingBox(dim,is_rat,count,stride,point)
01664         const ON_Plane&,
01665         double         // tolerance (if 0.0, a tolerance based on bounding box size is used)
01666         );
01667 
01668 /*
01669 Description:
01670   Use the quotient rule to compute derivatives of a one parameter
01671   rational function F(t) = X(t)/W(t), where W is a scalar
01672   and F and X are vectors of dimension dim.
01673 Parameters:
01674   dim - [in]
01675   der_count - [in] number of derivative (>=0)
01676   v_stride - [in] (>= dim+1)
01677   v - [in/out]
01678     v[] is an array of length (der_count+1)*v_stride.
01679     The input v[] array contains  derivatives of the numerator and
01680     denominator functions in the order (X, W), (Xt, Wt), (Xtt, Wtt), ...
01681     In general, the (dim+1) coordinates of the d-th derivative 
01682     are in (v[n],...,v[n+dim]) where n = d*v_stride.
01683     In the output v[] array the derivatives of X are replaced with
01684     the derivatives of F and the derivatives of W are divided by
01685     w = v[dim].
01686 Returns:
01687   True if input is valid; i.e., v[dim] != 0.
01688 See Also:
01689   ON_EvaluateQuotientRule2
01690   ON_EvaluateQuotientRule3
01691 */
01692 ON_DECL
01693 bool ON_EvaluateQuotientRule( 
01694           int dim, 
01695           int der_count,
01696           int v_stride, 
01697           double *v 
01698           );
01699 
01700 /*
01701 Description:
01702   Use the quotient rule to compute partial derivatives of a two parameter
01703   rational function F(s,t) = X(s,t)/W(s,t), where W is a scalar
01704   and F and X are vectors of dimension dim.
01705 Parameters:
01706   dim - [in]
01707   der_count - [in] number of derivative (>=0)
01708   v_stride - [in] (>= dim+1)
01709   v - [in/out]
01710     v[] is an array of length (der_count+2)*(der_count+1)*v_stride.
01711     The input array contains derivatives of the numerator and denominator
01712                 functions in the order X, W, Xs, Ws, Xt, Wt, Xss, Wss, Xst, Wst, Xtt, Wtt, ...
01713     In general, the (i,j)-th derivatives are in the (dim+1) entries of v[]
01714                 v[k], ..., answer[k+dim], where k = ((i+j)*(i+j+1)/2 + j)*v_stride.
01715     In the output v[] array the derivatives of X are replaced with
01716     the derivatives of F and the derivatives of W are divided by
01717     w = v[dim].
01718 Returns:
01719   True if input is valid; i.e., v[dim] != 0.
01720 See Also:
01721   ON_EvaluateQuotientRule
01722   ON_EvaluateQuotientRule3
01723 */
01724 ON_DECL
01725 bool ON_EvaluateQuotientRule2( 
01726           int dim, 
01727           int der_count, 
01728           int v_stride, 
01729           double *v 
01730           );
01731 
01732 /*
01733 Description:
01734   Use the quotient rule to compute partial derivatives of a 3 parameter
01735   rational function F(r,s,t) = X(r,s,t)/W(r,s,t), where W is a scalar
01736   and F and X are vectors of dimension dim.
01737 Parameters:
01738   dim - [in]
01739   der_count - [in] number of derivative (>=0)
01740   v_stride - [in] (>= dim+1)
01741   v - [in/out]
01742     v[] is an array of length 
01743     v_stride*(der_count+1)*(der_count+2)*(der_count+3)/6.
01744     The input v[] array contains  derivatives of the numerator and
01745     denominator functions in the order (X, W), (Xr, Wr), (Xs, Ws),
01746     (Xt, Wt), (Xrr, Wrr), (Xrs, Wrs), (Xrt, Wrt), (Xss, Wss), 
01747     (Xst, Wst), (Xtt, Wtt), ...
01748     In general, the (dim+1) coordinates of the derivative 
01749     (Dr^i Ds^j Dt^k, i+j+k=d) are at v[n], ..., v[n+dim] where 
01750     n = v_stride*( d*(d+1)*(d+2)/6  +  (d-i)*(d-i+1)/2  +  k ).
01751     In the output v[] array the derivatives of X are replaced with
01752     the derivatives of F and the derivatives of W are divided by
01753     w = v[dim].
01754 Returns:
01755   True if input is valid; i.e., v[dim] != 0.
01756 See Also:
01757   ON_EvaluateQuotientRule
01758   ON_EvaluateQuotientRule2
01759 */
01760 ON_DECL
01761 bool ON_EvaluateQuotientRule3( 
01762           int dim, 
01763           int der_count, 
01764           int v_stride,
01765           double *v 
01766           );
01767 
01768 ON_DECL
01769 bool ON_GetPolylineLength(
01770         int,           // dimension of points
01771         ON_BOOL32,          // bIsRational true if points are homogeneous rational
01772         int,           // number of points
01773         int,           // stride between points
01774         const double*, // points
01775         double*        // length returned here
01776         );
01777 
01778 
01779 /*
01780 Description:
01781   Find the index of the point in the point_list that is closest to P.
01782 Parameters:
01783   point_count - [in]
01784   point_list - [in]
01785   P - [in]
01786   closest_point_index - [out]
01787 Returns:
01788   True if successful and *closest_point_index is set.
01789   False if input is not valid, in which case *closest_point_index
01790   is undefined.
01791 */
01792 ON_DECL
01793 bool ON_GetClosestPointInPointList( 
01794           int point_count,
01795           const ON_3dPoint* point_list,
01796           ON_3dPoint P,
01797           int* closest_point_index
01798           );
01799 
01800 /*
01801 Description:
01802   Test math library functions.
01803 Parameters:
01804   function_index - [in]  Determines which math library function is called.
01805 
01806            1:    z = x+y
01807            2:    z = x-y
01808            3:    z = x*y
01809            4:    z = x/y
01810            5:    z = fabs(x)
01811            6:    z = exp(x)
01812            7:    z = log(x)
01813            8:    z = logb(x)
01814            9:    z = log10(x)
01815           10:    z = pow(x,y)
01816           11:    z = sqrt(x)
01817           12:    z = sin(x)
01818           13:    z = cos(x)
01819           14:    z = tan(x)
01820           15:    z = sinh(x)
01821           16:    z = cosh(x)
01822           17:    z = tanh(x)
01823           18:    z = asin(x)
01824           19:    z = acos(x)
01825           20:    z = atan(x)
01826           21:    z = atan2(y,x)
01827           22:    z = fmod(x,y)
01828           23:    z = modf(x,&y)
01829           24:    z = frexp(x,&y)
01830 
01831   double x - [in]
01832   double y - [in]
01833 Returns:
01834   Returns the "z" value listed in the function_index parameter
01835   description.
01836 Remarks:
01837   This function is used to test the results of class floating
01838   point functions.  It is primarily used to see what happens
01839   when opennurbs is used as a DLL and illegal operations are
01840   performed.
01841 */
01842 ON_DECL
01843 double ON_TestMathFunction( 
01844         int function_index, 
01845         double x, 
01846         double y 
01847         );
01848 
01849 // If performance is important, then
01850 // you are better off using ((b<a)?a:b)
01851 ON_DECL double ON_Max(double a, double b);
01852 
01853 // If performance is important, then
01854 // you are better off using ((b<a)?a:b)
01855 ON_DECL float ON_Max(float a, float b);
01856 
01857 // If performance is important, then
01858 // you are better off using ((b<a)?a:b)
01859 ON_DECL int ON_Max(int a, int b);
01860 
01861 // If performance is important, then
01862 // you are better off using ((a<b)?a:b)
01863 ON_DECL double ON_Min(double a, double b);
01864 
01865 // If performance is important, then
01866 // you are better off using ((a<b)?a:b)
01867 ON_DECL float ON_Min(float a, float b);
01868 
01869 // If performance is important, then
01870 // you are better off using ((a<b)?a:b)
01871 ON_DECL int ON_Min(int a, int b);
01872 
01873 // Do not call ON_Round() in any opennurbs code, tl code
01874 // or any other code that does critical calculations or
01875 // when there is any possibility that x is invalid or
01876 // fabs(x)>2147483647. Use floor(x+0.5) instead.
01877 ON_DECL int ON_Round(double x);
01878 
01879 
01880 /*
01881 Description:
01882   Find the equation of the parabola, ellipse or hyperbola 
01883   (non-degenerate conic) that passes through six distinct points.
01884 Parameters:
01885   stride - [in] (>=2) 
01886     points array stride
01887   points2d - [in] (>=2) 
01888     i-th point is (points[i*stride],points[i*stride+1])
01889   conic - [out]
01890     Coefficients of the conic equation.
01891     The points on the conic satisfy the equation
01892       0 = conic[0]*x^2 + conic[1]*xy + conic[2]*y^2 
01893         + conic[3]*x + conic[4]*y + conic[5]
01894   max_pivot - [out] (can be null)
01895   min_pivot - [out] (can be null)
01896   zero_pivot - [out] (can be null)
01897     If there are some near duplicates in the input point set,
01898     the calculation is not stable.  If you want to get an
01899     estimate of the validity of the solution, then inspect
01900     the returned values.  max_pivot should around 1, 
01901     min_pivot should be > 1e-4 or so, and zero_pivot should
01902     be < 1e-10 or so.  If the returned pivots don't satisify
01903     these condtions, then exercise caution when using the
01904     returned solution.
01905 Returns:
01906   True if a there is an ellipse, parabola or hyperbola through the  
01907   six points.
01908   False if the input is invalid or the conic degenerate (the
01909   points lie on one or two lines).
01910   If false is returned, then conic[0]=...=conic[5] = 0 and
01911   *min_pivot = *max_pivot = *zero_pivot = 0.
01912 */
01913 ON_DECL bool ON_GetConicEquationThrough6Points( 
01914         int stride, 
01915         const double* points2d, 
01916         double conic[6],
01917         double* max_pivot,
01918         double* min_pivot,
01919         double* zero_pivot
01920         );
01921 
01922 /*
01923 Description:
01924   Test a conic equation to see if it defines and ellipse. If so,
01925   return the center and axes of the ellipse.
01926 Parameters:
01927   conic - [in]
01928     Coefficients of the conic equation.
01929     The points on the conic satisfy the equation
01930       0 = conic[0]*x^2 + conic[1]*xy + conic[2]*y^2 
01931         + conic[3]*x + conic[4]*y + conic[5]
01932   center - [out]
01933   major_axis - [out]
01934   minor_axis - [out]
01935   major_radius - [out]
01936   minor_radius - [out]
01937 Returns:
01938   True if the conic is an ellipse and the center and axes were found.
01939   False if the conic is not an ellipse, in which case the input values
01940   of center, major_axis, minor_axis, major_radius, and minor_radius
01941   are not changed.
01942 */
01943 ON_DECL bool ON_IsConicEquationAnEllipse( 
01944         const double conic[6], 
01945         ON_2dPoint& center, 
01946         ON_2dVector& major_axis, 
01947         ON_2dVector& minor_axis, 
01948         double* major_radius, 
01949         double* minor_radius
01950         );
01951 
01952 /*
01953 Description:
01954   Get the conic equation of an ellipse.
01955 Parameters:
01956   a - [in] (a>0)
01957   b - [in] (b>0)
01958     a and b are the lengths of the axes. Either one
01959     may be largest and they can be equal.
01960   x0 - [in]
01961   y0 - [in]
01962     (x0,y0) is the enter of the ellipse.
01963   alpha - [in] (angle in radians)
01964     When alpha is 0, a corresponds to the x-axis and
01965     b corresponds to the y axis.  If alpha is non-zero
01966     it specifies the rotation of these axes.
01967   conic - [out]
01968     Coefficients of the conic equation.
01969     The points on the conic satisfy the equation
01970       0 = conic[0]*x^2 + conic[1]*xy + conic[2]*y^2 
01971         + conic[3]*x + conic[4]*y + conic[5]
01972   center - [out]
01973   major_axis - [out]
01974   minor_axis - [out]
01975   major_radius - [out]
01976   minor_radius - [out]
01977 Remarks:
01978   Here is the way to evaluate a point on the ellipse:
01979 
01980           
01981           double t = ellipse paramter in radians;
01982           double x = a*cos(t);
01983           double y = b*sin(t);
01984           ON_2dPoint ellipse_point;
01985           ellipse_point.x = x0 + x*cos(alpha) + y*sin(alpha);
01986           ellipse_point.y = y0 - x*sin(alpha) + y*cos(alpha);
01987 
01988 Returns:
01989   True if the input is valid and conic[] was filled in.
01990   Falis if the input is not valid.  In this case the values in conic[]
01991   are not changed.
01992 */
01993 ON_DECL bool ON_GetEllipseConicEquation( 
01994       double a, double b, 
01995       double x0, double y0, 
01996       double alpha,
01997       double conic[6]
01998       );
01999 
02000 /*
02001 Descripton:
02002   Return the length of a 2d vector (x,y)
02003 Returns:
02004  sqrt(x^2 + y^2) calculated in as precisely and safely as possible.
02005 */
02006 ON_DECL double ON_Length2d( double x, double y );
02007 
02008 /*
02009 Descripton:
02010   Return the length of a 3d vector (x,y,z)
02011 Returns:
02012  sqrt(x^2 + y^2 + z^2) calculated in as precisely and safely as possible.
02013 */
02014 ON_DECL double ON_Length3d( double x, double y, double z );
02015 
02016 
02017 /*
02018 Description:
02019   Convert a double x to the largest float f such that
02020   the mathematical value of f is at most the value of x.
02021 Parameters:
02022   x - [in]
02023 Returns
02024   The largest float f such that the mathematical value
02025   of f is at most the value of x.
02026 */
02027 ON_DECL float ON_FloatFloor(double x);
02028 
02029 /*
02030 Description:
02031   Convert a double x to the smallest float f such that
02032   the mathematical value of f is at least the value of x.
02033 Parameters:
02034   x - [in]
02035 Returns
02036   The smallest float f such that the mathematical value
02037   of f is at least the value of x.
02038 */
02039 ON_DECL float ON_FloatCeil(double x);
02040 
02041 #endif


pcl
Author(s): Open Perception
autogenerated on Wed Aug 26 2015 15:27:01