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 } else {
00038 T t = vcl_atan2( vcl_sqrt(ry_) , vcl_sqrt(rx_) * vcl_tan( theta_ ) );
00039 y0 = vcl_sqrt(rx_) * vcl_cos( t ) * vcl_sin( theta_ ) + vcl_sqrt(ry_) * vcl_sin( t ) * vcl_cos( theta_ );
00040 }
00041 if ( y0 < 0 ) y0 = -y0;
00042
00043 y_ = int( vcl_floor( yc_ + y0 ) ) + 1;
00044 min_y_ = int( vcl_ceil( yc_ - y0 ) );
00045 }
00046
00047 template <class T>
00048 bool vgl_ellipse_scan_iterator<T>::next()
00049 {
00050 --y_;
00051 if ( y_ < min_y_ ) return false;
00052
00053 T st = vcl_sin( -theta_ );
00054 T ct = vcl_cos( -theta_ );
00055 T A = rx_ * st * st + ry_ * ct * ct;
00056
00057 T x0, x1;
00058
00059 if ( A > 0 ) {
00060
00061
00062 T B = (rx_ - ry_) * (y_-yc_) * ct*st;
00063
00064 T D = rx_*ry_*(rx_*st*st + ry_*ct*ct - (y_-yc_)*(y_-yc_));
00065 if (D < 0) D=0;
00066
00067 x0 = (-B + vcl_sqrt( D )) / A;
00068 x1 = (-B - vcl_sqrt( D )) / A;
00069 } else {
00070
00071
00072 x0 = vcl_sqrt( my_max(rx_,ry_) );
00073 x1 = -x0;
00074 }
00075
00076 start_x_= int( vcl_ceil( xc_ + x1 - 1e-9 ) );
00077 end_x_ = int( vcl_floor( xc_ + x0 + 1e-9 ) );
00078
00079 if ( start_x_ > end_x_ ) {
00080
00081 return next();
00082 } else {
00083 return true;
00084 }
00085 }
00086
00087 #undef VGL_ELLIPSE_SCAN_ITERATOR_INSTANTIATE
00088 #define VGL_ELLIPSE_SCAN_ITERATOR_INSTANTIATE(T) \
00089 template class vgl_ellipse_scan_iterator<T >
00090
00091 #endif // vgl_ellipse_scan_iterator_txx_