mdsTriEdgeIterator.h

Go to the documentation of this file.
00001 //==============================================================================
00015 #ifndef MDS_TRIEDGEITERATOR_H
00016 #define MDS_TRIEDGEITERATOR_H
00017 
00018 #include "mdsTriBase.h"
00019 
00020 // MDSTk
00021 #include <MDSTk/Base/mdsMemory.h>
00022 #include <MDSTk/Base/mdsIterator.h>
00023 #include <MDSTk/Math/mdsBase.h>
00024 
00025 // VCTL
00026 #include <VectorEntity/mcentity.h>
00027 
00028 
00029 namespace mds
00030 {
00031 
00032 // Declare iterator traits first...
00033 MDS_ITERATOR_TRAITS(seg, CTriEdgeIterator, seg::CTriBase::tPixel);
00034 
00035 namespace seg
00036 {
00037 
00038 //==============================================================================
00043 class CTriEdgeIterator
00044     : public mds::base::CIteratorBase<CTriEdgeIterator>
00045     , public mds::base::CContainerHolder<CTriBase::tImage, CTriBase::tPixel>
00046 {
00047 public:
00049     typedef mds::base::CContainerHolder<CTriBase::tImage, CTriBase::tPixel> base;
00050 
00052     typedef CTriBase::tImage tImage;
00053     typedef CTriBase::tPixel tPixel;
00054 
00055 public:
00057     CTriEdgeIterator(tImage *pImage, vctl::MCEdge *pEdge)
00058     {
00059         init(pImage, pEdge);
00060     }
00061 
00063     CTriEdgeIterator(const CTriEdgeIterator& It)
00064         : base(It)
00065     {
00066         mds::base::memCopy(&m_Impl, &It.m_Impl, 1);
00067     }
00068 
00070     ~CTriEdgeIterator() {}
00071 
00073     CTriEdgeIterator& operator=(const CTriEdgeIterator& It)
00074     {
00075         base::m_pContainer = It.m_pContainer;
00076         base::m_pItem = It.m_pItem;
00077         mds::base::memCopy(&m_Impl, &It.m_Impl, 1);
00078         return *this;
00079     }
00080 
00081 
00083     mds::tSize getX() const { return *m_Impl.m_pX; }
00084     mds::tSize getY() const { return *m_Impl.m_pY; }
00085 
00087     bool isEnd() const { return (m_Impl.m_X > m_Impl.m_MaxX); }
00088 
00089 protected:
00091     struct SDataMembers
00092     {
00094         mds::tSize m_StepY;
00095 
00097         mds::tSize m_K1, m_K2, m_P;
00098 
00100         mds::tSize m_MaxX;
00101 
00103         mds::tSize m_X, m_Y;
00104 
00106         mds::tSize *m_pX, *m_pY;
00107     };
00108 
00110     SDataMembers m_Impl;
00111 
00112 public:
00114     void advance()
00115     {
00116         if( isEnd() )
00117         {
00118             return;
00119         }
00120         ++m_Impl.m_X;
00121         if( m_Impl.m_P < 0 )
00122         {
00123             m_Impl.m_P += m_Impl.m_K1;
00124         }
00125         else
00126         {
00127             m_Impl.m_P += m_Impl.m_K2;
00128             m_Impl.m_Y += m_Impl.m_StepY;
00129         }
00130         m_pItem = m_pContainer->getPtr(*m_Impl.m_pX, *m_Impl.m_pY);
00131     }
00132 
00133 protected:
00135     void init(tImage *pImage, vctl::MCEdge *pEdge)
00136     {
00137         MDS_ASSERT(pImage && pEdge);
00138 
00139         // Get vertices of the edge
00140         vctl::MCVertex *pVertices[2];
00141         pEdge->GetVerticeS(pVertices);
00142 
00143         // Round the line end-point positions
00144         int iX1 = mds::math::round2Int(pVertices[0]->GetX());
00145         int iY1 = mds::math::round2Int(pVertices[0]->GetY());
00146         int iX2 = mds::math::round2Int(pVertices[1]->GetX());
00147         int iY2 = mds::math::round2Int(pVertices[1]->GetY());
00148 
00149         // Difference in x and y axes
00150         int iDX = mds::math::getAbs(iX2 - iX1);
00151         int iDY = mds::math::getAbs(iY2 - iY1);
00152 
00153         // Exchange x and y axes
00154         if( iDY > iDX )
00155         {
00156             m_Impl.m_pX = &m_Impl.m_Y;
00157             m_Impl.m_pY = &m_Impl.m_X;
00158 
00159             mds::math::swap(iX1, iY1);
00160             mds::math::swap(iX2, iY2);
00161             mds::math::swap(iDX, iDY);
00162         }
00163         else
00164         {
00165             m_Impl.m_pX = &m_Impl.m_X;
00166             m_Impl.m_pY = &m_Impl.m_Y;
00167         }
00168 
00169         // Exchange line end-points
00170         if( iX1 > iX2 )
00171         {
00172             mds::math::swap(iX1, iX2);
00173             mds::math::swap(iY1, iY2);
00174         }
00175 
00176         // Step in y axis
00177         if( iY1 > iY2 )
00178         {
00179             m_Impl.m_StepY = -1;
00180         }
00181         else
00182         {
00183             m_Impl.m_StepY = 1;
00184         }
00185 
00186         // Bresenham's algorithm
00187         m_Impl.m_K1 = 2 * iDY;
00188         m_Impl.m_K2 = 2 * (iDY - iDX);
00189         m_Impl.m_P  = 2 * iDY - iDX;
00190 
00191         // Starting point
00192         m_Impl.m_X = iX1;
00193         m_Impl.m_Y = iY1;
00194 
00195         // End-point
00196         m_Impl.m_MaxX = iX2;
00197 
00198         // Save pointer to the image
00199         m_pContainer = pImage;
00200 
00201         // Initialize pointer to the first pixel
00202         m_pItem = pImage->getPtr(*m_Impl.m_pX, *m_Impl.m_pY);
00203     }
00204 };
00205 
00206 
00207 } // namespace seg
00208 } // namespace mds
00209 
00210 #endif // MDS_TRIEDGEITERATOR_H
00211 

Generated on Thu Mar 11 10:35:44 2010 for MDSTk Extension Libraries by  doxygen 1.4.6-NO