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__
Generated for Crystal Space 2.0 by doxygen 1.6.1
