Index   Main   Namespaces   Classes   Hierarchy   Annotated   Files   Compound   Global   Pages  

SgRect.h

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


Sun Mar 13 2011 Doxygen 1.7.1