Go to the documentation of this file.00001
00002 #ifndef vgl_triangle_scan_iterator_txx_
00003 #define vgl_triangle_scan_iterator_txx_
00004
00005
00006
00007
00008 #include "vgl_triangle_scan_iterator.h"
00009
00010 #include <vcl_cmath.h>
00011 #include <vcl_iostream.h>
00012
00013 template <class T>
00014 static inline
00015 void min_n_max(T a, T b, T c, T *min, T *max)
00016 {
00017 if (a < b) {
00018 if (a < c) {
00019 *min = a;
00020 if (b < c)
00021 *max = c;
00022 else
00023 *max = b;
00024 }
00025 else {
00026 *min = c;
00027 *max = b;
00028 }
00029 }
00030 else {
00031 if (b < c) {
00032 *min = b;
00033 if (a < c)
00034 *max = c;
00035 else
00036 *max = a;
00037 }
00038 else {
00039 *min = c;
00040 *max = a;
00041 }
00042 }
00043
00044 }
00045
00046 #if use_polygon_scan_iterator
00047 #include <vgl/vgl_polygon_scan_iterator.h>
00048 template <class T>
00049 struct vgl_triangle_scan_iterator<T>::data_t : public vgl_polygon_scan_iterator<T>
00050 {
00051 typedef vgl_polygon_scan_iterator<T> base;
00052 data_t(vgl_polygon<T> const &p) : base(p) {}
00053 };
00054
00055 template <class T>
00056 vgl_triangle_scan_iterator<T>::~vgl_triangle_scan_iterator()
00057 {
00058 if (data)
00059 delete data;
00060 data = 0;
00061 }
00062 #else
00063
00064
00065
00066 #endif
00067
00068 template <class T>
00069 void vgl_triangle_scan_iterator<T>::reset()
00070 {
00071 #if use_polygon_scan_iterator
00072 if (data)
00073 delete data;
00074 T x[3] = { a.x, b.x, c.x };
00075 T y[3] = { a.y, b.y, c.y };
00076 vgl_polygon<T> p(x, y, 3);
00077 data = new data_t(p);
00078 data->reset();
00079 #else
00080 T min, max;
00081
00082 min_n_max(a.x, b.x, c.x, &min, &max);
00083 x0 = (int) vcl_ceil (min);
00084 x1 = (int) vcl_floor(max);
00085 #ifdef DEBUG
00086 vcl_cerr << "x0 x1 = " << x0 << ' ' << x1 << '\n';
00087 #endif
00088
00089 min_n_max(a.y, b.y, c.y, &min, &max);
00090 y0 = (int) vcl_ceil (min);
00091 y1 = (int) vcl_floor(max);
00092 #ifdef DEBUG
00093 vcl_cerr << "y0 y1 = " << y0 << ' ' << y1 << '\n';
00094 #endif
00095
00096 scany_ = y0 - 1;
00097
00098
00099 g.x = vcl_floor((a.x + b.x + c.x)/3);
00100 g.y = vcl_floor((a.y + b.y + c.y)/3);
00101 #ifdef DEBUG
00102 vcl_cerr << "g = " << g.x << ' ' << g.y << '\n';
00103 #endif
00104
00105
00106 pt ag = { a.x - g.x, a.y - g.y };
00107 pt bg = { b.x - g.x, b.y - g.y };
00108 pt cg = { c.x - g.x, c.y - g.y };
00109
00110 data[0][0] = bg.y - cg.y; data[0][1] = cg.x - bg.x; data[0][2] = bg.x * cg.y - bg.y * cg.x;
00111 data[1][0] = cg.y - ag.y; data[1][1] = ag.x - cg.x; data[1][2] = cg.x * ag.y - cg.y * ag.x;
00112 data[2][0] = ag.y - bg.y; data[2][1] = bg.x - ag.x; data[2][2] = ag.x * bg.y - ag.y * bg.x;
00113
00114 T tmp = ( bg.x*cg.y - bg.x*ag.y - ag.x*cg.y - cg.x*bg.y + cg.x*ag.y + ag.x*bg.y );
00115 if (tmp < 0)
00116 tmp = -1;
00117 else
00118 tmp = +1;
00119 for (int i=0; i<3; ++i) {
00120 T f = tmp;
00121 for (int j=0; j<3; ++j)
00122 data[i][j] *= f;
00123 }
00124 #if 0
00125 vcl_cerr << "data:\n";
00126 for (int i=0; i<3; ++i) {
00127 for (int j=0; j<3; ++j)
00128 vcl_cerr << ' ' << data[i][j];
00129 vcl_cerr << vcl_endl;
00130 }
00131 vcl_cerr << vcl_endl;
00132 #endif
00133 #endif // use_polygon_scan_iterator
00134 }
00135
00136 template <class T>
00137 bool vgl_triangle_scan_iterator<T>::next()
00138 {
00139 #if use_polygon_scan_iterator
00140 if (data->next()) {
00141 scany_ = data->scany();
00142 startx_ = data->startx();
00143 endx_ = data->endx();
00144 return true;
00145 }
00146 else
00147 return false;
00148 #else
00149 if (++scany_ > y1)
00150 return false;
00151
00152 T minx = x0 - g.x;
00153 T maxx = x1 - g.x;
00154
00155 #ifdef DEBUG
00156 vcl_cerr << "minx maxx = " << minx << ' ' << maxx << '\n';
00157 #endif
00158 for (int i=0; i<3; ++i) {
00159 T a_ = data[i][0];
00160 T b_ = data[i][1] * (scany_ - g.y) + data[i][2];
00161
00162 if (a_ == 0) {
00163
00164 }
00165 else {
00166 T x = -b_/a_;
00167 if (a_ > 0) {
00168 if (x > minx)
00169 minx = x;
00170 }
00171 else {
00172 if (x < maxx)
00173 maxx = x;
00174 }
00175 }
00176 #ifdef DEBUG
00177 vcl_cerr << "minx maxx = " << minx << ' ' << maxx << '\n';
00178 #endif
00179 }
00180
00181 startx_ = (int) vcl_ceil (minx + g.x);
00182 endx_ = (int) vcl_floor(maxx + g.x);
00183
00184
00185
00186
00187
00188
00189 return true;
00190 #endif
00191 }
00192
00193 #undef VGL_TRIANGLE_SCAN_ITERATOR_INSTANTIATE
00194 #define VGL_TRIANGLE_SCAN_ITERATOR_INSTANTIATE(T) \
00195 template class vgl_triangle_scan_iterator<T >
00196
00197 #endif // vgl_triangle_scan_iterator_txx_