00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00015
00016
00017 #include "pcl/surface/3rdparty/opennurbs/opennurbs.h"
00018
00019 bool ON_IsValid(double x)
00020 {
00021 return ON_IS_VALID(x);
00022 }
00023
00024 bool ON_IsValidFloat(float x)
00025 {
00026 return ON_IS_VALID_FLOAT(x);
00027 }
00028
00029 const ON_Interval ON_Interval::EmptyInterval(ON_UNSET_VALUE,ON_UNSET_VALUE);
00030
00031 ON_Interval::ON_Interval()
00032 {
00033 m_t[0] = m_t[1] = ON_UNSET_VALUE;
00034 }
00035
00036 ON_Interval::ON_Interval(double t0, double t1)
00037 {
00038 Set(t0,t1);
00039 }
00040
00041 ON_Interval::~ON_Interval()
00042 {}
00043
00044 double&
00045 ON_Interval::operator[](int i)
00046 {
00047 return m_t[(i<=0)?0:1];
00048 }
00049
00050 double
00051 ON_Interval::operator[](int i) const
00052 {
00053 return m_t[(i<=0)?0:1];
00054 }
00055
00056 double
00057 ON_Interval::Min() const
00058 {
00059 return m_t[IsDecreasing()?1:0];
00060 }
00061
00062 void ON_Interval::Destroy()
00063 {
00064 Set(ON_UNSET_VALUE,ON_UNSET_VALUE);
00065 }
00066
00067 void ON_Interval::Set(double t0,double t1)
00068 {
00069 m_t[0] = t0;
00070 m_t[1] = t1;
00071 }
00072
00073 double ON_Interval::ParameterAt(double x) const
00074 {
00075 return (ON_IS_VALID(x) ? ((1.0-x)*m_t[0] + x*m_t[1]) : ON_UNSET_VALUE);
00076 }
00077
00078 ON_Interval ON_Interval::ParameterAt(ON_Interval x) const
00079 {
00080 return ON_Interval( ParameterAt(x[0]), ParameterAt(x[1]) );
00081 }
00082
00083 double ON_Interval::NormalizedParameterAt(
00084 double t
00085 ) const
00086 {
00087 if (!ON_IS_VALID(t))
00088 return ON_UNSET_VALUE;
00089
00090 double x = m_t[0];
00091 if ( m_t[0] != m_t[1] ) {
00092 x = ( t == m_t[1]) ? 1.0 : (t - m_t[0])/(m_t[1] - m_t[0]);
00093 }
00094 return x;
00095 }
00096
00097 ON_Interval ON_Interval::NormalizedParameterAt(
00098 ON_Interval t
00099 ) const
00100 {
00101 return ON_Interval( NormalizedParameterAt(t[0]) ,
00102 NormalizedParameterAt(t[1]) );
00103 }
00104
00105 double
00106 ON_Interval::Max() const
00107 {
00108 return m_t[IsDecreasing()?0:1];
00109 }
00110
00111 double
00112 ON_Interval::Mid() const
00113 {
00114 return 0.5*(m_t[0]+m_t[1]);
00115 }
00116
00117 double
00118 ON_Interval::Length() const
00119 {
00120 return ( ON_IS_VALID(m_t[0]) && ON_IS_VALID(m_t[1]) ) ? m_t[1]-m_t[0] : 0.0;
00121 }
00122
00123 bool
00124 ON_Interval::IsIncreasing() const
00125 {
00126 return ( m_t[0] < m_t[1] && ON_IS_VALID(m_t[0]) && ON_IS_VALID(m_t[1]) ) ? true : false;
00127 }
00128
00129 bool
00130 ON_Interval::IsDecreasing() const
00131 {
00132 return ( m_t[0] > m_t[1] && ON_IS_VALID(m_t[0]) && ON_IS_VALID(m_t[1]) ) ? true : false;
00133 }
00134
00135 bool
00136 ON_Interval::IsInterval() const
00137 {
00138 return ( m_t[0] != m_t[1] && ON_IS_VALID(m_t[0]) && ON_IS_VALID(m_t[1]) ) ? true : false;
00139 }
00140
00141
00142 bool
00143 ON_Interval::IsSingleton() const
00144 {
00145 return ( m_t[0] == m_t[1] && ON_IS_VALID(m_t[1]) ) ? true : false;
00146 }
00147
00148 bool
00149 ON_Interval::IsEmptyInterval() const
00150 {
00151 return ( m_t[0] == ON_UNSET_VALUE && m_t[1] == ON_UNSET_VALUE ) ? true : false;
00152 }
00153
00154 bool
00155 ON_Interval::IsEmptySet() const
00156 {
00157 return ( m_t[0] == ON_UNSET_VALUE && m_t[1] == ON_UNSET_VALUE ) ? true : false;
00158 }
00159
00160 bool
00161 ON_Interval::IsValid() const
00162 {
00163
00164 return ( ON_IS_VALID(m_t[0]) && ON_IS_VALID(m_t[1]) );
00165 }
00166
00167 bool
00168 ON_Interval::MakeIncreasing()
00169 {
00170 if( IsDecreasing()){
00171 Swap();
00172 return true;
00173 }
00174 return IsIncreasing();
00175 }
00176
00177 bool
00178 ON_Interval::operator!=(const ON_Interval& other) const
00179 {
00180 return Compare(other) ? true : false;
00181 }
00182
00183 bool
00184 ON_Interval::operator==(const ON_Interval& other) const
00185 {
00186 return Compare(other) ? false : true;
00187 }
00188
00189
00190 int
00191 ON_Interval::Compare( const ON_Interval& other ) const
00192 {
00193 if ( m_t[0] < other.m_t[0] )
00194 return -1;
00195 if ( m_t[0] > other.m_t[0] )
00196 return 1;
00197 if ( m_t[1] < other.m_t[1] )
00198 return -1;
00199 if ( m_t[1] > other.m_t[1] )
00200 return 1;
00201 return 0;
00202 }
00203
00204 bool
00205 ON_Interval::Includes( double t, bool bTestOpenInterval) const
00206 {
00207 bool rc = false;
00208 if ( ON_IS_VALID(t) && ON_IS_VALID(m_t[0]) && ON_IS_VALID(m_t[1]) )
00209 {
00210 int i = (m_t[0] <= m_t[1]) ? 0 : 1;
00211 if ( bTestOpenInterval )
00212 {
00213 rc = ( m_t[i] < t && t < m_t[1-i] ) ? true : false;
00214 }
00215 else
00216 {
00217 rc = ( m_t[i] <= t && t <= m_t[1-i] ) ? true : false;
00218 }
00219 }
00220 return rc;
00221 }
00222
00223 bool
00224 ON_Interval::Includes( const ON_Interval& other, bool bProperSubSet ) const
00225 {
00226 bool rc = ( Includes( other.m_t[0] ) && Includes( other.m_t[1] ) ) ? true : false;
00227 if ( rc && bProperSubSet )
00228 {
00229 if ( !Includes( other.m_t[0], true ) && !Includes( other.m_t[1], true ) )
00230 rc = false;
00231 }
00232 return rc;
00233 }
00234
00235 void
00236 ON_Interval::Reverse()
00237 {
00238 if ( !IsEmptySet() ) {
00239 const double x = -m_t[0];
00240 m_t[0] = -m_t[1];
00241 m_t[1] = x;
00242 }
00243 }
00244
00245 void
00246 ON_Interval::Swap()
00247 {
00248 const double x = m_t[0];
00249 m_t[0] = m_t[1];
00250 m_t[1] = x;
00251 }
00252
00254
00255
00256
00257
00258
00259
00260 bool ON_Interval::Intersection(
00261 const ON_Interval& other
00262 )
00263 {
00264 bool rc = false;
00265 if ( IsEmptySet() && other.IsEmptySet() )
00266 Destroy();
00267 else {
00268 double a, b, mn, mx;
00269 a = Min();
00270 b = other.Min();
00271 mn = (a>=b) ? a : b;
00272 a = Max();
00273 b = other.Max();
00274 mx = (a<=b) ? a : b;
00275 if ( mn <= mx ) {
00276 Set(mn,mx);
00277 rc = true;
00278 }
00279 else
00280 Destroy();
00281 }
00282 return rc;
00283 }
00284
00286
00287
00288
00289
00290
00291
00292 bool ON_Interval::Intersection(
00293 const ON_Interval& ain,
00294 const ON_Interval& bin
00295 )
00296 {
00297 bool rc = false;
00298 if ( ain.IsEmptySet() && bin.IsEmptySet() )
00299 Destroy();
00300 else {
00301 double a, b, mn, mx;
00302 a = ain.Min();
00303 b = bin.Min();
00304 mn = (a>=b) ? a : b;
00305 a = ain.Max();
00306 b = bin.Max();
00307 mx = (a<=b) ? a : b;
00308 if ( mn <= mx ) {
00309 Set(mn,mx);
00310 rc = true;
00311 }
00312 else
00313 Destroy();
00314 }
00315 return rc;
00316 }
00317
00319
00320
00321
00322
00323
00324
00325 bool ON_Interval::Union(
00326 const ON_Interval& other
00327 )
00328 {
00329 bool rc = false;
00330 if ( other.IsEmptySet() ) {
00331
00332 Set( Min(), Max() );
00333 rc = !IsEmptySet();
00334 }
00335 else if ( IsEmptySet() ) {
00336
00337 Set( other.Min(), other.Max() );
00338 rc = true;
00339 }
00340 else {
00341 double a, b, mn, mx;
00342 a = Min();
00343 b = other.Min();
00344 mn = (a<=b) ? a : b;
00345 a = Max();
00346 b = other.Max();
00347 mx = (a>=b) ? a : b;
00348 if ( mn <= mx ) {
00349 Set(mn,mx);
00350 rc = true;
00351 }
00352 else
00353 Destroy();
00354 }
00355 return rc;
00356 }
00357
00358 bool ON_Interval::Union(
00359 int count,
00360 const double* t
00361 )
00362 {
00363 bool rc = false;
00364 double a, mn, mx;
00365
00366 if ( 0 != t )
00367 {
00368 while ( count > 0 && !ON_IsValid(*t) )
00369 {
00370 count--;
00371 t++;
00372 }
00373 }
00374
00375 if ( count <= 0 || 0 == t )
00376 {
00377
00378 if ( !IsEmptySet() )
00379 {
00380 mn = Min();
00381 mx = Max();
00382 if ( mn <= mx && ON_IsValid(mn) && ON_IsValid(mx) )
00383 {
00384 Set( mn, mx );
00385 rc = true;
00386 }
00387 }
00388 }
00389 else
00390 {
00391 if ( IsEmptySet() )
00392 {
00393 a = *t++;
00394 Set( a, a );
00395 count--;
00396 rc = true;
00397 }
00398 mn = Min();
00399 mx = Max();
00400 while( count > 0 )
00401 {
00402 count--;
00403 a = *t++;
00404 if ( ON_IsValid(a) )
00405 {
00406 if ( a < mn )
00407 mn = a;
00408 else if ( a > mx )
00409 mx = a;
00410 }
00411 }
00412 if ( mn <= mx && ON_IsValid(mn) && ON_IsValid(mx) )
00413 {
00414 Set(mn,mx);
00415 rc = true;
00416 }
00417 else
00418 Destroy();
00419 }
00420 return rc;
00421 }
00422
00423 bool ON_Interval::Union(
00424 double t
00425 )
00426 {
00427 return Union(1,&t);
00428 }
00429
00431
00432
00433
00434
00435
00436
00437 bool ON_Interval::Union(
00438 const ON_Interval& ain,
00439 const ON_Interval& bin
00440 )
00441 {
00442 bool rc = false;
00443 if ( bin.IsEmptySet() ) {
00444
00445 Set( ain.Min(), ain.Max() );
00446 rc = !IsEmptySet();
00447 }
00448 else if ( ain.IsEmptySet() ) {
00449
00450 Set( bin.Min(), bin.Max() );
00451 rc = true;
00452 }
00453 else {
00454 double a, b, mn, mx;
00455 a = ain.Min();
00456 b = bin.Min();
00457 mn = (a<=b) ? a : b;
00458 a = ain.Max();
00459 b = bin.Max();
00460 mx = (a>=b) ? a : b;
00461 if ( mn <= mx ) {
00462 Set(mn,mx);
00463 rc = true;
00464 }
00465 else
00466 Destroy();
00467 }
00468 return rc;
00469 }
00470
00471
00472 bool ON_3dVector::Decompose(
00473
00474
00475
00476
00477 const ON_3dVector& X,
00478 const ON_3dVector& Y,
00479 const ON_3dVector& Z,
00480 double* a,
00481 double* b,
00482 double* c
00483 ) const
00484 {
00485 int rank;
00486 double pivot_ratio = 0.0;
00487 double row0[3], row1[3], row2[3];
00488 row0[0] = X*X; row0[1] = X*Y; row0[2] = X*Z;
00489 row1[0] = row0[1]; row1[1] = Y*Y; row1[2] = Y*Z;
00490 row2[0] = row0[2]; row2[1] = row1[2]; row2[2] = Z*Z;
00491 rank = ON_Solve3x3( row0, row1, row2,
00492 (*this)*X, (*this)*Y, (*this)*Z,
00493 a, b, c, &pivot_ratio );
00494 return (rank == 3) ? true : false;
00495 }
00496
00497 int ON_3dVector::IsParallelTo(
00498
00499
00500
00501
00502 const ON_3dVector& v,
00503 double angle_tolerance
00504 ) const
00505 {
00506 int rc = 0;
00507 const double ll = Length()*v.Length();
00508 if ( ll > 0.0 ) {
00509 const double cos_angle = (x*v.x + y*v.y + z*v.z)/ll;
00510 const double cos_tol = cos(angle_tolerance);
00511 if ( cos_angle >= cos_tol )
00512 rc = 1;
00513 else if ( cos_angle <= -cos_tol )
00514 rc = -1;
00515 }
00516 return rc;
00517 }
00518
00519 bool ON_3fVector::IsPerpendicularTo(
00520
00521
00522
00523 const ON_3fVector& v,
00524 double angle_tolerance
00525 ) const
00526 {
00527 ON_3dVector V(*this);
00528 return V.IsPerpendicularTo(ON_3dVector(v),angle_tolerance);
00529 }
00530
00531 bool ON_3dVector::IsPerpendicularTo(
00532
00533
00534
00535 const ON_3dVector& v,
00536 double angle_tolerance
00537 ) const
00538 {
00539 bool rc = false;
00540 const double ll = Length()*v.Length();
00541 if ( ll > 0.0 ) {
00542 if ( fabs((x*v.x + y*v.y + z*v.z)/ll) <= sin(angle_tolerance) )
00543 rc = true;
00544 }
00545 return rc;
00546 }
00547
00548 bool ON_3fVector::PerpendicularTo( const ON_3fVector& v )
00549 {
00550 ON_3dVector V(*this);
00551 return V.IsPerpendicularTo(ON_3dVector(v));
00552 }
00553
00554 bool ON_3dVector::PerpendicularTo( const ON_3dVector& v )
00555 {
00556
00557 int i, j, k;
00558 double a, b;
00559 k = 2;
00560 if ( fabs(v.y) > fabs(v.x) ) {
00561 if ( fabs(v.z) > fabs(v.y) ) {
00562
00563 i = 2;
00564 j = 1;
00565 k = 0;
00566 a = v.z;
00567 b = -v.y;
00568 }
00569 else if ( fabs(v.z) >= fabs(v.x) ){
00570
00571 i = 1;
00572 j = 2;
00573 k = 0;
00574 a = v.y;
00575 b = -v.z;
00576 }
00577 else {
00578
00579 i = 1;
00580 j = 0;
00581 k = 2;
00582 a = v.y;
00583 b = -v.x;
00584 }
00585 }
00586 else if ( fabs(v.z) > fabs(v.x) ) {
00587
00588 i = 2;
00589 j = 0;
00590 k = 1;
00591 a = v.z;
00592 b = -v.x;
00593 }
00594 else if ( fabs(v.z) > fabs(v.y) ) {
00595
00596 i = 0;
00597 j = 2;
00598 k = 1;
00599 a = v.x;
00600 b = -v.z;
00601 }
00602 else {
00603
00604 i = 0;
00605 j = 1;
00606 k = 2;
00607 a = v.x;
00608 b = -v.y;
00609 }
00610 double* this_v = &x;
00611 this_v[i] = b;
00612 this_v[j] = a;
00613 this_v[k] = 0.0;
00614 return (a != 0.0) ? true : false;
00615 }
00616
00617 bool
00618 ON_3dVector::PerpendicularTo(
00619 const ON_3dPoint& P0, const ON_3dPoint& P1, const ON_3dPoint& P2
00620 )
00621 {
00622
00623 ON_3dVector V0, V1, V2, N0, N1, N2;
00624
00625 Zero();
00626
00627 V0 = P2 - P1;
00628 V1 = P0 - P2;
00629 V2 = P1 - P0;
00630
00631 N0 = ON_CrossProduct( V1, V2 );
00632 if ( !N0.Unitize() )
00633 return false;
00634 N1 = ON_CrossProduct( V2, V0 );
00635 if ( !N1.Unitize() )
00636 return false;
00637 N2 = ON_CrossProduct( V0, V1 );
00638 if ( !N2.Unitize() )
00639 return false;
00640
00641 const double s0 = 1.0/V0.Length();
00642 const double s1 = 1.0/V1.Length();
00643 const double s2 = 1.0/V2.Length();
00644
00645
00646 const double e0 = s0*fabs(ON_DotProduct(N0,V0)) + s1*fabs(ON_DotProduct(N0,V1)) + s2*fabs(ON_DotProduct(N0,V2));
00647 const double e1 = s0*fabs(ON_DotProduct(N1,V0)) + s1*fabs(ON_DotProduct(N1,V1)) + s2*fabs(ON_DotProduct(N1,V2));
00648 const double e2 = s0*fabs(ON_DotProduct(N2,V0)) + s1*fabs(ON_DotProduct(N2,V1)) + s2*fabs(ON_DotProduct(N2,V2));
00649
00650 if ( e0 <= e1 ) {
00651 if ( e0 <= e2 ) {
00652 *this = N0;
00653 }
00654 else {
00655 *this = N2;
00656 }
00657 }
00658 else if (e1 <= e2) {
00659 *this = N1;
00660 }
00661 else {
00662 *this = N2;
00663 }
00664
00665 return true;
00666 }
00667
00668 void ON_2dPoint::Transform( const ON_Xform& xform )
00669 {
00670 double xx,yy,ww;
00671 if ( xform.m_xform ) {
00672 ww = xform.m_xform[3][0]*x + xform.m_xform[3][1]*y + xform.m_xform[3][3];
00673 if ( ww != 0.0 )
00674 ww = 1.0/ww;
00675 xx = ww*(xform.m_xform[0][0]*x + xform.m_xform[0][1]*y + xform.m_xform[0][3]);
00676 yy = ww*(xform.m_xform[1][0]*x + xform.m_xform[1][1]*y + xform.m_xform[1][3]);
00677 x = xx;
00678 y = yy;
00679 }
00680 }
00681
00682 void ON_3dPoint::Transform( const ON_Xform& xform )
00683 {
00684 double xx,yy,zz,ww;
00685 if ( xform.m_xform ) {
00686 ww = xform.m_xform[3][0]*x + xform.m_xform[3][1]*y + xform.m_xform[3][2]*z + xform.m_xform[3][3];
00687 if ( ww != 0.0 )
00688 ww = 1.0/ww;
00689 xx = ww*(xform.m_xform[0][0]*x + xform.m_xform[0][1]*y + xform.m_xform[0][2]*z + xform.m_xform[0][3]);
00690 yy = ww*(xform.m_xform[1][0]*x + xform.m_xform[1][1]*y + xform.m_xform[1][2]*z + xform.m_xform[1][3]);
00691 zz = ww*(xform.m_xform[2][0]*x + xform.m_xform[2][1]*y + xform.m_xform[2][2]*z + xform.m_xform[2][3]);
00692 x = xx;
00693 y = yy;
00694 z = zz;
00695 }
00696 }
00697
00698 void ON_4dPoint::Transform( const ON_Xform& xform )
00699 {
00700 double xx,yy,zz,ww;
00701 if ( xform.m_xform ) {
00702 xx = xform.m_xform[0][0]*x + xform.m_xform[0][1]*y + xform.m_xform[0][2]*z + xform.m_xform[0][3]*w;
00703 yy = xform.m_xform[1][0]*x + xform.m_xform[1][1]*y + xform.m_xform[1][2]*z + xform.m_xform[1][3]*w;
00704 zz = xform.m_xform[2][0]*x + xform.m_xform[2][1]*y + xform.m_xform[2][2]*z + xform.m_xform[2][3]*w;
00705 ww = xform.m_xform[3][0]*x + xform.m_xform[3][1]*y + xform.m_xform[3][2]*z + xform.m_xform[3][3]*w;
00706 x = xx;
00707 y = yy;
00708 z = zz;
00709 w = ww;
00710 }
00711 }
00712
00713 void ON_2fPoint::Transform( const ON_Xform& xform )
00714 {
00715 double xx,yy,ww;
00716 if ( xform.m_xform ) {
00717 ww = xform.m_xform[3][0]*x + xform.m_xform[3][1]*y + xform.m_xform[3][3];
00718 if ( ww != 0.0 )
00719 ww = 1.0/ww;
00720 xx = ww*(xform.m_xform[0][0]*x + xform.m_xform[0][1]*y + xform.m_xform[0][3]);
00721 yy = ww*(xform.m_xform[1][0]*x + xform.m_xform[1][1]*y + xform.m_xform[1][3]);
00722 x = (float)xx;
00723 y = (float)yy;
00724 }
00725 }
00726
00727 void ON_2fPoint::Rotate(
00728 double angle,
00729 const ON_2fPoint& center
00730 )
00731 {
00732 Rotate( sin(angle), cos(angle), center );
00733 }
00734
00735 void ON_2fPoint::Rotate(
00736 double sin_angle,
00737 double cos_angle,
00738 const ON_2fPoint& center
00739 )
00740 {
00741 ON_Xform rot;
00742 rot.Rotation( sin_angle, cos_angle, ON_zaxis, ON_3dPoint(center) );
00743 Transform(rot);
00744 }
00745
00746 void ON_3fPoint::Rotate(
00747 double angle,
00748 const ON_3fVector& axis,
00749 const ON_3fPoint& center
00750 )
00751 {
00752 Rotate( sin(angle), cos(angle), axis, center );
00753 }
00754
00755 void ON_3fPoint::Rotate(
00756 double sin_angle,
00757 double cos_angle,
00758 const ON_3fVector& axis,
00759 const ON_3fPoint& center
00760 )
00761 {
00762 ON_Xform rot;
00763 rot.Rotation( sin_angle, cos_angle, ON_3dVector(axis), ON_3dPoint(center) );
00764 Transform(rot);
00765 }
00766
00767 void ON_3fPoint::Transform( const ON_Xform& xform )
00768 {
00769 double xx,yy,zz,ww;
00770 if ( xform.m_xform ) {
00771 ww = xform.m_xform[3][0]*x + xform.m_xform[3][1]*y + xform.m_xform[3][2]*z + xform.m_xform[3][3];
00772 if ( ww != 0.0 )
00773 ww = 1.0/ww;
00774 xx = ww*(xform.m_xform[0][0]*x + xform.m_xform[0][1]*y + xform.m_xform[0][2]*z + xform.m_xform[0][3]);
00775 yy = ww*(xform.m_xform[1][0]*x + xform.m_xform[1][1]*y + xform.m_xform[1][2]*z + xform.m_xform[1][3]);
00776 zz = ww*(xform.m_xform[2][0]*x + xform.m_xform[2][1]*y + xform.m_xform[2][2]*z + xform.m_xform[2][3]);
00777 x = (float)xx;
00778 y = (float)yy;
00779 z = (float)zz;
00780 }
00781 }
00782
00783 void ON_4fPoint::Transform( const ON_Xform& xform )
00784 {
00785 double xx,yy,zz,ww;
00786 if ( xform.m_xform ) {
00787 xx = xform.m_xform[0][0]*x + xform.m_xform[0][1]*y + xform.m_xform[0][2]*z + xform.m_xform[0][3]*w;
00788 yy = xform.m_xform[1][0]*x + xform.m_xform[1][1]*y + xform.m_xform[1][2]*z + xform.m_xform[1][3]*w;
00789 zz = xform.m_xform[2][0]*x + xform.m_xform[2][1]*y + xform.m_xform[2][2]*z + xform.m_xform[2][3]*w;
00790 ww = xform.m_xform[3][0]*x + xform.m_xform[3][1]*y + xform.m_xform[3][2]*z + xform.m_xform[3][3]*w;
00791 x = (float)xx;
00792 y = (float)yy;
00793 z = (float)zz;
00794 w = (float)ww;
00795 }
00796 }
00797
00798 double ON_3fPoint::Fuzz(
00799 double absolute_tolerance
00800 ) const
00801 {
00802 double t = MaximumCoordinate()* ON_RELATIVE_TOLERANCE;
00803 return(t > absolute_tolerance) ? t : absolute_tolerance;
00804 }
00805
00806 bool ON_4dPoint::Normalize()
00807 {
00808 bool rc = false;
00809 const int i = MaximumCoordinateIndex();
00810 double f[4];
00811 f[0] = fabs(x);
00812 f[1] = fabs(y);
00813 f[2] = fabs(z);
00814 f[3] = fabs(w);
00815 const double c = f[i];
00816 if ( c > 0.0 ) {
00817 double len = 1.0/c;
00818 f[0] *= len;
00819 f[1] *= len;
00820 f[2] *= len;
00821 f[3] *= len;
00822 f[i] = 1.0;
00823
00824 const double s = 1.0/( c*sqrt(f[0]*f[0] + f[1]*f[1] + f[2]*f[2] + f[3]*f[3]));
00825 x *= s;
00826 y *= s;
00827 z *= s;
00828 w *= s;
00829 rc = true;
00830 }
00831 return rc;
00832 }
00833
00834 bool ON_4fPoint::Normalize()
00835 {
00836 bool rc = false;
00837 const int i = MaximumCoordinateIndex();
00838 double f[4];
00839 f[0] = fabs(x);
00840 f[1] = fabs(y);
00841 f[2] = fabs(z);
00842 f[3] = fabs(w);
00843 const double c = f[i];
00844 if ( c > 0.0 ) {
00845 double len = 1.0/c;
00846 f[0] *= len;
00847 f[1] *= len;
00848 f[2] *= len;
00849 f[3] *= len;
00850 f[i] = 1.0;
00851
00852 const double s = 1.0/(c*sqrt(f[0]*f[0] + f[1]*f[1] + f[2]*f[2] + f[3]*f[3]));
00853 x = (float)(s*x);
00854 y = (float)(s*y);
00855 z = (float)(s*z);
00856 w = (float)(s*w);
00857 rc = true;
00858 }
00859 return rc;
00860 }
00861
00862 bool ON_2fVector::Decompose(
00863
00864
00865
00866
00867 const ON_2fVector& X,
00868 const ON_2fVector& Y,
00869 double* a,
00870 double* b
00871 ) const
00872 {
00873 ON_2dVector V(*this);
00874 return V.Decompose(ON_2dVector(X),ON_2dVector(Y),a,b);
00875 }
00876
00877
00878 bool ON_2dVector::Decompose(
00879
00880
00881
00882
00883 const ON_2dVector& X,
00884 const ON_2dVector& Y,
00885 double* a,
00886 double* b
00887 ) const
00888 {
00889 int rank;
00890 double pivot_ratio = 0.0;
00891 double XoY = X*Y;
00892 rank = ON_Solve2x2( X*X, XoY, Y*Y, XoY,
00893 (*this)*X, (*this)*Y,
00894 a, b, &pivot_ratio );
00895 return (rank == 2) ? true : false;
00896 }
00897
00898
00899 int ON_2fVector::IsParallelTo(
00900
00901
00902
00903
00904 const ON_2fVector& v,
00905 double angle_tolerance
00906 ) const
00907 {
00908 ON_2dVector V(*this);
00909 return V.IsParallelTo(ON_2dVector(v),angle_tolerance);
00910 }
00911
00912 int ON_2dVector::IsParallelTo(
00913
00914
00915
00916
00917 const ON_2dVector& v,
00918 double angle_tolerance
00919 ) const
00920 {
00921 int rc = 0;
00922 const double ll = Length()*v.Length();
00923 if ( ll > 0.0 ) {
00924 const double cos_angle = (x*v.x + y*v.y)/ll;
00925 const double cos_tol = cos(angle_tolerance);
00926 if ( cos_angle >= cos_tol )
00927 rc = 1;
00928 else if ( cos_angle <= -cos_tol )
00929 rc = -1;
00930 }
00931 return rc;
00932 }
00933
00934
00935 bool ON_2fVector::IsPerpendicularTo(
00936
00937
00938
00939 const ON_2fVector& v,
00940 double angle_tolerance
00941 ) const
00942 {
00943 ON_2dVector V(*this);
00944 return V.IsPerpendicularTo(ON_2dVector(v),angle_tolerance);
00945 }
00946
00947 bool ON_2dVector::IsPerpendicularTo(
00948
00949
00950
00951 const ON_2dVector& v,
00952 double angle_tolerance
00953 ) const
00954 {
00955 bool rc = false;
00956 const double ll = Length()*v.Length();
00957 if ( ll > 0.0 ) {
00958 if ( fabs((x*v.x + y*v.y)/ll) <= sin(angle_tolerance) )
00959 rc = true;
00960 }
00961 return rc;
00962 }
00963
00964 void ON_2dVector::Transform( const ON_Xform& xform )
00965 {
00966 double xx,yy;
00967 xx = xform.m_xform[0][0]*x + xform.m_xform[0][1]*y;
00968 yy = xform.m_xform[1][0]*x + xform.m_xform[1][1]*y;
00969 x = xx;
00970 y = yy;
00971 }
00972
00973 void ON_3fVector::Transform( const ON_Xform& xform )
00974 {
00975 const double dx = x;
00976 const double dy = y;
00977 const double dz = z;
00978 double xx = xform.m_xform[0][0]*dx + xform.m_xform[0][1]*dy + xform.m_xform[0][2]*dz;
00979 double yy = xform.m_xform[1][0]*dx + xform.m_xform[1][1]*dy + xform.m_xform[1][2]*dz;
00980 double zz = xform.m_xform[2][0]*dx + xform.m_xform[2][1]*dy + xform.m_xform[2][2]*dz;
00981 x = (float)xx;
00982 y = (float)yy;
00983 z = (float)zz;
00984 }
00985
00986 void ON_3dVector::Transform( const ON_Xform& xform )
00987 {
00988 double xx,yy,zz;
00989 xx = xform.m_xform[0][0]*x + xform.m_xform[0][1]*y + xform.m_xform[0][2]*z;
00990 yy = xform.m_xform[1][0]*x + xform.m_xform[1][1]*y + xform.m_xform[1][2]*z;
00991 zz = xform.m_xform[2][0]*x + xform.m_xform[2][1]*y + xform.m_xform[2][2]*z;
00992 x = xx;
00993 y = yy;
00994 z = zz;
00995 }
00996
00997 void ON_3dPoint::Rotate(
00998 double angle,
00999 const ON_3dVector& axis,
01000 const ON_3dPoint& center
01001 )
01002 {
01003 Rotate( sin(angle), cos(angle), axis, center );
01004 }
01005
01006 void ON_3dPoint::Rotate(
01007 double sin_angle,
01008 double cos_angle,
01009 const ON_3dVector& axis,
01010 const ON_3dPoint& center
01011 )
01012 {
01013 ON_Xform rot;
01014 rot.Rotation( sin_angle, cos_angle, axis, center );
01015 Transform(rot);
01016 }
01017
01018 void ON_2dPoint::Rotate(
01019 double angle,
01020 const ON_2dPoint& center
01021 )
01022 {
01023 Rotate( sin(angle), cos(angle), center );
01024 }
01025
01026 void ON_2dPoint::Rotate(
01027 double sin_angle,
01028 double cos_angle,
01029 const ON_2dPoint& center
01030 )
01031 {
01032 ON_Xform rot;
01033 rot.Rotation( sin_angle, cos_angle, ON_zaxis, center );
01034 Transform(rot);
01035 }
01036
01037 void ON_2dVector::Rotate(
01038 double angle
01039 )
01040 {
01041 Rotate( sin(angle), cos(angle) );
01042 }
01043
01044 void ON_2dVector::Rotate(
01045 double sin_angle,
01046 double cos_angle
01047 )
01048 {
01049 ON_Xform rot;
01050 rot.Rotation( sin_angle, cos_angle, ON_zaxis, ON_origin );
01051 Transform(rot);
01052 }
01053
01054 bool ON_IsOrthogonalFrame( const ON_2dVector& X, const ON_2dVector& Y )
01055 {
01056
01057 double lx = X.Length();
01058 double ly = Y.Length();
01059 if ( lx <= ON_SQRT_EPSILON )
01060 return false;
01061 if ( ly <= ON_SQRT_EPSILON )
01062 return false;
01063 lx = 1.0/lx;
01064 ly = 1.0/ly;
01065 double x = ON_DotProduct( X, Y )*lx*ly;
01066 if ( fabs(x) > ON_SQRT_EPSILON )
01067 return false;
01068 return true;
01069 }
01070
01071 bool ON_IsOrthonormalFrame( const ON_2dVector& X, const ON_2dVector& Y )
01072 {
01073
01074 if ( !ON_IsOrthogonalFrame( X, Y ) )
01075 return false;
01076 double x = X.Length();
01077 if ( fabs(x-1.0) > ON_SQRT_EPSILON )
01078 return false;
01079 x = Y.Length();
01080 if ( fabs(x-1.0) > ON_SQRT_EPSILON )
01081 return false;
01082
01083 return true;
01084 }
01085
01086 bool ON_IsRightHandFrame( const ON_2dVector& X, const ON_2dVector& Y )
01087 {
01088
01089 if ( !ON_IsOrthonormalFrame(X,Y) )
01090 return false;
01091 double x = ON_DotProduct( ON_CrossProduct( X, Y ), ON_zaxis );
01092 if ( x <= ON_SQRT_EPSILON )
01093 return false;
01094 return true;
01095 }
01096 void ON_3fVector::Rotate(
01097 double angle,
01098 const ON_3fVector& axis
01099 )
01100 {
01101 Rotate( sin(angle), cos(angle), axis );
01102 }
01103
01104 void ON_3fVector::Rotate(
01105 double sin_angle,
01106 double cos_angle,
01107 const ON_3fVector& axis
01108 )
01109 {
01110
01111 ON_Xform rot;
01112 rot.Rotation( sin_angle, cos_angle, ON_3dVector(axis), ON_origin );
01113 Transform(rot);
01114 }
01115
01116 void ON_3dVector::Rotate(
01117 double angle,
01118 const ON_3dVector& axis
01119 )
01120 {
01121 Rotate( sin(angle), cos(angle), axis );
01122 }
01123
01124 void ON_3dVector::Rotate(
01125 double sin_angle,
01126 double cos_angle,
01127 const ON_3dVector& axis
01128 )
01129 {
01130
01131 ON_Xform rot;
01132 rot.Rotation( sin_angle, cos_angle, axis, ON_origin );
01133 Transform(rot);
01134 }
01135
01136 bool ON_IsOrthogonalFrame( const ON_3dVector& X, const ON_3dVector& Y, const ON_3dVector& Z )
01137 {
01138
01139 if (! X.IsValid() || !Y.IsValid() || !Z.IsValid() )
01140 return false;
01141
01142 double lx = X.Length();
01143 double ly = Y.Length();
01144 double lz = Z.Length();
01145 if ( lx <= ON_SQRT_EPSILON )
01146 return false;
01147 if ( ly <= ON_SQRT_EPSILON )
01148 return false;
01149 if ( lz <= ON_SQRT_EPSILON )
01150 return false;
01151 lx = 1.0/lx;
01152 ly = 1.0/ly;
01153 lz = 1.0/lz;
01154 double xy = (X.x*Y.x + X.y*Y.y + X.z*Y.z)*lx*ly;
01155 double yz = (Y.x*Z.x + Y.y*Z.y + Y.z*Z.z)*ly*lz;
01156 double zx = (Z.x*X.x + Z.y*X.y + Z.z*X.z)*lz*lx;
01157 if ( fabs(xy) > ON_SQRT_EPSILON
01158 || fabs(yz) > ON_SQRT_EPSILON
01159 || fabs(zx) > ON_SQRT_EPSILON
01160 )
01161 {
01162 double t = 0.0000152587890625;
01163 if ( fabs(xy) >= t || fabs(yz) >= t || fabs(zx) >= t )
01164 return false;
01165
01166
01167
01168 ON_3dVector V;
01169 V = (lx*ly)*ON_CrossProduct(X,Y);
01170 t = fabs((V.x*Z.x + V.y*Z.y + V.z*Z.z)*lz);
01171 if ( fabs(t-1.0) > ON_SQRT_EPSILON )
01172 return false;
01173
01174 V = (ly*lz)*ON_CrossProduct(Y,Z);
01175 t = fabs((V.x*X.x + V.y*X.y + V.z*X.z)*lx);
01176 if ( fabs(t-1.0) > ON_SQRT_EPSILON )
01177 return false;
01178
01179 V = (lz*lx)*ON_CrossProduct(Z,X);
01180 t = fabs((V.x*Y.x + V.y*Y.y + V.z*Y.z)*ly);
01181 if ( fabs(t-1.0) > ON_SQRT_EPSILON )
01182 return false;
01183 }
01184 return true;
01185 }
01186
01187 bool ON_IsOrthonormalFrame( const ON_3dVector& X, const ON_3dVector& Y, const ON_3dVector& Z )
01188 {
01189
01190 if ( !ON_IsOrthogonalFrame( X, Y, Z ) )
01191 return false;
01192 double x = X.Length();
01193 if ( fabs(x-1.0) > ON_SQRT_EPSILON )
01194 return false;
01195 x = Y.Length();
01196 if ( fabs(x-1.0) > ON_SQRT_EPSILON )
01197 return false;
01198 x = Z.Length();
01199 if ( fabs(x-1.0) > ON_SQRT_EPSILON )
01200 return false;
01201
01202 return true;
01203 }
01204
01205 bool ON_IsRightHandFrame( const ON_3dVector& X, const ON_3dVector& Y, const ON_3dVector& Z )
01206 {
01207
01208 if ( !ON_IsOrthonormalFrame(X,Y,Z) )
01209 return false;
01210 double x = ON_DotProduct( ON_CrossProduct( X, Y ), Z );
01211 if ( x <= ON_SQRT_EPSILON )
01212 return false;
01213 return true;
01214 }
01215
01216 ON_2dPoint ON_2dPoint::operator*( const ON_Xform& xform ) const
01217 {
01218 const double px = x;
01219 const double py = y;
01220 double hx[2], w;
01221 const double* m = &xform.m_xform[0][0];
01222 hx[0] = m[0]*px + m[4]*py + m[12];
01223 hx[1] = m[1]*px + m[5]*py + m[13];
01224 w = m[3]*px + m[7]*py + m[15];
01225 w = (w != 0.0) ? 1.0/w : 1.0;
01226 return ON_2dPoint( w*hx[0], w*hx[1] );
01227 }
01228
01229 ON_3dPoint ON_3dPoint::operator*( const ON_Xform& xform ) const
01230 {
01231 const double px = x;
01232 const double py = y;
01233 const double pz = z;
01234 double hx[3], w;
01235 const double* m = &xform.m_xform[0][0];
01236 hx[0] = m[0]*px + m[4]*py + m[ 8]*pz + m[12];
01237 hx[1] = m[1]*px + m[5]*py + m[ 9]*pz + m[13];
01238 hx[2] = m[2]*px + m[6]*py + m[10]*pz + m[14];
01239 w = m[3]*px + m[7]*py + m[11]*pz + m[15];
01240 w = (w != 0.0) ? 1.0/w : 1.0;
01241 return ON_3dPoint( w*hx[0], w*hx[1], w*hx[2] );
01242 }
01243
01244 double ON_3dPoint::Fuzz(
01245 double absolute_tolerance
01246 ) const
01247 {
01248 double t = MaximumCoordinate()* ON_RELATIVE_TOLERANCE;
01249 return(t > absolute_tolerance) ? t : absolute_tolerance;
01250 }
01251
01252 ON_4dPoint ON_4dPoint::operator*( const ON_Xform& xform ) const
01253 {
01254 const double px = x;
01255 const double py = y;
01256 const double pz = z;
01257 const double pw = w;
01258 double hx[4];
01259 const double* m = &xform.m_xform[0][0];
01260 hx[0] = m[0]*px + m[4]*py + m[ 8]*pz + m[12]*pw;
01261 hx[1] = m[1]*px + m[5]*py + m[ 9]*pz + m[13]*pw;
01262 hx[2] = m[2]*px + m[6]*py + m[10]*pz + m[14]*pw;
01263 hx[3] = m[3]*px + m[7]*py + m[11]*pz + m[15]*pw;
01264
01265 return ON_4dPoint( hx[0],hx[1],hx[2],hx[3] );
01266 }
01267
01268 ON_2dVector ON_2dVector::operator*( const ON_Xform& xform ) const
01269 {
01270 const double vx = x;
01271 const double vy = y;
01272 double hx[2];
01273 const double* m = &xform.m_xform[0][0];
01274 hx[0] = m[0]*vx + m[4]*vy;
01275 hx[1] = m[1]*vx + m[5]*vy;
01276 return ON_2dVector( hx[0],hx[1] );
01277 }
01278
01279 ON_3dVector ON_3dVector::operator*( const ON_Xform& xform ) const
01280 {
01281 const double vx = x;
01282 const double vy = y;
01283 const double vz = z;
01284 double hx[3];
01285 const double* m = &xform.m_xform[0][0];
01286 hx[0] = m[0]*vx + m[4]*vy + m[ 8]*vz;
01287 hx[1] = m[1]*vx + m[5]*vy + m[ 9]*vz;
01288 hx[2] = m[2]*vx + m[6]*vy + m[10]*vz;
01289 return ON_3dVector( hx[0],hx[1],hx[2] );
01290 }
01291
01292 double ON_3fVector::Fuzz(
01293 double absolute_tolerance
01294 ) const
01295 {
01296 double t = MaximumCoordinate()* ON_RELATIVE_TOLERANCE;
01297 return(t > absolute_tolerance) ? t : absolute_tolerance;
01298 }
01299
01300
01301 double ON_3dVector::Fuzz(
01302 double absolute_tolerance
01303 ) const
01304 {
01305 double t = MaximumCoordinate()* ON_RELATIVE_TOLERANCE;
01306 return(t > absolute_tolerance) ? t : absolute_tolerance;
01307 }
01308
01309 const ON_2dPoint ON_2dPoint::Origin(0.0,0.0);
01310 const ON_2dPoint ON_2dPoint::UnsetPoint(ON_UNSET_VALUE,ON_UNSET_VALUE);
01311
01312 const ON_3dPoint ON_3dPoint::Origin(0.0,0.0,0.0);
01313 const ON_3dPoint ON_3dPoint::UnsetPoint(ON_UNSET_VALUE,ON_UNSET_VALUE,ON_UNSET_VALUE);
01314
01315 const ON_2dVector ON_2dVector::ZeroVector(0.0,0.0);
01316 const ON_2dVector ON_2dVector::XAxis(1.0,0.0);
01317 const ON_2dVector ON_2dVector::YAxis(0.0,1.0);
01318 const ON_2dVector ON_2dVector::UnsetVector(ON_UNSET_VALUE,ON_UNSET_VALUE);
01319
01320 const ON_3dVector ON_3dVector::ZeroVector(0.0,0.0,0.0);
01321 const ON_3dVector ON_3dVector::XAxis(1.0,0.0,0.0);
01322 const ON_3dVector ON_3dVector::YAxis(0.0,1.0,0.0);
01323 const ON_3dVector ON_3dVector::ZAxis(0.0,0.0,1.0);
01324 const ON_3dVector ON_3dVector::UnsetVector(ON_UNSET_VALUE,ON_UNSET_VALUE,ON_UNSET_VALUE);
01325
01326 const ON_2fPoint ON_2fPoint::Origin(0.0f,0.0f);
01327 const ON_3fPoint ON_3fPoint::Origin(0.0f,0.0f,0.0f);
01328
01329 const ON_2fVector ON_2fVector::ZeroVector(0.0f,0.0f);
01330 const ON_2fVector ON_2fVector::XAxis(1.0f,0.0f);
01331 const ON_2fVector ON_2fVector::YAxis(0.0f,1.0f);
01332
01333 const ON_3fVector ON_3fVector::ZeroVector(0.0f,0.0f,0.0f);
01334 const ON_3fVector ON_3fVector::XAxis(1.0f,0.0f,0.0f);
01335 const ON_3fVector ON_3fVector::YAxis(0.0f,1.0f,0.0f);
01336 const ON_3fVector ON_3fVector::ZAxis(0.0f,0.0f,1.0f);
01337
01338
01339 const ON_3dPoint ON_UNSET_POINT(ON_UNSET_VALUE, ON_UNSET_VALUE, ON_UNSET_VALUE);
01340
01341
01342 const ON_3dVector ON_UNSET_VECTOR(ON_UNSET_VALUE, ON_UNSET_VALUE, ON_UNSET_VALUE);
01343
01344
01345 const ON_3dPoint ON_origin(0.0, 0.0,0.0);
01346
01347
01348 const ON_3dVector ON_xaxis(1.0, 0.0, 0.0);
01349
01350
01351 const ON_3dVector ON_yaxis(0.0, 1.0, 0.0);
01352
01353
01354 const ON_3dVector ON_zaxis(0.0, 0.0, 1.0);
01355
01356
01357 const ON_3fPoint ON_forigin(0.0f, 0.0f, 0.0f);
01358
01359
01360 const ON_3fVector ON_fxaxis(1.0f, 0.0f, 0.0f);
01361
01362
01363 const ON_3fVector ON_fyaxis(0.0f, 1.0f, 0.0f);
01364
01365
01366 const ON_3fVector ON_fzaxis(0.0f, 0.0f, 1.0f);
01367
01368
01372
01374
01375
01376
01377
01378 ON_2fPoint::ON_2fPoint()
01379 {}
01380
01381 ON_2fPoint::ON_2fPoint( const double* p )
01382 {
01383 if (p) {
01384 x = (float)p[0]; y = (float)p[1];
01385 }
01386 else {
01387 x = y = 0.0;
01388 }
01389 }
01390
01391 ON_2fPoint::ON_2fPoint( const float* p )
01392 {
01393 if (p) {
01394 x = p[0]; y = p[1];
01395 }
01396 else {
01397 x = y = 0.0;
01398 }
01399 }
01400
01401 ON_2fPoint::ON_2fPoint(float xx,float yy)
01402 {x=xx;y=yy;}
01403
01404 ON_2fPoint::ON_2fPoint(const ON_3fPoint& p)
01405 {x=p.x;y=p.y;}
01406
01407 ON_2fPoint::ON_2fPoint(const ON_4fPoint& h)
01408 {
01409 const float w = (h.w != 1.0f && h.w != 0.0f) ? 1.0f/h.w : 1.0f;
01410 x = w*h.x;
01411 y = w*h.y;
01412 }
01413
01414 ON_2fPoint::ON_2fPoint(const ON_2fVector& v)
01415 {x=v.x;y=v.y;}
01416
01417 ON_2fPoint::ON_2fPoint(const ON_3fVector& v)
01418 {x=v.x;y=v.y;}
01419
01420 ON_2fPoint::ON_2fPoint(const ON_2dPoint& p)
01421 {x=(float)p.x;y=(float)p.y;}
01422
01423 ON_2fPoint::ON_2fPoint(const ON_3dPoint& p)
01424 {x=(float)p.x;y=(float)p.y;}
01425
01426 ON_2fPoint::ON_2fPoint(const ON_4dPoint& h)
01427 {
01428 const double w = (h.w != 1.0 && h.w != 0.0) ? 1.0/h.w : 1.0;
01429 x = (float)(w*h.x);
01430 y = (float)(w*h.y);
01431 }
01432
01433 ON_2fPoint::ON_2fPoint(const ON_2dVector& v)
01434 {x=(float)v.x;y=(float)v.y;}
01435
01436 ON_2fPoint::ON_2fPoint(const ON_3dVector& v)
01437 {x=(float)v.x;y=(float)v.y;}
01438
01439
01440 ON_2fPoint::operator float*()
01441 {
01442 return &x;
01443 }
01444
01445 ON_2fPoint::operator const float*() const
01446 {
01447 return &x;
01448 }
01449
01450 ON_2fPoint& ON_2fPoint::operator=(const double* p)
01451 {
01452 if ( p ) {
01453 x = (float)p[0];
01454 y = (float)p[1];
01455 }
01456 else {
01457 x = y = 0.0;
01458 }
01459 return *this;
01460 }
01461
01462 ON_2fPoint& ON_2fPoint::operator=(const float* p)
01463 {
01464 if ( p ) {
01465 x = p[0];
01466 y = p[1];
01467 }
01468 else {
01469 x = y = 0.0;
01470 }
01471 return *this;
01472 }
01473
01474 ON_2fPoint& ON_2fPoint::operator=(const ON_3fPoint& p)
01475 {
01476 x = p.x;
01477 y = p.y;
01478 return *this;
01479 }
01480
01481 ON_2fPoint& ON_2fPoint::operator=(const ON_4fPoint& h)
01482 {
01483 const float w = (h.w != 1.0f && h.w != 0.0f) ? 1.0f/h.w : 1.0f;
01484 x = w*h.x;
01485 y = w*h.y;
01486 return *this;
01487 }
01488
01489 ON_2fPoint& ON_2fPoint::operator=(const ON_2fVector& v)
01490 {
01491 x = v.x;
01492 y = v.y;
01493 return *this;
01494 }
01495
01496 ON_2fPoint& ON_2fPoint::operator=(const ON_3fVector& v)
01497 {
01498 x = v.x;
01499 y = v.y;
01500 return *this;
01501 }
01502
01503 ON_2fPoint& ON_2fPoint::operator=(const ON_2dPoint& p)
01504 {
01505 x = (float)p.x;
01506 y = (float)p.y;
01507 return *this;
01508 }
01509
01510 ON_2fPoint& ON_2fPoint::operator=(const ON_3dPoint& p)
01511 {
01512 x = (float)p.x;
01513 y = (float)p.y;
01514 return *this;
01515 }
01516
01517 ON_2fPoint& ON_2fPoint::operator=(const ON_4dPoint& h)
01518 {
01519 const double w = (h.w != 1.0 && h.w != 0.0) ? 1.0/h.w : 1.0;
01520 x = (float)(w*h.x);
01521 y = (float)(w*h.y);
01522 return *this;
01523 }
01524
01525 ON_2fPoint& ON_2fPoint::operator=(const ON_2dVector& v)
01526 {
01527 x = (float)v.x;
01528 y = (float)v.y;
01529 return *this;
01530 }
01531
01532 ON_2fPoint& ON_2fPoint::operator=(const ON_3dVector& v)
01533 {
01534 x = (float)v.x;
01535 y = (float)v.y;
01536 return *this;
01537 }
01538
01539 ON_2fPoint& ON_2fPoint::operator*=(float d)
01540 {
01541 x *= d;
01542 y *= d;
01543 return *this;
01544 }
01545
01546 ON_2fPoint& ON_2fPoint::operator/=(float d)
01547 {
01548 const float one_over_d = 1.0f/d;
01549 x *= one_over_d;
01550 y *= one_over_d;
01551 return *this;
01552 }
01553
01554 ON_2fPoint& ON_2fPoint::operator+=(const ON_2fPoint& p)
01555 {
01556 x += p.x;
01557 y += p.y;
01558 return *this;
01559 }
01560
01561 ON_2fPoint& ON_2fPoint::operator+=(const ON_2fVector& v)
01562 {
01563 x += v.x;
01564 y += v.y;
01565 return *this;
01566 }
01567
01568 ON_2fPoint& ON_2fPoint::operator+=(const ON_3fVector& v)
01569 {
01570 x += v.x;
01571 y += v.y;
01572 return *this;
01573 }
01574
01575 ON_2fPoint& ON_2fPoint::operator-=(const ON_2fPoint& p)
01576 {
01577 x -= p.x;
01578 y -= p.y;
01579 return *this;
01580 }
01581
01582 ON_2fPoint& ON_2fPoint::operator-=(const ON_2fVector& v)
01583 {
01584 x -= v.x;
01585 y -= v.y;
01586 return *this;
01587 }
01588
01589 ON_2fPoint& ON_2fPoint::operator-=(const ON_3fVector& v)
01590 {
01591 x -= v.x;
01592 y -= v.y;
01593 return *this;
01594 }
01595
01596 ON_2fPoint ON_2fPoint::operator*( int d ) const
01597 {
01598 return ON_2fPoint(x*d,y*d);
01599 }
01600
01601 ON_2fPoint ON_2fPoint::operator*( float d ) const
01602 {
01603 return ON_2fPoint(x*d,y*d);
01604 }
01605
01606 ON_2dPoint ON_2fPoint::operator*( double d ) const
01607 {
01608 return ON_2dPoint(x*d,y*d);
01609 }
01610
01611 ON_2fPoint ON_2fPoint::operator/( int i ) const
01612 {
01613 const float one_over_d = 1.0f/((float)i);
01614 return ON_2fPoint(x*one_over_d,y*one_over_d);
01615 }
01616
01617 ON_2fPoint ON_2fPoint::operator/( float d ) const
01618 {
01619 const float one_over_d = 1.0f/d;
01620 return ON_2fPoint(x*one_over_d,y*one_over_d);
01621 }
01622
01623 ON_2dPoint ON_2fPoint::operator/( double d ) const
01624 {
01625 const double one_over_d = 1.0/d;
01626 return ON_2dPoint(x*one_over_d,y*one_over_d);
01627 }
01628
01629 ON_2fPoint ON_2fPoint::operator+( const ON_2fPoint& p ) const
01630 {
01631 return ON_2fPoint(x+p.x,y+p.y);
01632 }
01633
01634 ON_2fPoint ON_2fPoint::operator+( const ON_2fVector& v ) const
01635 {
01636 return ON_2fPoint(x+v.x,y+v.y);
01637 }
01638
01639 ON_2fVector ON_2fPoint::operator-( const ON_2fPoint& p ) const
01640 {
01641 return ON_2fVector(x-p.x,y-p.y);
01642 }
01643
01644 ON_2fPoint ON_2fPoint::operator-( const ON_2fVector& v ) const
01645 {
01646 return ON_2fPoint(x-v.x,y-v.y);
01647 }
01648
01649 ON_3fPoint ON_2fPoint::operator+( const ON_3fPoint& p ) const
01650 {
01651 return ON_3fPoint(x+p.x,y+p.y,p.z);
01652 }
01653
01654 ON_3fPoint ON_2fPoint::operator+( const ON_3fVector& v ) const
01655 {
01656 return ON_3fPoint(x+v.x,y+v.y,v.z);
01657 }
01658
01659 ON_3fVector ON_2fPoint::operator-( const ON_3fPoint& p ) const
01660 {
01661 return ON_3fVector(x-p.x,y-p.y,-p.y);
01662 }
01663
01664 ON_3fPoint ON_2fPoint::operator-( const ON_3fVector& v ) const
01665 {
01666 return ON_3fPoint(x-v.x,y-v.y,-v.z);
01667 }
01668
01669 ON_2dPoint ON_2fPoint::operator+( const ON_2dPoint& p ) const
01670 {
01671 return ON_2dPoint(x+p.x,y+p.y);
01672 }
01673
01674 ON_2dPoint ON_2fPoint::operator+( const ON_2dVector& v ) const
01675 {
01676 return ON_2dPoint(x+v.x,y+v.y);
01677 }
01678
01679 ON_2dVector ON_2fPoint::operator-( const ON_2dPoint& p ) const
01680 {
01681 return ON_2dVector(x-p.x,y-p.y);
01682 }
01683
01684 ON_2dPoint ON_2fPoint::operator-( const ON_2dVector& v ) const
01685 {
01686 return ON_2dPoint(x-v.x,y-v.y);
01687 }
01688
01689 ON_3dPoint ON_2fPoint::operator+( const ON_3dPoint& p ) const
01690 {
01691 return ON_3dPoint(x+p.x,y+p.y,p.z);
01692 }
01693
01694 ON_3dPoint ON_2fPoint::operator+( const ON_3dVector& v ) const
01695 {
01696 return ON_3dPoint(x+v.x,y+v.y,v.z);
01697 }
01698
01699 ON_3dVector ON_2fPoint::operator-( const ON_3dPoint& p ) const
01700 {
01701 return ON_3dVector(x-p.x,y-p.y,-p.y);
01702 }
01703
01704 ON_3dPoint ON_2fPoint::operator-( const ON_3dVector& v ) const
01705 {
01706 return ON_3dPoint(x-v.x,y-v.y,-v.z);
01707 }
01708
01709
01710 float ON_2fPoint::operator*(const ON_2fPoint& h) const
01711 {
01712 return x*h.x + y*h.y;
01713 }
01714
01715 float ON_2fPoint::operator*(const ON_2fVector& h) const
01716 {
01717 return x*h.x + y*h.y;
01718 }
01719
01720 float ON_2fPoint::operator*(const ON_4fPoint& h) const
01721 {
01722 return x*h.x + y*h.y + h.w;
01723 }
01724
01725 bool ON_2fPoint::operator==( const ON_2fPoint& p ) const
01726 {
01727 return (x==p.x&&y==p.y)?true:false;
01728 }
01729
01730 bool ON_2fPoint::operator!=( const ON_2fPoint& p ) const
01731 {
01732 return (x!=p.x||y!=p.y)?true:false;
01733 }
01734
01735 bool ON_2fPoint::operator<=( const ON_2fPoint& p ) const
01736 {
01737
01738 return ( (x<p.x) ? true : ((x==p.x&&y<=p.y)?true:false) );
01739 }
01740
01741 bool ON_2fPoint::operator>=( const ON_2fPoint& p ) const
01742 {
01743
01744 return ( (x>p.x) ? true : ((x==p.x&&y>=p.y)?true:false) );
01745 }
01746
01747 bool ON_2fPoint::operator<( const ON_2fPoint& p ) const
01748 {
01749
01750 return ( (x<p.x) ? true : ((x==p.x&&y<p.y)?true:false) );
01751 }
01752
01753 bool ON_2fPoint::operator>( const ON_2fPoint& p ) const
01754 {
01755
01756 return ( (x>p.x) ? true : ((x==p.x&&y>p.y)?true:false) );
01757 }
01758
01759 float ON_2fPoint::operator[](int i) const
01760 {
01761 return (i<=0) ? x : y;
01762 }
01763
01764 float& ON_2fPoint::operator[](int i)
01765 {
01766 float* pd = (i<=0)? &x : &y;
01767 return *pd;
01768 }
01769
01770 float ON_2fPoint::operator[](unsigned int i) const
01771 {
01772 return (i<=0) ? x : y;
01773 }
01774
01775 float& ON_2fPoint::operator[](unsigned int i)
01776 {
01777 float* pd = (i<=0)? &x : &y;
01778 return *pd;
01779 }
01780
01781 double ON_2fPoint::DistanceTo( const ON_2fPoint& p ) const
01782 {
01783 return ON_Length2d(p.x-x,p.y-y);
01784 }
01785
01786 int ON_2fPoint::MaximumCoordinateIndex() const
01787 {
01788 return (fabs(y)>fabs(x)) ? 1 : 0;
01789 }
01790
01791 double ON_2fPoint::MaximumCoordinate() const
01792 {
01793 double c = fabs(x); if (fabs(y)>c) c=fabs(y);
01794 return c;
01795 }
01796
01797 void ON_2fPoint::Zero()
01798 {
01799 x = y = 0.0;
01800 }
01801
01802 ON_2fPoint operator*(int d, const ON_2fPoint& p)
01803 {
01804 return ON_2fPoint(d*p.x,d*p.y);
01805 }
01806
01807 ON_2fPoint operator*(float d, const ON_2fPoint& p)
01808 {
01809 return ON_2fPoint(d*p.x,d*p.y);
01810 }
01811
01812 ON_2dPoint operator*(double d, const ON_2fPoint& p)
01813 {
01814 return ON_2dPoint(d*p.x,d*p.y);
01815 }
01816
01818
01819
01820
01821
01822 ON_3fPoint::ON_3fPoint()
01823 {}
01824
01825 ON_3fPoint::ON_3fPoint( const double* p )
01826 {
01827 if (p) {
01828 x = (float)p[0]; y = (float)p[1]; z = (float)p[2];
01829 }
01830 else {
01831 x = y = z = 0.0;
01832 }
01833 }
01834
01835 ON_3fPoint::ON_3fPoint( const float* p )
01836 {
01837 if (p) {
01838 x = p[0]; y = p[1]; z = p[2];
01839 }
01840 else {
01841 x = y = z = 0.0;
01842 }
01843 }
01844
01845 ON_3fPoint::ON_3fPoint(float xx,float yy,float zz)
01846 {x=xx;y=yy;z=zz;}
01847
01848 ON_3fPoint::ON_3fPoint(const ON_2fPoint& p)
01849 {x=p.x;y=p.y;z=0.0;}
01850
01851 ON_3fPoint::ON_3fPoint(const ON_4fPoint& p)
01852 {
01853 const double w = (p.w != 1.0f && p.w != 0.0f) ? 1.0/((double)p.w) : 1.0;
01854 x = (float)(w*p.x);
01855 y = (float)(w*p.y);
01856 z = (float)(w*p.z);
01857 }
01858
01859 ON_3fPoint::ON_3fPoint(const ON_2fVector& v)
01860 {x=v.x;y=v.y;z=0.0f;}
01861
01862 ON_3fPoint::ON_3fPoint(const ON_3fVector& v)
01863 {x=v.x;y=v.y;z=v.z;}
01864
01865 ON_3fPoint::ON_3fPoint(const ON_2dPoint& p)
01866 {x=(float)p.x;y=(float)p.y;z=0.0;}
01867
01868 ON_3fPoint::ON_3fPoint(const ON_3dPoint& p)
01869 {x=(float)p.x;y=(float)p.y;z=(float)p.z;}
01870
01871 ON_3fPoint::ON_3fPoint(const ON_4dPoint& p)
01872 {
01873 const double w = (p.w != 1.0 && p.w != 0.0) ? 1.0/p.w : 1.0;
01874 x = (float)(w*p.x);
01875 y = (float)(w*p.y);
01876 z = (float)(w*p.z);
01877 }
01878
01879 ON_3fPoint::ON_3fPoint(const ON_2dVector& v)
01880 {x=(float)v.x;y=(float)v.y;z=0.0f;}
01881
01882 ON_3fPoint::ON_3fPoint(const ON_3dVector& v)
01883 {x=(float)v.x;y=(float)v.y;z=(float)v.z;}
01884
01885 ON_3fPoint::operator float*()
01886 {
01887 return &x;
01888 }
01889
01890 ON_3fPoint::operator const float*() const
01891 {
01892 return &x;
01893 }
01894
01895 ON_3fPoint& ON_3fPoint::operator=(const double* p)
01896 {
01897 if ( p ) {
01898 x = (float)p[0];
01899 y = (float)p[1];
01900 z = (float)p[2];
01901 }
01902 else {
01903 x = y = z = 0.0;
01904 }
01905 return *this;
01906 }
01907
01908 ON_3fPoint& ON_3fPoint::operator=(const float* p)
01909 {
01910 if ( p ) {
01911 x = p[0];
01912 y = p[1];
01913 z = p[2];
01914 }
01915 else {
01916 x = y = z = 0.0;
01917 }
01918 return *this;
01919 }
01920
01921 ON_3fPoint& ON_3fPoint::operator=(const ON_2fPoint& p)
01922 {
01923 x = p.x;
01924 y = p.y;
01925 z = 0.0;
01926 return *this;
01927 }
01928
01929 ON_3fPoint& ON_3fPoint::operator=(const ON_4fPoint& p)
01930 {
01931 const float w = (p.w != 1.0f && p.w != 0.0f) ? 1.0f/p.w : 1.0f;
01932 x = w*p.x;
01933 y = w*p.y;
01934 z = w*p.z;
01935 return *this;
01936 }
01937
01938 ON_3fPoint& ON_3fPoint::operator=(const ON_2fVector& v)
01939 {
01940 x = v.x;
01941 y = v.y;
01942 z = 0.0f;
01943 return *this;
01944 }
01945
01946 ON_3fPoint& ON_3fPoint::operator=(const ON_3fVector& v)
01947 {
01948 x = v.x;
01949 y = v.y;
01950 z = v.z;
01951 return *this;
01952 }
01953
01954 ON_3fPoint& ON_3fPoint::operator=(const ON_2dPoint& p)
01955 {
01956 x = (float)p.x;
01957 y = (float)p.y;
01958 z = 0.0f;
01959 return *this;
01960 }
01961
01962 ON_3fPoint& ON_3fPoint::operator=(const ON_3dPoint& p)
01963 {
01964 x = (float)p.x;
01965 y = (float)p.y;
01966 z = (float)p.z;
01967 return *this;
01968 }
01969
01970 ON_3fPoint& ON_3fPoint::operator=(const ON_4dPoint& p)
01971 {
01972 const double w = (p.w != 1.0 && p.w != 0.0) ? 1.0/p.w : 1.0;
01973 x = (float)(w*p.x);
01974 y = (float)(w*p.y);
01975 z = (float)(w*p.z);
01976 return *this;
01977 }
01978
01979 ON_3fPoint& ON_3fPoint::operator=(const ON_2dVector& v)
01980 {
01981 x = (float)v.x;
01982 y = (float)v.y;
01983 z = 0.0f;
01984 return *this;
01985 }
01986
01987 ON_3fPoint& ON_3fPoint::operator=(const ON_3dVector& v)
01988 {
01989 x = (float)v.x;
01990 y = (float)v.y;
01991 z = (float)v.z;
01992 return *this;
01993 }
01994
01995 ON_3fPoint& ON_3fPoint::operator*=(float d)
01996 {
01997 x *= d;
01998 y *= d;
01999 z *= d;
02000 return *this;
02001 }
02002
02003 ON_3fPoint& ON_3fPoint::operator/=(float d)
02004 {
02005 const float one_over_d = 1.0f/d;
02006 x *= one_over_d;
02007 y *= one_over_d;
02008 z *= one_over_d;
02009 return *this;
02010 }
02011
02012 ON_3fPoint& ON_3fPoint::operator+=(const ON_3fPoint& p)
02013 {
02014 x += p.x;
02015 y += p.y;
02016 z += p.z;
02017 return *this;
02018 }
02019
02020 ON_3fPoint& ON_3fPoint::operator+=(const ON_3fVector& v)
02021 {
02022 x += v.x;
02023 y += v.y;
02024 z += v.z;
02025 return *this;
02026 }
02027
02028 ON_3fPoint& ON_3fPoint::operator-=(const ON_3fPoint& p)
02029 {
02030 x -= p.x;
02031 y -= p.y;
02032 z -= p.z;
02033 return *this;
02034 }
02035
02036 ON_3fPoint& ON_3fPoint::operator-=(const ON_3fVector& v)
02037 {
02038 x -= v.x;
02039 y -= v.y;
02040 z -= v.z;
02041 return *this;
02042 }
02043
02044 ON_3fPoint ON_3fPoint::operator*( int d ) const
02045 {
02046 return ON_3fPoint(x*d,y*d,z*d);
02047 }
02048
02049 ON_3fPoint ON_3fPoint::operator*( float d ) const
02050 {
02051 return ON_3fPoint(x*d,y*d,z*d);
02052 }
02053
02054 ON_3dPoint ON_3fPoint::operator*( double d ) const
02055 {
02056 return ON_3dPoint(x*d,y*d,z*d);
02057 }
02058
02059 ON_3fPoint ON_3fPoint::operator/( int d ) const
02060 {
02061 const float one_over_d = 1.0f/((float)d);
02062 return ON_3fPoint(x*one_over_d,y*one_over_d,z*one_over_d);
02063 }
02064
02065 ON_3fPoint ON_3fPoint::operator/( float d ) const
02066 {
02067 const float one_over_d = 1.0f/d;
02068 return ON_3fPoint(x*one_over_d,y*one_over_d,z*one_over_d);
02069 }
02070
02071 ON_3dPoint ON_3fPoint::operator/( double d ) const
02072 {
02073 const double one_over_d = 1.0/d;
02074 return ON_3dPoint(x*one_over_d,y*one_over_d,z*one_over_d);
02075 }
02076
02077 ON_3fPoint ON_3fPoint::operator+( const ON_3fPoint& p ) const
02078 {
02079 return ON_3fPoint(x+p.x,y+p.y,z+p.z);
02080 }
02081
02082 ON_3fPoint ON_3fPoint::operator+( const ON_3fVector& v ) const
02083 {
02084 return ON_3fPoint(x+v.x,y+v.y,z+v.z);
02085 }
02086
02087 ON_3fVector ON_3fPoint::operator-( const ON_3fPoint& p ) const
02088 {
02089 return ON_3fVector(x-p.x,y-p.y,z-p.z);
02090 }
02091
02092 ON_3fPoint ON_3fPoint::operator-( const ON_3fVector& v ) const
02093 {
02094 return ON_3fPoint(x-v.x,y-v.y,z-v.z);
02095 }
02096
02097
02098 ON_3fPoint ON_3fPoint::operator+( const ON_2fPoint& p ) const
02099 {
02100 return ON_3fPoint(x+p.x,y+p.y,z);
02101 }
02102
02103 ON_3fPoint ON_3fPoint::operator+( const ON_2fVector& v ) const
02104 {
02105 return ON_3fPoint(x+v.x,y+v.y,z);
02106 }
02107
02108 ON_3fVector ON_3fPoint::operator-( const ON_2fPoint& p ) const
02109 {
02110 return ON_3fVector(x-p.x,y-p.y,z);
02111 }
02112
02113 ON_3fPoint ON_3fPoint::operator-( const ON_2fVector& v ) const
02114 {
02115 return ON_3fPoint(x-v.x,y-v.y,z);
02116 }
02117
02118 ON_3dPoint ON_3fPoint::operator+( const ON_3dPoint& p ) const
02119 {
02120 return ON_3dPoint(x+p.x,y+p.y,z+p.z);
02121 }
02122
02123 ON_3dPoint ON_3fPoint::operator+( const ON_3dVector& v ) const
02124 {
02125 return ON_3dPoint(x+v.x,y+v.y,z+v.z);
02126 }
02127
02128 ON_3dVector ON_3fPoint::operator-( const ON_3dPoint& p ) const
02129 {
02130 return ON_3dVector(x-p.x,y-p.y,z-p.z);
02131 }
02132
02133 ON_3dPoint ON_3fPoint::operator-( const ON_3dVector& v ) const
02134 {
02135 return ON_3dPoint(x-v.x,y-v.y,z-v.z);
02136 }
02137
02138
02139 ON_3dPoint ON_3fPoint::operator+( const ON_2dPoint& p ) const
02140 {
02141 return ON_3dPoint(x+p.x,y+p.y,z);
02142 }
02143
02144 ON_3dPoint ON_3fPoint::operator+( const ON_2dVector& v ) const
02145 {
02146 return ON_3dPoint(x+v.x,y+v.y,z);
02147 }
02148
02149 ON_3dVector ON_3fPoint::operator-( const ON_2dPoint& p ) const
02150 {
02151 return ON_3dVector(x-p.x,y-p.y,z);
02152 }
02153
02154 ON_3dPoint ON_3fPoint::operator-( const ON_2dVector& v ) const
02155 {
02156 return ON_3dPoint(x-v.x,y-v.y,z);
02157 }
02158
02159
02160 float ON_3fPoint::operator*(const ON_3fPoint& h) const
02161 {
02162 return x*h.x + y*h.y + z*h.z;
02163 }
02164
02165 float ON_3fPoint::operator*(const ON_3fVector& h) const
02166 {
02167 return x*h.x + y*h.y + z*h.z;
02168 }
02169
02170 float ON_3fPoint::operator*(const ON_4fPoint& h) const
02171 {
02172 return x*h.x + y*h.y + z*h.z + h.w;
02173 }
02174
02175 bool ON_3fPoint::operator==( const ON_3fPoint& p ) const
02176 {
02177 return (x==p.x&&y==p.y&&z==p.z)?true:false;
02178 }
02179
02180 bool ON_3fPoint::operator!=( const ON_3fPoint& p ) const
02181 {
02182 return (x!=p.x||y!=p.y||z!=p.z)?true:false;
02183 }
02184
02185 bool ON_3fPoint::operator<=( const ON_3fPoint& p ) const
02186 {
02187
02188 return ((x<p.x)?true:((x==p.x)?((y<p.y)?true:(y==p.y&&z<=p.z)?true:false):false));
02189 }
02190
02191 bool ON_3fPoint::operator>=( const ON_3fPoint& p ) const
02192 {
02193
02194 return ((x>p.x)?true:((x==p.x)?((y>p.y)?true:(y==p.y&&z>=p.z)?true:false):false));
02195 }
02196
02197 bool ON_3fPoint::operator<( const ON_3fPoint& p ) const
02198 {
02199
02200 return ((x<p.x)?true:((x==p.x)?((y<p.y)?true:(y==p.y&&z<p.z)?true:false):false));
02201 }
02202
02203 bool ON_3fPoint::operator>( const ON_3fPoint& p ) const
02204 {
02205
02206 return ((x>p.x)?true:((x==p.x)?((y>p.y)?true:(y==p.y&&z>p.z)?true:false):false));
02207 }
02208
02209 float ON_3fPoint::operator[](int i) const
02210 {
02211 return ( (i<=0)?x:((i>=2)?z:y) );
02212 }
02213
02214 float& ON_3fPoint::operator[](int i)
02215 {
02216 float* pd = (i<=0)? &x : ( (i>=2) ? &z : &y);
02217 return *pd;
02218 }
02219
02220 float ON_3fPoint::operator[](unsigned int i) const
02221 {
02222 return ( (i<=0)?x:((i>=2)?z:y) );
02223 }
02224
02225 float& ON_3fPoint::operator[](unsigned int i)
02226 {
02227 float* pd = (i<=0)? &x : ( (i>=2) ? &z : &y);
02228 return *pd;
02229 }
02230
02231 double ON_3fPoint::DistanceTo( const ON_3fPoint& p ) const
02232 {
02233 return ON_Length3d(p.x-x,p.y-y,p.z-z);
02234 }
02235
02236 int ON_3fPoint::MaximumCoordinateIndex() const
02237 {
02238 return (fabs(y)>fabs(x)) ? ((fabs(z)>fabs(y))?2:1) : ((fabs(z)>fabs(x))?2:0);
02239 }
02240
02241 double ON_3fPoint::MaximumCoordinate() const
02242 {
02243 double c = fabs(x); if (fabs(y)>c) c=fabs(y); if (fabs(z)>c) c=fabs(z);
02244 return c;
02245 }
02246
02247 void ON_3fPoint::Zero()
02248 {
02249 x = y = z = 0.0;
02250 }
02251
02252 ON_3fPoint operator*(int d, const ON_3fPoint& p)
02253 {
02254 return ON_3fPoint(d*p.x,d*p.y,d*p.z);
02255 }
02256
02257 ON_3fPoint operator*(float d, const ON_3fPoint& p)
02258 {
02259 return ON_3fPoint(d*p.x,d*p.y,d*p.z);
02260 }
02261
02262 ON_3dPoint operator*(double d, const ON_3fPoint& p)
02263 {
02264 return ON_3dPoint(d*p.x,d*p.y,d*p.z);
02265 }
02266
02268
02269
02270
02271
02272 ON_4fPoint::ON_4fPoint()
02273 {}
02274
02275 ON_4fPoint::ON_4fPoint( const double* p )
02276 {
02277 if (p) {
02278 x = (float)p[0]; y = (float)p[1]; z = (float)p[2]; w = (float)p[3];
02279 }
02280 else {
02281 x = y = z = 0.0; w = 1.0;
02282 }
02283 }
02284
02285 ON_4fPoint::ON_4fPoint( const float* p )
02286 {
02287 if (p) {
02288 x = p[0]; y = p[1]; z = p[2]; w = p[3];
02289 }
02290 else {
02291 x = y = z = 0.0; w = 1.0;
02292 }
02293 }
02294
02295 ON_4fPoint::ON_4fPoint(float xx,float yy,float zz,float ww)
02296 {x=xx;y=yy;z=zz;w=ww;}
02297
02298 ON_4fPoint::ON_4fPoint(const ON_2fPoint& p)
02299 {x=p.x;y=p.y;z=0.0;w=1.0;}
02300
02301 ON_4fPoint::ON_4fPoint(const ON_3fPoint& p)
02302 {
02303 x=p.x;y=p.y;z=p.z;w=1.0;
02304 }
02305
02306 ON_4fPoint::ON_4fPoint(const ON_2fVector& v)
02307 {x=v.x;y=v.y;z=w=0.0;}
02308
02309 ON_4fPoint::ON_4fPoint(const ON_3fVector& v)
02310 {x=v.x;y=v.y;z=v.z;w=0.0;}
02311
02312 ON_4fPoint::ON_4fPoint(const ON_2dPoint& p)
02313 {x=(float)p.x;y=(float)p.y;z=0.0f;w=1.0f;}
02314
02315 ON_4fPoint::ON_4fPoint(const ON_3dPoint& p)
02316 {
02317 x=(float)p.x;y=(float)p.y;z=(float)p.z;w=1.0f;
02318 }
02319
02320 ON_4fPoint::ON_4fPoint(const ON_4dPoint& p)
02321 {
02322 x=(float)p.x;y=(float)p.y;z=(float)p.z;w=(float)p.w;
02323 }
02324
02325 ON_4fPoint::ON_4fPoint(const ON_2dVector& v)
02326 {x=(float)v.x;y=(float)v.y;z=w=0.0f;}
02327
02328 ON_4fPoint::ON_4fPoint(const ON_3dVector& v)
02329 {x=(float)v.x;y=(float)v.y;z=(float)v.z;w=0.0f;}
02330
02331 ON_4fPoint::operator float*()
02332 {
02333 return &x;
02334 }
02335
02336 ON_4fPoint::operator const float*() const
02337 {
02338 return &x;
02339 }
02340
02341 ON_4fPoint& ON_4fPoint::operator=(const double* p)
02342 {
02343 if ( p ) {
02344 x = (float)p[0];
02345 y = (float)p[1];
02346 z = (float)p[2];
02347 w = (float)p[3];
02348 }
02349 else {
02350 x = y = z = 0.0; w = 1.0;
02351 }
02352 return *this;
02353 }
02354
02355 ON_4fPoint& ON_4fPoint::operator=(const float* p)
02356 {
02357 if ( p ) {
02358 x = p[0];
02359 y = p[1];
02360 z = p[2];
02361 w = p[3];
02362 }
02363 else {
02364 x = y = z = 0.0; w = 1.0;
02365 }
02366 return *this;
02367 }
02368
02369 ON_4fPoint& ON_4fPoint::operator=(const ON_2fPoint& p)
02370 {
02371 x = p.x;
02372 y = p.y;
02373 z = 0.0;
02374 w = 1.0;
02375 return *this;
02376 }
02377
02378 ON_4fPoint& ON_4fPoint::operator=(const ON_3fPoint& p)
02379 {
02380 x = p.x;
02381 y = p.y;
02382 z = p.z;
02383 w = 1.0;
02384 return *this;
02385 }
02386
02387 ON_4fPoint& ON_4fPoint::operator=(const ON_2fVector& v)
02388 {
02389 x = v.x;
02390 y = v.y;
02391 z = 0.0;
02392 w = 0.0;
02393 return *this;
02394 }
02395
02396 ON_4fPoint& ON_4fPoint::operator=(const ON_3fVector& v)
02397 {
02398 x = v.x;
02399 y = v.y;
02400 z = v.z;
02401 w = 0.0;
02402 return *this;
02403 }
02404
02405 ON_4fPoint& ON_4fPoint::operator=(const ON_2dPoint& p)
02406 {
02407 x = (float)p.x;
02408 y = (float)p.y;
02409 z = 0.0;
02410 w = 1.0;
02411 return *this;
02412 }
02413
02414 ON_4fPoint& ON_4fPoint::operator=(const ON_3dPoint& p)
02415 {
02416 x = (float)p.x;
02417 y = (float)p.y;
02418 z = (float)p.z;
02419 w = 1.0;
02420 return *this;
02421 }
02422
02423 ON_4fPoint& ON_4fPoint::operator=(const ON_4dPoint& p)
02424 {
02425 x = (float)p.x;
02426 y = (float)p.y;
02427 z = (float)p.z;
02428 w = (float)p.w;
02429 return *this;
02430 }
02431
02432 ON_4fPoint& ON_4fPoint::operator=(const ON_2dVector& v)
02433 {
02434 x = (float)v.x;
02435 y = (float)v.y;
02436 z = 0.0;
02437 w = 0.0;
02438 return *this;
02439 }
02440
02441 ON_4fPoint& ON_4fPoint::operator=(const ON_3dVector& v)
02442 {
02443 x = (float)v.x;
02444 y = (float)v.y;
02445 z = (float)v.z;
02446 w = 0.0;
02447 return *this;
02448 }
02449
02450 ON_4fPoint& ON_4fPoint::operator*=(float d)
02451 {
02452 x *= d;
02453 y *= d;
02454 z *= d;
02455 w *= d;
02456 return *this;
02457 }
02458
02459 ON_4fPoint& ON_4fPoint::operator/=(float d)
02460 {
02461 const float one_over_d = 1.0f/d;
02462 x *= one_over_d;
02463 y *= one_over_d;
02464 z *= one_over_d;
02465 w *= one_over_d;
02466 return *this;
02467 }
02468
02469 ON_4fPoint& ON_4fPoint::operator+=(const ON_4fPoint& p)
02470 {
02471
02472 if ( p.w == w ) {
02473 x += p.x;
02474 y += p.y;
02475 z += p.z;
02476 }
02477 else if (p.w == 0.0 ) {
02478 x += p.x;
02479 y += p.y;
02480 z += p.z;
02481 }
02482 else if ( w == 0.0 ) {
02483 x += p.x;
02484 y += p.y;
02485 z += p.z;
02486 w = p.w;
02487 }
02488 else {
02489 const double sw1 = (w>0.0) ? sqrt(w) : -sqrt(-w);
02490 const double sw2 = (p.w>0.0) ? sqrt(p.w) : -sqrt(-p.w);
02491 const double s1 = sw2/sw1;
02492 const double s2 = sw1/sw2;
02493 x = (float)(x*s1 + p.x*s2);
02494 y = (float)(y*s1 + p.y*s2);
02495 z = (float)(z*s1 + p.z*s2);
02496 w = (float)(sw1*sw2);
02497 }
02498 return *this;
02499 }
02500
02501 ON_4fPoint& ON_4fPoint::operator-=(const ON_4fPoint& p)
02502 {
02503
02504 if ( p.w == w ) {
02505 x -= p.x;
02506 y -= p.y;
02507 z -= p.z;
02508 }
02509 else if (p.w == 0.0 ) {
02510 x -= p.x;
02511 y -= p.y;
02512 z -= p.z;
02513 }
02514 else if ( w == 0.0 ) {
02515 x -= p.x;
02516 y -= p.y;
02517 z -= p.z;
02518 w = p.w;
02519 }
02520 else {
02521 const double sw1 = (w>0.0) ? sqrt(w) : -sqrt(-w);
02522 const double sw2 = (p.w>0.0) ? sqrt(p.w) : -sqrt(-p.w);
02523 const double s1 = sw2/sw1;
02524 const double s2 = sw1/sw2;
02525 x = (float)(x*s1 - p.x*s2);
02526 y = (float)(y*s1 - p.y*s2);
02527 z = (float)(z*s1 - p.z*s2);
02528 w = (float)(sw1*sw2);
02529 }
02530 return *this;
02531 }
02532
02533 ON_4fPoint ON_4fPoint::operator+( const ON_4fPoint& p ) const
02534 {
02535 ON_4fPoint q(x,y,z,w);
02536 q+=p;
02537 return q;
02538 }
02539
02540 ON_4fPoint ON_4fPoint::operator-( const ON_4fPoint& p ) const
02541 {
02542 ON_4fPoint q(x,y,z,w);
02543 q-=p;
02544 return q;
02545 }
02546
02547
02548 ON_4fPoint ON_4fPoint::operator*( float d ) const
02549 {
02550 return ON_4fPoint(x*d,y*d,z*d,w*d);
02551 }
02552
02553 ON_4fPoint ON_4fPoint::operator/( float d ) const
02554 {
02555 const float one_over_d = 1.0f/d;
02556 return ON_4fPoint(x*one_over_d,y*one_over_d,z*one_over_d,w*one_over_d);
02557 }
02558
02559 float ON_4fPoint::operator*(const ON_4fPoint& h) const
02560 {
02561 return x*h.x + y*h.y + z*h.z + w*h.w;
02562 }
02563
02564 bool ON_4fPoint::operator==( ON_4fPoint p ) const
02565 {
02566 ON_4fPoint a = *this; a.Normalize(); p.Normalize();
02567 if ( fabs(a.x-p.x) > ON_SQRT_EPSILON ) return false;
02568 if ( fabs(a.y-p.y) > ON_SQRT_EPSILON ) return false;
02569 if ( fabs(a.z-p.z) > ON_SQRT_EPSILON ) return false;
02570 if ( fabs(a.w-p.w) > ON_SQRT_EPSILON ) return false;
02571 return true;
02572 }
02573
02574 bool ON_4fPoint::operator!=( const ON_4fPoint& p ) const
02575 {
02576 return (*this == p)?false:true;
02577 }
02578
02579 float ON_4fPoint::operator[](int i) const
02580 {
02581 return ((i<=0)?x:((i>=3)?w:((i==1)?y:z)));
02582 }
02583
02584 float& ON_4fPoint::operator[](int i)
02585 {
02586 float* pd = (i<=0) ? &x : ( (i>=3) ? &w : (i==1)?&y:&z);
02587 return *pd;
02588 }
02589
02590 float ON_4fPoint::operator[](unsigned int i) const
02591 {
02592 return ((i<=0)?x:((i>=3)?w:((i==1)?y:z)));
02593 }
02594
02595 float& ON_4fPoint::operator[](unsigned int i)
02596 {
02597 float* pd = (i<=0) ? &x : ( (i>=3) ? &w : (i==1)?&y:&z);
02598 return *pd;
02599 }
02600
02601 int ON_4fPoint::MaximumCoordinateIndex() const
02602 {
02603 const float* a = &x;
02604 int i = ( fabs(y) > fabs(x) ) ? 1 : 0;
02605 if (fabs(z) > fabs(a[i])) i = 2; if (fabs(w) > fabs(a[i])) i = 3;
02606 return i;
02607 }
02608
02609 double ON_4fPoint::MaximumCoordinate() const
02610 {
02611 double c = fabs(x); if (fabs(y)>c) c=fabs(y); if (fabs(z)>c) c=fabs(z); if (fabs(w)>c) c=fabs(w);
02612 return c;
02613 }
02614
02615 void ON_4fPoint::Zero()
02616 {
02617 x = y = z = w = 0.0;
02618 }
02619
02620 ON_4fPoint operator*( float d, const ON_4fPoint& p )
02621 {
02622 return ON_4fPoint( d*p.x, d*p.y, d*p.z, d*p.w );
02623 }
02624
02625 ON_4dPoint operator*( double d, const ON_4fPoint& p )
02626 {
02627 return ON_4dPoint( d*p.x, d*p.y, d*p.z, d*p.w );
02628 }
02629
02631
02632
02633
02634
02635
02636 const ON_2fVector& ON_2fVector::UnitVector(int index)
02637 {
02638 static ON_2fVector o(0.0,0.0);
02639 static ON_2fVector x(1.0,0.0);
02640 static ON_2fVector y(0.0,1.0);
02641 switch(index)
02642 {
02643 case 0:
02644 return x;
02645 case 1:
02646 return y;
02647 }
02648 return o;
02649 }
02650
02651 ON_2fVector::ON_2fVector()
02652 {}
02653
02654 ON_2fVector::ON_2fVector( const double* v )
02655 {
02656 if (v) {
02657 x = (float)v[0]; y = (float)v[1];
02658 }
02659 else {
02660 x = y = 0.0;
02661 }
02662 }
02663
02664 ON_2fVector::ON_2fVector( const float* v )
02665 {
02666 if (v) {
02667 x = v[0]; y = v[1];
02668 }
02669 else {
02670 x = y = 0.0;
02671 }
02672 }
02673
02674 ON_2fVector::ON_2fVector(float xx,float yy)
02675 {x=xx;y=yy;}
02676
02677 ON_2fVector::ON_2fVector(const ON_3fVector& v)
02678 {x=v.x;y=v.y;}
02679
02680 ON_2fVector::ON_2fVector(const ON_2fPoint& p)
02681 {x=p.x;y=p.y;}
02682
02683 ON_2fVector::ON_2fVector(const ON_3fPoint& p)
02684 {x=p.x;y=p.y;}
02685
02686 ON_2fVector::ON_2fVector(const ON_2dVector& v)
02687 {x=(float)v.x;y=(float)v.y;}
02688
02689 ON_2fVector::ON_2fVector(const ON_3dVector& v)
02690 {x=(float)v.x;y=(float)v.y;}
02691
02692 ON_2fVector::ON_2fVector(const ON_2dPoint& p)
02693 {x=(float)p.x;y=(float)p.y;}
02694
02695 ON_2fVector::ON_2fVector(const ON_3dPoint& p)
02696 {x=(float)p.x;y=(float)p.y;}
02697
02698 ON_2fVector::operator float*()
02699 {
02700 return &x;
02701 }
02702
02703 ON_2fVector::operator const float*() const
02704 {
02705 return &x;
02706 }
02707
02708 ON_2fVector& ON_2fVector::operator=(const double* v)
02709 {
02710 if ( v ) {
02711 x = (float)v[0];
02712 y = (float)v[1];
02713 }
02714 else {
02715 x = y = 0.0;
02716 }
02717 return *this;
02718 }
02719
02720 ON_2fVector& ON_2fVector::operator=(const float* v)
02721 {
02722 if ( v ) {
02723 x = v[0];
02724 y = v[1];
02725 }
02726 else {
02727 x = y = 0.0;
02728 }
02729 return *this;
02730 }
02731
02732 ON_2fVector& ON_2fVector::operator=(const ON_3fVector& v)
02733 {
02734 x = v.x;
02735 y = v.y;
02736 return *this;
02737 }
02738
02739 ON_2fVector& ON_2fVector::operator=(const ON_2fPoint& p)
02740 {
02741 x = p.x;
02742 y = p.y;
02743 return *this;
02744 }
02745
02746 ON_2fVector& ON_2fVector::operator=(const ON_3fPoint& p)
02747 {
02748 x = p.x;
02749 y = p.y;
02750 return *this;
02751 }
02752
02753
02754 ON_2fVector& ON_2fVector::operator=(const ON_2dVector& v)
02755 {
02756 x = (float)v.x;
02757 y = (float)v.y;
02758 return *this;
02759 }
02760
02761 ON_2fVector& ON_2fVector::operator=(const ON_3dVector& v)
02762 {
02763 x = (float)v.x;
02764 y = (float)v.y;
02765 return *this;
02766 }
02767
02768 ON_2fVector& ON_2fVector::operator=(const ON_2dPoint& p)
02769 {
02770 x = (float)p.x;
02771 y = (float)p.y;
02772 return *this;
02773 }
02774
02775 ON_2fVector& ON_2fVector::operator=(const ON_3dPoint& p)
02776 {
02777 x = (float)p.x;
02778 y = (float)p.y;
02779 return *this;
02780 }
02781
02782 ON_2fVector ON_2fVector::operator-() const
02783 {
02784 return ON_2fVector(-x,-y);
02785 }
02786
02787 ON_2fVector& ON_2fVector::operator*=(float d)
02788 {
02789 x *= d;
02790 y *= d;
02791 return *this;
02792 }
02793
02794 ON_2fVector& ON_2fVector::operator/=(float d)
02795 {
02796 const float one_over_d = 1.0f/d;
02797 x *= one_over_d;
02798 y *= one_over_d;
02799 return *this;
02800 }
02801
02802 ON_2fVector& ON_2fVector::operator+=(const ON_2fVector& v)
02803 {
02804 x += v.x;
02805 y += v.y;
02806 return *this;
02807 }
02808
02809 ON_2fVector& ON_2fVector::operator-=(const ON_2fVector& v)
02810 {
02811 x -= v.x;
02812 y -= v.y;
02813 return *this;
02814 }
02815
02816 ON_2fVector ON_2fVector::operator*( int d ) const
02817 {
02818 return ON_2fVector(x*d,y*d);
02819 }
02820
02821 ON_2fVector ON_2fVector::operator*( float d ) const
02822 {
02823 return ON_2fVector(x*d,y*d);
02824 }
02825
02826 ON_2dVector ON_2fVector::operator*( double d ) const
02827 {
02828 return ON_2dVector(x*d,y*d);
02829 }
02830
02831 float ON_2fVector::operator*( const ON_2fVector& v ) const
02832 {
02833 return (x*v.x + y*v.y);
02834 }
02835
02836 float ON_2fVector::operator*( const ON_2fPoint& v ) const
02837 {
02838 return (x*v.x + y*v.y);
02839 }
02840
02841 double ON_2fVector::operator*( const ON_2dVector& v ) const
02842 {
02843 return (x*v.x + y*v.y);
02844 }
02845
02846 ON_2fVector ON_2fVector::operator/( int d ) const
02847 {
02848 const float one_over_d = 1.0f/((float)d);
02849 return ON_2fVector(x*one_over_d,y*one_over_d);
02850 }
02851
02852 ON_2fVector ON_2fVector::operator/( float d ) const
02853 {
02854 const float one_over_d = 1.0f/d;
02855 return ON_2fVector(x*one_over_d,y*one_over_d);
02856 }
02857
02858 ON_2dVector ON_2fVector::operator/( double d ) const
02859 {
02860 const double one_over_d = 1.0/d;
02861 return ON_2dVector(x*one_over_d,y*one_over_d);
02862 }
02863
02864 ON_2fVector ON_2fVector::operator+( const ON_2fVector& v ) const
02865 {
02866 return ON_2fVector(x+v.x,y+v.y);
02867 }
02868
02869 ON_2fPoint ON_2fVector::operator+( const ON_2fPoint& p ) const
02870 {
02871 return ON_2fPoint(x+p.x,y+p.y);
02872 }
02873
02874 ON_2fVector ON_2fVector::operator-( const ON_2fVector& v ) const
02875 {
02876 return ON_2fVector(x-v.x,y-v.y);
02877 }
02878
02879 ON_2fPoint ON_2fVector::operator-( const ON_2fPoint& v ) const
02880 {
02881 return ON_2fPoint(x-v.x,y-v.y);
02882 }
02883
02884 ON_3fVector ON_2fVector::operator+( const ON_3fVector& v ) const
02885 {
02886 return ON_3fVector(x+v.x,y+v.y,v.z);
02887 }
02888
02889 ON_3fPoint ON_2fVector::operator+( const ON_3fPoint& p ) const
02890 {
02891 return ON_3fPoint(x+p.x,y+p.y,p.z);
02892 }
02893
02894 ON_3fVector ON_2fVector::operator-( const ON_3fVector& v ) const
02895 {
02896 return ON_3fVector(x-v.x,y-v.y,-v.z);
02897 }
02898
02899 ON_3fPoint ON_2fVector::operator-( const ON_3fPoint& v ) const
02900 {
02901 return ON_3fPoint(x-v.x,y-v.y,-v.z);
02902 }
02903
02905
02906
02907 ON_2dVector ON_2fVector::operator+( const ON_2dVector& v ) const
02908 {
02909 return ON_2dVector(x+v.x,y+v.y);
02910 }
02911
02912 ON_2dPoint ON_2fVector::operator+( const ON_2dPoint& p ) const
02913 {
02914 return ON_2dPoint(x+p.x,y+p.y);
02915 }
02916
02917 ON_2dVector ON_2fVector::operator-( const ON_2dVector& v ) const
02918 {
02919 return ON_2dVector(x-v.x,y-v.y);
02920 }
02921
02922 ON_2dPoint ON_2fVector::operator-( const ON_2dPoint& v ) const
02923 {
02924 return ON_2dPoint(x-v.x,y-v.y);
02925 }
02926
02927 ON_3dVector ON_2fVector::operator+( const ON_3dVector& v ) const
02928 {
02929 return ON_3dVector(x+v.x,y+v.y,v.z);
02930 }
02931
02932 ON_3dPoint ON_2fVector::operator+( const ON_3dPoint& p ) const
02933 {
02934 return ON_3dPoint(x+p.x,y+p.y,p.z);
02935 }
02936
02937 ON_3dVector ON_2fVector::operator-( const ON_3dVector& v ) const
02938 {
02939 return ON_3dVector(x-v.x,y-v.y,-v.z);
02940 }
02941
02942 ON_3dPoint ON_2fVector::operator-( const ON_3dPoint& v ) const
02943 {
02944 return ON_3dPoint(x-v.x,y-v.y,-v.z);
02945 }
02946
02947
02948 float ON_2fVector::operator*(const ON_4fPoint& h) const
02949 {
02950 return x*h.x + y*h.y;
02951 }
02952
02953 bool ON_2fVector::operator==( const ON_2fVector& v ) const
02954 {
02955 return (x==v.x&&y==v.y)?true:false;
02956 }
02957
02958 bool ON_2fVector::operator!=( const ON_2fVector& v ) const
02959 {
02960 return (x!=v.x||y!=v.y)?true:false;
02961 }
02962
02963 bool ON_2fVector::operator<=( const ON_2fVector& v ) const
02964 {
02965
02966 return ((x<v.x)?true:((x==v.x&&y<=v.y)?true:false));
02967 }
02968
02969 bool ON_2fVector::operator>=( const ON_2fVector& v ) const
02970 {
02971
02972 return ((x>v.x)?true:((x==v.x&&y>=v.y)?true:false));
02973 }
02974
02975 bool ON_2fVector::operator<( const ON_2fVector& v ) const
02976 {
02977
02978 return ((x<v.x)?true:((x==v.x&&y<v.y)?true:false));
02979 }
02980
02981 bool ON_2fVector::operator>( const ON_2fVector& v ) const
02982 {
02983
02984 return ((x>v.x)?true:((x==v.x&&y>v.y)?true:false));
02985 }
02986
02987 float ON_2fVector::operator[](int i) const
02988 {
02989 return ((i<=0)?x:y);
02990 }
02991
02992 float& ON_2fVector::operator[](int i)
02993 {
02994 float* pd = (i<=0)? &x : &y;
02995 return *pd;
02996 }
02997
02998 float ON_2fVector::operator[](unsigned int i) const
02999 {
03000 return ((i<=0)?x:y);
03001 }
03002
03003 float& ON_2fVector::operator[](unsigned int i)
03004 {
03005 float* pd = (i<=0)? &x : &y;
03006 return *pd;
03007 }
03008
03009 int ON_2fVector::MaximumCoordinateIndex() const
03010 {
03011 return ( (fabs(y)>fabs(x)) ? 1 : 0 );
03012 }
03013
03014 double ON_2fVector::MaximumCoordinate() const
03015 {
03016 double c = fabs(x); if (fabs(y)>c) c=fabs(y);
03017 return c;
03018 }
03019
03020 double ON_2fVector::LengthSquared() const
03021 {
03022 return (x*x + y*y);
03023 }
03024
03025 double ON_2fVector::Length() const
03026 {
03027 return ON_Length2d((double)x,(double)y);
03028 }
03029
03030 void ON_2fVector::Zero()
03031 {
03032 x = y = 0.0;
03033 }
03034
03035 void ON_2fVector::Reverse()
03036 {
03037 x = -x;
03038 y = -y;
03039 }
03040
03041 bool ON_2fVector::Unitize()
03042 {
03043 bool rc = false;
03044
03045
03046 double d = Length();
03047 if ( d > 0.0 )
03048 {
03049 double dx = (double)x;
03050 double dy = (double)y;
03051 x = (float)(dx/d);
03052 y = (float)(dy/d);
03053 rc = true;
03054 }
03055 return rc;
03056 }
03057
03058 bool ON_2fVector::IsUnitVector() const
03059 {
03060 return (x != ON_UNSET_FLOAT && y != ON_UNSET_FLOAT && fabs(Length() - 1.0) <= 1.0e-5);
03061 }
03062
03063 bool ON_3fVector::IsUnitVector() const
03064 {
03065 return (x != ON_UNSET_FLOAT && y != ON_UNSET_FLOAT && z != ON_UNSET_FLOAT && fabs(Length() - 1.0) <= 1.0e-5);
03066 }
03067
03068 bool ON_2fVector::IsTiny( double tiny_tol ) const
03069 {
03070 return (fabs(x) <= tiny_tol && fabs(y) <= tiny_tol );
03071 }
03072
03073 bool ON_2fVector::IsZero() const
03074 {
03075 return (x==0.0f && y==0.0f);
03076 }
03077
03078
03079 bool ON_2fVector::PerpendicularTo(
03080
03081 const ON_2fVector& v
03082 )
03083 {
03084 y = v.x;
03085 x = -v.y;
03086 return (x!= 0.0f || y!= 0.0f) ? true : false;
03087 }
03088
03089
03090 bool ON_2fVector::PerpendicularTo(
03091 const ON_2fPoint& p,
03092 const ON_2fPoint& q
03093 )
03094 {
03095 return PerpendicularTo(q-p);
03096 }
03097
03098 ON_2fVector operator*(int d, const ON_2fVector& v)
03099 {
03100 return ON_2fVector(d*v.x,d*v.y);
03101 }
03102
03103 ON_2fVector operator*(float d, const ON_2fVector& v)
03104 {
03105 return ON_2fVector(d*v.x,d*v.y);
03106 }
03107
03108 ON_2dVector operator*(double d, const ON_2fVector& v)
03109 {
03110 return ON_2dVector(d*v.x,d*v.y);
03111 }
03112
03113 float ON_DotProduct( const ON_2fVector& a , const ON_2fVector& b )
03114 {
03115
03116 return (a.x*b.x + a.y*b.y );
03117 }
03118
03119 ON_3fVector ON_CrossProduct( const ON_2fVector& a , const ON_2fVector& b )
03120 {
03121 return ON_3fVector(0.0, 0.0, a.x*b.y - b.x*a.y );
03122 }
03123
03125
03126
03127
03128
03129
03130 const ON_3fVector& ON_3fVector::UnitVector(int index)
03131 {
03132 static ON_3fVector o(0.0,0.0,0.0);
03133 static ON_3fVector x(1.0,0.0,0.0);
03134 static ON_3fVector y(0.0,1.0,0.0);
03135 static ON_3fVector z(0.0,0.0,1.0);
03136 switch(index)
03137 {
03138 case 0:
03139 return x;
03140 case 1:
03141 return y;
03142 case 2:
03143 return z;
03144 }
03145 return o;
03146 }
03147
03148 ON_3fVector::ON_3fVector()
03149 {}
03150
03151 ON_3fVector::ON_3fVector( const double* v )
03152 {
03153 if (v) {
03154 x = (float)v[0]; y = (float)v[1]; z = (float)v[2];
03155 }
03156 else {
03157 x = y = z = 0.0;
03158 }
03159 }
03160
03161 ON_3fVector::ON_3fVector( const float* v )
03162 {
03163 if (v) {
03164 x = v[0]; y = v[1]; z = v[2];
03165 }
03166 else {
03167 x = y = z = 0.0;
03168 }
03169 }
03170
03171 ON_3fVector::ON_3fVector(float xx,float yy,float zz)
03172 {x=xx;y=yy;z=zz;}
03173
03174 ON_3fVector::ON_3fVector(const ON_2fVector& v)
03175 {x=v.x;y=v.y;z=0.0f;}
03176
03177 ON_3fVector::ON_3fVector(const ON_2fPoint& p)
03178 {x=p.x;y=p.y;z=0.0f;}
03179
03180 ON_3fVector::ON_3fVector(const ON_3fPoint& p)
03181 {x=p.x;y=p.y;z=p.z;}
03182
03183 ON_3fVector::ON_3fVector(const ON_2dVector& v)
03184 {x=(float)v.x;y=(float)v.y;z=(float)0.0f;}
03185
03186 ON_3fVector::ON_3fVector(const ON_3dVector& v)
03187 {x=(float)v.x;y=(float)v.y;z=(float)v.z;}
03188
03189 ON_3fVector::ON_3fVector(const ON_2dPoint& p)
03190 {x=(float)p.x;y=(float)p.y;z=(float)0.0f;}
03191
03192 ON_3fVector::ON_3fVector(const ON_3dPoint& p)
03193 {x=(float)p.x;y=(float)p.y;z=(float)p.z;}
03194
03195 ON_3fVector::operator float*()
03196 {
03197 return &x;
03198 }
03199
03200 ON_3fVector::operator const float*() const
03201 {
03202 return &x;
03203 }
03204
03205 ON_3fVector& ON_3fVector::operator=(const double* v)
03206 {
03207 if ( v ) {
03208 x = (float)v[0];
03209 y = (float)v[1];
03210 z = (float)v[2];
03211 }
03212 else {
03213 x = y = z = 0.0;
03214 }
03215 return *this;
03216 }
03217
03218 ON_3fVector& ON_3fVector::operator=(const float* v)
03219 {
03220 if ( v ) {
03221 x = v[0];
03222 y = v[1];
03223 z = v[2];
03224 }
03225 else {
03226 x = y = z = 0.0;
03227 }
03228 return *this;
03229 }
03230
03231 ON_3fVector& ON_3fVector::operator=(const ON_2fVector& v)
03232 {
03233 x = v.x;
03234 y = v.y;
03235 z = 0.0;
03236 return *this;
03237 }
03238
03239 ON_3fVector& ON_3fVector::operator=(const ON_2fPoint& p)
03240 {
03241 x = p.x;
03242 y = p.y;
03243 z = 0.0f;
03244 return *this;
03245 }
03246
03247 ON_3fVector& ON_3fVector::operator=(const ON_3fPoint& p)
03248 {
03249 x = p.x;
03250 y = p.y;
03251 z = p.z;
03252 return *this;
03253 }
03254
03255
03256 ON_3fVector& ON_3fVector::operator=(const ON_2dVector& v)
03257 {
03258 x = (float)v.x;
03259 y = (float)v.y;
03260 z = 0.0f;
03261 return *this;
03262 }
03263
03264 ON_3fVector& ON_3fVector::operator=(const ON_3dVector& v)
03265 {
03266 x = (float)v.x;
03267 y = (float)v.y;
03268 z = (float)v.z;
03269 return *this;
03270 }
03271
03272 ON_3fVector& ON_3fVector::operator=(const ON_2dPoint& p)
03273 {
03274 x = (float)p.x;
03275 y = (float)p.y;
03276 z = 0.0f;
03277 return *this;
03278 }
03279
03280 ON_3fVector& ON_3fVector::operator=(const ON_3dPoint& p)
03281 {
03282 x = (float)p.x;
03283 y = (float)p.y;
03284 z = (float)p.z;
03285 return *this;
03286 }
03287
03288 ON_3fVector ON_3fVector::operator-() const
03289 {
03290 return ON_3fVector(-x,-y,-z);
03291 }
03292
03293 ON_3fVector& ON_3fVector::operator*=(float d)
03294 {
03295 x *= d;
03296 y *= d;
03297 z *= d;
03298 return *this;
03299 }
03300
03301 ON_3fVector& ON_3fVector::operator/=(float d)
03302 {
03303 const float one_over_d = 1.0f/d;
03304 x *= one_over_d;
03305 y *= one_over_d;
03306 z *= one_over_d;
03307 return *this;
03308 }
03309
03310 ON_3fVector& ON_3fVector::operator+=(const ON_3fVector& v)
03311 {
03312 x += v.x;
03313 y += v.y;
03314 z += v.z;
03315 return *this;
03316 }
03317
03318 ON_3fVector& ON_3fVector::operator-=(const ON_3fVector& v)
03319 {
03320 x -= v.x;
03321 y -= v.y;
03322 z -= v.z;
03323 return *this;
03324 }
03325
03326 ON_3fVector ON_3fVector::operator*( int d ) const
03327 {
03328 return ON_3fVector(x*d,y*d,z*d);
03329 }
03330
03331 ON_3fVector ON_3fVector::operator*( float d ) const
03332 {
03333 return ON_3fVector(x*d,y*d,z*d);
03334 }
03335
03336 ON_3dVector ON_3fVector::operator*( double d ) const
03337 {
03338 return ON_3dVector(x*d,y*d,z*d);
03339 }
03340
03341 float ON_3fVector::operator*( const ON_3fVector& v ) const
03342 {
03343 return (x*v.x + y*v.y + z*v.z);
03344 }
03345
03346 float ON_3fVector::operator*( const ON_3fPoint& v ) const
03347 {
03348 return (x*v.x + y*v.y + z*v.z);
03349 }
03350
03351 double ON_3fVector::operator*( const ON_3dVector& v ) const
03352 {
03353 return (x*v.x + y*v.y + z*v.z);
03354 }
03355
03356 ON_3fVector ON_3fVector::operator/( int d ) const
03357 {
03358 const float one_over_d = 1.0f/((int)d);
03359 return ON_3fVector(x*one_over_d,y*one_over_d,z*one_over_d);
03360 }
03361
03362 ON_3fVector ON_3fVector::operator/( float d ) const
03363 {
03364 const float one_over_d = 1.0f/d;
03365 return ON_3fVector(x*one_over_d,y*one_over_d,z*one_over_d);
03366 }
03367
03368 ON_3dVector ON_3fVector::operator/( double d ) const
03369 {
03370 const double one_over_d = 1.0/d;
03371 return ON_3dVector(x*one_over_d,y*one_over_d,z*one_over_d);
03372 }
03373
03374 ON_3fVector ON_3fVector::operator+( const ON_3fVector& v ) const
03375 {
03376 return ON_3fVector(x+v.x,y+v.y,z+v.z);
03377 }
03378
03379 ON_3fPoint ON_3fVector::operator+( const ON_3fPoint& p ) const
03380 {
03381 return ON_3fPoint(x+p.x,y+p.y,z+p.z);
03382 }
03383
03384 ON_3fVector ON_3fVector::operator-( const ON_3fVector& v ) const
03385 {
03386 return ON_3fVector(x-v.x,y-v.y,z-v.z);
03387 }
03388
03389 ON_3fPoint ON_3fVector::operator-( const ON_3fPoint& v ) const
03390 {
03391 return ON_3fPoint(x-v.x,y-v.y,z-v.z);
03392 }
03393
03394 ON_3fVector ON_3fVector::operator+( const ON_2fVector& v ) const
03395 {
03396 return ON_3fVector(x+v.x,y+v.y,z);
03397 }
03398
03399 ON_3fPoint ON_3fVector::operator+( const ON_2fPoint& p ) const
03400 {
03401 return ON_3fPoint(x+p.x,y+p.y,z);
03402 }
03403
03404 ON_3fVector ON_3fVector::operator-( const ON_2fVector& v ) const
03405 {
03406 return ON_3fVector(x-v.x,y-v.y,z);
03407 }
03408
03409 ON_3fPoint ON_3fVector::operator-( const ON_2fPoint& v ) const
03410 {
03411 return ON_3fPoint(x-v.x,y-v.y,z);
03412 }
03413
03415
03416
03417 ON_3dVector ON_3fVector::operator+( const ON_3dVector& v ) const
03418 {
03419 return ON_3dVector(x+v.x,y+v.y,z+v.z);
03420 }
03421
03422 ON_3dPoint ON_3fVector::operator+( const ON_3dPoint& p ) const
03423 {
03424 return ON_3dPoint(x+p.x,y+p.y,z+p.z);
03425 }
03426
03427 ON_3dVector ON_3fVector::operator-( const ON_3dVector& v ) const
03428 {
03429 return ON_3dVector(x-v.x,y-v.y,z-v.z);
03430 }
03431
03432 ON_3dPoint ON_3fVector::operator-( const ON_3dPoint& v ) const
03433 {
03434 return ON_3dPoint(x-v.x,y-v.y,z-v.z);
03435 }
03436
03437 ON_3dVector ON_3fVector::operator+( const ON_2dVector& v ) const
03438 {
03439 return ON_3dVector(x+v.x,y+v.y,z);
03440 }
03441
03442 ON_3dPoint ON_3fVector::operator+( const ON_2dPoint& p ) const
03443 {
03444 return ON_3dPoint(x+p.x,y+p.y,z);
03445 }
03446
03447 ON_3dVector ON_3fVector::operator-( const ON_2dVector& v ) const
03448 {
03449 return ON_3dVector(x-v.x,y-v.y,z);
03450 }
03451
03452 ON_3dPoint ON_3fVector::operator-( const ON_2dPoint& v ) const
03453 {
03454 return ON_3dPoint(x-v.x,y-v.y,z);
03455 }
03456
03457
03458 float ON_3fVector::operator*(const ON_4fPoint& h) const
03459 {
03460 return x*h.x + y*h.y + z*h.z;
03461 }
03462
03463 bool ON_3fVector::operator==( const ON_3fVector& v ) const
03464 {
03465 return (x==v.x&&y==v.y&&z==v.z)?true:false;
03466 }
03467
03468 bool ON_3fVector::operator!=( const ON_3fVector& v ) const
03469 {
03470 return (x!=v.x||y!=v.y||z!=v.z)?true:false;
03471 }
03472
03473 bool ON_3fVector::operator<=( const ON_3fVector& v ) const
03474 {
03475
03476 return ((x<v.x)?true:((x==v.x)?((y<v.y)?true:(y==v.y&&z<=v.z)?true:false):false));
03477 }
03478
03479 bool ON_3fVector::operator>=( const ON_3fVector& v ) const
03480 {
03481
03482 return ((x>v.x)?true:((x==v.x)?((y>v.y)?true:(y==v.y&&z>=v.z)?true:false):false));
03483 }
03484
03485 bool ON_3fVector::operator<( const ON_3fVector& v ) const
03486 {
03487
03488 return ((x<v.x)?true:((x==v.x)?((y<v.y)?true:(y==v.y&&z<v.z)?true:false):false));
03489 }
03490
03491 bool ON_3fVector::operator>( const ON_3fVector& v ) const
03492 {
03493
03494 return ((x>v.x)?true:((x==v.x)?((y>v.y)?true:(y==v.y&&z>v.z)?true:false):false));
03495 }
03496
03497 float ON_3fVector::operator[](int i) const
03498 {
03499 return ( (i<=0)?x:((i>=2)?z:y) );
03500 }
03501
03502 float& ON_3fVector::operator[](int i)
03503 {
03504 float* pd = (i<=0)? &x : ( (i>=2) ? &z : &y);
03505 return *pd;
03506 }
03507
03508 float ON_3fVector::operator[](unsigned int i) const
03509 {
03510 return ( (i<=0)?x:((i>=2)?z:y) );
03511 }
03512
03513 float& ON_3fVector::operator[](unsigned int i)
03514 {
03515 float* pd = (i<=0)? &x : ( (i>=2) ? &z : &y);
03516 return *pd;
03517 }
03518
03519 int ON_3fVector::MaximumCoordinateIndex() const
03520 {
03521 return (fabs(y)>fabs(x)) ? ((fabs(z)>fabs(y))?2:1) : ((fabs(z)>fabs(x))?2:0);
03522 }
03523
03524 double ON_3fVector::MaximumCoordinate() const
03525 {
03526 double c = fabs(x); if (fabs(y)>c) c=fabs(y); if (fabs(z)>c) c=fabs(z);
03527 return c;
03528 }
03529
03530 double ON_3fVector::LengthSquared() const
03531 {
03532 return (x*x + y*y + z*z);
03533 }
03534
03535 double ON_3fVector::Length() const
03536 {
03537 return ON_Length3d((double)x,(double)y,(double)z);
03538 }
03539
03540 void ON_3fVector::Zero()
03541 {
03542 x = y = z = 0.0;
03543 }
03544
03545 void ON_3fVector::Reverse()
03546 {
03547 x = -x;
03548 y = -y;
03549 z = -z;
03550 }
03551
03552 bool ON_3fVector::Unitize()
03553 {
03554 bool rc = false;
03555
03556
03557 double d = Length();
03558 if ( d > 0.0 )
03559 {
03560 double dx = x;
03561 double dy = y;
03562 double dz = z;
03563 x = (float)(dx/d);
03564 y = (float)(dy/d);
03565 z = (float)(dz/d);
03566 rc = true;
03567 }
03568 return rc;
03569 }
03570
03571 bool ON_3fVector::IsTiny( double tiny_tol ) const
03572 {
03573 return (fabs(x) <= tiny_tol && fabs(y) <= tiny_tol && fabs(z) <= tiny_tol );
03574 }
03575
03576 bool ON_3fVector::IsZero() const
03577 {
03578 return (x==0.0f && y==0.0f && z==0.0f);
03579 }
03580
03581
03582 ON_3fVector operator*(int d, const ON_3fVector& v)
03583 {
03584 return ON_3fVector(d*v.x,d*v.y,d*v.z);
03585 }
03586
03587 ON_3fVector operator*(float d, const ON_3fVector& v)
03588 {
03589 return ON_3fVector(d*v.x,d*v.y,d*v.z);
03590 }
03591
03592 ON_3dVector operator*(double d, const ON_3fVector& v)
03593 {
03594 return ON_3dVector(d*v.x,d*v.y,d*v.z);
03595 }
03596
03597 float ON_DotProduct( const ON_3fVector& a , const ON_3fVector& b )
03598 {
03599
03600 return (a.x*b.x + a.y*b.y + a.z*b.z);
03601 }
03602
03603 ON_3fVector ON_CrossProduct( const ON_3fVector& a , const ON_3fVector& b )
03604 {
03605 return ON_3fVector(a.y*b.z - b.y*a.z, a.z*b.x - b.z*a.x, a.x*b.y - b.x*a.y );
03606 }
03607
03608 ON_3fVector ON_CrossProduct( const float* a, const float* b )
03609 {
03610 return ON_3fVector(a[1]*b[2] - b[1]*a[2], a[2]*b[0] - b[2]*a[0], a[0]*b[1] - b[0]*a[1] );
03611 }
03612
03613 float ON_TripleProduct( const ON_3fVector& a, const ON_3fVector& b, const ON_3fVector& c )
03614 {
03615
03616 return (a.x*(b.y*c.z - b.z*c.y) + a.y*(b.z*c.x - b.x*c.z) + a.z*(b.x*c.y - b.y*c.x));
03617 }
03618
03619 float ON_TripleProduct( const float* a, const float* b, const float* c )
03620 {
03621
03622 return (a[0]*(b[1]*c[2] - b[2]*c[1]) + a[1]*(b[2]*c[0] - b[0]*c[2]) + a[2]*(b[0]*c[1] - b[1]*c[0]));
03623 }
03624
03626
03627
03628
03629
03630 ON_2dPoint::ON_2dPoint()
03631 {}
03632
03633 ON_2dPoint::ON_2dPoint( const float* p )
03634 {
03635 if (p) {
03636 x = (double)p[0]; y = (double)p[1];
03637 }
03638 else {
03639 x = y = 0.0;
03640 }
03641 }
03642
03643 ON_2dPoint::ON_2dPoint( const double* p )
03644 {
03645 if (p) {
03646 x = p[0]; y = p[1];
03647 }
03648 else {
03649 x = y = 0.0;
03650 }
03651 }
03652
03653 ON_2dPoint::ON_2dPoint(double xx,double yy)
03654 {x=xx;y=yy;}
03655
03656 ON_2dPoint::ON_2dPoint(const ON_3dPoint& p)
03657 {x=p.x;y=p.y;}
03658
03659 ON_2dPoint::ON_2dPoint(const ON_4dPoint& h)
03660 {
03661 x=h.x;y=h.y;
03662 const double w = (h.w != 1.0 && h.w != 0.0) ? 1.0/h.w : 1.0;
03663 x *= w;
03664 y *= w;
03665 }
03666
03667 ON_2dPoint::ON_2dPoint(const ON_2dVector& v)
03668 {x=v.x;y=v.y;}
03669
03670 ON_2dPoint::ON_2dPoint(const ON_3dVector& v)
03671 {x=v.x;y=v.y;}
03672
03673 ON_2dPoint::ON_2dPoint(const ON_2fPoint& p)
03674 {x=p.x;y=p.y;}
03675
03676 ON_2dPoint::ON_2dPoint(const ON_3fPoint& p)
03677 {x=p.x;y=p.y;}
03678
03679 ON_2dPoint::ON_2dPoint(const ON_4fPoint& h)
03680 {
03681 const double w = (h.w != 1.0f && h.w != 0.0f) ? 1.0/((double)h.w) : 1.0;
03682 x *= w*h.x;
03683 y *= w*h.y;
03684 }
03685
03686 ON_2dPoint::ON_2dPoint(const ON_2fVector& v)
03687 {x=v.x;y=v.y;}
03688
03689 ON_2dPoint::ON_2dPoint(const ON_3fVector& v)
03690 {x=v.x;y=v.y;}
03691
03692 ON_2dPoint::operator double*()
03693 {
03694 return &x;
03695 }
03696
03697 ON_2dPoint::operator const double*() const
03698 {
03699 return &x;
03700 }
03701
03702 ON_2dPoint& ON_2dPoint::operator=(const float* p)
03703 {
03704 if ( p ) {
03705 x = (double)p[0];
03706 y = (double)p[1];
03707 }
03708 else {
03709 x = y = 0.0;
03710 }
03711 return *this;
03712 }
03713
03714 ON_2dPoint& ON_2dPoint::operator=(const double* p)
03715 {
03716 if ( p ) {
03717 x = p[0];
03718 y = p[1];
03719 }
03720 else {
03721 x = y = 0.0;
03722 }
03723 return *this;
03724 }
03725
03726 ON_2dPoint& ON_2dPoint::operator=(const ON_3dPoint& p)
03727 {
03728 x = p.x;
03729 y = p.y;
03730 return *this;
03731 }
03732
03733 ON_2dPoint& ON_2dPoint::operator=(const ON_4dPoint& h)
03734 {
03735 const double w = (h.w != 1.0 && h.w != 0.0) ? 1.0/h.w : 1.0;
03736 x = w*h.x;
03737 y = w*h.y;
03738 return *this;
03739 }
03740
03741 ON_2dPoint& ON_2dPoint::operator=(const ON_2dVector& v)
03742 {
03743 x = v.x;
03744 y = v.y;
03745 return *this;
03746 }
03747
03748 ON_2dPoint& ON_2dPoint::operator=(const ON_3dVector& v)
03749 {
03750 x = v.x;
03751 y = v.y;
03752 y = v.z;
03753 return *this;
03754 }
03755
03756 ON_2dPoint& ON_2dPoint::operator=(const ON_2fPoint& p)
03757 {
03758 x = p.x;
03759 y = p.y;
03760 return *this;
03761 }
03762
03763 ON_2dPoint& ON_2dPoint::operator=(const ON_3fPoint& p)
03764 {
03765 x = p.x;
03766 y = p.y;
03767 return *this;
03768 }
03769
03770 ON_2dPoint& ON_2dPoint::operator=(const ON_4fPoint& h)
03771 {
03772 const double w = (h.w != 1.0f && h.w != 0.0f) ? 1.0/((double)h.w) : 1.0;
03773 x = w*h.x;
03774 y = w*h.y;
03775 return *this;
03776 }
03777
03778 ON_2dPoint& ON_2dPoint::operator=(const ON_2fVector& v)
03779 {
03780 x = v.x;
03781 y = v.y;
03782 return *this;
03783 }
03784
03785 ON_2dPoint& ON_2dPoint::operator=(const ON_3fVector& v)
03786 {
03787 x = v.x;
03788 y = v.y;
03789 y = v.z;
03790 return *this;
03791 }
03792
03793 ON_2dPoint& ON_2dPoint::operator*=(double d)
03794 {
03795 x *= d;
03796 y *= d;
03797 return *this;
03798 }
03799
03800 ON_2dPoint& ON_2dPoint::operator/=(double d)
03801 {
03802 const double one_over_d = 1.0/d;
03803 x *= one_over_d;
03804 y *= one_over_d;
03805 return *this;
03806 }
03807
03808 ON_2dPoint& ON_2dPoint::operator+=(const ON_2dPoint& p)
03809 {
03810 x += p.x;
03811 y += p.y;
03812 return *this;
03813 }
03814
03815 ON_2dPoint& ON_2dPoint::operator+=(const ON_2dVector& v)
03816 {
03817 x += v.x;
03818 y += v.y;
03819 return *this;
03820 }
03821
03822 ON_2dPoint& ON_2dPoint::operator+=(const ON_3dVector& v)
03823 {
03824 x += v.x;
03825 y += v.y;
03826 return *this;
03827 }
03828
03829 ON_2dPoint& ON_2dPoint::operator-=(const ON_2dPoint& p)
03830 {
03831 x -= p.x;
03832 y -= p.y;
03833 return *this;
03834 }
03835
03836 ON_2dPoint& ON_2dPoint::operator-=(const ON_2dVector& v)
03837 {
03838 x -= v.x;
03839 y -= v.y;
03840 return *this;
03841 }
03842
03843 ON_2dPoint& ON_2dPoint::operator-=(const ON_3dVector& v)
03844 {
03845 x -= v.x;
03846 y -= v.y;
03847 return *this;
03848 }
03849
03850 ON_2dPoint ON_2dPoint::operator*( int i ) const
03851 {
03852 double d = i;
03853 return ON_2dPoint(x*d,y*d);
03854 }
03855
03856 ON_2dPoint ON_2dPoint::operator*( float f ) const
03857 {
03858 double d = f;
03859 return ON_2dPoint(x*d,y*d);
03860 }
03861
03862 ON_2dPoint ON_2dPoint::operator*( double d ) const
03863 {
03864 return ON_2dPoint(x*d,y*d);
03865 }
03866
03867 ON_2dPoint ON_2dPoint::operator/( int i ) const
03868 {
03869 const double one_over_d = 1.0/((double)i);
03870 return ON_2dPoint(x*one_over_d,y*one_over_d);
03871 }
03872
03873 ON_2dPoint ON_2dPoint::operator/( float f ) const
03874 {
03875 const double one_over_d = 1.0/((double)f);
03876 return ON_2dPoint(x*one_over_d,y*one_over_d);
03877 }
03878
03879 ON_2dPoint ON_2dPoint::operator/( double d ) const
03880 {
03881 const double one_over_d = 1.0/d;
03882 return ON_2dPoint(x*one_over_d,y*one_over_d);
03883 }
03884
03885 ON_2dPoint ON_2dPoint::operator+( const ON_2dPoint& p ) const
03886 {
03887 return ON_2dPoint(x+p.x,y+p.y);
03888 }
03889
03890 ON_2dPoint ON_2dPoint::operator+( const ON_2dVector& v ) const
03891 {
03892 return ON_2dPoint(x+v.x,y+v.y);
03893 }
03894
03895 ON_2dVector ON_2dPoint::operator-( const ON_2dPoint& p ) const
03896 {
03897 return ON_2dVector(x-p.x,y-p.y);
03898 }
03899
03900 ON_2dPoint ON_2dPoint::operator-( const ON_2dVector& v ) const
03901 {
03902 return ON_2dPoint(x-v.x,y-v.y);
03903 }
03904
03905
03906 ON_3dPoint ON_2dPoint::operator+( const ON_3dPoint& p ) const
03907 {
03908 return ON_3dPoint(x+p.x,y+p.y,p.z);
03909 }
03910
03911 ON_3dPoint ON_2dPoint::operator+( const ON_3dVector& v ) const
03912 {
03913 return ON_3dPoint(x+v.x,y+v.y,v.z);
03914 }
03915
03916 ON_3dVector ON_2dPoint::operator-( const ON_3dPoint& p ) const
03917 {
03918 return ON_3dVector(x-p.x,y-p.y,-p.z);
03919 }
03920
03921 ON_3dPoint ON_2dPoint::operator-( const ON_3dVector& v ) const
03922 {
03923 return ON_3dPoint(x-v.x,y-v.y,-v.z);
03924 }
03925
03927
03928
03929 ON_2dPoint ON_2dPoint::operator+( const ON_2fPoint& p ) const
03930 {
03931 return ON_2dPoint(x+p.x,y+p.y);
03932 }
03933
03934 ON_2dPoint ON_2dPoint::operator+( const ON_2fVector& v ) const
03935 {
03936 return ON_2dPoint(x+v.x,y+v.y);
03937 }
03938
03939 ON_2dVector ON_2dPoint::operator-( const ON_2fPoint& p ) const
03940 {
03941 return ON_2dVector(x-p.x,y-p.y);
03942 }
03943
03944 ON_2dPoint ON_2dPoint::operator-( const ON_2fVector& v ) const
03945 {
03946 return ON_2dPoint(x-v.x,y-v.y);
03947 }
03948
03949
03950 ON_3dPoint ON_2dPoint::operator+( const ON_3fPoint& p ) const
03951 {
03952 return ON_3dPoint(x+p.x,y+p.y,p.z);
03953 }
03954
03955 ON_3dPoint ON_2dPoint::operator+( const ON_3fVector& v ) const
03956 {
03957 return ON_3dPoint(x+v.x,y+v.y,v.z);
03958 }
03959
03960 ON_3dVector ON_2dPoint::operator-( const ON_3fPoint& p ) const
03961 {
03962 return ON_3dVector(x-p.x,y-p.y,-p.z);
03963 }
03964
03965 ON_3dPoint ON_2dPoint::operator-( const ON_3fVector& v ) const
03966 {
03967 return ON_3dPoint(x-v.x,y-v.y,-v.z);
03968 }
03969
03970
03971 double ON_2dPoint::operator*(const ON_2dPoint& h) const
03972 {
03973 return x*h.x + y*h.y;
03974 }
03975
03976 double ON_2dPoint::operator*(const ON_2dVector& h) const
03977 {
03978 return x*h.x + y*h.y;
03979 }
03980
03981 double ON_2dPoint::operator*(const ON_4dPoint& h) const
03982 {
03983 return x*h.x + y*h.y + h.w;
03984 }
03985
03986 bool ON_2dPoint::operator==( const ON_2dPoint& p ) const
03987 {
03988 return (x==p.x&&y==p.y)?true:false;
03989 }
03990
03991 bool ON_2dPoint::operator!=( const ON_2dPoint& p ) const
03992 {
03993 return (x!=p.x||y!=p.y)?true:false;
03994 }
03995
03996 bool ON_2dPoint::operator<=( const ON_2dPoint& p ) const
03997 {
03998
03999 return ( (x<p.x) ? true : ((x==p.x&&y<=p.y)?true:false) );
04000 }
04001
04002 bool ON_2dPoint::operator>=( const ON_2dPoint& p ) const
04003 {
04004
04005 return ( (x>p.x) ? true : ((x==p.x&&y>=p.y)?true:false) );
04006 }
04007
04008 bool ON_2dPoint::operator<( const ON_2dPoint& p ) const
04009 {
04010
04011 return ( (x<p.x) ? true : ((x==p.x&&y<p.y)?true:false) );
04012 }
04013
04014 bool ON_2dPoint::operator>( const ON_2dPoint& p ) const
04015 {
04016
04017 return ( (x>p.x) ? true : ((x==p.x&&y>p.y)?true:false) );
04018 }
04019
04020 double ON_2dPoint::operator[](int i) const
04021 {
04022 return (i<=0) ? x : y;
04023 }
04024
04025 double& ON_2dPoint::operator[](int i)
04026 {
04027 double* pd = (i<=0)? &x : &y;
04028 return *pd;
04029 }
04030
04031 double ON_2dPoint::operator[](unsigned int i) const
04032 {
04033 return (i<=0) ? x : y;
04034 }
04035
04036 double& ON_2dPoint::operator[](unsigned int i)
04037 {
04038 double* pd = (i<=0)? &x : &y;
04039 return *pd;
04040 }
04041
04042 double ON_2dPoint::DistanceTo( const ON_2dPoint& p ) const
04043 {
04044 return ON_Length2d(p.x-x,p.y-y);
04045 }
04046
04047 int ON_2dPoint::MaximumCoordinateIndex() const
04048 {
04049 return (fabs(y)>fabs(x)) ? 1 : 0;
04050 }
04051
04052 double ON_2dPoint::MaximumCoordinate() const
04053 {
04054 double c = fabs(x); if (fabs(y)>c) c=fabs(y);
04055 return c;
04056 }
04057
04058 int ON_2dPoint::MinimumCoordinateIndex() const
04059 {
04060 return (fabs(y)<fabs(x)) ? 1 : 0;
04061 }
04062
04063 double ON_2dPoint::MinimumCoordinate() const
04064 {
04065 double c = fabs(x); if (fabs(y)<c) c=fabs(y);
04066 return c;
04067 }
04068
04069
04070 void ON_2dPoint::Zero()
04071 {
04072 x = y = 0.0;
04073 }
04074
04075 ON_2dPoint operator*(int i, const ON_2dPoint& p)
04076 {
04077 double d = i;
04078 return ON_2dPoint(d*p.x,d*p.y);
04079 }
04080
04081 ON_2dPoint operator*(float f, const ON_2dPoint& p)
04082 {
04083 double d = f;
04084 return ON_2dPoint(d*p.x,d*p.y);
04085 }
04086
04087 ON_2dPoint operator*(double d, const ON_2dPoint& p)
04088 {
04089 return ON_2dPoint(d*p.x,d*p.y);
04090 }
04091
04093
04094
04095
04096
04097 ON_3dPoint::ON_3dPoint()
04098 {}
04099
04100 ON_3dPoint::ON_3dPoint( const float* p )
04101 {
04102 if (p) {
04103 x = (double)p[0]; y = (double)p[1]; z = (double)p[2];
04104 }
04105 else {
04106 x = y = z = 0.0;
04107 }
04108 }
04109
04110 ON_3dPoint::ON_3dPoint(const ON_2fPoint& p)
04111 {x=(double)p.x;y=(double)p.y;z=0.0;}
04112
04113 ON_3dPoint::ON_3dPoint(const ON_3fPoint& p)
04114 {x=(double)p.x;y=(double)p.y;z=(double)p.z;}
04115
04116 ON_3dPoint::ON_3dPoint(const ON_4fPoint& p)
04117 {
04118 const double w = (p.w != 1.0f && p.w != 0.0f) ? 1.0/((double)p.w) : 1.0;
04119 x = w*((double)p.x);
04120 y = w*((double)p.y);
04121 z = w*((double)p.z);
04122 }
04123
04124 ON_3dPoint::ON_3dPoint(const ON_2fVector& p)
04125 {x=(double)p.x;y=(double)p.y;z=0.0;}
04126
04127 ON_3dPoint::ON_3dPoint(const ON_3fVector& p)
04128 {x=(double)p.x;y=(double)p.y;z=(double)p.z;}
04129
04130 ON_3dRay::ON_3dRay()
04131 {}
04132
04133 ON_3dRay::~ON_3dRay()
04134 {}
04135
04136 ON_3dPoint::ON_3dPoint( const double* p )
04137 {
04138 if (p) {
04139 x = p[0]; y = p[1]; z = p[2];
04140 }
04141 else {
04142 x = y = z = 0.0;
04143 }
04144 }
04145
04146 ON_3dPoint::ON_3dPoint(double xx,double yy,double zz)
04147 {x=xx;y=yy;z=zz;}
04148
04149 ON_3dPoint::ON_3dPoint(const ON_2dPoint& p)
04150 {x=p.x;y=p.y;z=0.0;}
04151
04152 ON_3dPoint::ON_3dPoint(const ON_4dPoint& p)
04153 {
04154 x=p.x;y=p.y;z=p.z;
04155 const double w = (p.w != 1.0 && p.w != 0.0) ? 1.0/p.w : 1.0;
04156 x *= w;
04157 y *= w;
04158 z *= w;
04159 }
04160
04161 ON_3dPoint::ON_3dPoint(const ON_2dVector& v)
04162 {x=v.x;y=v.y;z=0.0;}
04163
04164 ON_3dPoint::ON_3dPoint(const ON_3dVector& v)
04165 {x=v.x;y=v.y;z=v.z;}
04166
04167 ON_3dPoint::operator double*()
04168 {
04169 return &x;
04170 }
04171
04172 ON_3dPoint::operator const double*() const
04173 {
04174 return &x;
04175 }
04176
04177 ON_3dPoint& ON_3dPoint::operator=(const float* p)
04178 {
04179 if ( p ) {
04180 x = (double)p[0];
04181 y = (double)p[1];
04182 z = (double)p[2];
04183 }
04184 else {
04185 x = y = z = 0.0;
04186 }
04187 return *this;
04188 }
04189
04190 ON_3dPoint& ON_3dPoint::operator=(const double* p)
04191 {
04192 if ( p ) {
04193 x = p[0];
04194 y = p[1];
04195 z = p[2];
04196 }
04197 else {
04198 x = y = z = 0.0;
04199 }
04200 return *this;
04201 }
04202
04203 ON_3dPoint& ON_3dPoint::operator=(const ON_2dPoint& p)
04204 {
04205 x = p.x;
04206 y = p.y;
04207 z = 0.0;
04208 return *this;
04209 }
04210
04211 ON_3dPoint& ON_3dPoint::operator=(const ON_4dPoint& p)
04212 {
04213 const double w = (p.w != 1.0 && p.w != 0.0) ? 1.0/p.w : 1.0;
04214 x = w*p.x;
04215 y = w*p.y;
04216 z = w*p.z;
04217 return *this;
04218 }
04219
04220 ON_3dPoint& ON_3dPoint::operator=(const ON_2dVector& v)
04221 {
04222 x = v.x;
04223 y = v.y;
04224 z = 0.0;
04225 return *this;
04226 }
04227
04228 ON_3dPoint& ON_3dPoint::operator=(const ON_3dVector& v)
04229 {
04230 x = v.x;
04231 y = v.y;
04232 z = v.z;
04233 return *this;
04234 }
04235
04236 ON_3dPoint& ON_3dPoint::operator=(const ON_2fPoint& p)
04237 {
04238 x = (double)p.x;
04239 y = (double)p.y;
04240 z = (double)0.0;
04241 return *this;
04242 }
04243
04244 ON_3dPoint& ON_3dPoint::operator=(const ON_3fPoint& p)
04245 {
04246 x = (double)p.x;
04247 y = (double)p.y;
04248 z = (double)p.z;
04249 return *this;
04250 }
04251
04252 ON_3dPoint& ON_3dPoint::operator=(const ON_4fPoint& p)
04253 {
04254 const double w = (p.w != 1.0f && p.w != 0.0f) ? 1.0/((double)p.w) : 1.0;
04255 x = w*((double)p.x);
04256 y = w*((double)p.y);
04257 z = w*((double)p.z);
04258 return *this;
04259 }
04260
04261 ON_3dPoint& ON_3dPoint::operator=(const ON_2fVector& v)
04262 {
04263 x = v.x;
04264 y = v.y;
04265 z = 0.0;
04266 return *this;
04267 }
04268
04269 ON_3dPoint& ON_3dPoint::operator=(const ON_3fVector& v)
04270 {
04271 x = v.x;
04272 y = v.y;
04273 z = v.z;
04274 return *this;
04275 }
04276
04277
04278 ON_3dPoint& ON_3dPoint::operator*=(double d)
04279 {
04280 x *= d;
04281 y *= d;
04282 z *= d;
04283 return *this;
04284 }
04285
04286 ON_3dPoint& ON_3dPoint::operator/=(double d)
04287 {
04288 const double one_over_d = 1.0/d;
04289 x *= one_over_d;
04290 y *= one_over_d;
04291 z *= one_over_d;
04292 return *this;
04293 }
04294
04295 ON_3dPoint& ON_3dPoint::operator+=(const ON_3dPoint& p)
04296 {
04297 x += p.x;
04298 y += p.y;
04299 z += p.z;
04300 return *this;
04301 }
04302
04303 ON_3dPoint& ON_3dPoint::operator+=(const ON_3dVector& v)
04304 {
04305 x += v.x;
04306 y += v.y;
04307 z += v.z;
04308 return *this;
04309 }
04310
04311 ON_3dPoint& ON_3dPoint::operator-=(const ON_3dPoint& p)
04312 {
04313 x -= p.x;
04314 y -= p.y;
04315 z -= p.z;
04316 return *this;
04317 }
04318
04319 ON_3dPoint& ON_3dPoint::operator-=(const ON_3dVector& v)
04320 {
04321 x -= v.x;
04322 y -= v.y;
04323 z -= v.z;
04324 return *this;
04325 }
04326
04327 ON_3dPoint ON_3dPoint::operator*( int i ) const
04328 {
04329 double d = i;
04330 return ON_3dPoint(x*d,y*d,z*d);
04331 }
04332
04333 ON_3dPoint ON_3dPoint::operator*( float f ) const
04334 {
04335 double d = f;
04336 return ON_3dPoint(x*d,y*d,z*d);
04337 }
04338
04339 ON_3dPoint ON_3dPoint::operator*( double d ) const
04340 {
04341 return ON_3dPoint(x*d,y*d,z*d);
04342 }
04343
04344 ON_3dPoint ON_3dPoint::operator/( int i ) const
04345 {
04346 const double one_over_d = 1.0/((double)i);
04347 return ON_3dPoint(x*one_over_d,y*one_over_d,z*one_over_d);
04348 }
04349
04350 ON_3dPoint ON_3dPoint::operator/( float f ) const
04351 {
04352 const double one_over_d = 1.0/((double)f);
04353 return ON_3dPoint(x*one_over_d,y*one_over_d,z*one_over_d);
04354 }
04355
04356 ON_3dPoint ON_3dPoint::operator/( double d ) const
04357 {
04358 const double one_over_d = 1.0/d;
04359 return ON_3dPoint(x*one_over_d,y*one_over_d,z*one_over_d);
04360 }
04361
04362 ON_3dPoint ON_3dPoint::operator+( const ON_3dPoint& p ) const
04363 {
04364 return ON_3dPoint(x+p.x,y+p.y,z+p.z);
04365 }
04366
04367 ON_3dPoint ON_3dPoint::operator+( const ON_3dVector& v ) const
04368 {
04369 return ON_3dPoint(x+v.x,y+v.y,z+v.z);
04370 }
04371
04372 ON_3dVector ON_3dPoint::operator-( const ON_3dPoint& p ) const
04373 {
04374 return ON_3dVector(x-p.x,y-p.y,z-p.z);
04375 }
04376
04377 ON_3dPoint ON_3dPoint::operator-( const ON_3dVector& v ) const
04378 {
04379 return ON_3dPoint(x-v.x,y-v.y,z-v.z);
04380 }
04381
04382 ON_3dPoint ON_3dPoint::operator+( const ON_2dPoint& p ) const
04383 {
04384 return ON_3dPoint(x+p.x,y+p.y,z);
04385 }
04386
04387 ON_3dPoint ON_3dPoint::operator+( const ON_2dVector& v ) const
04388 {
04389 return ON_3dPoint(x+v.x,y+v.y,z);
04390 }
04391
04392 ON_3dVector ON_3dPoint::operator-( const ON_2dPoint& p ) const
04393 {
04394 return ON_3dVector(x-p.x,y-p.y,z);
04395 }
04396
04397 ON_3dPoint ON_3dPoint::operator-( const ON_2dVector& v ) const
04398 {
04399 return ON_3dPoint(x-v.x,y-v.y,z);
04400 }
04401
04402 ON_3dPoint ON_3dPoint::operator+( const ON_3fPoint& p ) const
04403 {
04404 return ON_3dPoint(x+p.x,y+p.y,z+p.z);
04405 }
04406
04407 ON_3dPoint ON_3dPoint::operator+( const ON_3fVector& v ) const
04408 {
04409 return ON_3dPoint(x+v.x,y+v.y,z+v.z);
04410 }
04411
04412 ON_3dVector ON_3dPoint::operator-( const ON_3fPoint& p ) const
04413 {
04414 return ON_3dVector(x-p.x,y-p.y,z-p.z);
04415 }
04416
04417 ON_3dPoint ON_3dPoint::operator-( const ON_3fVector& v ) const
04418 {
04419 return ON_3dPoint(x-v.x,y-v.y,z-v.z);
04420 }
04421
04422 ON_3dPoint ON_3dPoint::operator+( const ON_2fPoint& p ) const
04423 {
04424 return ON_3dPoint(x+p.x,y+p.y,z);
04425 }
04426
04427 ON_3dPoint ON_3dPoint::operator+( const ON_2fVector& v ) const
04428 {
04429 return ON_3dPoint(x+v.x,y+v.y,z);
04430 }
04431
04432 ON_3dVector ON_3dPoint::operator-( const ON_2fPoint& p ) const
04433 {
04434 return ON_3dVector(x-p.x,y-p.y,z);
04435 }
04436
04437 ON_3dPoint ON_3dPoint::operator-( const ON_2fVector& v ) const
04438 {
04439 return ON_3dPoint(x-v.x,y-v.y,z);
04440 }
04441
04442 double ON_3dPoint::operator*(const ON_3dPoint& h) const
04443 {
04444 return x*h.x + y*h.y + z*h.z;
04445 }
04446
04447 double ON_3dPoint::operator*(const ON_3dVector& h) const
04448 {
04449 return x*h.x + y*h.y + z*h.z;
04450 }
04451
04452 double ON_3dPoint::operator*(const ON_4dPoint& h) const
04453 {
04454 return x*h.x + y*h.y + z*h.z + h.w;
04455 }
04456
04457 bool ON_3dPoint::operator==( const ON_3dPoint& p ) const
04458 {
04459 return (x==p.x&&y==p.y&&z==p.z)?true:false;
04460 }
04461
04462 bool ON_3dPoint::operator!=( const ON_3dPoint& p ) const
04463 {
04464 return (x!=p.x||y!=p.y||z!=p.z)?true:false;
04465 }
04466
04467 bool ON_3dPoint::operator<=( const ON_3dPoint& p ) const
04468 {
04469
04470 return ((x<p.x)?true:((x==p.x)?((y<p.y)?true:(y==p.y&&z<=p.z)?true:false):false));
04471 }
04472
04473 bool ON_3dPoint::operator>=( const ON_3dPoint& p ) const
04474 {
04475
04476 return ((x>p.x)?true:((x==p.x)?((y>p.y)?true:(y==p.y&&z>=p.z)?true:false):false));
04477 }
04478
04479 bool ON_3dPoint::operator<( const ON_3dPoint& p ) const
04480 {
04481
04482 return ((x<p.x)?true:((x==p.x)?((y<p.y)?true:(y==p.y&&z<p.z)?true:false):false));
04483 }
04484
04485 bool ON_3dPoint::operator>( const ON_3dPoint& p ) const
04486 {
04487
04488 return ((x>p.x)?true:((x==p.x)?((y>p.y)?true:(y==p.y&&z>p.z)?true:false):false));
04489 }
04490
04491 double ON_3dPoint::operator[](int i) const
04492 {
04493 return ( (i<=0)?x:((i>=2)?z:y) );
04494 }
04495
04496 double& ON_3dPoint::operator[](int i)
04497 {
04498 double* pd = (i<=0)? &x : ( (i>=2) ? &z : &y);
04499 return *pd;
04500 }
04501
04502 double ON_3dPoint::operator[](unsigned int i) const
04503 {
04504 return ( (i<=0)?x:((i>=2)?z:y) );
04505 }
04506
04507 double& ON_3dPoint::operator[](unsigned int i)
04508 {
04509 double* pd = (i<=0)? &x : ( (i>=2) ? &z : &y);
04510 return *pd;
04511 }
04512
04513 double ON_3dPoint::DistanceTo( const ON_3dPoint& p ) const
04514 {
04515 return ON_Length3d(p.x-x,p.y-y,p.z-z);
04516 }
04517
04518 int ON_3dPoint::MaximumCoordinateIndex() const
04519 {
04520 return (fabs(y)>fabs(x)) ? ((fabs(z)>fabs(y))?2:1) : ((fabs(z)>fabs(x))?2:0);
04521 }
04522
04523 double ON_3dPoint::MaximumCoordinate() const
04524 {
04525 double c = fabs(x); if (fabs(y)>c) c=fabs(y); if (fabs(z)>c) c=fabs(z);
04526 return c;
04527 }
04528
04529 int ON_3dPoint::MinimumCoordinateIndex() const
04530 {
04531 return (fabs(y)<fabs(x)) ? ((fabs(z)<fabs(y))?2:1) : ((fabs(z)<fabs(x))?2:0);
04532 }
04533
04534 double ON_3dPoint::MinimumCoordinate() const
04535 {
04536 double c = fabs(x); if (fabs(y)<c) c=fabs(y); if (fabs(z)<c) c=fabs(z);
04537 return c;
04538 }
04539
04540 void ON_3dPoint::Zero()
04541 {
04542 x = y = z = 0.0;
04543 }
04544
04545 ON_3dPoint operator*(int i, const ON_3dPoint& p)
04546 {
04547 double d = i;
04548 return ON_3dPoint(d*p.x,d*p.y,d*p.z);
04549 }
04550
04551 ON_3dPoint operator*(float f, const ON_3dPoint& p)
04552 {
04553 double d = f;
04554 return ON_3dPoint(d*p.x,d*p.y,d*p.z);
04555 }
04556
04557 ON_3dPoint operator*(double d, const ON_3dPoint& p)
04558 {
04559 return ON_3dPoint(d*p.x,d*p.y,d*p.z);
04560 }
04561
04563
04564
04565
04566
04567 ON_4dPoint::ON_4dPoint()
04568 {}
04569
04570 ON_4dPoint::ON_4dPoint( const float* p )
04571 {
04572 if (p) {
04573 x = (double)p[0]; y = (double)p[1]; z = (double)p[2]; w = (double)p[3];
04574 }
04575 else {
04576 x = y = z = 0.0; w = 1.0;
04577 }
04578 }
04579
04580 ON_4dPoint::ON_4dPoint( const double* p )
04581 {
04582 if (p) {
04583 x = p[0]; y = p[1]; z = p[2]; w = p[3];
04584 }
04585 else {
04586 x = y = z = 0.0; w = 1.0;
04587 }
04588 }
04589
04590 ON_4dPoint::ON_4dPoint(double xx,double yy,double zz,double ww)
04591 {x=xx;y=yy;z=zz;w=ww;}
04592
04593 ON_4dPoint::ON_4dPoint(const ON_2dPoint& p)
04594 {x=p.x;y=p.y;z=0.0;w=1.0;}
04595
04596 ON_4dPoint::ON_4dPoint(const ON_3dPoint& p)
04597 {
04598 x=p.x;y=p.y;z=p.z;w=1.0;
04599 }
04600
04601 ON_4dPoint::ON_4dPoint(const ON_2dVector& v)
04602 {x=v.x;y=v.y;z=w=0.0;}
04603
04604 ON_4dPoint::ON_4dPoint(const ON_3dVector& v)
04605 {x=v.x;y=v.y;z=v.z;w=0.0;}
04606
04607
04608 ON_4dPoint::ON_4dPoint(const ON_2fPoint& p)
04609 {x=p.x;y=p.y;z=0.0;w=1.0;}
04610
04611 ON_4dPoint::ON_4dPoint(const ON_3fPoint& p)
04612 {
04613 x=p.x;y=p.y;z=p.z;w=1.0;
04614 }
04615
04616 ON_4dPoint::ON_4dPoint(const ON_4fPoint& p)
04617 {
04618 x=p.x;y=p.y;z=p.z;w=p.w;
04619 }
04620
04621 ON_4dPoint::ON_4dPoint(const ON_2fVector& v)
04622 {x=v.x;y=v.y;z=w=0.0;}
04623
04624 ON_4dPoint::ON_4dPoint(const ON_3fVector& v)
04625 {x=v.x;y=v.y;z=v.z;w=0.0;}
04626
04627 ON_4dPoint::operator double*()
04628 {
04629 return &x;
04630 }
04631
04632 ON_4dPoint::operator const double*() const
04633 {
04634 return &x;
04635 }
04636
04637 ON_4dPoint& ON_4dPoint::operator=(const float* p)
04638 {
04639 if ( p ) {
04640 x = (double)p[0];
04641 y = (double)p[1];
04642 z = (double)p[2];
04643 w = (double)p[3];
04644 }
04645 else {
04646 x = y = z = 0.0; w = 1.0;
04647 }
04648 return *this;
04649 }
04650
04651 ON_4dPoint& ON_4dPoint::operator=(const double* p)
04652 {
04653 if ( p ) {
04654 x = p[0];
04655 y = p[1];
04656 z = p[2];
04657 w = p[3];
04658 }
04659 else {
04660 x = y = z = 0.0; w = 1.0;
04661 }
04662 return *this;
04663 }
04664
04665 ON_4dPoint& ON_4dPoint::operator=(const ON_2dPoint& p)
04666 {
04667 x = p.x;
04668 y = p.y;
04669 z = 0.0;
04670 w = 1.0;
04671 return *this;
04672 }
04673
04674 ON_4dPoint& ON_4dPoint::operator=(const ON_3dPoint& p)
04675 {
04676 x = p.x;
04677 y = p.y;
04678 z = p.z;
04679 w = 1.0;
04680 return *this;
04681 }
04682
04683 ON_4dPoint& ON_4dPoint::operator=(const ON_2dVector& v)
04684 {
04685 x = v.x;
04686 y = v.y;
04687 z = 0.0;
04688 w = 0.0;
04689 return *this;
04690 }
04691
04692 ON_4dPoint& ON_4dPoint::operator=(const ON_3dVector& v)
04693 {
04694 x = v.x;
04695 y = v.y;
04696 z = v.z;
04697 w = 0.0;
04698 return *this;
04699 }
04700
04701 ON_4dPoint& ON_4dPoint::operator=(const ON_2fPoint& p)
04702 {
04703 x = (double)p.x;
04704 y = (double)p.y;
04705 z = 0.0;
04706 w = 1.0;
04707 return *this;
04708 }
04709
04710 ON_4dPoint& ON_4dPoint::operator=(const ON_3fPoint& p)
04711 {
04712 x = (double)p.x;
04713 y = (double)p.y;
04714 z = (double)p.z;
04715 w = 1.0;
04716 return *this;
04717 }
04718
04719 ON_4dPoint& ON_4dPoint::operator=(const ON_4fPoint& p)
04720 {
04721 x = (double)p.x;
04722 y = (double)p.y;
04723 z = (double)p.z;
04724 w = (double)p.w;
04725 return *this;
04726 }
04727
04728 ON_4dPoint& ON_4dPoint::operator=(const ON_2fVector& v)
04729 {
04730 x = (double)v.x;
04731 y = (double)v.y;
04732 z = 0.0;
04733 w = 0.0;
04734 return *this;
04735 }
04736
04737 ON_4dPoint& ON_4dPoint::operator=(const ON_3fVector& v)
04738 {
04739 x = (double)v.x;
04740 y = (double)v.y;
04741 z = (double)v.z;
04742 w = 0.0;
04743 return *this;
04744 }
04745
04746
04747 ON_4dPoint& ON_4dPoint::operator*=(double d)
04748 {
04749 x *= d;
04750 y *= d;
04751 z *= d;
04752 w *= d;
04753 return *this;
04754 }
04755
04756 ON_4dPoint& ON_4dPoint::operator/=(double d)
04757 {
04758 const double one_over_d = 1.0/d;
04759 x *= one_over_d;
04760 y *= one_over_d;
04761 z *= one_over_d;
04762 w *= one_over_d;
04763 return *this;
04764 }
04765
04766 ON_4dPoint& ON_4dPoint::operator+=(const ON_4dPoint& p)
04767 {
04768
04769 if ( p.w == w ) {
04770 x += p.x;
04771 y += p.y;
04772 z += p.z;
04773 }
04774 else if (p.w == 0.0 ) {
04775 x += p.x;
04776 y += p.y;
04777 z += p.z;
04778 }
04779 else if ( w == 0.0 ) {
04780 x += p.x;
04781 y += p.y;
04782 z += p.z;
04783 w = p.w;
04784 }
04785 else {
04786 const double sw1 = (w>0.0) ? sqrt(w) : -sqrt(-w);
04787 const double sw2 = (p.w>0.0) ? sqrt(p.w) : -sqrt(-p.w);
04788 const double s1 = sw2/sw1;
04789 const double s2 = sw1/sw2;
04790 x = x*s1 + p.x*s2;
04791 y = y*s1 + p.y*s2;
04792 z = z*s1 + p.z*s2;
04793 w = sw1*sw2;
04794 }
04795 return *this;
04796 }
04797
04798 ON_4dPoint& ON_4dPoint::operator-=(const ON_4dPoint& p)
04799 {
04800
04801 if ( p.w == w ) {
04802 x -= p.x;
04803 y -= p.y;
04804 z -= p.z;
04805 }
04806 else if (p.w == 0.0 ) {
04807 x -= p.x;
04808 y -= p.y;
04809 z -= p.z;
04810 }
04811 else if ( w == 0.0 ) {
04812 x -= p.x;
04813 y -= p.y;
04814 z -= p.z;
04815 w = p.w;
04816 }
04817 else {
04818 const double sw1 = (w>0.0) ? sqrt(w) : -sqrt(-w);
04819 const double sw2 = (p.w>0.0) ? sqrt(p.w) : -sqrt(-p.w);
04820 const double s1 = sw2/sw1;
04821 const double s2 = sw1/sw2;
04822 x = x*s1 - p.x*s2;
04823 y = y*s1 - p.y*s2;
04824 z = z*s1 - p.z*s2;
04825 w = sw1*sw2;
04826 }
04827 return *this;
04828 }
04829
04830 ON_4dPoint ON_4dPoint::operator+( const ON_4dPoint& p ) const
04831 {
04832 ON_4dPoint q(x,y,z,w);
04833 q+=p;
04834 return q;
04835 }
04836
04837 ON_4dPoint ON_4dPoint::operator-( const ON_4dPoint& p ) const
04838 {
04839 ON_4dPoint q(x,y,z,w);
04840 q-=p;
04841 return q;
04842 }
04843
04844 ON_4dPoint ON_4dPoint::operator*( double d ) const
04845 {
04846 return ON_4dPoint(x*d,y*d,z*d,w*d);
04847 }
04848
04849 ON_4dPoint ON_4dPoint::operator/( double d ) const
04850 {
04851 const double one_over_d = 1.0/d;
04852 return ON_4dPoint(x*one_over_d,y*one_over_d,z*one_over_d,w*one_over_d);
04853 }
04854
04855 double ON_4dPoint::operator*(const ON_4dPoint& h) const
04856 {
04857 return x*h.x + y*h.y + z*h.z + w*h.w;
04858 }
04859
04860 bool ON_4dPoint::operator==( ON_4dPoint p ) const
04861 {
04862 ON_4dPoint a = *this; a.Normalize(); p.Normalize();
04863 if ( fabs(a.x-p.x) > ON_SQRT_EPSILON ) return false;
04864 if ( fabs(a.y-p.y) > ON_SQRT_EPSILON ) return false;
04865 if ( fabs(a.z-p.z) > ON_SQRT_EPSILON ) return false;
04866 if ( fabs(a.w-p.w) > ON_SQRT_EPSILON ) return false;
04867 return true;
04868 }
04869
04870 bool ON_4dPoint::operator!=( const ON_4dPoint& p ) const
04871 {
04872 return (*this == p)?false:true;
04873 }
04874
04875 double ON_4dPoint::operator[](int i) const
04876 {
04877 return ((i<=0)?x:((i>=3)?w:((i==1)?y:z)));
04878 }
04879
04880 double& ON_4dPoint::operator[](int i)
04881 {
04882 double* pd = (i<=0) ? &x : ( (i>=3) ? &w : (i==1)?&y:&z);
04883 return *pd;
04884 }
04885
04886 double ON_4dPoint::operator[](unsigned int i) const
04887 {
04888 return ((i<=0)?x:((i>=3)?w:((i==1)?y:z)));
04889 }
04890
04891 double& ON_4dPoint::operator[](unsigned int i)
04892 {
04893 double* pd = (i<=0) ? &x : ( (i>=3) ? &w : (i==1)?&y:&z);
04894 return *pd;
04895 }
04896
04897 int ON_4dPoint::MaximumCoordinateIndex() const
04898 {
04899 const double* a = &x;
04900 int i = ( fabs(y) > fabs(x) ) ? 1 : 0;
04901 if (fabs(z) > fabs(a[i])) i = 2; if (fabs(w) > fabs(a[i])) i = 3;
04902 return i;
04903 }
04904
04905 double ON_4dPoint::MaximumCoordinate() const
04906 {
04907 double c = fabs(x); if (fabs(y)>c) c=fabs(y); if (fabs(z)>c) c=fabs(z); if (fabs(w)>c) c=fabs(w);
04908 return c;
04909 }
04910
04911 int ON_4dPoint::MinimumCoordinateIndex() const
04912 {
04913 const double* a = &x;
04914 int i = ( fabs(y) < fabs(x) ) ? 1 : 0;
04915 if (fabs(z) < fabs(a[i])) i = 2; if (fabs(w) < fabs(a[i])) i = 3;
04916 return i;
04917 }
04918
04919 double ON_4dPoint::MinimumCoordinate() const
04920 {
04921 double c = fabs(x); if (fabs(y)<c) c=fabs(y); if (fabs(z)<c) c=fabs(z); if (fabs(w)<c) c=fabs(w);
04922 return c;
04923 }
04924
04925
04926 void ON_4dPoint::Zero()
04927 {
04928 x = y = z = w = 0.0;
04929 }
04930
04931 ON_4dPoint operator*( double d, const ON_4dPoint& p )
04932 {
04933 return ON_4dPoint( d*p.x, d*p.y, d*p.z, d*p.w );
04934 }
04935
04937
04938
04939
04940
04941
04942 const ON_2dVector& ON_2dVector::UnitVector(int index)
04943 {
04944 static ON_2dVector o(0.0,0.0);
04945 static ON_2dVector x(1.0,0.0);
04946 static ON_2dVector y(0.0,1.0);
04947 switch(index)
04948 {
04949 case 0:
04950 return x;
04951 case 1:
04952 return y;
04953 }
04954 return o;
04955 }
04956
04957 ON_2dVector::ON_2dVector()
04958 {}
04959
04960 ON_2dVector::ON_2dVector( const float* v )
04961 {
04962 if (v) {
04963 x = (double)v[0]; y = (double)v[1];
04964 }
04965 else {
04966 x = y = 0.0;
04967 }
04968 }
04969
04970 ON_2dVector::ON_2dVector( const double* v )
04971 {
04972 if (v) {
04973 x = v[0]; y = v[1];
04974 }
04975 else {
04976 x = y = 0.0;
04977 }
04978 }
04979
04980 ON_2dVector::ON_2dVector(double xx,double yy)
04981 {x=xx;y=yy;}
04982
04983 ON_2dVector::ON_2dVector(const ON_3dVector& v)
04984 {x=v.x;y=v.y;}
04985
04986 ON_2dVector::ON_2dVector(const ON_2dPoint& p)
04987 {x=p.x;y=p.y;}
04988
04989 ON_2dVector::ON_2dVector(const ON_3dPoint& p)
04990 {x=p.x;y=p.y;}
04991
04992 ON_2dVector::ON_2dVector(const ON_2fVector& v)
04993 {x=v.x;y=v.y;}
04994
04995 ON_2dVector::ON_2dVector(const ON_3fVector& v)
04996 {x=v.x;y=v.y;}
04997
04998 ON_2dVector::ON_2dVector(const ON_2fPoint& p)
04999 {x=p.x;y=p.y;}
05000
05001 ON_2dVector::ON_2dVector(const ON_3fPoint& p)
05002 {x=p.x;y=p.y;}
05003
05004
05005 ON_2dVector::operator double*()
05006 {
05007 return &x;
05008 }
05009
05010 ON_2dVector::operator const double*() const
05011 {
05012 return &x;
05013 }
05014
05015 ON_2dVector& ON_2dVector::operator=(const float* v)
05016 {
05017 if ( v ) {
05018 x = (double)v[0];
05019 y = (double)v[1];
05020 }
05021 else {
05022 x = y = 0.0;
05023 }
05024 return *this;
05025 }
05026
05027 ON_2dVector& ON_2dVector::operator=(const double* v)
05028 {
05029 if ( v ) {
05030 x = v[0];
05031 y = v[1];
05032 }
05033 else {
05034 x = y = 0.0;
05035 }
05036 return *this;
05037 }
05038
05039 ON_2dVector& ON_2dVector::operator=(const ON_3dVector& v)
05040 {
05041 x = v.x;
05042 y = v.y;
05043 return *this;
05044 }
05045
05046 ON_2dVector& ON_2dVector::operator=(const ON_2dPoint& p)
05047 {
05048 x = p.x;
05049 y = p.y;
05050 return *this;
05051 }
05052
05053 ON_2dVector& ON_2dVector::operator=(const ON_3dPoint& p)
05054 {
05055 x = p.x;
05056 y = p.y;
05057 return *this;
05058 }
05059
05060 ON_2dVector& ON_2dVector::operator=(const ON_2fVector& v)
05061 {
05062 x = v.x;
05063 y = v.y;
05064 return *this;
05065 }
05066
05067 ON_2dVector& ON_2dVector::operator=(const ON_3fVector& v)
05068 {
05069 x = v.x;
05070 y = v.y;
05071 return *this;
05072 }
05073
05074 ON_2dVector& ON_2dVector::operator=(const ON_2fPoint& p)
05075 {
05076 x = p.x;
05077 y = p.y;
05078 return *this;
05079 }
05080
05081 ON_2dVector& ON_2dVector::operator=(const ON_3fPoint& p)
05082 {
05083 x = p.x;
05084 y = p.y;
05085 return *this;
05086 }
05087
05088 ON_2dVector ON_2dVector::operator-() const
05089 {
05090 return ON_2dVector(-x,-y);
05091 }
05092
05093 ON_2dVector& ON_2dVector::operator*=(double d)
05094 {
05095 x *= d;
05096 y *= d;
05097 return *this;
05098 }
05099
05100 ON_2dVector& ON_2dVector::operator/=(double d)
05101 {
05102 const double one_over_d = 1.0/d;
05103 x *= one_over_d;
05104 y *= one_over_d;
05105 return *this;
05106 }
05107
05108 ON_2dVector& ON_2dVector::operator+=(const ON_2dVector& v)
05109 {
05110 x += v.x;
05111 y += v.y;
05112 return *this;
05113 }
05114
05115 ON_2dVector& ON_2dVector::operator-=(const ON_2dVector& v)
05116 {
05117 x -= v.x;
05118 y -= v.y;
05119 return *this;
05120 }
05121
05122 ON_2dVector ON_2dVector::operator*( int i ) const
05123 {
05124 double d = i;
05125 return ON_2dVector(x*d,y*d);
05126 }
05127
05128 ON_2dVector ON_2dVector::operator*( float f ) const
05129 {
05130 double d = f;
05131 return ON_2dVector(x*d,y*d);
05132 }
05133
05134 ON_2dVector ON_2dVector::operator*( double d ) const
05135 {
05136 return ON_2dVector(x*d,y*d);
05137 }
05138
05139 double ON_2dVector::operator*( const ON_2dVector& v ) const
05140 {
05141 return (x*v.x + y*v.y);
05142 }
05143
05144 double ON_2dVector::operator*( const ON_2dPoint& v ) const
05145 {
05146 return (x*v.x + y*v.y);
05147 }
05148
05149 double ON_2dVector::operator*( const ON_2fVector& v ) const
05150 {
05151 return (x*v.x + y*v.y);
05152 }
05153
05154 ON_2dVector ON_2dVector::operator/( int i ) const
05155 {
05156 const double one_over_d = 1.0/((double)i);
05157 return ON_2dVector(x*one_over_d,y*one_over_d);
05158 }
05159
05160 ON_2dVector ON_2dVector::operator/( float f ) const
05161 {
05162 const double one_over_d = 1.0/((double)f);
05163 return ON_2dVector(x*one_over_d,y*one_over_d);
05164 }
05165
05166 ON_2dVector ON_2dVector::operator/( double d ) const
05167 {
05168 const double one_over_d = 1.0/d;
05169 return ON_2dVector(x*one_over_d,y*one_over_d);
05170 }
05171
05172 ON_2dVector ON_2dVector::operator+( const ON_2dVector& v ) const
05173 {
05174 return ON_2dVector(x+v.x,y+v.y);
05175 }
05176
05177 ON_2dPoint ON_2dVector::operator+( const ON_2dPoint& p ) const
05178 {
05179 return ON_2dPoint(x+p.x,y+p.y);
05180 }
05181
05182 ON_2dVector ON_2dVector::operator-( const ON_2dVector& v ) const
05183 {
05184 return ON_2dVector(x-v.x,y-v.y);
05185 }
05186
05187 ON_2dPoint ON_2dVector::operator-( const ON_2dPoint& v ) const
05188 {
05189 return ON_2dPoint(x-v.x,y-v.y);
05190 }
05191
05192
05193 ON_3dVector ON_2dVector::operator+( const ON_3dVector& v ) const
05194 {
05195 return ON_3dVector(x+v.x,y+v.y,v.z);
05196 }
05197
05198 ON_3dPoint ON_2dVector::operator+( const ON_3dPoint& p ) const
05199 {
05200 return ON_3dPoint(x+p.x,y+p.y,p.z);
05201 }
05202
05203 ON_3dVector ON_2dVector::operator-( const ON_3dVector& v ) const
05204 {
05205 return ON_3dVector(x-v.x,y-v.y,-v.z);
05206 }
05207
05208 ON_3dPoint ON_2dVector::operator-( const ON_3dPoint& v ) const
05209 {
05210 return ON_3dPoint(x-v.x,y-v.y,-v.z);
05211 }
05212
05213 ON_2dVector ON_2dVector::operator+( const ON_2fVector& v ) const
05214 {
05215 return ON_2dVector(x+v.x,y+v.y);
05216 }
05217
05218 ON_2dPoint ON_2dVector::operator+( const ON_2fPoint& p ) const
05219 {
05220 return ON_2dPoint(x+p.x,y+p.y);
05221 }
05222
05223 ON_2dVector ON_2dVector::operator-( const ON_2fVector& v ) const
05224 {
05225 return ON_2dVector(x-v.x,y-v.y);
05226 }
05227
05228 ON_2dPoint ON_2dVector::operator-( const ON_2fPoint& v ) const
05229 {
05230 return ON_2dPoint(x-v.x,y-v.y);
05231 }
05232
05233
05234 ON_3dVector ON_2dVector::operator+( const ON_3fVector& v ) const
05235 {
05236 return ON_3dVector(x+v.x,y+v.y,v.z);
05237 }
05238
05239 ON_3dPoint ON_2dVector::operator+( const ON_3fPoint& p ) const
05240 {
05241 return ON_3dPoint(x+p.x,y+p.y,p.z);
05242 }
05243
05244 ON_3dVector ON_2dVector::operator-( const ON_3fVector& v ) const
05245 {
05246 return ON_3dVector(x-v.x,y-v.y,-v.z);
05247 }
05248
05249 ON_3dPoint ON_2dVector::operator-( const ON_3fPoint& v ) const
05250 {
05251 return ON_3dPoint(x-v.x,y-v.y,-v.z);
05252 }
05253
05254
05255
05256 double ON_2dVector::operator*(const ON_4dPoint& h) const
05257 {
05258 return x*h.x + y*h.y;
05259 }
05260
05261 bool ON_2dVector::operator==( const ON_2dVector& v ) const
05262 {
05263 return (x==v.x&&y==v.y)?true:false;
05264 }
05265
05266 bool ON_2dVector::operator!=( const ON_2dVector& v ) const
05267 {
05268 return (x!=v.x||y!=v.y)?true:false;
05269 }
05270
05271 bool ON_2dVector::operator<=( const ON_2dVector& v ) const
05272 {
05273
05274 return ((x<v.x)?true:((x==v.x&&y<=v.y)?true:false));
05275 }
05276
05277 bool ON_2dVector::operator>=( const ON_2dVector& v ) const
05278 {
05279
05280 return ((x>v.x)?true:((x==v.x&&y>=v.y)?true:false));
05281 }
05282
05283 bool ON_2dVector::operator<( const ON_2dVector& v ) const
05284 {
05285
05286 return ((x<v.x)?true:((x==v.x&&y<v.y)?true:false));
05287 }
05288
05289 bool ON_2dVector::operator>( const ON_2dVector& v ) const
05290 {
05291
05292 return ((x>v.x)?true:((x==v.x&&y>v.y)?true:false));
05293 }
05294
05295 double ON_2dVector::operator[](int i) const
05296 {
05297 return ((i<=0)?x:y);
05298 }
05299
05300 double& ON_2dVector::operator[](int i)
05301 {
05302 double* pd = (i<=0)? &x : &y;
05303 return *pd;
05304 }
05305
05306 double ON_2dVector::operator[](unsigned int i) const
05307 {
05308 return ((i<=0)?x:y);
05309 }
05310
05311 double& ON_2dVector::operator[](unsigned int i)
05312 {
05313 double* pd = (i<=0)? &x : &y;
05314 return *pd;
05315 }
05316
05317 int ON_2dVector::MaximumCoordinateIndex() const
05318 {
05319 return ( (fabs(y)>fabs(x)) ? 1 : 0 );
05320 }
05321
05322 double ON_2dVector::MaximumCoordinate() const
05323 {
05324 double c = fabs(x); if (fabs(y)>c) c=fabs(y);
05325 return c;
05326 }
05327
05328 int ON_2dVector::MinimumCoordinateIndex() const
05329 {
05330 return (fabs(y)<fabs(x)) ? 1: 0;
05331 }
05332
05333 double ON_2dVector::MinimumCoordinate() const
05334 {
05335 double c = fabs(x); if (fabs(y)<c) c=fabs(y);
05336 return c;
05337 }
05338
05339 double ON_2dVector::LengthSquared() const
05340 {
05341 return (x*x + y*y);
05342 }
05343
05344 double ON_Length2d( double x, double y )
05345 {
05346 double len;
05347 x = fabs(x);
05348 y = fabs(y);
05349 if ( y > x ) {
05350 len = x; x = y; y = len;
05351 }
05352
05353
05354
05355
05356
05357
05358
05359
05360
05361 if ( x > ON_DBL_MIN )
05362 {
05363 y /= x;
05364 len = x*sqrt(1.0 + y*y);
05365 }
05366 else if ( x > 0.0 && ON_IS_FINITE(x) )
05367 len = x;
05368 else
05369 len = 0.0;
05370
05371 return len;
05372 }
05373
05374 double ON_2dVector::Length() const
05375 {
05376 return ON_Length2d(x,y);
05377 }
05378
05379 double ON_2dVector::WedgeProduct(const ON_2dVector& B) const{
05380 return x*B.y - y*B.x;
05381 }
05382
05383 void ON_2dVector::Zero()
05384 {
05385 x = y = 0.0;
05386 }
05387
05388 void ON_2dVector::Reverse()
05389 {
05390 x = -x;
05391 y = -y;
05392 }
05393
05394 bool ON_2dVector::Unitize()
05395 {
05396
05397
05398
05399 double d = Length();
05400 if ( ON_IS_FINITE(d) )
05401 {
05402 if ( d > ON_DBL_MIN )
05403 {
05404 x /= d;
05405 y /= d;
05406 return true;
05407 }
05408
05409 if ( d > 0.0 )
05410 {
05411
05412
05413
05414
05415
05416
05417 ON_2dVector tmp;
05418 tmp.x = x*8.9884656743115795386465259539451e+307;
05419 tmp.y = y*8.9884656743115795386465259539451e+307;
05420 d = tmp.Length();
05421 if ( ON_IS_FINITE(d) && d > ON_DBL_MIN )
05422 {
05423 x = tmp.x/d;
05424 y = tmp.y/d;
05425 return true;
05426 }
05427 }
05428 }
05429
05430 x = 0.0;
05431 y = 0.0;
05432
05433 return false;
05434 }
05435
05436 bool ON_2dVector::IsTiny( double tiny_tol ) const
05437 {
05438 return (fabs(x) <= tiny_tol && fabs(y) <= tiny_tol );
05439 }
05440
05441 bool ON_2dVector::IsZero() const
05442 {
05443 return (x==0.0 && y==0.0);
05444 }
05445
05446 bool ON_2dVector::IsUnitVector() const
05447 {
05448 return (x != ON_UNSET_VALUE && y != ON_UNSET_VALUE && fabs(Length() - 1.0) <= ON_SQRT_EPSILON);
05449 }
05450
05451
05452 bool ON_2dVector::PerpendicularTo(
05453
05454 const ON_2dVector& v
05455 )
05456 {
05457 y = v.x;
05458 x = -v.y;
05459 return (x!= 0.0 || y!= 0.0) ? true : false;
05460 }
05461
05462
05463 bool ON_2dVector::PerpendicularTo(
05464 const ON_2dPoint& p,
05465 const ON_2dPoint& q
05466 )
05467 {
05468 return PerpendicularTo(q-p);
05469 }
05470
05471 ON_2dVector operator*(int i, const ON_2dVector& v)
05472 {
05473 double d = i;
05474 return ON_2dVector(d*v.x,d*v.y);
05475 }
05476
05477 ON_2dVector operator*(float f, const ON_2dVector& v)
05478 {
05479 double d = f;
05480 return ON_2dVector(d*v.x,d*v.y);
05481 }
05482
05483 ON_2dVector operator*(double d, const ON_2dVector& v)
05484 {
05485 return ON_2dVector(d*v.x,d*v.y);
05486 }
05487
05488 double ON_DotProduct( const ON_2dVector& a , const ON_2dVector& b )
05489 {
05490
05491 return (a.x*b.x + a.y*b.y );
05492 }
05493
05494 double ON_WedgeProduct( const ON_2dVector& a , const ON_2dVector& b )
05495 {
05496
05497 return (a.x*b.y - a.y*b.x );
05498 }
05499
05500 ON_3dVector ON_CrossProduct( const ON_2dVector& a , const ON_2dVector& b )
05501 {
05502 return ON_3dVector(0.0, 0.0, a.x*b.y - b.x*a.y );
05503 }
05504
05506
05507
05508
05509
05510
05511 const ON_3dVector& ON_3dVector::UnitVector(int index)
05512 {
05513 static ON_3dVector o(0.0,0.0,0.0);
05514 static ON_3dVector x(1.0,0.0,0.0);
05515 static ON_3dVector y(0.0,1.0,0.0);
05516 static ON_3dVector z(0.0,0.0,1.0);
05517 switch(index)
05518 {
05519 case 0:
05520 return x;
05521 case 1:
05522 return y;
05523 case 2:
05524 return z;
05525 }
05526 return o;
05527 }
05528
05529 ON_3dVector::ON_3dVector()
05530 {}
05531
05532 ON_3dVector::ON_3dVector( const float* v )
05533 {
05534 if (v) {
05535 x = (double)v[0]; y = (double)v[1]; z = (double)v[2];
05536 }
05537 else {
05538 x = y = z = 0.0;
05539 }
05540 }
05541
05542 ON_3dVector::ON_3dVector( const double* v )
05543 {
05544 if (v) {
05545 x = v[0]; y = v[1]; z = v[2];
05546 }
05547 else {
05548 x = y = z = 0.0;
05549 }
05550 }
05551
05552 ON_3dVector::ON_3dVector(double xx,double yy,double zz)
05553 {x=xx;y=yy;z=zz;}
05554
05555 ON_3dVector::ON_3dVector(const ON_2dVector& v)
05556 {x=v.x;y=v.y;z=0.0;}
05557
05558 ON_3dVector::ON_3dVector(const ON_2dPoint& p)
05559 {x=p.x;y=p.y;z=0.0;}
05560
05561 ON_3dVector::ON_3dVector(const ON_3dPoint& p)
05562 {x=p.x;y=p.y;z=p.z;}
05563
05564 ON_3dVector::ON_3dVector(const ON_2fVector& v)
05565 {x=v.x;y=v.y;z=0.0;}
05566
05567 ON_3dVector::ON_3dVector(const ON_3fVector& v)
05568 {x=v.x;y=v.y;z=v.z;}
05569
05570 ON_3dVector::ON_3dVector(const ON_2fPoint& p)
05571 {x=p.x;y=p.y;z=0.0;}
05572
05573 ON_3dVector::ON_3dVector(const ON_3fPoint& p)
05574 {x=p.x;y=p.y;z=p.z;}
05575
05576 ON_3dVector::operator double*()
05577 {
05578 return &x;
05579 }
05580
05581 ON_3dVector::operator const double*() const
05582 {
05583 return &x;
05584 }
05585
05586 ON_3dVector& ON_3dVector::operator=(const float* v)
05587 {
05588 if ( v ) {
05589 x = (double)v[0];
05590 y = (double)v[1];
05591 z = (double)v[2];
05592 }
05593 else {
05594 x = y = z = 0.0;
05595 }
05596 return *this;
05597 }
05598
05599 ON_3dVector& ON_3dVector::operator=(const double* v)
05600 {
05601 if ( v ) {
05602 x = v[0];
05603 y = v[1];
05604 z = v[2];
05605 }
05606 else {
05607 x = y = z = 0.0;
05608 }
05609 return *this;
05610 }
05611
05612 ON_3dVector& ON_3dVector::operator=(const ON_2dVector& v)
05613 {
05614 x = v.x;
05615 y = v.y;
05616 z = 0.0;
05617 return *this;
05618 }
05619
05620 ON_3dVector& ON_3dVector::operator=(const ON_2dPoint& p)
05621 {
05622 x = p.x;
05623 y = p.y;
05624 z = 0.0;
05625 return *this;
05626 }
05627
05628 ON_3dVector& ON_3dVector::operator=(const ON_3dPoint& p)
05629 {
05630 x = p.x;
05631 y = p.y;
05632 z = p.z;
05633 return *this;
05634 }
05635
05636
05637 ON_3dVector& ON_3dVector::operator=(const ON_2fVector& v)
05638 {
05639 x = v.x;
05640 y = v.y;
05641 z = 0.0;
05642 return *this;
05643 }
05644
05645 ON_3dVector& ON_3dVector::operator=(const ON_3fVector& v)
05646 {
05647 x = v.x;
05648 y = v.y;
05649 z = v.z;
05650 return *this;
05651 }
05652
05653 ON_3dVector& ON_3dVector::operator=(const ON_2fPoint& p)
05654 {
05655 x = p.x;
05656 y = p.y;
05657 z = 0.0;
05658 return *this;
05659 }
05660
05661 ON_3dVector& ON_3dVector::operator=(const ON_3fPoint& p)
05662 {
05663 x = p.x;
05664 y = p.y;
05665 z = p.z;
05666 return *this;
05667 }
05668
05669 ON_3dVector ON_3dVector::operator-() const
05670 {
05671 return ON_3dVector(-x,-y,-z);
05672 }
05673
05674 ON_3dVector& ON_3dVector::operator*=(double d)
05675 {
05676 x *= d;
05677 y *= d;
05678 z *= d;
05679 return *this;
05680 }
05681
05682 ON_3dVector& ON_3dVector::operator/=(double d)
05683 {
05684 const double one_over_d = 1.0/d;
05685 x *= one_over_d;
05686 y *= one_over_d;
05687 z *= one_over_d;
05688 return *this;
05689 }
05690
05691 ON_3dVector& ON_3dVector::operator+=(const ON_3dVector& v)
05692 {
05693 x += v.x;
05694 y += v.y;
05695 z += v.z;
05696 return *this;
05697 }
05698
05699 ON_3dVector& ON_3dVector::operator-=(const ON_3dVector& v)
05700 {
05701 x -= v.x;
05702 y -= v.y;
05703 z -= v.z;
05704 return *this;
05705 }
05706
05707 ON_3dVector ON_3dVector::operator*( int i ) const
05708 {
05709 double d = i;
05710 return ON_3dVector(x*d,y*d,z*d);
05711 }
05712
05713 ON_3dVector ON_3dVector::operator*( float f ) const
05714 {
05715 double d = f;
05716 return ON_3dVector(x*d,y*d,z*d);
05717 }
05718
05719 ON_3dVector ON_3dVector::operator*( double d ) const
05720 {
05721 return ON_3dVector(x*d,y*d,z*d);
05722 }
05723
05724 double ON_3dVector::operator*( const ON_3dVector& v ) const
05725 {
05726 return (x*v.x + y*v.y + z*v.z);
05727 }
05728
05729 double ON_3dVector::operator*( const ON_3dPoint& v ) const
05730 {
05731 return (x*v.x + y*v.y + z*v.z);
05732 }
05733
05734 double ON_3dVector::operator*( const ON_3fVector& v ) const
05735 {
05736 return (x*v.x + y*v.y + z*v.z);
05737 }
05738
05739 ON_3dVector ON_3dVector::operator/( int i ) const
05740 {
05741 const double one_over_d = 1.0/((double)i);
05742 return ON_3dVector(x*one_over_d,y*one_over_d,z*one_over_d);
05743 }
05744
05745 ON_3dVector ON_3dVector::operator/( float f ) const
05746 {
05747 const double one_over_d = 1.0/((double)f);
05748 return ON_3dVector(x*one_over_d,y*one_over_d,z*one_over_d);
05749 }
05750
05751 ON_3dVector ON_3dVector::operator/( double d ) const
05752 {
05753 const double one_over_d = 1.0/d;
05754 return ON_3dVector(x*one_over_d,y*one_over_d,z*one_over_d);
05755 }
05756
05757 ON_3dVector ON_3dVector::operator+( const ON_3dVector& v ) const
05758 {
05759 return ON_3dVector(x+v.x,y+v.y,z+v.z);
05760 }
05761
05762 ON_3dPoint ON_3dVector::operator+( const ON_3dPoint& p ) const
05763 {
05764 return ON_3dPoint(x+p.x,y+p.y,z+p.z);
05765 }
05766
05767 ON_3dVector ON_3dVector::operator-( const ON_3dVector& v ) const
05768 {
05769 return ON_3dVector(x-v.x,y-v.y,z-v.z);
05770 }
05771
05772 ON_3dPoint ON_3dVector::operator-( const ON_3dPoint& v ) const
05773 {
05774 return ON_3dPoint(x-v.x,y-v.y,z-v.z);
05775 }
05776
05777 ON_3dVector ON_3dVector::operator+( const ON_2dVector& v ) const
05778 {
05779 return ON_3dVector(x+v.x,y+v.y,z);
05780 }
05781
05782 ON_3dPoint ON_3dVector::operator+( const ON_2dPoint& p ) const
05783 {
05784 return ON_3dPoint(x+p.x,y+p.y,z);
05785 }
05786
05787 ON_3dVector ON_3dVector::operator-( const ON_2dVector& v ) const
05788 {
05789 return ON_3dVector(x-v.x,y-v.y,z);
05790 }
05791
05792 ON_3dPoint ON_3dVector::operator-( const ON_2dPoint& v ) const
05793 {
05794 return ON_3dPoint(x-v.x,y-v.y,z);
05795 }
05796
05797 ON_3dVector ON_3dVector::operator+( const ON_3fVector& v ) const
05798 {
05799 return ON_3dVector(x+v.x,y+v.y,z+v.z);
05800 }
05801
05802 ON_3dPoint ON_3dVector::operator+( const ON_3fPoint& p ) const
05803 {
05804 return ON_3dPoint(x+p.x,y+p.y,z+p.z);
05805 }
05806
05807 ON_3dVector ON_3dVector::operator-( const ON_3fVector& v ) const
05808 {
05809 return ON_3dVector(x-v.x,y-v.y,z-v.z);
05810 }
05811
05812 ON_3dPoint ON_3dVector::operator-( const ON_3fPoint& v ) const
05813 {
05814 return ON_3dPoint(x-v.x,y-v.y,z-v.z);
05815 }
05816
05817 ON_3dVector ON_3dVector::operator+( const ON_2fVector& v ) const
05818 {
05819 return ON_3dVector(x+v.x,y+v.y,z);
05820 }
05821
05822 ON_3dPoint ON_3dVector::operator+( const ON_2fPoint& p ) const
05823 {
05824 return ON_3dPoint(x+p.x,y+p.y,z);
05825 }
05826
05827 ON_3dVector ON_3dVector::operator-( const ON_2fVector& v ) const
05828 {
05829 return ON_3dVector(x-v.x,y-v.y,z);
05830 }
05831
05832 ON_3dPoint ON_3dVector::operator-( const ON_2fPoint& v ) const
05833 {
05834 return ON_3dPoint(x-v.x,y-v.y,z);
05835 }
05836
05837
05838 double ON_3dVector::operator*(const ON_4dPoint& h) const
05839 {
05840 return x*h.x + y*h.y + z*h.z;
05841 }
05842
05843 bool ON_3dVector::operator==( const ON_3dVector& v ) const
05844 {
05845 return (x==v.x&&y==v.y&&z==v.z)?true:false;
05846 }
05847
05848 bool ON_3dVector::operator!=( const ON_3dVector& v ) const
05849 {
05850 return (x!=v.x||y!=v.y||z!=v.z)?true:false;
05851 }
05852
05853 bool ON_3dVector::operator<=( const ON_3dVector& v ) const
05854 {
05855
05856 return ((x<v.x)?true:((x==v.x)?((y<v.y)?true:(y==v.y&&z<=v.z)?true:false):false));
05857 }
05858
05859 bool ON_3dVector::operator>=( const ON_3dVector& v ) const
05860 {
05861
05862 return ((x>v.x)?true:((x==v.x)?((y>v.y)?true:(y==v.y&&z>=v.z)?true:false):false));
05863 }
05864
05865 bool ON_3dVector::operator<( const ON_3dVector& v ) const
05866 {
05867
05868 return ((x<v.x)?true:((x==v.x)?((y<v.y)?true:(y==v.y&&z<v.z)?true:false):false));
05869 }
05870
05871 bool ON_3dVector::operator>( const ON_3dVector& v ) const
05872 {
05873
05874 return ((x>v.x)?true:((x==v.x)?((y>v.y)?true:(y==v.y&&z>v.z)?true:false):false));
05875 }
05876
05877 double ON_3dVector::operator[](int i) const
05878 {
05879 return ( (i<=0)?x:((i>=2)?z:y) );
05880 }
05881
05882 double& ON_3dVector::operator[](int i)
05883 {
05884 double* pd = (i<=0)? &x : ( (i>=2) ? &z : &y);
05885 return *pd;
05886 }
05887
05888 double ON_3dVector::operator[](unsigned int i) const
05889 {
05890 return ( (i<=0)?x:((i>=2)?z:y) );
05891 }
05892
05893 double& ON_3dVector::operator[](unsigned int i)
05894 {
05895 double* pd = (i<=0)? &x : ( (i>=2) ? &z : &y);
05896 return *pd;
05897 }
05898
05899 int ON_3dVector::MaximumCoordinateIndex() const
05900 {
05901 return (fabs(y)>fabs(x)) ? ((fabs(z)>fabs(y))?2:1) : ((fabs(z)>fabs(x))?2:0);
05902 }
05903
05904 double ON_3dVector::MaximumCoordinate() const
05905 {
05906 double c = fabs(x); if (fabs(y)>c) c=fabs(y); if (fabs(z)>c) c=fabs(z);
05907 return c;
05908 }
05909
05910 int ON_3dVector::MinimumCoordinateIndex() const
05911 {
05912 return (fabs(y)<fabs(x)) ? ((fabs(z)<fabs(y))?2:1) : ((fabs(z)<fabs(x))?2:0);
05913 }
05914
05915 double ON_3dVector::MinimumCoordinate() const
05916 {
05917 double c = fabs(x); if (fabs(y)<c) c=fabs(y); if (fabs(z)<c) c=fabs(z);
05918 return c;
05919 }
05920
05921 double ON_3dVector::LengthSquared() const
05922 {
05923 return (x*x + y*y + z*z);
05924 }
05925
05926 double ON_Length3d(double x, double y, double z)
05927 {
05928 double len;
05929 x = fabs(x);
05930 y = fabs(y);
05931 z = fabs(z);
05932 if ( y >= x && y >= z ) {
05933 len = x; x = y; y = len;
05934 }
05935 else if ( z >= x && z >= y ) {
05936 len = x; x = z; z = len;
05937 }
05938
05939
05940
05941
05942
05943
05944
05945
05946
05947 if ( x > ON_DBL_MIN )
05948 {
05949 y /= x;
05950 z /= x;
05951 len = x*sqrt(1.0 + y*y + z*z);
05952 }
05953 else if ( x > 0.0 && ON_IS_FINITE(x) )
05954 len = x;
05955 else
05956 len = 0.0;
05957
05958 return len;
05959 }
05960
05961 double ON_3dVector::Length() const
05962 {
05963 return ON_Length3d(x,y,z);
05964 }
05965
05966 void ON_3dVector::Zero()
05967 {
05968 x = y = z = 0.0;
05969 }
05970
05971 void ON_3dVector::Reverse()
05972 {
05973 x = -x;
05974 y = -y;
05975 z = -z;
05976 }
05977
05978 bool ON_3dVector::Unitize()
05979 {
05980
05981
05982
05983 double d = Length();
05984
05985 if ( ON_IS_FINITE(d) )
05986 {
05987 if ( d > ON_DBL_MIN )
05988 {
05989 x /= d;
05990 y /= d;
05991 z /= d;
05992 return true;
05993 }
05994
05995 if ( d > 0.0 )
05996 {
05997
05998
05999
06000
06001
06002
06003 ON_3dVector tmp;
06004 tmp.x = x*8.9884656743115795386465259539451e+307;
06005 tmp.y = y*8.9884656743115795386465259539451e+307;
06006 tmp.z = z*8.9884656743115795386465259539451e+307;
06007 d = tmp.Length();
06008 if ( ON_IS_FINITE(d) && d > ON_DBL_MIN )
06009 {
06010 x = tmp.x/d;
06011 y = tmp.y/d;
06012 z = tmp.z/d;
06013 return true;
06014 }
06015 }
06016 }
06017
06018 x = 0.0;
06019 y = 0.0;
06020 z = 0.0;
06021
06022 return false;
06023 }
06024
06025 double ON_3dVector::LengthAndUnitize()
06026 {
06027 double d;
06028 double len = Length();
06029 if ( len > ON_DBL_MIN )
06030 {
06031 d = 1.0/len;
06032 x *= d;
06033 y *= d;
06034 z *= d;
06035 }
06036 else if ( len > 0.0 && ON_IS_FINITE(len) )
06037 {
06038
06039
06040
06041
06042
06043
06044 ON_3dVector tmp;
06045 tmp.x = x*8.9884656743115795386465259539451e+307;
06046 tmp.y = y*8.9884656743115795386465259539451e+307;
06047 tmp.z = z*8.9884656743115795386465259539451e+307;
06048 d = tmp.Length();
06049 if ( d > ON_DBL_MIN )
06050 {
06051 d = 1.0/d;
06052 x = tmp.x*d;
06053 y = tmp.y*d;
06054 z = tmp.z*d;
06055 }
06056 else
06057 {
06058 len = 0.0;
06059 x = 0.0;
06060 y = 0.0;
06061 z = 0.0;
06062 }
06063 }
06064 else
06065 {
06066 len = 0.0;
06067 x = 0.0;
06068 y = 0.0;
06069 z = 0.0;
06070 }
06071
06072 return len;
06073 }
06074
06075
06076 bool ON_3dVector::IsTiny( double tiny_tol ) const
06077 {
06078 return (fabs(x) <= tiny_tol && fabs(y) <= tiny_tol && fabs(z) <= tiny_tol );
06079 }
06080
06081 bool ON_3dVector::IsZero() const
06082 {
06083 return (x==0.0 && y==0.0 && z==0.0);
06084 }
06085
06086 bool ON_3dVector::IsUnitVector() const
06087 {
06088 return (x != ON_UNSET_VALUE && y != ON_UNSET_VALUE && z != ON_UNSET_VALUE && fabs(Length() - 1.0) <= ON_SQRT_EPSILON);
06089 }
06090
06091 ON_3dVector operator*(int i, const ON_3dVector& v)
06092 {
06093 double d = i;
06094 return ON_3dVector(d*v.x,d*v.y,d*v.z);
06095 }
06096
06097 ON_3dVector operator*(float f, const ON_3dVector& v)
06098 {
06099 double d = f;
06100 return ON_3dVector(d*v.x,d*v.y,d*v.z);
06101 }
06102
06103 ON_3dVector operator*(double d, const ON_3dVector& v)
06104 {
06105 return ON_3dVector(d*v.x,d*v.y,d*v.z);
06106 }
06107
06108 double ON_DotProduct( const ON_3dVector& a , const ON_3dVector& b )
06109 {
06110
06111 return (a.x*b.x + a.y*b.y + a.z*b.z);
06112 }
06113
06114 ON_3dVector ON_CrossProduct( const ON_3dVector& a , const ON_3dVector& b )
06115 {
06116 return ON_3dVector(a.y*b.z - b.y*a.z, a.z*b.x - b.z*a.x, a.x*b.y - b.x*a.y );
06117 }
06118
06119 ON_3dVector ON_CrossProduct( const double* a, const double* b )
06120 {
06121 return ON_3dVector(a[1]*b[2] - b[1]*a[2], a[2]*b[0] - b[2]*a[0], a[0]*b[1] - b[0]*a[1] );
06122 }
06123
06124 double ON_TripleProduct( const ON_3dVector& a, const ON_3dVector& b, const ON_3dVector& c )
06125 {
06126
06127 return (a.x*(b.y*c.z - b.z*c.y) + a.y*(b.z*c.x - b.x*c.z) + a.z*(b.x*c.y - b.y*c.x));
06128 }
06129
06130 double ON_TripleProduct( const double* a, const double* b, const double* c )
06131 {
06132
06133 return (a[0]*(b[1]*c[2] - b[2]*c[1]) + a[1]*(b[2]*c[0] - b[0]*c[2]) + a[2]*(b[0]*c[1] - b[1]*c[0]));
06134 }
06135
06136 bool ON_2dVector::IsValid() const
06137 {
06138 return ( ON_IS_VALID(x) && ON_IS_VALID(y) ) ? true : false;
06139 }
06140
06141 bool ON_2dVector::IsUnsetVector() const
06142 {
06143 return ( ON_UNSET_VALUE == x && ON_UNSET_VALUE == y );
06144 }
06145
06146 bool ON_3dVector::IsValid() const
06147 {
06148 return ( ON_IS_VALID(x) && ON_IS_VALID(y) && ON_IS_VALID(z) ) ? true : false;
06149 }
06150
06151 bool ON_3dVector::IsUnsetVector() const
06152 {
06153 return ( ON_UNSET_VALUE == x && ON_UNSET_VALUE == y && ON_UNSET_VALUE == z );
06154 }
06155
06156 bool ON_2dPoint::IsValid() const
06157 {
06158 return (ON_IS_VALID(x) && ON_IS_VALID(y)) ? true : false;
06159 }
06160
06161 bool ON_2dPoint::IsUnsetPoint() const
06162 {
06163 return ( ON_UNSET_VALUE == x && ON_UNSET_VALUE == y );
06164 }
06165
06166 bool ON_3dPoint::IsValid() const
06167 {
06168 return (ON_IS_VALID(x) && ON_IS_VALID(y) && ON_IS_VALID(z) ) ? true : false;
06169 }
06170
06171 bool ON_3dPoint::IsUnsetPoint() const
06172 {
06173 return ( ON_UNSET_VALUE == x && ON_UNSET_VALUE == y && ON_UNSET_VALUE == z );
06174 }
06175
06176 bool ON_4dPoint::IsValid() const
06177 {
06178 return (ON_IS_VALID(x) && ON_IS_VALID(y) && ON_IS_VALID(z) && ON_IS_VALID(w)) ? true : false;
06179 }
06180
06181 bool ON_4dPoint::IsUnsetPoint() const
06182 {
06183 return ( ON_UNSET_VALUE == x && ON_UNSET_VALUE == y && ON_UNSET_VALUE == z && ON_UNSET_VALUE == w );
06184 }
06185
06186
06187 void ON_2dPoint::Set(double xx, double yy)
06188 {
06189 x = xx; y = yy;
06190 }
06191
06192 void ON_3dPoint::Set(double xx, double yy, double zz)
06193 {
06194 x = xx; y = yy; z = zz;
06195 }
06196
06197
06198 void ON_4dPoint::Set(double xx, double yy, double zz, double ww)
06199 {
06200 x = xx; y = yy; z = zz; w = ww;
06201 }
06202
06203 void ON_2dVector::Set(double xx, double yy)
06204 {
06205 x = xx; y = yy;
06206 }
06207
06208 void ON_3dVector::Set(double xx, double yy, double zz)
06209 {
06210 x = xx; y = yy; z = zz;
06211 }
06212
06213
06214 void ON_2fPoint::Set(float xx, float yy)
06215 {
06216 x = xx; y = yy;
06217 }
06218
06219 void ON_3fPoint::Set(float xx, float yy, float zz)
06220 {
06221 x = xx; y = yy; z = zz;
06222 }
06223
06224
06225 void ON_4fPoint::Set(float xx, float yy, float zz, float ww)
06226 {
06227 x = xx; y = yy; z = zz; w = ww;
06228 }
06229
06230 void ON_2fVector::Set(float xx, float yy)
06231 {
06232 x = xx; y = yy;
06233 }
06234
06235 void ON_3fVector::Set(float xx, float yy, float zz)
06236 {
06237 x = xx; y = yy; z = zz;
06238 }
06239
06240 bool ON_PlaneEquation::Create( ON_3dPoint P, ON_3dVector N )
06241 {
06242 bool rc = false;
06243 if ( P.IsValid() && N.IsValid() )
06244 {
06245 x = N.x;
06246 y = N.y;
06247 z = N.z;
06248 rc = ( fabs(1.0 - Length()) > ON_ZERO_TOLERANCE ) ? Unitize() : true;
06249 d = -(x*P.x + y*P.y + z*P.z);
06250 }
06251 return rc;
06252 }
06253
06254 ON_PlaneEquation::ON_PlaneEquation()
06255 : ON_3dVector(0.0,0.0,0.0)
06256 , d(0.0)
06257 {}
06258
06259 ON_PlaneEquation::ON_PlaneEquation(double xx, double yy, double zz, double dd)
06260 : ON_3dVector(xx,yy,zz)
06261 , d(dd)
06262 {}
06263
06264 const ON_PlaneEquation ON_PlaneEquation::UnsetPlaneEquation(ON_UNSET_VALUE,ON_UNSET_VALUE,ON_UNSET_VALUE,ON_UNSET_VALUE);
06265 const ON_PlaneEquation ON_PlaneEquation::ZeroPlaneEquation(0.0,0.0,0.0,0.0);
06266
06267 bool ON_PlaneEquation::IsValid() const
06268 {
06269 return ( ON_IS_VALID(x) && ON_IS_VALID(y) && ON_IS_VALID(z) && ON_IS_VALID(d) );
06270 }
06271
06272 bool ON_PlaneEquation::IsSet() const
06273 {
06274 return ( ON_IS_VALID(x) && ON_IS_VALID(y) && ON_IS_VALID(z) && ON_IS_VALID(d)
06275 && (0.0 != x || 0.0 != y || 0.0 != z)
06276 );
06277 }
06278
06279 double ON_PlaneEquation::ZeroTolerance() const
06280 {
06281 double zero_tolerance = 0.0;
06282 ON_3dVector N(x,y,z);
06283 if ( N.Unitize() && ON_IS_VALID(d) )
06284 {
06285 const ON_3dPoint P( -d*N.x, -d*N.y, -d*N.z );
06286
06287 zero_tolerance = fabs(ValueAt(P));
06288
06289 ON_3dVector X;
06290 X.PerpendicularTo(N);
06291 X.Unitize();
06292
06293 double t = fabs(ValueAt(P+X));
06294 if ( t > zero_tolerance )
06295 zero_tolerance = t;
06296 t = fabs(ValueAt(P-X));
06297 if ( t > zero_tolerance )
06298 zero_tolerance = t;
06299 t = fabs(ValueAt(P+d*X));
06300 if ( t > zero_tolerance )
06301 zero_tolerance = t;
06302 t = fabs(ValueAt(P-d*X));
06303 if ( t > zero_tolerance )
06304 zero_tolerance = t;
06305
06306 ON_3dVector Y = ON_CrossProduct(N,X);
06307 Y.Unitize();
06308
06309 t = fabs(ValueAt(P+Y));
06310 if ( t > zero_tolerance )
06311 zero_tolerance = t;
06312 t = fabs(ValueAt(P-Y));
06313 if ( t > zero_tolerance )
06314 zero_tolerance = t;
06315 t = fabs(ValueAt(P+d*Y));
06316 if ( t > zero_tolerance )
06317 zero_tolerance = t;
06318 t = fabs(ValueAt(P-d*Y));
06319 if ( t > zero_tolerance )
06320 zero_tolerance = t;
06321 }
06322
06323 return zero_tolerance;
06324 }
06325
06326 bool ON_PlaneEquation::Transform( const ON_Xform& xform )
06327 {
06328 bool rc = IsValid();
06329 if ( rc )
06330 {
06331
06332 ON_Xform T(xform);
06333 rc = T.Invert();
06334 if ( rc )
06335 {
06336 const double xx=x;
06337 const double yy=y;
06338 const double zz=z;
06339 const double dd=d;
06340 x = T.m_xform[0][0]*xx + T.m_xform[1][0]*yy + T.m_xform[2][0]*zz + T.m_xform[3][0]*dd;
06341 y = T.m_xform[0][1]*xx + T.m_xform[1][1]*yy + T.m_xform[2][1]*zz + T.m_xform[3][1]*dd;
06342 z = T.m_xform[0][2]*xx + T.m_xform[1][2]*yy + T.m_xform[2][2]*zz + T.m_xform[3][2]*dd;
06343 d = T.m_xform[0][3]*xx + T.m_xform[1][3]*yy + T.m_xform[2][3]*zz + T.m_xform[3][3]*dd;
06344 }
06345 }
06346 return rc;
06347 }
06348
06349 double ON_PlaneEquation::ValueAt(ON_3dPoint P) const
06350 {
06351 return (x*P.x + y*P.y + z*P.z + d);
06352 }
06353
06354 double ON_PlaneEquation::ValueAt(ON_4dPoint P) const
06355 {
06356 return (x*P.x + y*P.y + z*P.z + d*P.w);
06357 }
06358
06359 double ON_PlaneEquation::ValueAt(ON_3dVector P) const
06360 {
06361 return (x*P.x + y*P.y + z*P.z + d);
06362 }
06363
06364 double ON_PlaneEquation::ValueAt(double xx, double yy, double zz) const
06365 {
06366 return (x*xx + y*yy + z*zz + d);
06367 }
06368
06369 double* ON_PlaneEquation::ValueAt(
06370 int Pcount,
06371 const ON_3fPoint* P,
06372 double* value,
06373 double value_range[2]
06374 ) const
06375 {
06376 if ( Pcount <= 0 || 0 == P )
06377 return 0;
06378
06379 int i;
06380 double s;
06381 const double* e = &x;
06382
06383 if ( 0 == value )
06384 value = (double*)onmalloc(Pcount * sizeof(*value) );
06385 if ( 0 == value )
06386 return 0;
06387
06388 if ( 0 != value_range )
06389 {
06390 value[0] = s = e[0]*((double)P[0].x) + e[1]*((double)P[0].y) + e[2]*((double)P[0].z) + e[3];
06391 value_range[0] = s;
06392 value_range[1] = s;
06393 for ( i = 1; i < Pcount; i++ )
06394 {
06395 value[i] = s = e[0]*((double)P[i].x) + e[1]*((double)P[i].y) + e[2]*((double)P[i].z) + e[3];
06396 if ( s < value_range[0] )
06397 value_range[0] = s;
06398 else if ( s > value_range[1] )
06399 value_range[1] = s;
06400 }
06401 }
06402 else
06403 {
06404 for ( i = 0; i < Pcount; i++ )
06405 {
06406 value[i] = e[0]*((double)P[i].x) + e[1]*((double)P[i].y) + e[2]*((double)P[i].z) + e[3];
06407 }
06408 }
06409
06410 return value;
06411 }
06412
06413 double* ON_PlaneEquation::ValueAt(
06414 int Pcount,
06415 const ON_3dPoint* P,
06416 double* value,
06417 double value_range[2]
06418 ) const
06419 {
06420 if ( Pcount <= 0 || 0 == P )
06421 return 0;
06422
06423 int i;
06424 double s;
06425 const double* e = &x;
06426
06427 if ( 0 == value )
06428 value = (double*)onmalloc(Pcount * sizeof(*value) );
06429 if ( 0 == value )
06430 return 0;
06431
06432 if ( 0 != value_range )
06433 {
06434 value[0] = s = e[0]*(P[0].x) + e[1]*(P[0].y) + e[2]*(P[0].z) + e[3];
06435 value_range[0] = s;
06436 value_range[1] = s;
06437 for ( i = 1; i < Pcount; i++ )
06438 {
06439 value[i] = s = e[0]*(P[i].x) + e[1]*(P[i].y) + e[2]*(P[i].z) + e[3];
06440 if ( s < value_range[0] )
06441 value_range[0] = s;
06442 else if ( s > value_range[1] )
06443 value_range[1] = s;
06444 }
06445 }
06446 else
06447 {
06448 for ( i = 0; i < Pcount; i++ )
06449 {
06450 value[i] = e[0]*(P[i].x) + e[1]*(P[i].y) + e[2]*(P[i].z) + e[3];
06451 }
06452 }
06453
06454 return value;
06455 }
06456
06457
06458
06459 ON_3dPoint ON_PlaneEquation::ClosestPointTo( ON_3dPoint P ) const
06460 {
06461 const double t = -(x*P.x + y*P.y + z*P.z + d)/(x*x+y*y+z*z);
06462 return ON_3dPoint( P.x + t*x, P.y + t*y, P.z + t*z);
06463 }
06464
06465 double ON_PlaneEquation::MinimumValueAt(const ON_BoundingBox& bbox) const
06466 {
06467 double xx, yy, zz, s;
06468
06469 s = x*bbox.m_min.x;
06470 if ( s < (xx = x*bbox.m_max.x) ) xx = s;
06471
06472 s = y*bbox.m_min.y;
06473 if ( s < (yy = y*bbox.m_max.y) ) yy = s;
06474
06475 s = z*bbox.m_min.z;
06476 if ( s < (zz = z*bbox.m_max.z) ) zz = s;
06477
06478 return (xx + yy + zz + d);
06479 }
06480
06481 double ON_PlaneEquation::MaximumValueAt(const ON_BoundingBox& bbox) const
06482 {
06483 double xx, yy, zz, s;
06484
06485 s = x*bbox.m_min.x;
06486 if ( s > (xx = x*bbox.m_max.x) ) xx = s;
06487
06488 s = y*bbox.m_min.y;
06489 if ( s > (yy = y*bbox.m_max.y) ) yy = s;
06490
06491 s = z*bbox.m_min.z;
06492 if ( s > (zz = z*bbox.m_max.z) ) zz = s;
06493
06494 return (xx + yy + zz + d);
06495 }
06496
06497
06498 double ON_PlaneEquation::MaximumAbsoluteValueAt(
06499 bool bRational,
06500 int point_count,
06501 int point_stride,
06502 const double* points,
06503 double stop_value
06504 ) const
06505 {
06506 double value, max_value, w;
06507
06508 if ( point_count < 1
06509 || point_stride < (bRational?4:3)
06510 || 0 == points
06511 )
06512 {
06513 return ON_UNSET_VALUE;
06514 }
06515
06516 if ( ON_IsValid(stop_value) )
06517 {
06518 if ( bRational )
06519 {
06520 w = points[3];
06521 w = (0.0 != w) ? 1.0/w : 1.0;
06522 max_value = fabs(x*w*points[0]+y*w*points[1]+z*w*points[2]+points[3]);
06523 if ( max_value > stop_value )
06524 return max_value;
06525 for(point_count--; point_count--; )
06526 {
06527 points += point_stride;
06528 w = points[3];
06529 w = (0.0 != w) ? 1.0/w : 1.0;
06530 value = fabs(x*w*points[0]+y*w*points[1]+z*w*points[2]+points[3]);
06531 if ( value > max_value )
06532 {
06533 if ( (max_value = value) > stop_value )
06534 return max_value;
06535 }
06536 }
06537 }
06538 else
06539 {
06540 max_value = fabs(x*points[0]+y*points[1]+z*points[2]+d);
06541 if ( max_value > stop_value )
06542 return max_value;
06543 for(point_count--; point_count--; )
06544 {
06545 points += point_stride;
06546 value = fabs(x*points[0]+y*points[1]+z*points[2]+d);
06547 if ( value > max_value )
06548 {
06549 if ( (max_value = value) > stop_value )
06550 return max_value;
06551 }
06552 }
06553 }
06554 }
06555 else
06556 {
06557 if ( bRational )
06558 {
06559 w = points[3];
06560 w = (0.0 != w) ? 1.0/w : 1.0;
06561 max_value = fabs(x*w*points[0]+y*w*points[1]+z*w*points[2]+points[3]);
06562 for(point_count--; point_count--; )
06563 {
06564 points += point_stride;
06565 w = points[3];
06566 w = (0.0 != w) ? 1.0/w : 1.0;
06567 value = fabs(x*w*points[0]+y*w*points[1]+z*w*points[2]+points[3]);
06568 if ( value > max_value )
06569 max_value = value;
06570 }
06571 }
06572 else
06573 {
06574 max_value = fabs(x*points[0]+y*points[1]+z*points[2]+d);
06575 for(point_count--; point_count--; )
06576 {
06577 points += point_stride;
06578 value = fabs(x*points[0]+y*points[1]+z*points[2]+d);
06579 if ( value > max_value )
06580 max_value = value;
06581 }
06582 }
06583 }
06584
06585 return max_value;
06586 }
06587
06588 double ON_PlaneEquation::MaximumValueAt(
06589 bool bRational,
06590 int point_count,
06591 int point_stride,
06592 const double* points,
06593 double stop_value
06594 ) const
06595 {
06596 double value, max_value, w;
06597
06598 if ( point_count < 1
06599 || point_stride < (bRational?4:3)
06600 || 0 == points
06601 )
06602 {
06603 return ON_UNSET_VALUE;
06604 }
06605
06606 if ( ON_IsValid(stop_value) )
06607 {
06608 if ( bRational )
06609 {
06610 w = points[3];
06611 w = (0.0 != w) ? 1.0/w : 1.0;
06612 max_value = x*w*points[0]+y*w*points[1]+z*w*points[2]+points[3];
06613 if ( max_value > stop_value )
06614 return max_value;
06615 for(point_count--; point_count--; )
06616 {
06617 points += point_stride;
06618 w = points[3];
06619 w = (0.0 != w) ? 1.0/w : 1.0;
06620 value = x*w*points[0]+y*w*points[1]+z*w*points[2]+points[3];
06621 if ( value > max_value )
06622 {
06623 if ( (max_value = value) > stop_value )
06624 return max_value;
06625 }
06626 }
06627 }
06628 else
06629 {
06630 max_value = x*points[0]+y*points[1]+z*points[2]+d;
06631 if ( max_value > stop_value )
06632 return max_value;
06633 for(point_count--; point_count--; )
06634 {
06635 points += point_stride;
06636 value = x*points[0]+y*points[1]+z*points[2]+d;
06637 if ( value > max_value )
06638 {
06639 if ( (max_value = value) > stop_value )
06640 return max_value;
06641 }
06642 }
06643 }
06644 }
06645 else
06646 {
06647 if ( bRational )
06648 {
06649 w = points[3];
06650 w = (0.0 != w) ? 1.0/w : 1.0;
06651 max_value = x*w*points[0]+y*w*points[1]+z*w*points[2]+points[3];
06652 for(point_count--; point_count--; )
06653 {
06654 points += point_stride;
06655 w = points[3];
06656 w = (0.0 != w) ? 1.0/w : 1.0;
06657 value = x*w*points[0]+y*w*points[1]+z*w*points[2]+points[3];
06658 if ( value > max_value )
06659 max_value = value;
06660 }
06661 }
06662 else
06663 {
06664 max_value = x*points[0]+y*points[1]+z*points[2]+d;
06665 for(point_count--; point_count--; )
06666 {
06667 points += point_stride;
06668 value = x*points[0]+y*points[1]+z*points[2]+d;
06669 if ( value > max_value )
06670 max_value = value;
06671 }
06672 }
06673 }
06674
06675 return max_value;
06676 }
06677
06678 double ON_PlaneEquation::MinimumValueAt(
06679 bool bRational,
06680 int point_count,
06681 int point_stride,
06682 const double* points,
06683 double stop_value
06684 ) const
06685 {
06686 double value, min_value, w;
06687
06688 if ( point_count < 1
06689 || point_stride < (bRational?4:3)
06690 || 0 == points
06691 )
06692 {
06693 return ON_UNSET_VALUE;
06694 }
06695
06696 if ( ON_IsValid(stop_value) )
06697 {
06698 if ( bRational )
06699 {
06700 w = points[3];
06701 w = (0.0 != w) ? 1.0/w : 1.0;
06702 min_value = x*w*points[0]+y*w*points[1]+z*w*points[2]+points[3];
06703 if ( min_value < stop_value )
06704 return min_value;
06705 for(point_count--; point_count--; )
06706 {
06707 points += point_stride;
06708 w = points[3];
06709 w = (0.0 != w) ? 1.0/w : 1.0;
06710 value = x*w*points[0]+y*w*points[1]+z*w*points[2]+points[3];
06711 if ( value < min_value )
06712 {
06713 if ( (min_value = value) < stop_value )
06714 return min_value;
06715 }
06716 }
06717 }
06718 else
06719 {
06720 min_value = x*points[0]+y*points[1]+z*points[2]+d;
06721 if ( min_value < stop_value )
06722 return min_value;
06723 for(point_count--; point_count--; )
06724 {
06725 points += point_stride;
06726 value = x*points[0]+y*points[1]+z*points[2]+d;
06727 if ( value < min_value )
06728 {
06729 if ( (min_value = value) < stop_value )
06730 return min_value;
06731 }
06732 }
06733 }
06734 }
06735 else
06736 {
06737 if ( bRational )
06738 {
06739 w = points[3];
06740 w = (0.0 != w) ? 1.0/w : 1.0;
06741 min_value = x*w*points[0]+y*w*points[1]+z*w*points[2]+points[3];
06742 for(point_count--; point_count--; )
06743 {
06744 points += point_stride;
06745 w = points[3];
06746 w = (0.0 != w) ? 1.0/w : 1.0;
06747 value = x*w*points[0]+y*w*points[1]+z*w*points[2]+points[3];
06748 if ( value < min_value )
06749 min_value = value;
06750 }
06751 }
06752 else
06753 {
06754 min_value = x*points[0]+y*points[1]+z*points[2]+d;
06755 for(point_count--; point_count--; )
06756 {
06757 points += point_stride;
06758 value = x*points[0]+y*points[1]+z*points[2]+d;
06759 if ( value < min_value )
06760 min_value = value;
06761 }
06762 }
06763 }
06764
06765 return min_value;
06766 }
06767
06768
06769 bool ON_PlaneEquation::IsNearerThan(
06770 const ON_BezierCurve& bezcrv,
06771 double s0,
06772 double s1,
06773 int sample_count,
06774 double endpoint_tolerance,
06775 double interior_tolerance,
06776 double* smin,
06777 double* smax
06778 ) const
06779 {
06780 int i, n;
06781 double smn, smx, vmn, vmx, s, v, w;
06782 ON_3dPoint P;
06783 P.z = 0.0;
06784
06785 sample_count--;
06786 s = 0.5*(s0+s1);
06787 bezcrv.Evaluate(s,0,3,&P.x);
06788 vmn = vmx = x*P.x + y*P.y + z*P.z + d;
06789 smn = smx = s;
06790 if ( vmn > interior_tolerance )
06791 {
06792 if ( smin )
06793 *smin = s;
06794 if ( smax )
06795 *smax = s;
06796 return false;
06797 }
06798
06799 if ( endpoint_tolerance >= 0.0 )
06800 {
06801 bezcrv.Evaluate(s0,0,3,&P.x);
06802 v = x*P.x + y*P.y + z*P.z + d;
06803 if (v > endpoint_tolerance )
06804 {
06805 if ( smin )
06806 *smin = smn;
06807 if ( smax )
06808 *smax = s0;
06809 return false;
06810 }
06811 if ( v < vmn ) { vmn = v; smn = s0; } else if (v > vmx) { vmx = v; smx = s0; }
06812
06813 bezcrv.Evaluate(s1,0,3,&P.x);
06814 v = x*P.x + y*P.y + z*P.z + d;
06815 if (v > endpoint_tolerance )
06816 {
06817 if ( smin )
06818 *smin = smn;
06819 if ( smax )
06820 *smax = s1;
06821 return false;
06822 }
06823 if ( v < vmn ) { vmn = v; smn = s1; } else if (v > vmx) { vmx = v; smx = s1; }
06824 }
06825
06826 w = 0.5;
06827 for ( n = 4; sample_count > 0; n *= 2 )
06828 {
06829 w *= 0.5;
06830 for ( i = 1; i < n; i+= 2 )
06831 {
06832 s = w*i;
06833 s = (1.0-s)*s0 + s*s1;
06834 bezcrv.Evaluate(s,0,3,&P.x);
06835 v = x*P.x + y*P.y + z*P.z + d;
06836
06837 if ( v < vmn )
06838 {
06839 vmn = v;
06840 smn = s;
06841 }
06842 else if (v > vmx)
06843 {
06844 vmx = v;
06845 smx = s;
06846 if ( vmx > interior_tolerance )
06847 {
06848 if ( smin )
06849 *smin = smn;
06850 if ( smax )
06851 *smax = s;
06852 return false;
06853 }
06854 }
06855
06856 sample_count--;
06857 }
06858 }
06859
06860 if ( smin )
06861 *smin = smn;
06862 if ( smax )
06863 *smax = smx;
06864 return true;
06865 }
06866
06867 bool ON_PlaneEquation::operator==( const ON_PlaneEquation& eq ) const
06868 {
06869 return (x==eq.x && y==eq.y && z==eq.z && d==eq.d)?true:false;
06870 }
06871
06872 bool ON_PlaneEquation::operator!=( const ON_PlaneEquation& eq ) const
06873 {
06874 return (x!=eq.x || y!=eq.y || z!=eq.z || d!=eq.d)?true:false;
06875 }
06876
06877
06878
06879 int ON_Get3dConvexHull(
06880 const ON_SimpleArray<ON_3dPoint>& points,
06881 ON_SimpleArray<ON_PlaneEquation>& hull
06882 )
06883 {
06884
06885
06886
06887
06888 const int point_count = points.Count();
06889 if ( point_count < 3 )
06890 return 0;
06891
06892 const int count0 = hull.Count();
06893 hull.Reserve(count0+4);
06894
06895 int i,j,k,n;
06896 ON_3dPoint A,B,C;
06897 ON_PlaneEquation e;
06898 double d0,d1,h0,h1,d;
06899 bool bGoodSide;
06900 for ( i = 0; i < point_count; i++ )
06901 {
06902 A = points[i];
06903 for ( j = i+1; j < point_count; j++ )
06904 {
06905 B = points[j];
06906 for (k = j+1; k < point_count; k++ )
06907 {
06908 C = points[k];
06909 e.ON_3dVector::operator=(ON_CrossProduct(B-A,C-A));
06910 if ( !e.ON_3dVector::Unitize() )
06911 continue;
06912 e.d = -(A.x*e.x + A.y*e.y + A.z*e.z);
06913 d0 = d1 = e.ValueAt(A);
06914 d = e.ValueAt(B); if ( d < d0 ) d0 = d; else if (d > d1) d1 = d;
06915 d = e.ValueAt(C); if ( d < d0 ) d0 = d; else if (d > d1) d1 = d;
06916 if ( d0 > -ON_ZERO_TOLERANCE )
06917 d0 = -ON_ZERO_TOLERANCE;
06918 if ( d1 < ON_ZERO_TOLERANCE )
06919 d1 = ON_ZERO_TOLERANCE;
06920
06921 h0 = 0.0; h1 = 0.0;
06922
06923 bGoodSide = true;
06924 for ( n = 0; n < point_count && bGoodSide; n++ )
06925 {
06926 d = e.ValueAt(points[n]);
06927 if ( d < h0 )
06928 {
06929 h0 = d;
06930 bGoodSide = (d0 <= h0 || h1 <= d1);
06931 }
06932 else if ( d > h1 )
06933 {
06934 h1 = d;
06935 bGoodSide = (d0 <= h0 || h1 <= d1);
06936 }
06937 }
06938
06939 if ( bGoodSide )
06940 {
06941 if ( h1 <= d1 )
06942 {
06943
06944 if ( d0 <= h0 )
06945 {
06946
06947 hull.SetCount(count0);
06948 ON_PlaneEquation& e0 = hull.AppendNew();
06949 e0.x = -e.x;
06950 e0.y = -e.y;
06951 e0.z = -e.z;
06952 e0.d = -(e.d-h0);
06953 }
06954 ON_PlaneEquation& e1 = hull.AppendNew();
06955 e1.x = e.x;
06956 e1.y = e.y;
06957 e1.z = e.z;
06958 e1.d = (e.d-h1);
06959 if ( d0 <= h0 )
06960 {
06961
06962 return 2;
06963 }
06964 }
06965 else if ( d0 <= h0 )
06966 {
06967
06968 ON_PlaneEquation& e0 = hull.AppendNew();
06969 e0.x = -e.x;
06970 e0.y = -e.y;
06971 e0.z = -e.z;
06972 e0.d = -(e.d-h0);
06973 }
06974 }
06975 }
06976 }
06977 }
06978
06979 if ( hull.Count() < count0 + 4 )
06980 hull.SetCount(count0);
06981
06982 return hull.Count() - count0;
06983 }
06984
06985 bool ON_BoundingBox::IsValid() const
06986 {
06987 return ( m_min.x <= m_max.x
06988 && ON_IS_VALID(m_min.x)
06989 && ON_IS_VALID(m_max.x)
06990 && m_min.y <= m_max.y
06991 && ON_IS_VALID(m_min.y)
06992 && ON_IS_VALID(m_max.y)
06993 && m_min.z <= m_max.z
06994 && ON_IS_VALID(m_min.z)
06995 && ON_IS_VALID(m_max.z)
06996 );
06997 };
06998
06999 void ON_BoundingBox::Dump(ON_TextLog& text_log) const
07000 {
07001 text_log.Print("Bounding box: ");
07002 if ( !IsValid() )
07003 {
07004 text_log.Print("not valid ");
07005 }
07006 text_log.Print("%.17g to %.17g, %.17g to %.17g, %.17g to %.17g\n",
07007 m_min.x,m_max.x,
07008 m_min.y,m_max.y,
07009 m_min.z,m_max.z
07010 );
07011 }
07012
07013 bool ON_IsDegenrateConicHelper(double A, double B, double C, double D, double E)
07014 {
07015
07016
07017
07018
07019
07020
07021
07022
07023
07024
07025
07026
07027
07028
07029
07030
07031
07032
07033 const double zero_tol = 1.0e-9;
07034
07035 double x, y;
07036 double M[3][3];
07037 int i0, i1, i2;
07038
07039
07040
07041 x = fabs(A);
07042 if ( x < (y=fabs(B)) ) x = y;
07043 if ( x < (y=fabs(C)) ) x = y;
07044 if ( x < (y=fabs(D)) ) x = y;
07045 if ( x < (y=fabs(E)) ) x = y;
07046 if ( x <= 1.0e-12 )
07047 return true;
07048
07049 x = 1.0/x;
07050
07051
07052 M[0][0] = x*A;
07053 M[1][1] = x*C;
07054 x *= 0.5;
07055 M[0][1] = M[1][0] = x*B;
07056 M[0][2] = M[2][0] = x*D;
07057 M[1][2] = M[2][1] = x*E;
07058 M[2][2] = 0.0;
07059
07060
07061
07062
07063 i0 = 0;
07064 x = fabs(M[0][0]);
07065 if ( x < (y=fabs(M[1][0])) ) {x=y;i0=1;}
07066 if ( x < (y=fabs(M[2][0])) ) {x=y;i0=2;}
07067 if ( x <= zero_tol )
07068 return true;
07069
07070
07071 x = 1.0/M[i0][0];
07072 M[i0][1] *= x;
07073 M[i0][2] *= x;
07074 i1 = (i0+1)%3;
07075 if ( 0.0 != (y = -M[i1][0]) )
07076 {
07077 M[i1][1] += y*M[i0][1];
07078 M[i1][2] += y*M[i0][2];
07079 }
07080 i2 = (i0+2)%3;
07081 if ( 0.0 != (y = -M[i2][0]) )
07082 {
07083 M[i2][1] += y*M[i0][1];
07084 M[i2][2] += y*M[i0][2];
07085 }
07086
07087
07088 if ( fabs(M[i1][1]) < fabs(M[i2][1]) )
07089 {
07090 i1 = i2;
07091 i2 = (i0+1)%3;
07092 }
07093 if ( fabs(M[i1][1]) <= zero_tol )
07094 return true;
07095
07096
07097 x = 1.0/M[i1][1];
07098 M[i1][2] *= x;
07099 if ( 0.0 != (y = -M[i2][1]) )
07100 M[i2][2] += y*M[i1][2];
07101
07102
07103 if ( fabs(M[i2][2]) <= zero_tol )
07104 return true;
07105
07106 return false;
07107 }
07108
07109 bool ON_GetConicEquationThrough6Points(
07110 int stride,
07111 const double* points2d,
07112 double conic[6],
07113 double* max_pivot,
07114 double* min_pivot,
07115 double* zero_pivot
07116 )
07117 {
07118
07119
07120
07121
07122
07123
07124
07125
07126
07127 ON_2dPoint pts[6], bboxmin, bboxmax;
07128 double scale, x, y, M[5][5], N[5][5], max_piv, min_piv;
07129 const double* p;
07130 int i, j, k;
07131
07132 if ( 0 == conic )
07133 return false;
07134 memset(conic,0,6*sizeof(conic[0]));
07135 if ( max_pivot )
07136 *max_pivot = 0.0;
07137 if ( min_pivot )
07138 *min_pivot = 0.0;
07139 if ( zero_pivot )
07140 *zero_pivot = 0.0;
07141
07142
07143 bboxmin.x = bboxmax.x = pts[0].x = points2d[0];
07144 bboxmin.y = bboxmax.y = pts[0].y = points2d[1];
07145 if ( !pts[0].IsValid() )
07146 return false;
07147 for ( i = 1; i < 6; i++ )
07148 {
07149 points2d += stride;
07150 pts[i].x = points2d[0];
07151 pts[i].y = points2d[1];
07152 if ( !pts[i].IsValid() )
07153 return false;
07154 if ( pts[i].x < bboxmin.x ) bboxmin.x = pts[i].x;
07155 else if ( pts[i].x > bboxmax.x ) bboxmax.x = pts[i].x;
07156 if ( pts[i].y < bboxmin.y ) bboxmin.y = pts[i].y;
07157 else if ( pts[i].y > bboxmax.y ) bboxmax.y = pts[i].y;
07158 }
07159
07160
07161
07162
07163
07164 x = bboxmax.x-bboxmin.x;
07165 y = bboxmax.y-bboxmin.y;
07166 if ( x >= y )
07167 {
07168 if ( x > 0.0 )
07169 {
07170 y /= x;
07171 scale = x*sqrt(1.0 + y*y);
07172 }
07173 else
07174 return false;
07175 }
07176 else
07177 {
07178 x /= y;
07179 scale = y*sqrt(1.0 + x*x);
07180 }
07181 if ( scale > 0.0 )
07182 scale = 1.0/scale;
07183 else
07184 return false;
07185
07186 for ( i = 0; i < 5; i++ )
07187 {
07188 x = scale*(pts[i].x - pts[5].x);
07189 y = scale*(pts[i].y - pts[5].y);
07190 M[i][0] = x*x;
07191 M[i][1] = x*y;
07192 M[i][2] = y*y;
07193 M[i][3] = x;
07194 M[i][4] = y;
07195 }
07196
07197 memset( N,0,sizeof(N) );
07198 N[0][0] = N[1][1] = N[2][2] = N[3][3] = N[4][4] = 1.0;
07199
07200
07201
07203
07204
07205
07206 j = 0;
07207 p = &M[0][0];
07208 x = fabs(*p);
07209 for ( i = 1; i < 25; i++ )
07210 {
07211 if ( x < (y = fabs(*(++p))) )
07212 {
07213 x = y;
07214 j = i;
07215 }
07216 }
07217 max_piv = min_piv = x;
07218 if ( 0.0 == x )
07219 return false;
07220 i = j/5;
07221 j %= 5;
07222
07223 if ( 0 != i )
07224 {
07225
07226
07227 for ( k = 0; k < 5; k++ )
07228 {
07229 y = M[0][k]; M[0][k] = M[i][k]; M[i][k] = y;
07230 }
07231 }
07232 if ( 0 != j )
07233 {
07234
07235
07236
07237 for ( k = 0; k < 5; k++ )
07238 {
07239 y = M[k][0]; M[k][0] = M[k][j]; M[k][j] = y;
07240 y = N[k][0]; N[k][0] = N[k][j]; N[k][j] = y;
07241 }
07242 }
07243
07244
07245
07246 x = 1.0/M[0][0];
07247 M[0][0] = 1.0;
07248 M[0][1] *= x; M[0][2] *= x; M[0][3] *= x; M[0][4] *= x;
07249
07250
07251 for ( i = 1; i < 5; i++)
07252 {
07253 if ( 0.0 != (y = -M[i][0]) )
07254 {
07255
07256
07257 M[i][0] = 0.0;
07258 M[i][1] += y*M[0][1]; M[i][2] += y*M[0][2]; M[i][3] += y*M[0][3]; M[i][4] += y*M[0][4];
07259 }
07260 }
07261
07262
07264
07265
07266
07267 j = 6;
07268 p = &M[1][1];
07269 x = fabs(*p);
07270 for ( i = 7; i < 25; i++ )
07271 {
07272 if ( x < (y = fabs(*(++p))) )
07273 {
07274 x = y;
07275 j = i;
07276 }
07277 }
07278 if ( x > max_piv ) max_piv = x; else if ( x < min_piv ) min_piv = x;
07279 if ( 0.0 == x )
07280 {
07281 if ( 0 != max_pivot )
07282 *max_pivot = max_piv;
07283 return false;
07284 }
07285 i = j/5;
07286 j %= 5;
07287
07288 if ( i > 1 )
07289 {
07290
07291
07292 for ( k = 1; k < 5; k++ )
07293 {
07294 y = M[1][k]; M[1][k] = M[i][k]; M[i][k] = y;
07295 }
07296 }
07297 if ( j > 1 )
07298 {
07299
07300
07301
07302 for ( k = 0; k < 5; k++ )
07303 {
07304 y = M[k][1]; M[k][1] = M[k][j]; M[k][j] = y;
07305 y = N[k][1]; N[k][1] = N[k][j]; N[k][j] = y;
07306 }
07307 }
07308
07309
07310
07311 x = 1.0/M[1][1];
07312 M[1][1] = 1.0;
07313 M[1][2] *= x; M[1][3] *= x; M[1][4] *= x;
07314
07315
07316 for ( i = 2; i < 5; i++)
07317 {
07318 if ( 0.0 != (y = -M[i][1]) )
07319 {
07320
07321
07322 M[i][1] = 0.0;
07323 M[i][2] += y*M[1][2]; M[i][3] += y*M[1][3]; M[i][4] += y*M[1][4];
07324 }
07325 }
07326
07327
07329
07330
07331
07332 j = 12;
07333 p = &M[2][2];
07334 x = fabs(*p);
07335 for ( i = 13; i < 25; i++ )
07336 {
07337 if ( x < (y = fabs(*(++p))) )
07338 {
07339 x = y;
07340 j = i;
07341 }
07342 }
07343 if ( x > max_piv ) max_piv = x; else if ( x < min_piv ) min_piv = x;
07344 if ( 0.0 == x )
07345 {
07346 if ( 0 != max_pivot )
07347 *max_pivot = max_piv;
07348 return false;
07349 }
07350 i = j/5;
07351 j %= 5;
07352
07353 if ( i > 2 )
07354 {
07355
07356
07357 for ( k = 2; k < 5; k++ )
07358 {
07359 y = M[2][k]; M[2][k] = M[i][k]; M[i][k] = y;
07360 }
07361 }
07362 if ( j > 2 )
07363 {
07364
07365
07366
07367 for ( k = 0; k < 5; k++ )
07368 {
07369 y = M[k][2]; M[k][2] = M[k][j]; M[k][j] = y;
07370 y = N[k][2]; N[k][2] = N[k][j]; N[k][j] = y;
07371 }
07372 }
07373
07374
07375
07376 x = 1.0/M[2][2];
07377 M[2][2] = 1.0; M[2][3] *= x; M[2][4] *= x;
07378
07379
07380 for ( i = 3; i < 5; i++)
07381 {
07382 if ( 0.0 != (y = -M[i][2]) )
07383 {
07384
07385
07386 M[i][2] = 0.0;
07387 M[i][3] += y*M[2][3]; M[i][4] += y*M[2][4];
07388 }
07389 }
07390
07392
07393
07394
07395 i = j = 3;
07396 x = fabs(M[3][3]);
07397 if ( x < (y = fabs(M[3][4])) )
07398 {
07399 x = y; j = 4;
07400 }
07401 if ( x < (y = fabs(M[4][3])) )
07402 {
07403 x = y; i = 4; j = 3;
07404 }
07405 if ( x < (y = fabs(M[4][4])) )
07406 {
07407 x = y; i = j = 4;
07408 }
07409 if ( x > max_piv ) max_piv = x; else if ( x < min_piv ) min_piv = x;
07410 if ( 0.0 == x )
07411 {
07412 if ( 0 != max_pivot )
07413 *max_pivot = max_piv;
07414 return false;
07415 }
07416
07417 if ( i > 3 )
07418 {
07419
07420
07421 y = M[3][3]; M[3][3] = M[4][3]; M[4][3] = y;
07422 y = M[3][4]; M[3][4] = M[i][4]; M[4][4] = y;
07423 }
07424 if ( j > 3 )
07425 {
07426
07427
07428
07429 for ( k = 0; k < 5; k++ )
07430 {
07431 y = M[k][3]; M[k][3] = M[k][4]; M[k][4] = y;
07432 y = N[k][3]; N[k][3] = N[k][4]; N[k][4] = y;
07433 }
07434 }
07435
07436
07437
07438 x = 1.0/M[3][3];
07439 M[3][3] = 1.0;
07440 M[3][4] *= x;
07441
07442
07443 if ( 0.0 != M[4][3] )
07444 {
07445
07446
07447 M[4][4] -= M[4][3]*M[3][4];
07448 M[4][3] = 0.0;
07449 }
07450
07451
07452
07453 if ( max_pivot )
07454 *max_pivot = max_piv;
07455 if ( min_pivot )
07456 *min_pivot = max_piv;
07457 if ( zero_pivot )
07458 *zero_pivot = fabs(M[4][4]);
07459
07460
07461
07462
07463 for ( i = 0; i < 4; i++ )
07464 {
07465 for (j = i+1; j < 5; j++ )
07466 {
07467 if ( 0.0 != (y = -M[i][j]) )
07468 {
07469
07470 for ( k = 0; k < 5; k++ )
07471 {
07472
07473 N[k][j] += y*N[k][i];
07474 }
07475 }
07476 }
07477 }
07478
07479
07480
07481
07482
07483
07484
07485
07486
07487
07488 double A = N[0][4];
07489 double B = N[1][4];
07490 double C = N[2][4];
07491 double D = N[3][4];
07492 double E = N[4][4];
07493
07494
07495
07496 if ( ON_IsDegenrateConicHelper(A,B,C,D,E) )
07497 {
07498
07499 return false;
07500 }
07501
07502
07503
07504
07505 x = scale*scale;
07506 A *= x;
07507 B *= x;
07508 C *= x;
07509 D *= scale;
07510 E *= scale;
07511
07512
07513 x = -pts[5].x;
07514 y = -pts[5].y;
07515 double F = A*x*x + B*x*y + C*y*y + D*x + E*y;
07516 D += 2.0*A*x + B*y;
07517 E += 2.0*C*y + B*x;
07518
07519 if ( (fabs(A) >= fabs(C)) ? (A<0.0):(C<0.0) )
07520 {
07521
07522 A = -A; B = -B; C = -C; D = -D; E = -E; F = -F;
07523 }
07524
07525 conic[0] = A; conic[1] = B; conic[2] = C;
07526 conic[3] = D; conic[4] = E; conic[5] = F;
07527
07528
07529 j = 0;
07530 x = fabs(conic[0]);
07531 for ( i = 0; i < 6; i++ )
07532 {
07533 if ( x < (y = fabs(conic[i])) )
07534 {
07535 x = y;
07536 j = i;
07537 }
07538 }
07539 if ( !(conic[j] != 0.0) )
07540 return false;
07541 y = 1.0/conic[j];
07542 conic[0] *= y; conic[1] *= y; conic[2] *= y;
07543 conic[3] *= y; conic[4] *= y; conic[5] *= y;
07544 conic[j] = 1.0;
07545
07546 return true;
07547 }
07548
07549 bool ON_IsConicEquationAnEllipse(
07550 const double conic[6],
07551 ON_2dPoint& center,
07552 ON_2dVector& major_axis,
07553 ON_2dVector& minor_axis,
07554 double* major_radius,
07555 double* minor_radius
07556 )
07557 {
07558 double A, C, D, E, F, x0, y0;
07559 double X[2], Y[2], P[2];
07560
07561 if ( !ON_IsValid(conic[0])
07562 || !ON_IsValid(conic[1])
07563 || !ON_IsValid(conic[2])
07564 || !ON_IsValid(conic[3])
07565 || !ON_IsValid(conic[4])
07566 || !ON_IsValid(conic[5])
07567 )
07568 {
07569 return false;
07570 }
07571
07572 if ( fabs(conic[1]) > 1.0e-14*fabs(conic[0]+fabs(conic[2])) )
07573 {
07574
07575 const double alpha = 0.5*atan2(conic[1],conic[0]-conic[2]);
07576 const double s = sin(alpha);
07577 const double c = cos(alpha);
07578 X[0] = c; X[1] = s;
07579 Y[0] = -s; Y[1] = c;
07580
07581 A = conic[0]*c*c + conic[1]*c*s + conic[2]*s*s;
07582
07583 C = conic[0]*s*s - conic[1]*c*s + conic[2]*c*c;
07584 D = conic[3]*c + conic[4]*s;
07585 E = conic[4]*c - conic[3]*s;
07586
07587 }
07588 else
07589 {
07590 A = conic[0];
07591
07592 C = conic[2];
07593 D = conic[3];
07594 E = conic[4];
07595
07596 X[0] = 1.0; X[1] = 0.0;
07597 Y[0] = 0.0; Y[1] = 1.0;
07598 }
07599
07600 F = conic[5];
07601
07602
07603 if ( !((A > 0.0 && C > 0.0) || (A < 0.0 && C < 0.0)) )
07604 return false;
07605
07606
07607 x0 = -0.5*D/A;
07608 y0 = -0.5*E/C;
07609 P[0] = x0*X[0] + y0*Y[0];
07610 P[1] = x0*X[1] + y0*Y[1];
07611
07612
07613 F = conic[5] -(A*x0*x0 + C*y0*y0);
07614 if ( !(0.0 != F) )
07615 return false;
07616
07617
07618 A = sqrt(-F/A);
07619 C = sqrt(-F/C);
07620
07621 if ( A == C )
07622 {
07623
07624 major_axis.x = 1.0;
07625 major_axis.y = 0.0;
07626 minor_axis.x = 0.0;
07627 minor_axis.y = 1.0;
07628 *major_radius = A;
07629 *minor_radius = C;
07630 }
07631 else if ( A > C )
07632 {
07633
07634 major_axis.x = X[0];
07635 major_axis.y = X[1];
07636 minor_axis.x = Y[0];
07637 minor_axis.y = Y[1];
07638 *major_radius = A;
07639 *minor_radius = C;
07640 }
07641 else if ( C > A )
07642 {
07643
07644 major_axis.x = Y[0];
07645 major_axis.y = Y[1];
07646 minor_axis.x = -X[0];
07647 minor_axis.y = -X[1];
07648 *major_radius = C;
07649 *minor_radius = A;
07650 }
07651 else
07652 {
07653
07654 return false;
07655 }
07656
07657 center.x = P[0];
07658 center.y = P[1];
07659
07660 return true;
07661 }
07662
07663 bool ON_GetEllipseConicEquation(
07664 double a, double b,
07665 double x0, double y0,
07666 double alpha,
07667 double conic[6]
07668 )
07669 {
07670 if ( 0 == conic )
07671 return false;
07672
07673 if ( !(a > 0.0 && b > 0.0 && ON_IsValid(x0) && ON_IsValid(y0) && ON_IsValid(alpha)) )
07674 {
07675 return false;
07676 }
07677
07678 int k;
07679 double e, y;
07680 double a2 = a*a;
07681 double b2 = b*b;
07682
07683 double A0 = 1.0/a2;
07684 double B0 = 0.0;
07685 double C0 = 1.0/b2;
07686 double D0 = 0.0;
07687 double E0 = 0.0;
07688 double F0 = -1.0;
07689
07690
07691 const double ca = cos(-alpha);
07692 const double sa = sin(-alpha);
07693 const double A = A0*ca*ca + B0*ca*sa + C0*sa*sa;
07694 const double B = B0*(ca*ca - sa*sa) + 2.0*(C0-A0)*sa*ca;
07695 const double C = C0*ca*ca - B0*sa*ca + A0*sa*sa;
07696 const double D = D0*ca + E0*sa;
07697 const double E = E0*ca - D0*sa;
07698 const double F = F0;
07699
07700 if ( !((A > 0.0 && C > 0.0) || (A < 0.0 && C < 0.0)) )
07701 {
07702 return false;
07703 }
07704
07705
07706 conic[0] = A;
07707 conic[1] = B;
07708 conic[2] = C;
07709 conic[3] = D - 2.0*A*x0 - B*y0;
07710 conic[4] = E - 2.0*C*y0 - B*x0;
07711 conic[5] = F + A*x0*x0 + B*x0*y0 + C*y0*y0 - D*x0 - E*y0;
07712
07713 k = 0;
07714 e = fabs(conic[0]);
07715 if ( e < (y=fabs(conic[1])) ) {e=y;k=1;}
07716 if ( e < (y=fabs(conic[2])) ) {e=y;k=2;}
07717 if ( e < (y=fabs(conic[3])) ) {e=y;k=3;}
07718 if ( e < (y=fabs(conic[4])) ) {e=y;k=4;}
07719 if ( e < (y=fabs(conic[5])) ) {e=y;k=5;}
07720 e = 1.0/conic[k];
07721 conic[0] *= e; conic[1] *= e; conic[2] *= e;
07722 conic[3] *= e; conic[4] *= e; conic[5] *= e;
07723 conic[k] = 1.0;
07724 if ( conic[0] < 0.0 )
07725 {
07726 conic[0] = -conic[0]; conic[1] = -conic[1]; conic[2] = -conic[2];
07727 conic[3] = -conic[3]; conic[4] = -conic[4]; conic[5] = -conic[5];
07728 }
07729
07730 return true;
07731 }