Contour Iterators (or Cursors)
Hi.
Recently I have been working on problems where I need to iterate over a
cyclic structure; the edges of a "face" in a planar map, for example (a
planar map partitions the plane into faces, edges, and vertices). In this
case the planar map is encoded as a "doubly connected edge list". Each edge
has a start vertex and an end vertex (giving it a direction), a left face
and a right face, and next and previous edges. The idea is to iterate over
the edges forming the outer contour of a face, given the face and some edge
on its outer contour. I would like to use the STL start/end approach
(actually, a cursor/property_map approach, but that is not the issue here).
The difficulty is that the start and end are the same edge. A GOF style
iterator (ignoring error checking, and type parameterization issues) is
simple:
class EdgeIterator
{
public:
EdgeIterator(const PlanarFace *pF, const PlanarEdge *pE)
: pFace(pF), pEStart(pE), pENext(0) {}
const PlanarEdge* First()
{
if (! pEStart)
return pEStart;
if ( pEStart->LeftFace() == pFace )
pENext = pEStart->Next();
else
pENext = pEStart->Previous();
return pEStart;
}
const PlanarEdge* Next()
{
if ( pENext == pEStart )
return 0;
const PlanarEdge *pE = pENext;
if ( pENext->LeftFace() == pFace )
pENext = pENext->Next();
else
pENext = pENext->Previous();
return pE;
}
private:
const PlanarFace *pFace;
const PlanarEdge *pEStart;
const PlanarEdge *pENext;
};
The only idea I have had so far for creating a Start/End pair is to make an
adaptor (ignoring many details):
class EdgeIteratorAdaptor : private EdgeIterator
{
public:
EdgeIteratorAdaptor(const PlanarFace *pF, const PlanarEdge *pE)
: EdgeIterator(pF, pE), pEdge(First()) {}
const PlanarEdge operator*() const { return pEdge; }
EdgeIteratorAdaptor& operator++() { pEdge = Next(); return *this; }
bool operator==(const EdgeIteratorAdaptor& x) const
{ return pEdge == x.pEdge; }
bool operator!=(const EdgeIteratorAdaptor& x) const
{ return pEdge != x.pEdge; }
private:
const PlanarEdge *pEdge;
};
class PlanarFace
{
....
EdgeIteratorAdaptor begin(const PlanarEdge *p) const
{ return EdgeIteratorAdaptor(this, p); }
EdgeIteratorAdaptor end() const
{ return EdgeIteratorAdaptor(this, 0); }
....
};
Any better ideas?
-- Michael
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]