00001 #ifndef CAJUN_RECT_FILLER_H 00002 #define CAJUN_RECT_FILLER_H 00003 00004 00005 #include <deque> 00006 #include <vector> 00007 00008 00009 namespace cajun 00010 { 00011 00012 00013 class rect_filler_t 00014 { 00015 public: 00016 template <class filler_t> 00017 void fill (filler_t &filler_, 00018 double x0_, double y0_, 00019 double x1_, double y1_, double size_) 00020 { 00021 init_et (x0_, y0_, x1_, y1_, size_); 00022 00023 int y = m_et[0].y_min; 00024 00025 while (update_et (y)) 00026 { 00027 for (unsigned e = 0; e < m_aet.size (); e += 2) 00028 filler_.fill (m_aet[e].x, y, 00029 m_aet[e + 1].x - m_aet[e].x + 1); 00030 update_edges (++y); 00031 } 00032 } 00033 00034 struct pt_t 00035 { 00036 double x; 00037 double y; 00038 }; 00039 00040 template <class filler_t> 00041 void fill (filler_t &filler_, std::vector<pt_t> const &pts_) 00042 { 00043 init_et (pts_); 00044 00045 int y = m_et[0].y_min; 00046 00047 while (update_et (y)) 00048 { 00049 for (unsigned e = 0; e < m_aet.size (); e += 2) 00050 filler_.fill (m_aet[e].x, y, 00051 m_aet[e + 1].x - m_aet[e].x + 1); 00052 update_edges (++y); 00053 } 00054 } 00055 00056 protected: 00057 struct edge_t 00058 { 00059 bool init (double x0_, double y0_, 00060 double x1_, double y1_); 00061 00062 int y_min; 00063 int y_max; 00064 int dx; 00065 int dy; 00066 int x; 00067 int px; 00068 }; 00069 00070 struct x_sort_t 00071 { 00072 bool operator () (edge_t const &v1_, 00073 edge_t const &v2_) const 00074 { return v1_.x < v2_.x; } 00075 }; 00076 struct y_sort_t 00077 { 00078 bool operator () (edge_t const &v1_, 00079 edge_t const &v2_) const 00080 { return v1_.y_min < v2_.y_min; } 00081 }; 00082 struct y_max_equal_t 00083 { 00084 y_max_equal_t (int y_) : y (y_) {} 00085 00086 bool operator () (edge_t const &v_) const 00087 { return v_.y_max == y; } 00088 00089 int y; 00090 }; 00091 00092 std::deque<edge_t> m_et; 00093 std::deque<edge_t> m_aet; 00094 00095 void init_et (double x0_, double y0_, 00096 double x1_, double y1_, double size_); 00097 void init_et (std::vector<pt_t> const &pts_); 00098 00099 bool update_et (int y_); 00100 void update_edges (int y_); 00101 }; 00102 00103 00104 }; 00105 00106 00107 #endif