00001
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #pragma once
00030
00031 #include <stdio.h>
00032 #include <stdlib.h>
00033 #include <time.h>
00034 #include <cmath>
00035
00036 #define TINY (0.0000001)
00037
00038 class K3dMath
00039 {
00041 static float ConvertHalfPiSin ( const float fAngle, bool &rbNeg );
00042 static float ConvertHalfPiCos ( const float fAngle, bool &rbNeg );
00043
00044 static float ConvertTwoPi ( const float fAngle );
00045
00046 public:
00047 K3dMath();
00048 ~K3dMath();
00049
00050
00051
00052 static bool IsOddNumber ( int i )
00053 {
00054 if ( i%2 )
00055 {
00056 return true;
00057 }
00058 else
00059 {
00060 return false;
00061 }
00062 }
00063
00069 static float ACos ( const float fValue );
00070 static float ASin ( const float fValue );
00071 static float ATan ( const float fValue );
00072 static float ATan2 ( const float fY, const float fX );
00073 static float Ceil ( const float fValue );
00074 static float Cos ( const float fValue );
00075 static float Exp ( const float fValue );
00076 static float FAbs ( const float fValue );
00077 static float Floor ( const float fValue );
00078 static float FMod ( const float fX, const float fY );
00079 static float InvSqrt ( const float fValue );
00080 static float Log ( const float fValue );
00081 static float Pow ( const float fBase, const float fExponent );
00082 static float Sin ( const float fValue );
00083 static float Sqr ( const float fValue );
00084 static float Sqrt ( const float fValue );
00085 static float Tan ( const float fValue );
00086
00089 static int Sign ( const int iValue );
00090 static int Sign ( const float fValue );
00091
00096 static float FastSin0 ( const float fAngle );
00097 static float FastSin1 ( const float fAngle );
00102 static float FastCos0 ( const float fAngle );
00103 static float FastCos1 ( const float fAngle );
00108 static float FastTan0 ( const float fAngle );
00109 static float FastTan1 ( const float fAngle );
00113 static float FastASin ( const float fValue );
00117 static float FastACos ( const float fValue );
00122 static float FastATan0 ( const float fValue );
00123 static float FastATan1 ( const float fValue );
00126 static float UnitRandom ( const float fSeed = ( float ) 0.0 );
00129 static float SymmetricRandom ( const float fSeed = ( float ) 0.0 );
00132 static float IntervalRandom ( const float fMin, const float fMax, const float fSeed = ( float ) 0.0 );
00134 static float Positive ( const float fValue );
00136 static int Positive ( const int iValue );
00138 static float Negative ( const float fValue );
00140 static int Negative ( const int iValue );
00141 static bool EqualRange ( const float _f0, const float _f1, const float _fRange );
00142
00144 static const float EPSILON;
00145 static const float MAX_REAL;
00146 static const float K_PI;
00147 static const float TWO_PI;
00148 static const float HALF_PI;
00149 static const float QUARTER_PI;
00150 static const float THREE_HALF_PI;
00151 static const float INV_PI;
00152 static const float INV_TWO_PI;
00153 static const float K_DEG_TO_RAD;
00154 static const float K_RAD_TO_DEG;
00155 static const float K_FI;
00156
00157
00158
00159 };
00160
00161 inline float K3dMath::ACos ( const float fValue )
00162 {
00163 if ( - ( float ) 1.0 < fValue )
00164 {
00165 if ( fValue < ( float ) 1.0 )
00166 return ( float ) acos ( ( double ) fValue );
00167 else
00168 return ( float ) 0.0;
00169 }
00170 else
00171 {
00172 return K_PI;
00173 }
00174 }
00175
00176 inline float K3dMath::ASin ( const float fValue )
00177 {
00178 if ( - ( float ) 1.0 < fValue )
00179 {
00180 if ( fValue < ( float ) 1.0 )
00181 return ( float ) asin ( ( double ) fValue );
00182 else
00183 return -HALF_PI;
00184 }
00185 else
00186 {
00187 return HALF_PI;
00188 }
00189 }
00190
00191 inline float K3dMath::ATan ( const float fValue )
00192 {
00193 return ( float ) atan ( ( double ) fValue );
00194 }
00195
00196 inline float K3dMath::ATan2 ( const float fY, const float fX )
00197 {
00198 return ( float ) atan2 ( ( double ) fY, ( double ) fX );
00199 }
00200
00201 inline float K3dMath::Ceil ( const float fValue )
00202 {
00203 return ( float ) ceil ( ( double ) fValue );
00204 }
00205
00206 inline float K3dMath::Cos ( const float fValue )
00207 {
00208 return ( float ) cos ( ( double ) fValue );
00209 }
00210
00211 inline float K3dMath::Exp ( const float fValue )
00212 {
00213 return ( float ) exp ( ( double ) fValue );
00214 }
00215
00216 inline float K3dMath::FAbs ( const float fValue )
00217 {
00218 return ( float ) fabs ( ( double ) fValue );
00219 }
00220
00221 inline float K3dMath::Floor ( const float fValue )
00222 {
00223 return ( float ) floor ( ( double ) fValue );
00224 }
00225
00226 inline float K3dMath::FMod ( const float fX, const float fY )
00227 {
00228 return ( float ) fmod ( ( double ) fX, ( double ) fY );
00229 }
00230
00231 inline float K3dMath::InvSqrt ( const float fValue )
00232 {
00233 return ( float ) ( 1.0/sqrt ( ( double ) fValue ) );
00234 }
00235
00236 inline float K3dMath::Log ( const float fValue )
00237 {
00238 return ( float ) log ( ( double ) fValue );
00239 }
00240
00241 inline float K3dMath::Pow ( const float fBase, const float fExponent )
00242 {
00243 return ( float ) pow ( ( double ) fBase, ( double ) fExponent );
00244 }
00245
00246 inline float K3dMath::Sin ( const float fValue )
00247 {
00248 return ( float ) sin ( ( double ) fValue );
00249 }
00250
00251 inline float K3dMath::Sqr ( const float fValue )
00252 {
00253 return fValue*fValue;
00254 }
00255
00256 inline float K3dMath::Sqrt ( const float fValue )
00257 {
00258 return ( float ) sqrt ( ( double ) fValue );
00259 }
00260
00261 inline float K3dMath::Tan ( const float fValue )
00262 {
00263 return ( float ) tan ( ( double ) fValue );
00264 }
00265
00266 inline int K3dMath::Sign ( const int iValue )
00267 {
00268 if ( iValue > 0 )
00269 return 1;
00270
00271 if ( iValue < 0 )
00272 return -1;
00273
00274 return 0;
00275 }
00276
00277 inline int K3dMath::Sign ( const float fValue )
00278 {
00279 if ( fValue > ( float ) 0.0 )
00280 return 1;
00281
00282 if ( fValue < ( float ) 0.0 )
00283 return -1;
00284
00285 return 0;
00286 }
00287
00288 inline float K3dMath::ConvertHalfPiSin ( const float fAngle, bool &rbNeg )
00289 {
00290 float fA;
00291 fA = fAngle;
00292
00294
00296
00297
00298 if ( fA > TWO_PI )
00299 {
00300 while ( fA > TWO_PI )
00301 {
00302 fA -= TWO_PI;
00303 }
00304 }
00305
00306 if ( fA > THREE_HALF_PI )
00307 {
00308 fA -= THREE_HALF_PI;
00309 fA = HALF_PI - fA;
00310 rbNeg = 1;
00311 return fA;
00312 }
00313
00314 if ( fA > K_PI )
00315 {
00316 fA -= K_PI;
00317 rbNeg = 1;
00318 return fA;
00319 }
00320
00321 if ( fA > HALF_PI )
00322 {
00323 fA -=HALF_PI;
00324 fA = HALF_PI - fA;
00325 return fA;
00326 }
00327
00329
00331
00332
00333 if ( fA < -TWO_PI )
00334 {
00335 while ( fA < -TWO_PI )
00336 {
00337 fA += TWO_PI;
00338 }
00339 }
00340
00341 if ( fA < -THREE_HALF_PI )
00342 {
00343 fA += THREE_HALF_PI;
00344 fA = HALF_PI + fA;
00345 return fA;
00346 }
00347
00348 if ( fA < -K_PI )
00349 {
00350 fA += K_PI;
00351 rbNeg = 1;
00352 return fA;
00353 }
00354
00355 if ( fA < -HALF_PI )
00356 {
00357 fA +=HALF_PI;
00358 fA = HALF_PI + fA;
00359 rbNeg = 1;
00360 return fA;
00361 }
00362
00363 return fA;
00364 }
00365
00366 inline float K3dMath::ConvertHalfPiCos ( const float fAngle, bool &rbNeg )
00367 {
00368 float fA;
00369 fA = fAngle;
00370
00372
00374
00375
00376 if ( fA > TWO_PI )
00377 {
00378 while ( fA > TWO_PI )
00379 {
00380 fA -= TWO_PI;
00381 }
00382 }
00383
00384 if ( fA > THREE_HALF_PI )
00385 {
00386 fA -= THREE_HALF_PI;
00387 fA = HALF_PI - fA;
00388 return fA;
00389 }
00390
00391 if ( fA > K_PI )
00392 {
00393 fA -= K_PI;
00394 rbNeg = 1;
00395 return fA;
00396 }
00397
00398 if ( fA > HALF_PI )
00399 {
00400 fA -=HALF_PI;
00401 fA = HALF_PI - fA;
00402 rbNeg = 1;
00403 return fA;
00404 }
00405
00409
00411 if ( fA < -TWO_PI )
00412 {
00413 while ( fA < -TWO_PI )
00414 {
00415 fA += TWO_PI;
00416 }
00417 }
00418
00419 if ( fA < -THREE_HALF_PI )
00420 {
00421 fA += THREE_HALF_PI;
00422 fA = HALF_PI + fA;
00423 return fA;
00424 }
00425
00426 if ( fA < -K_PI )
00427 {
00428 fA += K_PI;
00429 rbNeg = 1;
00430 return fA;
00431 }
00432
00433 if ( fA < -HALF_PI )
00434 {
00435 fA +=HALF_PI;
00436 fA = HALF_PI + fA;
00437 rbNeg = 1;
00438 return fA;
00439 }
00440
00441 return fA;
00442 }
00443
00444
00445 inline float K3dMath::ConvertTwoPi ( const float fAngle )
00446 {
00447 float fA;
00448 fA = fAngle;
00449
00451
00453
00454
00455 if ( fA > TWO_PI )
00456 {
00457 while ( fA > TWO_PI )
00458 {
00459 fA -= TWO_PI;
00460 }
00461 }
00462
00464
00466
00467
00468 if ( fA < -TWO_PI )
00469 {
00470 while ( fA < -TWO_PI )
00471 {
00472 fA += TWO_PI;
00473 }
00474 }
00475
00476 return fA;
00477 }
00478
00479 inline float K3dMath::FastSin0 ( const float fAngle )
00480 {
00481 float fA;
00482 bool bNeg = 0;
00483
00484 if ( ( fAngle>HALF_PI ) || ( fAngle<0 ) )
00485 {
00486
00487 fA = ConvertHalfPiSin ( fAngle, bNeg );
00488 }
00489 else
00490 {
00491 fA = fAngle;
00492 }
00493
00494 float fASqr = fA*fA;
00495 float fResult = ( float ) 7.61e-03;
00496 fResult *= fASqr;
00497 fResult -= ( float ) 1.6605e-01;
00498 fResult *= fASqr;
00499 fResult += ( float ) 1.0;
00500 fResult *= fA;
00501
00502
00503 if ( bNeg )
00504 {
00505 fResult = -fResult;
00506 }
00507
00508 return fResult;
00509 }
00510
00511 inline float K3dMath::FastSin1 ( const float fAngle )
00512 {
00513 float fA;
00514 bool bNeg = 0;
00515
00516 if ( ( fAngle>HALF_PI ) || ( fAngle<0 ) )
00517 {
00518
00519 fA = ConvertHalfPiSin ( fAngle, bNeg );
00520 }
00521 else
00522 {
00523 fA = fAngle;
00524 }
00525
00526 float fASqr = fA*fA;
00527 float fResult = - ( float ) 2.39e-08;
00528 fResult *= fASqr;
00529 fResult += ( float ) 2.7526e-06;
00530 fResult *= fASqr;
00531 fResult -= ( float ) 1.98409e-04;
00532 fResult *= fASqr;
00533 fResult += ( float ) 8.3333315e-03;
00534 fResult *= fASqr;
00535 fResult -= ( float ) 1.666666664e-01;
00536 fResult *= fASqr;
00537 fResult += ( float ) 1.0;
00538 fResult *= fA;
00539
00540
00541 if ( bNeg )
00542 {
00543 fResult = -fResult;
00544 }
00545
00546 return fResult;
00547 }
00548
00549 inline float K3dMath::FastCos0 ( const float fAngle )
00550 {
00551 float fA;
00552 bool bNeg = 0;
00553
00554 if ( ( fAngle>HALF_PI ) || ( fAngle<0 ) )
00555 {
00556
00557 fA = ConvertHalfPiCos ( fAngle, bNeg );
00558 }
00559 else
00560 {
00561 fA = fAngle;
00562 }
00563
00564
00565 float fASqr = fA*fA;
00566 float fResult = ( float ) 3.705e-02;
00567 fResult *= fASqr;
00568 fResult -= ( float ) 4.967e-01;
00569 fResult *= fASqr;
00570 fResult += ( float ) 1.0;
00571
00572
00573 if ( bNeg )
00574 {
00575 fResult = -fResult;
00576 }
00577
00578 return fResult;
00579 }
00580
00581 inline float K3dMath::FastCos1 ( const float fAngle )
00582 {
00583 float fA;
00584 bool bNeg = 0;
00585
00586 if ( ( fAngle>HALF_PI ) || ( fAngle<0 ) )
00587 {
00588
00589 fA = ConvertHalfPiCos ( fAngle, bNeg );
00590 }
00591 else
00592 {
00593 fA = fAngle;
00594 }
00595
00596 float fASqr = fA*fA;
00597 float fResult = - ( float ) 2.605e-07;
00598 fResult *= fASqr;
00599 fResult += ( float ) 2.47609e-05;
00600 fResult *= fASqr;
00601 fResult -= ( float ) 1.3888397e-03;
00602 fResult *= fASqr;
00603 fResult += ( float ) 4.16666418e-02;
00604 fResult *= fASqr;
00605 fResult -= ( float ) 4.999999963e-01;
00606 fResult *= fASqr;
00607 fResult += ( float ) 1.0;
00608
00609
00610 if ( bNeg )
00611 {
00612 fResult = -fResult;
00613 }
00614 return fResult;
00615 }
00616
00617 inline float K3dMath::FastTan0 ( const float fAngle )
00618 {
00619 float fA;
00620 float fSinA;
00621 float fCosA;
00622 if ( ( fAngle>QUARTER_PI ) || ( fAngle<0 ) )
00623 {
00624 if ( ( fAngle>TWO_PI ) || ( fAngle<0 ) )
00625 {
00626
00627 fA = K3dMath::ConvertTwoPi ( fAngle );
00628 fCosA = K3dMath::FastCos1 ( fA );
00629 }
00630 else
00631 {
00632 fA = fAngle;
00633 fCosA = K3dMath::FastCos1 ( fA );
00634 }
00635
00636 if ( fCosA )
00637 {
00638 fSinA = K3dMath::FastSin1 ( fA );
00639 return fSinA/fCosA;
00640 }
00641 else
00642 {
00643 return 0.0f;
00644 }
00645 }
00646 else
00647 {
00648 fA = fAngle;
00649 }
00650 float fASqr = fA*fA;
00651 float fResult = ( float ) 2.033e-01;
00652 fResult *= fASqr;
00653 fResult += ( float ) 3.1755e-01;
00654 fResult *= fASqr;
00655 fResult += ( float ) 1.0;
00656 fResult *= fA;
00657 return fResult;
00658 }
00659
00660 inline float K3dMath::FastTan1 ( const float fAngle )
00661 {
00662 float fA;
00663 float fSinA;
00664 float fCosA;
00665 if ( ( fAngle>QUARTER_PI ) || ( fAngle<0 ) )
00666 {
00667 if ( ( fAngle>TWO_PI ) || ( fAngle<0 ) )
00668 {
00669
00670 fA = K3dMath::ConvertTwoPi ( fAngle );
00671 fCosA = K3dMath::FastCos1 ( fA );
00672 }
00673 else
00674 {
00675 fA = fAngle;
00676 fCosA = K3dMath::FastCos1 ( fA );
00677 }
00678
00679 if ( fCosA )
00680 {
00681 fSinA = K3dMath::FastSin1 ( fA );
00682 return fSinA/fCosA;
00683 }
00684 else
00685 {
00686 return 0.0f;
00687 }
00688 }
00689 else
00690 {
00691 fA = fAngle;
00692 }
00693 float fASqr = fA*fA;
00694 float fResult = ( float ) 9.5168091e-03;
00695 fResult *= fASqr;
00696 fResult += ( float ) 2.900525e-03;
00697 fResult *= fASqr;
00698 fResult += ( float ) 2.45650893e-02;
00699 fResult *= fASqr;
00700 fResult += ( float ) 5.33740603e-02;
00701 fResult *= fASqr;
00702 fResult += ( float ) 1.333923995e-01;
00703 fResult *= fASqr;
00704 fResult += ( float ) 3.333314036e-01;
00705 fResult *= fASqr;
00706 fResult += ( float ) 1.0;
00707 fResult *= fA;
00708 return fResult;
00709 }
00710
00711 inline float K3dMath::FastASin ( const float fValue )
00712 {
00713 float fV;
00714 if ( ( fValue>1.0f ) || ( fValue<-1.0f ) )
00715 {
00716 return 0.0f;
00717 }
00718 if ( fValue<0 )
00719 {
00720 fV = -fValue;
00721 }
00722 else
00723 {
00724 fV = fValue;
00725 }
00726 float fRoot = sqrt ( ( ( float ) 1.0 )-fV );
00727 float fResult = - ( float ) 0.0187293;
00728 fResult *= fV;
00729 fResult += ( float ) 0.0742610;
00730 fResult *= fV;
00731 fResult -= ( float ) 0.2121144;
00732 fResult *= fV;
00733 fResult += ( float ) 1.5707288;
00734 fResult = HALF_PI - fRoot*fResult;
00735 if ( fValue<0 )
00736 {
00737 fResult = -fResult;
00738 }
00739 return fResult;
00740 }
00741
00742 inline float K3dMath::FastACos ( const float fValue )
00743 {
00744 float fV;
00745 if ( ( fValue>1.0f ) || ( fValue<-1.0f ) )
00746 {
00747 return 0.0f;
00748 }
00749 if ( fValue<0 )
00750 {
00751 fV = -fValue;
00752 }
00753 else
00754 {
00755 fV = fValue;
00756 }
00757
00758 float fRoot = sqrt ( ( ( float ) 1.0 )-fV );
00759 float fResult = - ( float ) 0.0187293;
00760 fResult *= fV;
00761 fResult += ( float ) 0.0742610;
00762 fResult *= fV;
00763 fResult -= ( float ) 0.2121144;
00764 fResult *= fV;
00765 fResult += ( float ) 1.5707288;
00766 fResult *= fRoot;
00767 if ( fValue<0 )
00768 {
00769 fResult = K_PI-fResult;
00770 }
00771 return fResult;
00772
00773 }
00774
00775 inline float K3dMath::FastATan0 ( const float fValue )
00776 {
00777 float fV;
00778 if ( ( fValue>1.0f ) || ( fValue<-1.0f ) )
00779 {
00780 if ( fValue )
00781 {
00782 fV = 1/fValue;
00783 }
00784 else
00785 {
00786 return 0.0f;
00787 }
00788
00789 }
00790 else
00791 {
00792 fV = fValue;
00793 }
00794
00795 float fVSqr = fV*fV;
00796 float fResult = ( float ) 0.0208351;
00797 fResult *= fVSqr;
00798 fResult -= ( float ) 0.085133;
00799 fResult *= fVSqr;
00800 fResult += ( float ) 0.180141;
00801 fResult *= fVSqr;
00802 fResult -= ( float ) 0.3302995;
00803 fResult *= fVSqr;
00804 fResult += ( float ) 0.999866;
00805 fResult *= fV;
00806
00807 if ( fValue>1.0f )
00808 {
00809 fResult = HALF_PI - fResult;
00810 }
00811 if ( fValue<-1.0f )
00812 {
00813 fResult = - ( fResult + HALF_PI );
00814 }
00815
00816 return fResult;
00817 }
00818
00819 inline float K3dMath::FastATan1 ( const float fValue )
00820 {
00821 float fV;
00822 if ( ( fValue>1.0f ) || ( fValue<-1.0f ) )
00823 {
00824 if ( fValue )
00825 {
00826 fV = 1/fValue;
00827 }
00828 else
00829 {
00830 return 0.0f;
00831 }
00832
00833 }
00834 else
00835 {
00836 fV = fValue;
00837 }
00838
00839 float fVSqr = fV*fV;
00840 float fResult = ( float ) 0.0028662257;
00841 fResult *= fVSqr;
00842 fResult -= ( float ) 0.0161657367;
00843 fResult *= fVSqr;
00844 fResult += ( float ) 0.0429096138;
00845 fResult *= fVSqr;
00846 fResult -= ( float ) 0.0752896400;
00847 fResult *= fVSqr;
00848 fResult += ( float ) 0.1065626393;
00849 fResult *= fVSqr;
00850 fResult -= ( float ) 0.1420889944;
00851 fResult *= fVSqr;
00852 fResult += ( float ) 0.1999355085;
00853 fResult *= fVSqr;
00854 fResult -= ( float ) 0.3333314528;
00855 fResult *= fVSqr;
00856 fResult += ( float ) 1.0;
00857 fResult *= fV;
00858 if ( fValue>1.0f )
00859 {
00860 fResult = HALF_PI - fResult;
00861 }
00862 if ( fValue<-1.0f )
00863 {
00864 fResult = - ( fResult + HALF_PI );
00865 }
00866 return fResult;
00867 }
00868
00869 inline float K3dMath::UnitRandom ( const float fSeed )
00870 {
00871 if ( fSeed > ( float ) 0.0 )
00872 srand ( ( unsigned int ) fSeed );
00873
00874 double dRatio = ( ( double ) rand() ) / ( ( double ) ( RAND_MAX ) );
00875 return ( float ) dRatio;
00876 }
00877
00878 inline float K3dMath::SymmetricRandom ( const float fSeed )
00879 {
00880 if ( fSeed > ( float ) 0.0 )
00881 srand ( ( unsigned int ) fSeed );
00882
00883 double dRatio = ( ( double ) rand() ) / ( ( double ) ( RAND_MAX ) );
00884 return ( float ) ( 2.0*dRatio - 1.0 );
00885 }
00886
00887 inline float K3dMath::IntervalRandom ( const float fMin, const float fMax, const float fSeed )
00888 {
00889 if ( fSeed > ( float ) 0.0 )
00890 srand ( ( unsigned int ) fSeed );
00891
00892 double dRatio = ( ( double ) rand() ) / ( ( double ) ( RAND_MAX ) );
00893 return fMin+ ( fMax-fMin ) * ( ( float ) dRatio );
00894 }
00895
00896 inline float K3dMath::Positive ( const float fValue )
00897 {
00898 if ( fValue < 0 )
00899 {
00900 return -fValue;
00901 }
00902
00903 return fValue;
00904 }
00905
00906 inline int K3dMath::Positive ( const int iValue )
00907 {
00908 if ( iValue < 0 )
00909 {
00910 return -iValue;
00911 }
00912
00913 return iValue;
00914 }
00915
00916
00917 inline float K3dMath::Negative ( const float fValue )
00918 {
00919 if ( fValue > 0 )
00920 {
00921 return -fValue;
00922 }
00923
00924 return fValue;
00925 }
00926
00927
00928 inline int K3dMath::Negative ( const int iValue )
00929 {
00930 if ( iValue > 0 )
00931 {
00932 return -iValue;
00933 }
00934
00935 return iValue;
00936 }
00937