csgeom/math.h Source File (Crystal Space 2.0 Public API Reference)

| ## Public API Reference

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

csgeom/math.h
Go to the documentation of this file.

    00001 /*
    00002   Copyright (C) 2005 by Marten Svanfeldt
    00003
    00004   This library is free software; you can redistribute it and/or
    00005   modify it under the terms of the GNU Library General Public
    00006   License as published by the Free Software Foundation; either
    00007   version 2 of the License, or (at your option) any later version.
    00008
    00009   This library is distributed in the hope that it will be useful,
    00010   but WITHOUT ANY WARRANTY; without even the implied warranty of
    00011   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00012   Library General Public License for more details.
    00013
    00014   You should have received a copy of the GNU Library General Public
    00015   License along with this library; if not, write to the Free
    00016   Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
    00017 */
    00018
    00019 #ifndef __CS_MATH_H__
    00020 #define __CS_MATH_H__
    00021
    00022 #include "csutil/algorithms.h"
    00023
    00034 template<class T>
    00035 const T& csMax (const T& a, const T& b)
    00036 {
    00037   if (b < a) return a;
    00038   return b;
    00039 }
    00040
    00044 template<class T>
    00045 const T& csMin (const T& a, const T& b)
    00046 {
    00047   if (a < b) return a;
    00048   return b;
    00049 }
    00050
    00054 template<class T>
    00055 void csSort (T& a, T& b)
    00056 {
    00057   if (b < a)
    00058     CS::Swap (a, b);
    00059 }
    00060
    00065 template<class T, class U>
    00066 void csSort (T& a, T& b, U& x, U& y)
    00067 {
    00068   if (b < a)
    00069   {
    00070     CS::Swap (a, b);
    00071     CS::Swap (x, y);
    00072   }
    00073 }
    00074
    00075
    00079 template<class T>
    00080 T csClamp (const T& a, T max, T min)
    00081 {
    00082   return csMin (csMax (a, min), max);
    00083 }
    00084
    00090 template<class T>
    00091 T csSmoothStep (const T& a, T max, T min)
    00092 {
    00093   T tmp, tmp2;
    00094   if (a <= min)
    00095     tmp = 0.0f;
    00096   else if (a >= max)
    00097     tmp = 1.0f;
    00098   else
    00099   {
    00100     tmp2 = (a - min) / (max-min);
    00101     tmp = tmp2*tmp2 * (3.0 - 2.0*tmp2);
    00102   }
    00103   return tmp;
    00104 }
    00105
    00110 template<class T, class Tfactor>
    00111 T csLerp (const T& a, const T& b, const Tfactor& f)
    00112 {
    00113   return (a + (b - a) * f);
    00114 }
    00115
    00119 template<class T>
    00120 T csSquare (const T& x)
    00121 {
    00122   return x * x;
    00123 }
    00124
    00125 namespace CS
    00126 {
    00129   /* IsNaN() is implemented by looking at the binary values directly
    00130      as using built-in functions turned out to be unreliable.
    00131      (Specifically, gcc's built-in isnan() always returns false if
    00132      -ffast-math is enabled.) */
    00134   CS_FORCEINLINE bool IsNaN (float f)
    00135   {
    00136   #ifdef CS_IEEE_DOUBLE_FORMAT
    00137     const uint32 exponentMask = 0x7f800000;
    00138     const uint32 mantissaMask = 0x007fffff;
    00139     union
    00140     {
    00141       float f;
    00142       uint32 ui32;
    00143     } u;
    00144     u.f = f;
    00145     return ((u.ui32 & exponentMask) == exponentMask)
    00146         && ((u.ui32 & mantissaMask) != 0);
    00147   #else
    00148     #error Do not know how to test for NaN
    00149   #endif
    00150   }
    00151   // External definition; used below as a workaround for __STRICT_ANSI__
    00152   CS_CRYSTALSPACE_EXPORT bool IsNaN_ext (double d);
    00154   CS_FORCEINLINE bool IsNaN (double d)
    00155   {
    00156   #ifdef __STRICT_ANSI__
    00157     return IsNaN_ext (d);
    00158   #else
    00159   #ifdef CS_IEEE_DOUBLE_FORMAT
    00160     const uint64 exponentMask = CONST_UINT64(0x7ff0000000000000);
    00161     const uint64 mantissaMask = CONST_UINT64(0x000fffffffffffff);
    00162     union
    00163     {
    00164       double d;
    00165       uint64 ui64;
    00166     } u;
    00167     u.d = d;
    00168     return ((u.ui64 & exponentMask) == exponentMask)
    00169         && ((u.ui64 & mantissaMask) != 0);
    00170   #else
    00171     #error Do not know how to test for NaN
    00172   #endif
    00173   #endif
    00174   }
    00175
    00177   CS_FORCEINLINE bool IsFinite (float f)
    00178   {
    00179   #ifdef CS_IEEE_DOUBLE_FORMAT
    00180     const uint32 exponentMask = 0x7f800000;
    00181     union
    00182     {
    00183       float f;
    00184       uint32 ui32;
    00185     } u;
    00186     u.f = f;
    00187     return ((u.ui32 & exponentMask) != exponentMask);
    00188   #else
    00189     #error Do not know how to test for NaN
    00190   #endif
    00191   }
    00192   // External definition; used below as a workaround for __STRICT_ANSI__
    00193   CS_CRYSTALSPACE_EXPORT bool IsFinite_ext (double d);
    00195   CS_FORCEINLINE bool IsFinite (double d)
    00196   {
    00197   #ifdef __STRICT_ANSI__
    00198     return IsFinite_ext (d);
    00199   #else
    00200   #ifdef CS_IEEE_DOUBLE_FORMAT
    00201     const uint64 exponentMask = CONST_UINT64(0x7ff0000000000000);
    00202     union
    00203     {
    00204       double d;
    00205       uint64 ui64;
    00206     } u;
    00207     u.d = d;
    00208     return ((u.ui64 & exponentMask) != exponentMask);
    00209   #else
    00210     #error Do not know how to test for NaN
    00211   #endif
    00212   #endif
    00213   }
    00214
    00216   CS_FORCEINLINE float Infinity()
    00217   {
    00218   #ifdef CS_IEEE_DOUBLE_FORMAT
    00219     union
    00220     {
    00221       uint32 ui32;
    00222       float f;
    00223     } u;
    00224     u.ui32 = 0x7f800000;
    00225     return u.f;
    00226   #else
    00227     return std::numeric_limits<float>::infinity();
    00228   #endif
    00229   }
    00231 } // namespace CS
    00232
    00234
    00238 CS_DEPRECATED_METHOD_MSG("Use CS::IsFinite(x) instead")
    00239 CS_FORCEINLINE bool csFinite (float f)
    00240 {
    00241   return CS::IsFinite (f);
    00242 }
    00247 CS_DEPRECATED_METHOD_MSG("Use CS::IsFinite(x) instead")
    00248 CS_FORCEINLINE bool csFinite (double d)
    00249 {
    00250   return CS::IsFinite (d);
    00251 }
    00252
    00257 CS_DEPRECATED_METHOD_MSG("Use CS::IsNaN(x) instead")
    00258 CS_FORCEINLINE bool csNaN (float f)
    00259 {
    00260   return CS::IsNaN (f);
    00261 }
    00266 CS_DEPRECATED_METHOD_MSG("Use CS::IsNaN(x) instead")
    00267 CS_FORCEINLINE bool csNaN (double d)
    00268 {
    00269   return CS::IsNaN (d);
    00270 }
    00271
    00277 CS_DEPRECATED_METHOD_MSG("Usage not recommended, inconsistent results")
    00278 CS_FORCEINLINE bool csNormal (float f)
    00279 {
    00280 #if defined (CS_HAVE_NORMALF)
    00281   return normalf (f);
    00282 #elif defined (CS_HAVE_STD__ISNORMAL)
    00283   return std::isnormal (f);
    00284 #elif defined(CS_HAVE_ISNORMAL)
    00285   return isnormal (f);
    00286 #else
    00287   return CS::IsFinite(f) && !CS::IsNaN(f);
    00288 #endif
    00289 }
    00295 CS_DEPRECATED_METHOD_MSG("Usage not recommended, inconsistent results")
    00296 CS_FORCEINLINE bool csNormal (double d)
    00297 {
    00298 #if defined (CS_HAVE_STD__ISNORMAL)
    00299   return std::isnormal (d);
    00300 #elif defined(CS_HAVE_ISNORMAL)
    00301   return isnormal (d);
    00302 #else
    00303   return CS::IsFinite(d) && !CS::IsNaN(d);
    00304 #endif
    00305 }
    00307
    00308
    00309 namespace CS
    00310 {
    00311 namespace Math
    00312 {
    00314   template<typename T>
    00315   CS_FORCEINLINE_TEMPLATEMETHOD T NextModulo3 (T number)
    00316   {
    00317     return (1 << number) & 0x3;
    00318   }
    00319 }
    00320 }
    00321
    00322
    00325 #endif //__CS_MATH_H__