Go to the documentation of this file.00001
00063 #ifndef SCANLINE_POLYGON_FILL_HPP
00064 #define SCANLINE_POLYGON_FILL_HPP
00065
00066 #include <set>
00067 #include <list>
00068 #include <algorithm>
00069
00070 namespace cob_3d_mapping
00071 {
00072 template<typename T>
00073 void ScanlinePolygonFill<T>::draw(std::vector<std::vector<T> >& out)
00074 {
00075 out.resize(w*h);
00076 yque.sort();
00077
00078 float xstep = (xmax - xmin) / float(w);
00079 float ystep = (ymax - ymin) / float(h);
00080 for(float y=ymin + 0.5f * ystep; y<ymax; y+=ystep)
00081 {
00082
00083 int yidx = y2h(y)*w;
00084 std::list<std::pair<float,T> > xque;
00085 typename std::list<ScanlineEdge<T> >::iterator ycurr = yque.begin();
00086 while (ycurr != yque.end() && ycurr->ymin < y)
00087 {
00088 if(ycurr->ymax <= y) {
00089 ycurr = yque.erase(ycurr);
00090 }
00091 else {
00092 float x = ycurr->intersection(y);
00093 if(x>xmin && x<xmax) {
00094 out[ yidx + x2w(x) ].push_back(ycurr->id);
00095 }
00096 ++ycurr;
00097 }
00098 }
00099 }
00100 }
00101
00102 template<typename T>
00103 void ScanlinePolygonFill<T>::fill(std::vector<std::vector<T> >& out)
00104 {
00105 out.resize(w*h);
00106 yque.sort();
00107
00108 float xstep = (xmax - xmin) / float(w);
00109 float ystep = (ymax - ymin) / float(h);
00110
00111 for(float y=ymin + 0.5f * ystep; y<ymax; y+=ystep)
00112 {
00113 int yidx = y2h(y)*w;
00114 std::list<std::pair<float,T> > xque;
00115 typename std::list<ScanlineEdge<T> >::iterator ycurr = yque.begin();
00116
00117
00118 while (ycurr != yque.end() && ycurr->ymin < y)
00119 {
00120 if(ycurr->ymax <= y) {
00121 ycurr = yque.erase(ycurr);
00122 }
00123 else {
00124 xque.push_back(std::pair<float,T>(ycurr->intersection(y),ycurr->id));
00125 ++ycurr;
00126 }
00127 }
00128
00129 xque.sort();
00130 typename std::list<std::pair<float,T> >::iterator xcurr = xque.begin();
00131 typename std::list<std::pair<float,T> >::iterator xprev = xcurr++;
00132 std::set<T> curr_ids;
00133
00134
00135 while(xcurr->first < xmin && xcurr!=xque.end()) {
00136 std::pair<typename std::set<T>::iterator, bool> res
00137 = curr_ids.insert(xprev->second);
00138 if( !res.second ) curr_ids.erase(res.first);
00139 xprev = xcurr++;
00140 }
00141
00142
00143
00144 while (xprev->first < xmax && xcurr!=xque.end())
00145 {
00146 std::pair<typename std::set<T>::iterator, bool> res
00147 = curr_ids.insert(xprev->second);
00148 if( !res.second ) curr_ids.erase(res.first);
00149 if( curr_ids.size() )
00150 {
00151 float xstart = (xprev->first<xmin ? xmin : xprev->first);
00152 float xstop = (xcurr->first>xmax ? xmax : xcurr->first);
00153 for(float x=xstart; x<=xstop; x+=xstep)
00154 {
00155 std::list<std::pair<float,T> > zque;
00156
00157
00158 typename std::set<T>::iterator id = curr_ids.begin();
00159 for(; id != curr_ids.end(); ++id) {
00160 float z = polys.find(*id)->second.intersection(x,y);
00161 if(z > zmin && z < zmax) zque.push_back(std::pair<float,T>(z, *id));
00162 }
00163
00164 zque.sort();
00165 typename std::list<std::pair<float,T> >::iterator zcurr = zque.begin();
00166
00167
00168 while(zcurr != zque.end()) {
00169 if(zcurr->first < (zque.begin()->first + zthr)) {
00170 out[ yidx + x2w(x) ].push_back(zcurr->second);
00171 }
00172 else {
00173 break;
00174 }
00175 ++zcurr;
00176 }
00177 }
00178 }
00179 xprev = xcurr++;
00180 }
00181 }
00182 }
00183 }
00184
00185 #endif