00001
00002
00003
00004
00005
00006
00007 #ifndef SG_RECT_H
00008 #define SG_RECT_H
00009
00010 #include "SgPoint.h"
00011
00012
00013
00014
00015
00016
00017 class SgRect
00018 {
00019 public:
00020 SgRect();
00021
00022 SgRect(int left, int right, int top, int bottom)
00023 : m_left(left),
00024 m_right(right),
00025 m_top(top),
00026 m_bottom(bottom)
00027 { }
00028
00029 SgRect(const SgPoint& topleft, const SgPoint& bottomright)
00030 : m_left(SgPointUtil::Col(topleft)),
00031 m_right(SgPointUtil::Col(bottomright)),
00032 m_top(SgPointUtil::Row(topleft)),
00033 m_bottom(SgPointUtil::Row(bottomright))
00034 { }
00035
00036 bool operator==(const SgRect& rhs) const
00037 {
00038 return m_left == rhs.m_left
00039 && m_right == rhs.m_right
00040 && m_top == rhs.m_top
00041 && m_bottom == rhs.m_bottom;
00042 }
00043
00044 void Set(int left, int right, int top, int bottom)
00045 {
00046 m_left = left;
00047 m_right = right;
00048 m_top = top;
00049 m_bottom = bottom;
00050 }
00051
00052 void MirrorX(int boardSize)
00053 {
00054 int temp = m_left;
00055 m_left = boardSize + 1 - m_right;
00056 m_right = boardSize + 1 - temp;
00057 }
00058
00059 void MirrorY(int boardSize)
00060 {
00061 int temp = m_top;
00062 m_top = boardSize + 1 - m_bottom;
00063 m_bottom = boardSize + 1 - temp;
00064 }
00065
00066 void SwapXY()
00067 {
00068 std::swap(m_top, m_left);
00069 std::swap(m_bottom, m_right);
00070 }
00071
00072 void Include(SgPoint p);
00073
00074 void Include(const SgRect& rect);
00075
00076 void Intersect(const SgRect& rect);
00077
00078 bool IsEmpty() const
00079 {
00080
00081 return m_left > m_right;
00082 }
00083
00084 bool InRect(SgPoint p) const;
00085
00086 SgPoint Center() const;
00087
00088 bool Contains(SgPoint p) const
00089 {
00090 return InRect(p);
00091 }
00092
00093 bool Contains(const SgRect& rect) const;
00094
00095 bool Overlaps(const SgRect& rect) const;
00096
00097 void Expand(int margin);
00098
00099 int Left() const
00100 {
00101 return m_left;
00102 }
00103
00104 int Right() const
00105 {
00106 return m_right;
00107 }
00108
00109 int Top() const
00110 {
00111 return m_top;
00112 }
00113
00114 int Bottom() const
00115 {
00116 return m_bottom;
00117 }
00118
00119 int Width() const
00120 {
00121 SG_ASSERT(! IsEmpty());
00122 return m_right - m_left + 1;
00123 }
00124
00125 int Height() const
00126 {
00127 SG_ASSERT(! IsEmpty());
00128 return m_bottom - m_top + 1;
00129 }
00130
00131 int Area() const
00132 {
00133 return Width() * Height();
00134 }
00135
00136 void IncLeft()
00137 {
00138 ++m_left;
00139 }
00140
00141 void DecRight()
00142 {
00143 --m_right;
00144 }
00145
00146 void IncTop()
00147 {
00148 ++m_top;
00149 }
00150
00151 void DecBottom()
00152 {
00153 --m_bottom;
00154 }
00155
00156 void SetLeft(int value)
00157 {
00158 m_left = value;
00159 }
00160
00161 void SetRight(int value)
00162 {
00163 m_right = value;
00164 }
00165
00166 void SetTop(int value)
00167 {
00168 m_top = value;
00169 }
00170
00171 void SetBottom(int value)
00172 {
00173 m_bottom = value;
00174 }
00175
00176 private:
00177 int m_left;
00178
00179 int m_right;
00180
00181 int m_top;
00182
00183 int m_bottom;
00184 };
00185
00186
00187
00188
00189
00190 class SgRectIterator
00191 {
00192 public:
00193
00194 SgRectIterator(const SgRect& rect)
00195 : m_rect(rect),
00196 m_cursor(SgPointUtil::Pt(rect.Left(), rect.Top())),
00197 m_end(SgPointUtil::Pt(rect.Right(), rect.Bottom()))
00198 { }
00199
00200
00201 void operator++()
00202 {
00203 SG_ASSERT(m_rect.Contains(m_cursor));
00204 if (SgPointUtil::Col(m_cursor) == m_rect.Right())
00205 m_cursor += SG_NS + m_rect.Left() - m_rect.Right();
00206 else
00207 m_cursor += SG_WE;
00208 }
00209
00210
00211 SgPoint operator*() const
00212 {
00213 return m_cursor;
00214 }
00215
00216
00217 operator bool() const
00218 {
00219 return m_cursor <= m_end;
00220 }
00221
00222 private:
00223 const SgRect& m_rect;
00224
00225 SgPoint m_cursor;
00226
00227 SgPoint m_end;
00228 };
00229
00230 std::ostream& operator<<(std::ostream& stream, const SgRect& rect);
00231
00232
00233
00234 #endif // SG_RECT_H