00001
00002
00003
00004
00005
00006
00007
00008
00013 #ifndef cml_util_h
00014 #define cml_util_h
00015
00016 #include <algorithm>
00017 #include <cstdlib>
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
00093
00094
00095
00096
00097
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
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
00229 inline long random_integer(long min, long max) {
00230 return min + std::rand() % (max - min + 1);
00231 }
00232
00233
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 }
00359
00360 #if defined(_MSC_VER)
00361 #pragma pop_macro("min")
00362 #pragma pop_macro("max")
00363 #endif
00364
00365 #endif
00366
00367
00368