00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef SGMisc_H
00019 #define SGMisc_H
00020
00021 template<typename T>
00022 class SGMisc {
00023 public:
00024 static T pi() { return T(3.1415926535897932384626433832795029L); }
00025 static T twopi() { return 2*T(3.1415926535897932384626433832795029L); }
00026
00027 static T min(const T& a, const T& b)
00028 { return a < b ? a : b; }
00029 static T min(const T& a, const T& b, const T& c)
00030 { return min(min(a, b), c); }
00031 static T min(const T& a, const T& b, const T& c, const T& d)
00032 { return min(min(min(a, b), c), d); }
00033 static T max(const T& a, const T& b)
00034 { return a > b ? a : b; }
00035 static T max(const T& a, const T& b, const T& c)
00036 { return max(max(a, b), c); }
00037 static T max(const T& a, const T& b, const T& c, const T& d)
00038 { return max(max(max(a, b), c), d); }
00039
00040
00041 static T clip(const T& a, const T& _min, const T& _max)
00042 { return max(_min, min(_max, a)); }
00043
00044 static int sign(const T& a)
00045 {
00046 if (a < -SGLimits<T>::min())
00047 return -1;
00048 else if (SGLimits<T>::min() < a)
00049 return 1;
00050 else
00051 return 0;
00052 }
00053
00054 static T rad2deg(const T& val)
00055 { return val*180/pi(); }
00056 static T deg2rad(const T& val)
00057 { return val*pi()/180; }
00058
00059
00060 static T
00061 normalizePeriodic(const T& min, const T& max, const T& value)
00062 {
00063 T range = max - min;
00064 if (range < SGLimits<T>::min())
00065 return min;
00066 T normalized = value - range*floor((value - min)/range);
00067
00068 if (value <= min)
00069 return min;
00070 if (max <= normalized)
00071 return min;
00072 return normalized;
00073 }
00074
00075
00076 static T
00077 normalizeAngle(const T& angle)
00078 { return normalizePeriodic(-pi(), pi(), angle); }
00079
00080
00081 static T
00082 normalizeAngle2(const T& angle)
00083 { return normalizePeriodic(0, twopi(), angle); }
00084
00085 static T round(const T& v)
00086 { return floor(v + T(0.5)); }
00087 static int roundToInt(const T& v)
00088 { return int(round(v)); }
00089
00090 #ifndef NDEBUG
00093 static bool isNaN(const T& v)
00094 {
00095 #ifdef HAVE_ISNAN
00096 return isnan(v);
00097 #elif defined HAVE_STD_ISNAN
00098 return std::isnan(v);
00099 #else
00100
00101
00102
00103
00104 return !(v == v);
00105 #endif
00106 }
00107 #endif
00108 };
00109
00110 #endif