Go to the documentation of this file.00001
00002 #ifndef vgl_ellipse_scan_iterator_txx_
00003 #define vgl_ellipse_scan_iterator_txx_
00004
00005 #include "vgl_ellipse_scan_iterator.h"
00006 #include <vcl_cmath.h>
00007
00008
00009 namespace {
00010 template <class T> inline T my_max( T x, T y ) { return x<y ? y : x; }
00011 }
00012
00013 template <class T>
00014 vgl_ellipse_scan_iterator<T>::vgl_ellipse_scan_iterator( T xc, T yc, T rx, T ry, T theta )
00015 : xc_( xc ),
00016 yc_( yc ),
00017 rx_( rx*rx ),
00018 ry_( ry*ry ),
00019 theta_( theta ),
00020 y_( 0 ),
00021 min_y_( 0 )
00022 {
00023 }
00024
00025 template <class T>
00026 vgl_ellipse_scan_iterator<T>::~vgl_ellipse_scan_iterator()
00027 {
00028 }
00029
00030 template <class T>
00031 void vgl_ellipse_scan_iterator<T>::reset()
00032 {
00033
00034 T y0;
00035 if ( vcl_sin( theta_ ) == 0.0 ) {
00036 y0 = vcl_sqrt(ry_);
00037 }
00038 else {
00039 T t = vcl_atan2( vcl_sqrt(ry_) , vcl_sqrt(rx_) * vcl_tan( theta_ ) );
00040 y0 = vcl_sqrt(rx_) * vcl_cos( t ) * vcl_sin( theta_ ) + vcl_sqrt(ry_) * vcl_sin( t ) * vcl_cos( theta_ );
00041 }
00042 if ( y0 < 0 ) y0 = -y0;
00043
00044 y_ = int( vcl_floor( yc_ + y0 ) ) + 1;
00045 min_y_ = int( vcl_ceil( yc_ - y0 ) );
00046 }
00047
00048 template <class T>
00049 bool vgl_ellipse_scan_iterator<T>::next()
00050 {
00051 --y_;
00052 if ( y_ < min_y_ ) return false;
00053
00054 T st = vcl_sin( -theta_ );
00055 T ct = vcl_cos( -theta_ );
00056 T A = rx_ * st * st + ry_ * ct * ct;
00057
00058 T x0, x1;
00059
00060 if ( A > 0 ) {
00061
00062
00063 T B = (rx_ - ry_) * (y_-yc_) * ct*st;
00064
00065 T D = rx_*ry_*(rx_*st*st + ry_*ct*ct - (y_-yc_)*(y_-yc_));
00066 if (D < 0) D=0;
00067
00068 x0 = (-B + vcl_sqrt( D )) / A;
00069 x1 = (-B - vcl_sqrt( D )) / A;
00070 }
00071 else {
00072
00073
00074 x0 = vcl_sqrt( my_max(rx_,ry_) );
00075 x1 = -x0;
00076 }
00077
00078 start_x_= int( vcl_ceil( xc_ + x1 - 1e-9 ) );
00079 end_x_ = int( vcl_floor( xc_ + x0 + 1e-9 ) );
00080
00081 if ( start_x_ > end_x_ ) {
00082
00083 return next();
00084 }
00085 else {
00086 return true;
00087 }
00088 }
00089
00090 #undef VGL_ELLIPSE_SCAN_ITERATOR_INSTANTIATE
00091 #define VGL_ELLIPSE_SCAN_ITERATOR_INSTANTIATE(T) \
00092 template class vgl_ellipse_scan_iterator<T >
00093
00094 #endif // vgl_ellipse_scan_iterator_txx_