00001
00027 #ifndef _HUGIN_MATH_HUGIN_MATH_H
00028 #define _HUGIN_MATH_HUGIN_MATH_H
00029
00030 #include <hugin_shared.h>
00031 #include <cmath>
00032 #include <math.h>
00033 #include <iostream>
00034 #include <vigra/diff2d.hxx>
00035
00036 #ifndef M_PI
00037 #define M_PI 3.14159265358979323846
00038 #endif
00039
00040 #ifndef PI
00041 #define PI 3.14159265358979323846
00042 #endif
00043
00044 #define DEG_TO_RAD( x ) ( (x) * 2.0 * PI / 360.0 )
00045 #define RAD_TO_DEG( x ) ( (x) * 360.0 / ( 2.0 * PI ) )
00046
00047
00048 #ifndef HAVE_LOG2
00049
00050
00051 inline double log2(double x)
00052 {
00053 return log(x)/log(2.0);
00054 }
00055
00056
00057
00058
00059
00060
00061
00062
00063 #endif
00064
00065
00067 namespace hugin_utils
00068 {
00069
00070 inline double round(double x);
00071
00072 inline double round(double x)
00073 {
00074 return floor(x+0.5);
00075 }
00076
00077 inline float roundf(float x);
00078
00079 inline float roundf(float x)
00080 {
00081 return (float) floor(x+0.5f);
00082 }
00083
00084 inline int ceili(double x)
00085 {
00086 return (int) ceil(x);
00087 }
00088
00089 inline int floori(double x)
00090 {
00091 return (int) floor(x);
00092 }
00093
00094
00095
00096 template <class T>
00097 inline int roundi(T x)
00098 {
00099 return ((x < 0.0) ?
00100 ((x < (float)INT_MIN) ? INT_MIN : static_cast<int>(x - 0.5)) :
00101 ((x > (float)INT_MAX) ? INT_MAX : static_cast<int>(x + 0.5)));
00102 }
00103
00104 inline int isnan(double x)
00105 {
00106 #ifndef _MSC_VER
00107 return std::isnan(x);
00108 #else
00109 return _isnan(x);
00110 #endif
00111 }
00112
00113
00114 template <class T>
00115 struct TDiff2D
00116 {
00117 TDiff2D()
00118 : x(0), y(0)
00119 { }
00120 TDiff2D(T x, T y)
00121 : x(x), y(y)
00122 { }
00123 TDiff2D(const vigra::Diff2D &d)
00124 : x(d.x), y(d.y)
00125 { }
00126
00127 bool operator==(TDiff2D rhs) const
00128 {
00129 return x == rhs.x && y == rhs.y;
00130 }
00131
00132 bool operator!=(TDiff2D rhs) const
00133 {
00134 return x != rhs.x || y != rhs.y;
00135 }
00136
00137 TDiff2D operator+(TDiff2D rhs) const
00138 {
00139 return TDiff2D (x+rhs.x, y+rhs.y);
00140 }
00141
00142 TDiff2D operator-(TDiff2D rhs) const
00143 {
00144 return TDiff2D (x-rhs.x, y-rhs.y);
00145 }
00146
00147 TDiff2D & operator*=(double val)
00148 {
00149 x = x*val;
00150 y = y*val;
00151 return *this;
00152 }
00153
00154 TDiff2D operator*(double val)
00155 {
00156 TDiff2D<T> result;
00157 result.x = x * val;
00158 result.y = y * val;
00159 return result;
00160 }
00161
00162 vigra::Diff2D toDiff2D() const
00163 {
00164 return vigra::Diff2D(roundi(x), roundi(y));
00165 }
00166
00168 T squareDistance(TDiff2D<T> other) const
00169 {
00170 return (other - *this).squareLength();
00171 }
00172
00174 T squareLength() const
00175 {
00176 return x*x + y*y;
00177 }
00178
00179 double x,y;
00180 };
00181
00183 typedef TDiff2D<double> FDiff2D;
00184
00185
00190 template <class T>
00191 T simpleClipPoint(const T & point, const T & min, const T & max)
00192 {
00193 T p(point);
00194 if (p.x < min.x) p.x = min.x;
00195 if (p.x > max.x) p.x = max.x;
00196 if (p.y < min.y) p.y = min.y;
00197 if (p.y > max.y) p.y = max.y;
00198 return p;
00199 }
00200
00201 template <class T>
00202 T sqr(T t)
00203 {
00204 return t*t;
00205 }
00206
00207 template <class T>
00208 double norm(T t)
00209 {
00210 return sqrt(t.x*t.x + t.y*t.y);
00211 }
00212
00215 template <class InputIterator1, class InputIterator2>
00216 double euclid_dist(InputIterator1 first1, InputIterator1 last1,
00217 InputIterator2 first2)
00218 {
00219 typename InputIterator1::value_type res = 0;
00220 InputIterator1 i(first1);
00221 while (i != last1) {
00222 double a = *i;
00223 double b = *(first2 + (i - first1));
00224 res = res + a*a + b*b;
00225 ++i;
00226 }
00227 return sqrt(res);
00228 }
00229
00232 template <class InputIterator1, class InputIterator2, class T>
00233 T sqr_dist(InputIterator1 first1, InputIterator1 last1,
00234 InputIterator2 first2, T res)
00235 {
00236 InputIterator1 i(first1);
00237 while (i != last1) {
00238 T a = (T)(*i) - (T) (*(first2 + (i - first1)));
00239 res = res + a*a;
00240 ++i;
00241 }
00242 return res;
00243 }
00244
00249 template <class POINT>
00250 vigra::Rect2D calcCircleROIFromPoints(const POINT& p1, const POINT & p2)
00251 {
00252 double dx = p2.x - p1.x;
00253 double dy = p2.y - p1.y;
00254 double r = sqrt(dx*dx + dy*dy) / 2.0;
00255 double mx = p1.x + dx/2;
00256 double my = p1.y + dy/2;
00257
00258 vigra::Rect2D rect;
00259 rect.setUpperLeft(vigra::Point2D(roundi(mx-r), roundi(my -r)));
00260 rect.setLowerRight(vigra::Point2D(roundi(mx+r), roundi(my+r)));
00261 return rect;
00262 }
00263
00264
00265
00266 }
00267
00268
00269
00270
00271 template <class T>
00272 inline std::ostream & operator<<(std::ostream & o, const hugin_utils::TDiff2D<T> & d)
00273 {
00274 return o << "( " << d.x << " " << d.y << " )";
00275 }
00276
00277 inline hugin_utils::FDiff2D operator/(const hugin_utils::FDiff2D & lhs, double val)
00278 {
00279 return hugin_utils::FDiff2D(lhs.x/val, lhs.y/val);
00280 }
00281
00282
00283 inline vigra::Diff2D operator*(const vigra::Diff2D & d, double scale)
00284 {
00285 return vigra::Diff2D((int)(ceil(d.x * scale)),
00286 (int)(ceil(d.y * scale)));
00287 }
00288
00289 #if 0
00292 inline vigra::Size2D operator*(const vigra::Size2D & d, double scale)
00293 {
00294 return vigra::Size2D((int)(ceil(d.x * scale)),
00295 (int)(ceil(d.y * scale)));
00296 }
00297 #endif
00298
00300 inline vigra::Rect2D operator*(const vigra::Rect2D & r, double scale)
00301 {
00302 return vigra::Rect2D( (int)floor(r.left()*scale),
00303 (int)floor(r.top()*scale),
00304 (int)ceil(r.right()*scale),
00305 (int)ceil(r.bottom()*scale));
00306 }
00307
00308 #endif // _H