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 
00007 #ifndef SG_RECT_H
00008 #define SG_RECT_H
00009 
00010 #include "SgPoint.h"
00011 
00012 //----------------------------------------------------------------------------
00013 
00014 /** Rectangle on the Go board. 
00015     top < bottom, coordinates grow from top to bottom.
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         // no points inside, see constructor
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 /** Iterator for rectangle on the Go board, based on SgRect object
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     /** Iterate through rectangle: left to right, top to bottom */
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     /** Return the value of the current element. */
00211     SgPoint operator*() const
00212     {
00213         return m_cursor;
00214     }
00215 
00216     /** Return true if iteration is valid, otherwise false. */
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


17 Jun 2010 Doxygen 1.4.7