FBX SDK Reference Guide: maths.h Source File
00001 #ifndef FBXFILESDK_COMPONENTS_KBASELIB_KMATH_MATHS_H
00002 #define FBXFILESDK_COMPONENTS_KBASELIB_KMATH_MATHS_H
00003 
00004 /**************************************************************************************
00005 
00006  Copyright © 1998 - 2008 Autodesk, Inc. and/or its licensors.
00007  All Rights Reserved.
00008 
00009  The coded instructions, statements, computer programs, and/or related material 
00010  (collectively the "Data") in these files contain unpublished information 
00011  proprietary to Autodesk, Inc. and/or its licensors, which is protected by 
00012  Canada and United States of America federal copyright law and by international 
00013  treaties. 
00014  
00015  The Data may not be disclosed or distributed to third parties, in whole or in
00016  part, without the prior written consent of Autodesk, Inc. ("Autodesk").
00017 
00018  THE DATA IS PROVIDED "AS IS" AND WITHOUT WARRANTY.
00019  ALL WARRANTIES ARE EXPRESSLY EXCLUDED AND DISCLAIMED. AUTODESK MAKES NO
00020  WARRANTY OF ANY KIND WITH RESPECT TO THE DATA, EXPRESS, IMPLIED OR ARISING
00021  BY CUSTOM OR TRADE USAGE, AND DISCLAIMS ANY IMPLIED WARRANTIES OF TITLE, 
00022  NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE OR USE. 
00023  WITHOUT LIMITING THE FOREGOING, AUTODESK DOES NOT WARRANT THAT THE OPERATION
00024  OF THE DATA WILL BE UNINTERRUPTED OR ERROR FREE. 
00025  
00026  IN NO EVENT SHALL AUTODESK, ITS AFFILIATES, PARENT COMPANIES, LICENSORS
00027  OR SUPPLIERS ("AUTODESK GROUP") BE LIABLE FOR ANY LOSSES, DAMAGES OR EXPENSES
00028  OF ANY KIND (INCLUDING WITHOUT LIMITATION PUNITIVE OR MULTIPLE DAMAGES OR OTHER
00029  SPECIAL, DIRECT, INDIRECT, EXEMPLARY, INCIDENTAL, LOSS OF PROFITS, REVENUE
00030  OR DATA, COST OF COVER OR CONSEQUENTIAL LOSSES OR DAMAGES OF ANY KIND),
00031  HOWEVER CAUSED, AND REGARDLESS OF THE THEORY OF LIABILITY, WHETHER DERIVED
00032  FROM CONTRACT, TORT (INCLUDING, BUT NOT LIMITED TO, NEGLIGENCE), OR OTHERWISE,
00033  ARISING OUT OF OR RELATING TO THE DATA OR ITS USE OR ANY OTHER PERFORMANCE,
00034  WHETHER OR NOT AUTODESK HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH LOSS
00035  OR DAMAGE. 
00036 
00037 **************************************************************************************/
00038 
00039 #include <fbxfilesdk/components/kbaselib/klib/itype.h>
00040 #include <fbxfilesdk/components/kbaselib/kmath/types.h>
00041 #include <fbxfilesdk/components/kbaselib/kmath/const.h>
00042 
00043 #include <math.h>
00044 
00045 #ifdef KARCH_ENV_WIN32
00046     #ifndef logb
00047         #define logb    _logb
00048     #endif
00049     #ifndef isnan
00050         #define isnan   _isnan
00051     #endif
00052 #endif
00053 
00054 
00055 //******************************************************************************
00056 //
00057 //  integer only templates
00058 //
00059 //******************************************************************************
00060 
00061 template<class T> K_INLINE T kIsOdd(T i)
00062 {
00063     return i & 1;
00064 }
00065 
00066 template<class T> K_INLINE T kIsEven(T i)
00067 {
00068     return !kIsOdd(i);
00069 }
00070 
00071 // -1^^i
00072 template<class T> K_INLINE T kAlt(T i)
00073 {
00074     return -(i & 1) | 1;
00075 }
00076 
00077 // factorial
00078 template<class T> K_INLINE T kFact(T x)
00079 {
00080     T y = 1; 
00081     
00082     while(x > 1) { 
00083         y *= x;
00084         x--;
00085     }
00086     
00087     return y;
00088 }
00089 
00090 // binomial coefficient
00091 template<class T> K_INLINE T kBC(T n, T k)
00092 {
00093     return kFact(n) / (kFact(k) * kFact(n - k));
00094 }
00095 
00096 // k-permutation
00097 template<class T> K_INLINE T kPerm(T n, T k)
00098 {
00099     return kFact(n) / kFact(n - k);
00100 }
00101 
00102 // k-combination
00103 template<class T> K_INLINE T kComb(T n, T k)
00104 {
00105     return kBCoef(n, k);
00106 }
00107 
00108 // greatest common divisor
00109 template<class T> K_INLINE T kGCD(T x, T y)
00110 {
00111     T r; while(y) { r = x % y; x = y; y = r; } return x;
00112 }
00113 
00114 // least common multiple
00115 template<class T> K_INLINE T kLCM(T x, T y)
00116 { 
00117     return x * (y / kGCD(x, y));
00118 }
00119 
00120 // r = x % y, x / y
00121 template<class T> K_INLINE T kDiv(T x, T y, T *r)
00122 {
00123     T q = x / y; return *r = x - y * q, q;
00124 }
00125 
00126 //******************************************************************************
00127 //
00128 //  floating-point number classification
00129 //
00130 //******************************************************************************
00131 
00132 // is not a number
00133 template<class T> K_INLINE bool kIsNan(T x);
00134 
00135 // is a finite number
00136 template<class T> K_INLINE bool kIsFinite(T x)
00137 {
00138     return (x != K_INF) && (x != -K_INF);
00139 }
00140 
00141 // is an infinite number
00142 template<class T> K_INLINE bool kIsInfinite(T x)
00143 {
00144     return !kIsFinite(x);
00145 }
00146 
00147 // is normalized
00148 template<class T> K_INLINE bool kIsNormalized(T x);
00149 
00150 template<class T> K_INLINE T kHuge(T);
00151 template<class T> K_INLINE T kTiny(T);
00152 
00153 //******************************************************************************
00154 //
00155 //  floating-point number manipulation
00156 //
00157 //******************************************************************************
00158 
00159 // mantissa of x
00160 template<class T> K_INLINE T kMantissa(T x);
00161 
00162 // exponent of x
00163 template<class T> K_INLINE int kExponent(T x);
00164 
00165 // mantissa and exponent of x
00166 template<class T> K_INLINE T kManExp(T x, int *y);
00167 
00168 // x * 2^y
00169 template<class T> K_INLINE T kScalb(T x, int y);
00170 
00171 // fractional part
00172 template<class T> K_INLINE T kMod(T x)
00173 {
00174     return kMod(x, T(1));
00175 }
00176 
00177 template<class T> K_INLINE T kMod(T x, T *y);
00178 
00179 // next representable value
00180 template<class T> K_INLINE T kNextAfter(T x, T y)
00181 {
00182     return x + kPolarity(y - x);
00183 }
00184 
00185 // validate value
00186 template<class T> K_INLINE T kValidate(T x)
00187 {
00188     return x;
00189 }
00190 
00191 //******************************************************************************
00192 //
00193 //  floating-point number sign
00194 //
00195 //******************************************************************************
00196 
00197 // sign(x) (-1,1)
00198 template<class T> K_INLINE T kSign(T x)
00199 {
00200     return (x < 0) ? T(-1) : T(1);
00201 }
00202 
00203 // polarity(x) (-1,0,1)
00204 template<class T> K_INLINE T kPolarity(T x)
00205 {
00206     return (x < 0) ? T(-1) : T(x > 0);
00207 }
00208 
00209 // |x|*sign(y)
00210 template<class T> K_INLINE T kCopysign(T x, T y)
00211 {
00212     return (x < 0) ? ((y < 0) ? x : -x) : ((y < 0) ? -x : x);
00213 }
00214 
00215 template<class T, class S> K_INLINE S kConvert(T x, S)
00216 {
00217     return S(x);
00218 }
00219 
00220 
00221 //******************************************************************************
00222 //
00223 //  integer rounding
00224 //
00225 //******************************************************************************
00226 
00227 // round toward -inf
00228 
00229 // floor to multiple
00230 // template<class T> K_INLINE T kFloor(T x, T y);
00231 
00232 // ceil to multiple
00233 // template<class T> K_INLINE T kCeil(T x, T y);
00234 
00235 // round to nearest
00236 template<class T> K_INLINE T kRound(T x)
00237 {
00238     T y = kFloor(x); return (x - y < T(0.5)) ? y : y + T(1);
00239 }
00240 
00241 // round to multiple
00242 template<class T> K_INLINE T kRound(T x, T y)
00243 {
00244     return y * kRound(x / y);
00245 }
00246 
00247 // round toward zero
00248 template<class T> K_INLINE T kTrunc(T x)
00249 {
00250     return (x < 0) ? kCeil(x) : kFloor(x);
00251 }
00252 
00253 // trunc to multiple
00254 template<class T> K_INLINE T kTrunc(T x, T y)
00255 {
00256     return y * kTrunc(x / y);
00257 }
00258 
00259 //******************************************************************************
00260 //
00261 //  moduli
00262 //
00263 //******************************************************************************
00264 
00265 // signed modulo
00266 // template<class T> K_INLINE T kMod(T x, T y);
00267 
00268 K_TEMPLATE_SPEC(float) K_INLINE float kMod(float x, float y)
00269 {
00270     return float(fmod(x, y));
00271 }
00272 K_TEMPLATE_SPEC(double) K_INLINE double kMod(double x, double y)
00273 {
00274     return fmod(x, y);
00275 }
00276 
00277 // remainder of closest
00278 template<class T> K_INLINE T kRem(T x, T y)
00279 {
00280     return x - kRound(x, y);
00281 }
00282 
00283 // unsigned modulo
00284 template<class T> K_INLINE T kRoll(T x, T y)
00285 {
00286     return x - kFloor(x, y);
00287 }
00288 
00289 // unroll
00290 template<class T> K_INLINE T kUnroll(T x, T y, T z)
00291 {
00292     return x + kRound(z - x, y);
00293 }
00294 
00295 // fold
00296 template<class T> K_INLINE T kFold(T x, T y)
00297 {
00298     kLong n = kLong(x / y); 
00299     
00300     return n ? (((n < 0) ^ (n & 1)) ? y - kRoll(x, y) : kRoll(x, y)) : kAbs(x);
00301 }
00302 
00303 //******************************************************************************
00304 //
00305 //  floating-point number comparison
00306 //
00307 //******************************************************************************
00308 
00309 K_TEMPLATE_SPEC(float) K_INLINE float kMin(float)
00310 {
00311     return K_FLOAT_MIN;
00312 }
00313 K_TEMPLATE_SPEC(double) K_INLINE double kMin(double)
00314 {
00315     return K_DOUBLE_MIN;
00316 }
00317 K_TEMPLATE_SPEC(float) K_INLINE float kMax(float)
00318 {
00319     return K_FLOAT_MAX;
00320 }
00321 K_TEMPLATE_SPEC(double) K_INLINE double kMax(double)
00322 {
00323     return K_DOUBLE_MAX;
00324 }
00325 // x == y within epsilon
00326 template<class T> K_INLINE bool kEq(T x, T y, T e)
00327 {
00328     return kAbs(x - y) <= e;
00329 }
00330 
00331 //******************************************************************************
00332 //
00333 //  squares and cubes
00334 //
00335 //******************************************************************************
00336 
00337 // reciprocal
00338 template<class T> K_INLINE T kRecip(T x)
00339 {
00340     return T(1) / x;
00341 }
00342 
00343 // square root
00344 template<class T> K_INLINE T kSqrt(T x)
00345 {
00346     if(x > 1) {
00347         T z, y = x >> 1; 
00348         do 
00349         { 
00350             z = y; 
00351             y = (y + (x / y)) >> 1; 
00352         } while(y < z); 
00353         return z;
00354     } else {
00355         return x;
00356     }
00357 }
00358 
00359 // square root of non-zero argument
00360 template<class T> K_INLINE T kSqrtnz(T x)
00361 {
00362     return kSqrt(x);
00363 }
00364 
00365 // square root reciprocal
00366 template<class T> K_INLINE T kRsqrt(T x)
00367 {
00368     return 1.0 / kSqrtnz(x);
00369 }
00370 
00371 // cubic root
00372 template<class T> K_INLINE T kCbrt(T x);
00373 
00374 // square
00375 template<class T> K_INLINE T kSq(T x)
00376 {
00377     return x * x;
00378 }
00379 
00380 // cube
00381 template<class T> K_INLINE T kCb(T x)
00382 {
00383     return x * x * x;
00384 }
00385 
00386 //******************************************************************************
00387 //
00388 //  exponential functions
00389 //
00390 //******************************************************************************
00391 
00392 // e^x
00393 template<class T> K_INLINE T kExp(T x);
00394 
00395 // 2^x
00396 template<class T> K_INLINE T kExp2(T x)
00397 {
00398     return kExp(x * T(K_LN2));
00399 }
00400 
00401 // 10^x
00402 template<class T> K_INLINE T kExp10(T x)
00403 {
00404     return kExp(x * T(K_LN10));
00405 }
00406 
00407 // e^x - 1
00408 template<class T> K_INLINE T kExpm1(T x)
00409 {
00410     return kExp(x) - T(1);
00411 }
00412 
00413 // 2^x - 1
00414 template<class T> K_INLINE T kExp2m1(T x)
00415 {
00416     return kExpm1(x * T(K_LN2));
00417 }
00418 
00419 // 10^x - 1
00420 template<class T> K_INLINE T kExp10m1(T x)
00421 {
00422     return kExpm1(x * T(K_LN10));
00423 }
00424 
00425 // x^y
00426 template<class T> K_INLINE T kPow(T x, T y)
00427 {
00428     return kExp(y * kLog(x));
00429 }
00430 
00431 //******************************************************************************
00432 //
00433 //  logarithm functions
00434 //
00435 //******************************************************************************
00436 
00437 // log(x)
00438 template<class T> K_INLINE T kLog(T x);
00439 
00440 // log2(x)
00441 template<class T> K_INLINE T kLog2(T x)
00442 {
00443     return kLog(x) * T(K_1_LN2);
00444 }
00445 
00446 // log10(x)
00447 template<class T> K_INLINE T kLog10(T x)
00448 {
00449     return kLog(x) * T(K_1_LN10);
00450 }
00451 
00452 // log(x + 1)
00453 template<class T> K_INLINE T kLogp1(T x)
00454 {
00455     return kLog(x + T(1));
00456 }
00457 
00458 // log2(x + 1)
00459 template<class T> K_INLINE T kLog2p1(T x)
00460 {
00461     return kLog2(x + T(1));
00462 }
00463 
00464 // log10(x + 1)
00465 template<class T> K_INLINE T kLog10p1(T x)
00466 {
00467     return kLog10(x + T(1));
00468 }
00469 
00470 
00471 //******************************************************************************
00472 //
00473 //  trigonometric functions
00474 //
00475 //******************************************************************************
00476 
00477 // sin(x)
00478 template<class T> K_INLINE T kSin(T x);
00479 
00480 // sin(x * pi)
00481 template<class T> K_INLINE T kSinpi(T x)
00482 {
00483     return kSin(x * K_PI);
00484 }
00485 
00486 // sin(x * pi/180)
00487 template<class T> K_INLINE T kSind(T x)
00488 {
00489     return kSin(x * K_PI_180);
00490 }
00491 
00492 // cos(x)
00493 template<class T> K_INLINE T kCos(T x);
00494 
00495 // cos(x * pi)
00496 template<class T> K_INLINE T kCospi(T x)
00497 {
00498     return kCos(x * K_PI);
00499 }
00500 
00501 // cos(x * pi/180)
00502 template<class T> K_INLINE T kCosd(T x)
00503 {
00504     return kCos(x * K_PI_180);
00505 }
00506 
00507 // *y = cos(x), sin(x)
00508 template<class T> K_INLINE T kSinCos(T x, T *y)
00509 {
00510     return *y = kCos(x), kSin(x);
00511 }
00512 
00513 // *y = cos(x * pi), sin(x * pi)
00514 template<class T> K_INLINE T kSinCospi(T x, T *y)
00515 {
00516     return kSinCos(T(x * K_PI), y);
00517 }
00518 
00519 // *y = cos(x * pi/180), sin(x * pi/180)
00520 template<class T> K_INLINE T kSinCosd(T x, T *y)
00521 {
00522     return kSinCos(T(x * K_PI_180), y);
00523 }
00524 
00525 // tan(x)
00526 template<class T> K_INLINE T kTan(T x)
00527 {
00528     return kSin(x) / kCos(x);
00529 }
00530 
00531 // tan(x * pi)
00532 template<class T> K_INLINE T kTanpi(T x)
00533 {
00534     return kTan(x * K_PI);
00535 }
00536 
00537 // tan(x * pi/180)
00538 template<class T> K_INLINE T kTand(T x)
00539 {
00540     return kTan(x * K_PI_180);
00541 }
00542 
00543 // sec(x)
00544 template<class T> K_INLINE T kSec(T x)
00545 {
00546     return kRecip(kSin(x));
00547 }
00548 
00549 // cosec(x)
00550 template<class T> K_INLINE T kCosec(T x)
00551 {
00552     return kRecip(kCos(x));
00553 }
00554 
00555 // cotan(x)
00556 template<class T> K_INLINE T kCotan(T x)
00557 {
00558     return kRecip(kTan(x));
00559 }
00560 
00561 // asin(x)
00562 template<class T> K_INLINE T kAsin(T x);
00563 
00564 // asin(x) / pi
00565 template<class T> K_INLINE T kAsinpi(T x)
00566 {
00567     return kAsin(x) * K_1_PI;
00568 }
00569 
00570 // asin(x) * 180/pi
00571 template<class T> K_INLINE T kAsind(T x)
00572 {
00573     return kAsin(x) * K_180_PI;
00574 }
00575 
00576 // acos(x)
00577 template<class T> K_INLINE T kAcos(T x);
00578 
00579 // acos(x) / pi
00580 template<class T> K_INLINE T kAcospi(T x)
00581 {
00582     return kAcos(x) * K_1_PI;
00583 }
00584 
00585 // acos(x) * 180/pi
00586 template<class T> K_INLINE T kAcosd(T x)
00587 {
00588     return kAcos(x) * K_180_PI;
00589 }
00590 
00591 // atan(x)
00592 template<class T> K_INLINE T kAtan(T x);
00593 
00594 // atan(x) / pi
00595 template<class T> K_INLINE T kAtanpi(T x)
00596 {
00597     return kAtan(x) * K_1_PI;
00598 }
00599 
00600 // atan(x) * 180/pi
00601 template<class T> K_INLINE T kAtand(T x)
00602 {
00603     return kAtan(x) * K_180_PI;
00604 }
00605 
00606 // atan(y/x)
00607 template<class T> K_INLINE T kAtan(T y, T x);
00608 
00609 // atan(y/x) / pi
00610 template<class T> K_INLINE T kAtanpi(T y, T x)
00611 {
00612     return kAtan(y, x) * K_1_PI;
00613 }
00614 
00615 // atan(y/x) * 180/pi
00616 template<class T> K_INLINE T kAtand(T y, T x)
00617 {
00618     return kAtan(y, x) * K_180_PI;
00619 }
00620 
00621 // arc tangent approximation
00622 template<class T> K_INLINE T kAtanq(T y, T x)
00623 {
00624     if(x >= 0) {
00625         if(y > 0) {
00626             return (x > y) ? (y / x) * T(K_PI_4) : (T(2) - (x / y)) * T(K_PI_4);
00627         } else if(y < 0) {
00628             return (x > -y) ? (y / x) * T(K_PI_4) : ((x / y) + T(2)) * T(-K_PI_4);
00629         } else {
00630             return 0;
00631         }
00632     } else {
00633         if(y > 0) {
00634             return (-x > y) ? (T(4) + (y / x)) * T(K_PI_4) : (T(2) - (x / y)) * T(K_PI_4);
00635         } else if(y < 0) {
00636             return (x < y) ? ((y / x) - T(4)) * T(K_PI_4) : ((x / y) + T(2)) * T(-K_PI_4);
00637         } else {
00638             return T(-K_PI);
00639         }
00640     }
00641 }
00642 
00643 // haversine(x)
00644 template<class T> K_INLINE T kHaversin(T x)
00645 {
00646     return T(0.5) * (T(1) - kCos(x));
00647 }
00648 
00649 // haversine(x)
00650 template<class T> K_INLINE T kHavercos(T x)
00651 {
00652     return T(0.5) * (T(1) - kSin(x));
00653 }
00654 
00655 // eucledian norm
00656 template<class T> K_INLINE T kNorm(T x, T y)
00657 {
00658     return kSqrt(x * x + y * y);
00659 }
00660 
00661 // eucledian norm
00662 template<class T> K_INLINE T kNorm(T x, T y, T z)
00663 {
00664     return kSqrt(x * x + y * y + z * z);
00665 }
00666 
00667 // eucledian norm
00668 template<class T> K_INLINE T kNorm(T w, T x, T y, T z)
00669 {
00670     return kSqrt(w * w + x * x + y * y + z * z);
00671 }
00672 
00673 // hypothenuse length
00674 template<class T> K_INLINE T kHypot(T x, T y)
00675 {
00676     return kSqrtnz(x * x + y * y);
00677 }
00678 
00679 template<class T> K_INLINE T kHypot(T x, T y, T z)
00680 {
00681     return kSqrtnz(x * x + y * y + z * z);
00682 }
00683 
00684 template<class T> K_INLINE T kHypot(T w, T x, T y, T z)
00685 {
00686     return kSqrtnz(w * w + x * x + y * y + z * z);
00687 }
00688 
00689 //******************************************************************************
00690 //
00691 //  complex number functions
00692 //
00693 //******************************************************************************
00694 
00695 template<class T> K_INLINE T kRe(T x)
00696 {
00697     return x;
00698 }
00699 
00700 template<class T> K_INLINE T kIm(T x)
00701 {
00702     return 0;
00703 }
00704 
00705 // abs(x + iy)
00706 template<class T> K_INLINE T kAbs(T x, T y)
00707 {
00708     T ax, ay;
00709 
00710     if(x) {
00711         if(ax = kAbs(x), y) {
00712             return (ax > (ay = kAbs(y))) ? ay * kSqrtnz(T(1) + kSq(x / y)) : ax * kSqrtnz(T(1) + kSq(y / x));
00713         } else {
00714             return ax;
00715         }
00716     } else {
00717         return kAbs(y);
00718     }
00719 }
00720 
00721 // arg(x + iy)
00722 template<class T> K_INLINE T kArg(T x, T y)
00723 {
00724     return kAtan(y, x);
00725 }
00726 
00727 // e + if = (a + ib) + (c + id)
00728 #define kComplexAdd(e, f, a, b, c, d) \
00729     (e) = (a)+(c); (f) = (b)+(d)
00730 
00731 // e + if = (a + ib) - (c + id)
00732 #define kComplexSub(e, f, a, b, c, d) \
00733     (e) = (a)-(c); (f) = (b)-(d)
00734 
00735 // c + id = (a + ib)(a + ib)
00736 #ifdef KARCH_SLOW_MULT
00737 #define kComplexSq(c, d, a, b, t) \
00738     (e) = (a)*(a); (t) = (a)+(b); (f) = (t)*(t)-(e); (t) = (b)*(b); (f) -= (t); (e) -= (t)
00739 #else
00740 #define kComplexSq(c, d, a, b, t) \
00741     (c) = (a)*(a)-(b)*(b); (d) = 2*(a)*(b)
00742 #endif
00743 
00744 // e + if = (a + ib)(c + id)
00745 #ifdef KARCH_SLOW_MULT
00746 #define kComplexMult(e, f, a, b, c, d, t) \
00747     (e) = (a)*(c); (t) = (b)*(d); (f) = ((a)+(b))*((c)+(d))-(e)-(t); (e) -= (t)
00748 #else
00749 #define kComplexMult(e, f, a, b, c, d, t) \
00750     (e) = (a)*(c)-(b)*(d); (f) = (b)*(c)+(a)*(d)
00751 #endif
00752 
00753 // e + if = (a + ib)(c - id)
00754 #ifdef KARCH_SLOW_MULT
00755 #define kComplexConjMult(e, f, a, b, c, d, t) \
00756     (e) = (a)*(c); (t) = (b)*(d); (f) = ((a)+(b))*((c)-(d))-(e)+(t); (e) += (t)
00757 #else
00758 #define kComplexConjMult(e, f, a, b, c, d, t) \
00759     (e) = (a)*(c)+(b)*(d); (f) = (b)*(c)-(a)*(d)
00760 #endif
00761 
00762 // e + if = (a + ib)/(c + id)
00763 #ifdef KARCH_SLOW_MULT
00764 #define kComplexDiv(e, f, a, b, c, d, t) \
00765     (e) = (a)*(c); (t) = (b)*(d); (f) = ((a)+(b))*((c)-(d))-(e)+(t); (e) += (t); (t) = 1/((c)*(c)+(d)*(d)); (e) *= (t); (f) *= (t)
00766 #else
00767 #define kComplexDiv(e, f, a, b, c, d, t) \
00768     (t) = 1/((c)*(c) + (d)*(d)); (e) = (t)*((a)*(c)+(b)*(d)); (f) = (t)*((b)*(c)-(a)*(d))
00769 #endif
00770 
00771 //******************************************************************************
00772 //
00773 //  hyperbolic functions
00774 //
00775 //******************************************************************************
00776 
00777 // sinh(x)
00778 template<class T> K_INLINE T kSinh(T x);
00779 
00780 // sech(x)
00781 template<class T> K_INLINE T kSech(T x)
00782 {
00783     return kRecip(kSinh(x));
00784 }
00785 
00786 // cosh(x)
00787 template<class T> K_INLINE T kCosh(T x);
00788 
00789 // cosech(x)
00790 template<class T> K_INLINE T kCosech(T x)
00791 {
00792     return kRecip(kCosh(x));
00793 }
00794 /*
00795 // y = cosh(x), sinh(x)
00796 template<class T> K_INLINE T kSinhCosh(T x, T *y)
00797 {
00798     return *y = kCosh(), kSinh();
00799 }
00800 */
00801 // tanh(x)
00802 template<class T> K_INLINE T kTanh(T x);
00803 
00804 // cotanh(x)
00805 template<class T> K_INLINE T kCotanh(T x)
00806 {
00807     return kRecip(kTanh(x));
00808 }
00809 
00810 // asinh(x)
00811 template<class T> K_INLINE T kAsinh(T x)
00812 {
00813     return kLog(x + kSqrtnz(x * x + T(1)));
00814 }
00815 
00816 // acosh(x)
00817 template<class T> K_INLINE T kAcosh(T x)
00818 {
00819     return kLog(x + kSqrtnz(x * x));
00820 }
00821 
00822 // atanh(z)
00823 template<class T> K_INLINE T kAtanh(T x)
00824 {
00825     return 0.5 * kLog((T(1) + x) / (T(1) - x));
00826 }
00827 
00828 //******************************************************************************
00829 //
00830 //  polynomial roots
00831 //
00832 //******************************************************************************
00833 
00834 // quadratic
00835 template<class T> K_INLINE int kQuadRoots(T a, T b, T c, T *x1, T *x2)
00836 {
00837     T t, q;
00838 
00839     if((t = b * b - a * c * T(4)) > 0) {
00840         q = (b + kSign(b) * kSqrtnz(t)) * T(-0.5);
00841         *x1 = q / a;
00842         *x2 = c / q;
00843         return 2;
00844     } else if(t == 0) {
00845         *x1 = *x2 = -b / (a + a);
00846         return 1;
00847     } else {
00848         return 0;
00849     }
00850 }
00851 
00852 // cubic
00853 template<class T> K_INLINE int kCubicRoots(T a, T b, T c, T *x1, T *x2, T *x3)
00854 {
00855     T A, B, Q, R, D, theta;
00856 
00857     Q = (kSq(a) - b * T(3)) * T(K_1_9);
00858     R = (kCb(a) * T(2) - a * b * T(9) + c * T(27)) * T(K_1_54);
00859     a *= T(K_1_3);
00860 
00861     D = R * R - Q * Q * Q;
00862     if(D < 0) {
00863         theta = kAcos(R / kSqrt(Q * Q * Q)) * T(K_1_3);
00864         Q = kSqrt(Q) * T(-2);
00865         *x1 = Q * kCos(theta) - a;
00866         *x2 = Q * kCos(theta + T(K_2PI_3)) - a;
00867         *x3 = Q * kCos(theta - T(K_2PI_3)) - a;
00868         return 3;
00869     } else {
00870         A = -kSign(R)*kCbrt(kAbs(R) + kSqrt(D));
00871         B = A ? Q / A : 0;
00872         *x1 = (A + B) - a;
00873         *x2 = *x3 = T(-0.5) * (A + B) - a;
00874         return 2 - (*x1 == *x2);
00875     }
00876 }
00877 
00878 K_TEMPLATE_SPEC(double) K_INLINE bool kIsNan(double x)
00879 {
00880     return !!isnan(x);
00881 }
00882 
00883 K_TEMPLATE_SPEC(double) K_INLINE double kSqrt(double x)
00884 {
00885     return sqrt(x);
00886 }
00887 
00888 K_TEMPLATE_SPEC(float) K_INLINE float kSqrt(float x)
00889 {
00890     return sqrtf(x);
00891 }
00892 
00893 
00894 //******************************************************************************
00895 //
00896 //  exponential functions
00897 //
00898 //******************************************************************************
00899 
00900 K_TEMPLATE_SPEC(float) K_INLINE float kExp(float x)
00901 {
00902     return expf(x);
00903 }
00904 K_TEMPLATE_SPEC(double) K_INLINE double kExp(double x)
00905 {
00906     return exp(x);
00907 }
00908 //******************************************************************************
00909 //
00910 //  logarithm functions
00911 //
00912 //******************************************************************************
00913 
00914 K_TEMPLATE_SPEC(float) K_INLINE float kLog(float x)
00915 {
00916     return float(log(x));
00917 }
00918 K_TEMPLATE_SPEC(double) K_INLINE double kLog(double x)
00919 {
00920     return log(x);
00921 }
00922 
00923 K_TEMPLATE_SPEC(float) K_INLINE float kLog10(float x)
00924 {
00925     return float(log10(x));
00926 }
00927 K_TEMPLATE_SPEC(double) K_INLINE double kLog10(double x)
00928 {
00929     return log10(x);
00930 }
00931 
00932 K_TEMPLATE_SPEC(float) K_INLINE int kExponent(float x)
00933 {
00934     return int(logb(x));
00935 }
00936 K_TEMPLATE_SPEC(double) K_INLINE int kExponent(double x)
00937 {
00938     return int(logb(x));
00939 }
00940 
00941 //******************************************************************************
00942 //
00943 //  trigonometric functions
00944 //
00945 //******************************************************************************
00946 
00947 K_TEMPLATE_SPEC(float) K_INLINE float kSin(float x)
00948 {
00949     return sinf(x);
00950 }
00951 K_TEMPLATE_SPEC(double) K_INLINE double kSin(double x)
00952 {
00953     return sin(x);
00954 }
00955 K_TEMPLATE_SPEC(float) K_INLINE float kCos(float x)
00956 {
00957     return cosf(x);
00958 }
00959 K_TEMPLATE_SPEC(double) K_INLINE double kCos(double x)
00960 {
00961     return cos(x);
00962 }
00963 K_TEMPLATE_SPEC(float) K_INLINE float kTan(float x)
00964 {
00965     return tanf(x);
00966 }
00967 K_TEMPLATE_SPEC(double) K_INLINE double kTan(double x)
00968 {
00969     return tan(x);
00970 }
00971 K_TEMPLATE_SPEC(float) K_INLINE float kAsin(float x)
00972 {
00973     return asinf(x);
00974 }
00975 K_TEMPLATE_SPEC(double) K_INLINE double kAsin(double x)
00976 {
00977     return asin(x);
00978 }
00979 K_TEMPLATE_SPEC(float) K_INLINE float kAcos(float x)
00980 {
00981     return acosf(x);
00982 }
00983 K_TEMPLATE_SPEC(double) K_INLINE double kAcos(double x)
00984 {
00985     return acos(x);
00986 }
00987 K_TEMPLATE_SPEC(float) K_INLINE float kAtan(float x)
00988 {
00989     return atanf(x);
00990 }
00991 K_TEMPLATE_SPEC(double) K_INLINE double kAtan(double x)
00992 {
00993     return atan(x);
00994 }
00995 K_TEMPLATE_SPEC(float) K_INLINE float kAtan(float y, float x)
00996 {
00997     return atan2f(y, x);
00998 }
00999 K_TEMPLATE_SPEC(double) K_INLINE double kAtan(double y, double x)
01000 {
01001     return atan2(y, x);
01002 }
01003 
01004 // template<class T> K_INLINE T kAbs(T x)
01005 K_TEMPLATE_SPEC(float) K_INLINE float kAbs(float x)
01006 {
01007     return fabs(x);
01008 }
01009 
01010 K_TEMPLATE_SPEC(double) K_INLINE double kAbs(double x)
01011 {
01012     return fabs(x);
01013 }
01014 
01015 // template<class T> K_INLINE T kFloor(T x);
01016 K_TEMPLATE_SPEC(float) K_INLINE float kFloor(float x)
01017 {
01018     return float(floor(x));
01019 }
01020 K_TEMPLATE_SPEC(double) K_INLINE double kFloor(double x)
01021 {
01022     return floor(x);
01023 }
01024 
01025 // template<class T> K_INLINE T kCeil(T x);
01026 K_TEMPLATE_SPEC(float) K_INLINE float kCeil(float x)
01027 {
01028     return float(ceil(x));
01029 }
01030 K_TEMPLATE_SPEC(double) K_INLINE double kCeil(double x)
01031 {
01032     return ceil(x);
01033 }
01034 
01035 // template<class T> K_INLINE T kCeil(T x, T y)
01036 K_TEMPLATE_SPEC(float) K_INLINE float kCeil(float x, float y)
01037 {
01038     return y * (kCeil(x / y));
01039 }
01040 
01041 K_TEMPLATE_SPEC(double) K_INLINE double kCeil(double x, double y)
01042 {
01043     return y * (kCeil(x / y));
01044 }
01045 
01046 #endif // FBXFILESDK_COMPONENTS_KBASELIB_KMATH_MATHS_H
01047