[an error occurred while processing this directive]
Main Page | Modules | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

hugin_base/hugin_math/hugin_math.h

Go to the documentation of this file.
00001 // -*- c-basic-offset: 4 -*-
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 // #ifdef _MSC_VER
00051 inline double log2(double x)
00052 {
00053     return log(x)/log(2.0);
00054 }
00055 
00056 // #else
00057 // FreeBSD downstream patch used to implement it as define
00058 // check if the 
00059 // #define log2(x)      (log(x) / log(2))
00060 
00061 // #endif
00062 
00063 #endif
00064 
00065 
00067 namespace hugin_utils
00068 {
00069 
00070     inline double round(double x); // do we need this?
00071         
00072     inline double round(double x)
00073     {
00074         return floor(x+0.5);
00075     }
00076 
00077     inline float roundf(float x); // do we need this?
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     // a simple point class
00114     template <class T>
00115     struct IMPEX 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 } // namespace
00267 
00268 // backward compatibility
00269 //typedef hugin_utils::FDiff2D FDiff2D; 
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 // uses ceil for rounding.
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

Generated on Mon Sep 20 01:01:27 2010 for Hugintrunk by doxygen 1.3.9.1