00001
00015 #ifndef MDS_TRIEDGEITERATOR_H
00016 #define MDS_TRIEDGEITERATOR_H
00017
00018 #include "mdsTriBase.h"
00019
00020
00021 #include <MDSTk/Base/mdsMemory.h>
00022 #include <MDSTk/Base/mdsIterator.h>
00023 #include <MDSTk/Math/mdsBase.h>
00024
00025
00026 #include <VectorEntity/mcentity.h>
00027
00028
00029 namespace mds
00030 {
00031
00032
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
00140 vctl::MCVertex *pVertices[2];
00141 pEdge->GetVerticeS(pVertices);
00142
00143
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
00150 int iDX = mds::math::getAbs(iX2 - iX1);
00151 int iDY = mds::math::getAbs(iY2 - iY1);
00152
00153
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
00170 if( iX1 > iX2 )
00171 {
00172 mds::math::swap(iX1, iX2);
00173 mds::math::swap(iY1, iY2);
00174 }
00175
00176
00177 if( iY1 > iY2 )
00178 {
00179 m_Impl.m_StepY = -1;
00180 }
00181 else
00182 {
00183 m_Impl.m_StepY = 1;
00184 }
00185
00186
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
00192 m_Impl.m_X = iX1;
00193 m_Impl.m_Y = iY1;
00194
00195
00196 m_Impl.m_MaxX = iX2;
00197
00198
00199 m_pContainer = pImage;
00200
00201
00202 m_pItem = pImage->getPtr(*m_Impl.m_pX, *m_Impl.m_pY);
00203 }
00204 };
00205
00206
00207 }
00208 }
00209
00210 #endif // MDS_TRIEDGEITERATOR_H
00211