util.h

Go to the documentation of this file.
00001 /* -*- C++ -*- ------------------------------------------------------------
00002  
00003 Copyright (c) 2007 Jesse Anders and Demian Nave http://cmldev.net/
00004 
00005 The Configurable Math Library (CML) is distributed under the terms of the
00006 Boost Software License, v1.0 (see cml/LICENSE for details).
00007 
00008  *-----------------------------------------------------------------------*/
00013 #ifndef cml_util_h
00014 #define cml_util_h
00015 
00016 #include <algorithm>   // For std::min and std::max.
00017 #include <cstdlib>     // For std::rand.
00018 #include <cml/constants.h>
00019 
00020 #if defined(_MSC_VER)
00021 #pragma push_macro("min")
00022 #pragma push_macro("max")
00023 #undef min
00024 #undef max
00025 #endif
00026 
00027 namespace cml {
00028 
00030 template < typename T >
00031 double sign(T value) {
00032     return value < T(0) ? -1.0 : (value > T(0) ? 1.0 : 0.0);
00033 }
00034 
00036 template < typename T >
00037 T clamp(T value, T min, T max) {
00038     return std::max(std::min(value, max), min);
00039 }
00040 
00042 template < typename T >
00043 bool in_range(T value, T min, T max) {
00044     return !(value < min) && !(value > max);
00045 }
00046 
00048 template < typename T >
00049 T map_range(T value, T min1, T max1, T min2, T max2) {
00050     return min2 + ((value - min1) / (max1 - min1)) * (max2 - min2);
00051 }
00052 
00053 
00055 template < typename T >
00056 T acos_safe(T theta) {
00057     return T(std::acos(clamp(theta, T(-1.0), T(1.0))));
00058 }
00059 
00061 template < typename T >
00062 T asin_safe(T theta) {
00063     return T(std::asin(clamp(theta, T(-1.0), T(1.0))));
00064 }
00065 
00067 template < typename T >
00068 T sqrt_safe(T value) {
00069     return T(std::sqrt(std::max(value, T(0.0))));
00070 }
00071 
00072 
00074 template < typename T >
00075 T sqr(T value) {
00076     return value * value;
00077 }
00078 
00080 template < typename T >
00081 T cub(T value) {
00082     return value * value * value;
00083 }
00084 
00086 template < typename T >
00087 T inv_sqrt(T value) {
00088     return T(1.0 / std::sqrt(value));
00089 }
00090 
00091 
00092 /* The next few functions deal with indexing. next() and prev() are useful
00093  * for operations involving the vertices of a polygon or other cyclic set,
00094  * and cyclic_permutation() is used by various functions that deal with
00095  * axes or basis vectors in a generic way. As these functions are only
00096  * relevant for unsigned integer types, I've just used size_t, but there
00097  * may be reasons I haven't thought of that they should be templated.
00098  */
00099 
00101 inline size_t next(size_t i, size_t N) {
00102     return (i + 1) % N;
00103 }
00104 
00106 inline size_t prev(size_t i, size_t N) {
00107     return i ? (i - 1) : (N - 1);
00108 }
00109 
00111 inline void cyclic_permutation(size_t first, size_t& i, size_t& j) {
00112     i = first;
00113     j = next(i, 2);
00114 }
00115 
00117 inline void cyclic_permutation(size_t first, size_t& i, size_t& j, size_t& k)
00118 {
00119     i = first;
00120     j = next(i, 3);
00121     k = next(j, 3);
00122 }
00123 
00125 inline void cyclic_permutation(
00126         size_t first, size_t& i, size_t& j, size_t& k, size_t& l)
00127 {
00128     i = first;
00129     j = next(i, 4);
00130     k = next(j, 4);
00131     l = next(k, 4);
00132 }
00133 
00134 
00136 template < typename T >
00137 T deg(T theta) {
00138     return theta * constants<T>::deg_per_rad();
00139 }
00140 
00142 template < typename T >
00143 T rad(T theta) {
00144     return theta * constants<T>::rad_per_deg();
00145 }
00146 
00147 /* Note: Moving interpolation functions to interpolation.h */
00148 
00149 #if 0
00150 
00155 template <typename T, typename Scalar>
00156 T lerp(const T& f0, const T& f1, Scalar u) {
00157     return (Scalar(1.0) - u) * f0 + u * f1;
00158 }
00159 #endif
00160 
00161 #if 0
00162 
00167 template <typename T, typename Scalar>
00168 T bilerp(const T& f00, const T& f10,
00169          const T& f01, const T& f11,
00170          Scalar u, Scalar v)
00171 {
00172     Scalar uv = u * v;
00173     return (
00174         (Scalar(1.0) - u - v + uv) * f00 +
00175                           (u - uv) * f10 +
00176                           (v - uv) * f01 +
00177                                 uv * f11
00178     );
00179 }
00180 #endif
00181 
00182 #if 0
00183 
00188 template <typename T, typename Scalar>
00189 T trilerp(const T& f000, const T& f100,
00190           const T& f010, const T& f110,
00191           const T& f001, const T& f101,
00192           const T& f011, const T& f111,
00193           Scalar u, Scalar v, Scalar w)
00194 {
00195     Scalar uv = u * v;
00196     Scalar vw = v * w;
00197     Scalar wu = w * u;
00198     Scalar uvw = uv * w;
00199     
00200     return (
00201         (Scalar(1.0) - u - v - w + uv + vw + wu - uvw) * f000 +
00202                                    (u - uv - wu + uvw) * f100 +
00203                                    (v - uv - vw + uvw) * f010 +
00204                                             (uv - uvw) * f110 +
00205                                    (w - vw - wu + uvw) * f001 +
00206                                             (wu - uvw) * f101 +
00207                                             (vw - uvw) * f011 +
00208                                                    uvw * f111
00209     );
00210 }
00211 #endif
00212 
00214 inline size_t random_binary() {
00215     return std::rand() % 2;
00216 }
00217 
00219 inline int random_polar() {
00220     return random_binary() ? 1 : -1;
00221 }
00222 
00224 inline double random_unit() {
00225     return double(std::rand()) / double(RAND_MAX);
00226 }
00227 
00228 /* Random integer in the range [min, max] */
00229 inline long random_integer(long min, long max) {
00230     return min + std::rand() % (max - min + 1);
00231 }
00232 
00233 /* Random real number in the range [min, max] */
00234 template < typename T >
00235 T random_real(T min, T max) {
00236     return min + random_unit() * (max - min);
00237 }
00238 
00240 template < typename T >
00241 T length_squared(T x, T y) {
00242     return x * x + y * y;
00243 }
00244 
00246 template < typename T >
00247 T length_squared(T x, T y, T z) {
00248     return x * x + y * y + z * z;
00249 }
00250 
00252 template < typename T >
00253 T length(T x, T y) {
00254     return std::sqrt(length_squared(x,y));
00255 }
00256 
00258 template < typename T >
00259 T length(T x, T y, T z) {
00260     return std::sqrt(length_squared(x,y,z));
00261 }
00262 
00264 template < typename T >
00265 size_t index_of_max(T a, T b) {
00266     return a > b ? 0 : 1;
00267 }
00268 
00270 template < typename T >
00271 size_t index_of_max_abs(T a, T b) {
00272     return index_of_max(std::fabs(a),std::fabs(b));
00273 }
00274 
00276 template < typename T >
00277 size_t index_of_min(T a, T b) {
00278     return a < b ? 0 : 1;
00279 }
00280 
00282 template < typename T >
00283 size_t index_of_min_abs(T a, T b) {
00284     return index_of_min(std::fabs(a),std::fabs(b));
00285 }
00286 
00288 template < typename T >
00289 size_t index_of_max(T a, T b, T c) {
00290     return a > b ? (c > a ? 2 : 0) : (b > c ? 1 : 2);
00291 }
00292 
00294 template < typename T >
00295 size_t index_of_max_abs(T a, T b, T c) {
00296     return index_of_max(std::fabs(a),std::fabs(b),std::fabs(c));
00297 }
00298 
00300 template < typename T >
00301 size_t index_of_min(T a, T b, T c) {
00302     return a < b ? (c < a ? 2 : 0) : (b < c ? 1 : 2);
00303 }
00304 
00306 template < typename T >
00307 size_t index_of_min_abs(T a, T b, T c) {
00308     return index_of_min(std::fabs(a),std::fabs(b),std::fabs(c));
00309 }
00310 
00312 template < typename T >
00313 T wrap(T value, T min, T max) {
00314     max -= min;
00315     value = std::fmod(value - min, max);
00316     if (value < T(0)) {
00317         value += max;
00318     }
00319     return min + value;
00320 }
00321 
00323 template < typename T >
00324 T xfov_to_yfov(T xfov, T aspect) {
00325     return T(2.0 * std::atan(std::tan(xfov * T(.5)) / double(aspect)));
00326 }
00327 
00329 template < typename T >
00330 T yfov_to_xfov(T yfov, T aspect) {
00331     return T(2.0 * std::atan(std::tan(yfov * T(.5)) * double(aspect)));
00332 }
00333 
00335 template < typename T >
00336 T xzoom_to_yzoom(T xzoom, T aspect) {
00337     return xzoom * aspect;
00338 }
00339 
00341 template < typename T >
00342 T yzoom_to_xzoom(T yzoom, T aspect) {
00343     return yzoom / aspect;
00344 }
00345 
00347 template < typename T >
00348 T zoom_to_fov(T zoom) {
00349     return T(2) * T(std::atan(T(1) / zoom));
00350 }
00351 
00353 template < typename T >
00354 T fov_to_zoom(T fov) {
00355     return T(1) / T(std::tan(fov * T(.5)));
00356 }
00357 
00358 } // namespace cml
00359 
00360 #if defined(_MSC_VER)
00361 #pragma pop_macro("min")
00362 #pragma pop_macro("max")
00363 #endif
00364 
00365 #endif
00366 
00367 // -------------------------------------------------------------------------
00368 // vim:ft=cpp

Generated on Sat Jul 18 19:35:32 2009 for CML 1.0 by  doxygen 1.5.9