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