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