Skip to content

Commit

Permalink
Merge pull request #801 from troussil/ArithmeticalDSSRandomAccessIter…
Browse files Browse the repository at this point in the history
…ator

random access iterators in ArithmeticalDSL
  • Loading branch information
dcoeurjo committed Apr 21, 2014
2 parents 267db20 + d0d2266 commit 9021574
Show file tree
Hide file tree
Showing 6 changed files with 195 additions and 44 deletions.
46 changes: 42 additions & 4 deletions src/DGtal/geometry/curves/ArithmeticalDSL.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,6 @@ namespace DGtal
*/
typedef TInteger Integer;
BOOST_CONCEPT_ASSERT(( CInteger<Integer> ));

/**
* Type of digital plane.
*/
Expand All @@ -146,6 +145,10 @@ namespace DGtal
* Type of step vectors, defined as STL pair of vectors.
*/
typedef std::pair<Vector,Vector> Steps;
/**
* Type used for the position of a point in the DSL.
*/
typedef Coordinate Position;

/**
* \brief Aim: This class aims at representing an iterator
Expand All @@ -165,12 +168,14 @@ namespace DGtal
class ConstIterator
: public boost::iterator_facade<ConstIterator, //derived type, the ConstIterator class itself
Point const, //value type
boost::bidirectional_traversal_tag, //traversal tag
Point const //reference type
boost::random_access_traversal_tag, //traversal tag
Point const, //reference type
//NB: since there is no underlying container,
//we cannot return a reference.
Position //difference type
>
{

// ------------------------- Private data -----------------------
private:

Expand Down Expand Up @@ -220,6 +225,14 @@ namespace DGtal
* Destructor. Does nothing.
*/
~ConstIterator();

// ------------------------- useful services -------------------------
public:
/**
* @return the remainder of the current point
* (without any computation)
*/
Integer remainder() const;

// ------------------------- iteration services -------------------------
private:
Expand Down Expand Up @@ -250,6 +263,23 @@ namespace DGtal
* @return 'true' if their current points coincide.
*/
bool equal(const ConstIterator& aOther) const;

/**
* Moves @a myCurrentPoint lying at position i to the
* point of the DSL lying at position i + @a aShift
* @param aShift position difference
* NB: in O(1)
*/
void advance(const Position& aShift);

/**
* Computes the distance between *this and @a aOther, ie.
* the difference between their positions
* @param aOther any other iterator
* @return distance between the two iterators
*/
Position distance_to(const ConstIterator& aOther) const;

};

/**
Expand Down Expand Up @@ -436,7 +466,15 @@ namespace DGtal
* @param aPoint the point whose position is returned
* @return the position
*/
Integer position(const Point& aPoint) const;
Position position(const Point& aPoint) const;

/**
* Returns the unique point of the DSL located at position @a aPosition
* in O(1).
* @param aPosition position of the returned point
* @return the point of the DSL located at position @a aPosition
*/
Point getPoint(const Position& aPosition) const;

/**
* Returns a boolean equal to 'true' if @a aP1 is
Expand Down
65 changes: 62 additions & 3 deletions src/DGtal/geometry/curves/ArithmeticalDSL.ih
Original file line number Diff line number Diff line change
Expand Up @@ -289,11 +289,42 @@ DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::orthogonalPosition(con
//-----------------------------------------------------------------------------
template <typename TCoordinate, typename TInteger, unsigned short adjacency>
inline
typename DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::Integer
typename DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::Position
DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::position(const Point& aPoint) const
{
return ( -static_cast<Integer>(myShift[1]) * static_cast<Integer>(aPoint[0])
+static_cast<Integer>(myShift[0]) * static_cast<Integer>(aPoint[1]) );
return ( -static_cast<Position>(myShift[1]) * static_cast<Position>(aPoint[0])
+static_cast<Position>(myShift[0]) * static_cast<Position>(aPoint[1]) );
}

//-----------------------------------------------------------------------------
template <typename TCoordinate, typename TInteger, unsigned short adjacency>
inline
typename DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::Point
DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::getPoint(const Position& aPosition) const
{
Integer shiftRemainder = omega();

//point of position 0 lying below the straight line of remainder mu
Point origin(0,0);
Integer originRemainder = 0;
if (myLowerBound > 0)
{
Integer q0 = myLowerBound / shiftRemainder;
if (myLowerBound != (q0 * shiftRemainder))
q0++;
origin = static_cast<Position>(q0) * myShift;
originRemainder = q0 * shiftRemainder;
}
ASSERT( remainder(origin) == originRemainder );
ASSERT( remainder(origin) >= myLowerBound );

//point of position aPosition
Integer q = ( (myLowerBound - (originRemainder + static_cast<Integer>(aPosition) * remainder( mySteps.first )))
/ shiftRemainder );
Point res = origin + ( aPosition * mySteps.first + static_cast<Position>(q) * myShift );
ASSERT( isInDSL(res) );
ASSERT( position(res) == aPosition );
return res;
}

//-----------------------------------------------------------------------------
Expand Down Expand Up @@ -447,6 +478,15 @@ DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::ConstIterator::~ConstI
{
}

//-----------------------------------------------------------------------------
template <typename TCoordinate, typename TInteger, unsigned short adjacency>
inline
typename DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::Integer
DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::ConstIterator::remainder() const
{
return myCurrentRemainder;
}

//-----------------------------------------------------------------------------
template <typename TCoordinate, typename TInteger, unsigned short adjacency>
inline
Expand Down Expand Up @@ -503,6 +543,25 @@ equal(const ConstIterator& aOther) const
return myCurrentPoint == aOther.myCurrentPoint;
}

//-----------------------------------------------------------------------------
template <typename TCoordinate, typename TInteger, unsigned short adjacency>
inline
void
DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::ConstIterator
::advance(const Position& aShift)
{
myCurrentPoint = myDSLPtr->getPoint( myDSLPtr->position(myCurrentPoint) + aShift );
}

//-----------------------------------------------------------------------------
template <typename TCoordinate, typename TInteger, unsigned short adjacency>
inline
typename DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::Position
DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::ConstIterator
::distance_to(const ConstIterator& aOther) const
{
return ( myDSLPtr->position(aOther.myCurrentPoint) - myDSLPtr->position(myCurrentPoint) );
}

///////////////////////////////////////////////////////////////////////////////
// Aliases //
Expand Down
6 changes: 5 additions & 1 deletion src/DGtal/geometry/curves/ArithmeticalDSS.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,10 @@ namespace DGtal
* Type of steps (defined as a STL pair of vectors).
*/
typedef typename DSL::Steps Steps;
/**
* Type used for the position of a point in the DSL.
*/
typedef Coordinate Position;
/**
* Type of iterator.
*/
Expand Down Expand Up @@ -405,7 +409,7 @@ namespace DGtal
* @param aPoint the point whose position is returned
* @return the position
*/
Integer position(const Point& aPoint) const;
Position position(const Point& aPoint) const;

/**
* Returns a boolean equal to 'true' if @a aP1 is
Expand Down
2 changes: 1 addition & 1 deletion src/DGtal/geometry/curves/ArithmeticalDSS.ih
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ DGtal::ArithmeticalDSS<TCoordinate, TInteger, adjacency>::orthogonalPosition(con
//-----------------------------------------------------------------------------
template <typename TCoordinate, typename TInteger, unsigned short adjacency>
inline
typename DGtal::ArithmeticalDSS<TCoordinate, TInteger, adjacency>::Integer
typename DGtal::ArithmeticalDSS<TCoordinate, TInteger, adjacency>::Position
DGtal::ArithmeticalDSS<TCoordinate, TInteger, adjacency>::position(const Point& aPoint) const
{
return myDSL.position(aPoint);
Expand Down
9 changes: 6 additions & 3 deletions src/DGtal/geometry/doc/moduleArithDSSReco.dox
Original file line number Diff line number Diff line change
Expand Up @@ -149,15 +149,18 @@ For instance, for each x-coordinate \f$ x \f$, there is one and only one point \
that belongs to the \b naive DSL \f$ D(2,5,0) \f$. Similarly, for each value \f$ x+y \f$,
there is one and only one point \f$ (x,y) \in \mathbb{Z}^2 \f$ that belongs to the \b standard DSL \f$ D(2,5,0) \f$.
Method ArithmeticalDSL.position() returns
the position of any input point, whereas methods ArithmeticalDSL.before() and
the position of any input point, whereas method
ArithmeticalDSL.getPoint() returns the point located at the
specified position. Methods ArithmeticalDSL.before() and
ArithmeticalDSL.beforeOrEqual() provide a way of comparing the position of two given points,
with respect to the orientation given by \f$ a \f$ and \f$ b \f$.
with respect to the orientation given by \f$ a \f$ and \f$ b \f$.


ArithmeticalDSL also provides services to iterate over the DSL points
from any point belonging to the DSL.
ArithmeticalDSL is a model of CConstBidirectionalRange that has inner types called
ArithmeticalDSL::ConstIterator and ArithmeticalDSL::ConstReverseIterator,
both models of readable iterator and bidirectional iterator.
both models of readable iterator and random access iterator.
The reader may have a look at the increment and decrement operator of
ArithmeticalDSL::ConstIterator (ie. ArithmeticalDSL::ConstIterator.increment and
ArithmeticalDSL::ConstIterator.decrement) to see that the code is generic.
Expand Down
111 changes: 79 additions & 32 deletions tests/geometry/curves/testArithmeticalDSL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,6 @@ bool mainTest()
template <typename DSL>
bool rangeTest(const DSL& dsl)
{
ASSERT( dsl.mu() == 0 );
typedef typename DSL::Point Point;

unsigned int nbok = 0;
Expand All @@ -202,8 +201,8 @@ bool rangeTest(const DSL& dsl)
trace.beginBlock ( "Range/Iterator services..." );
trace.info() << dsl << std::endl;

Point first(0,0);
Point last(dsl.b(), dsl.a());
Point first = dsl.getPoint(0);
Point last = Point(first[0]+dsl.b(), first[1]+dsl.a());
trace.info() << "from " << first << " to " << last << std::endl;

if (dsl.isValid())
Expand Down Expand Up @@ -241,7 +240,7 @@ bool rangeTest(const DSL& dsl)
{//backward pass
typedef typename DSL::ConstReverseIterator I;
BOOST_CONCEPT_ASSERT(( boost_concepts::ReadableIteratorConcept<I> ));
BOOST_CONCEPT_ASSERT(( boost_concepts::BidirectionalTraversalConcept<I> ));
BOOST_CONCEPT_ASSERT(( boost_concepts::RandomAccessTraversalConcept<I> ));
bool res = true;
int c = 0;
for (I it = dsl.rbegin(last), itEnd = dsl.rend(first);
Expand All @@ -263,6 +262,54 @@ bool rangeTest(const DSL& dsl)
<< std::endl;
}

{//random access services
typedef typename DSL::ConstIterator I;
BOOST_CONCEPT_ASSERT(( boost_concepts::ReadableIteratorConcept<I> ));
BOOST_CONCEPT_ASSERT(( boost_concepts::RandomAccessTraversalConcept<I> ));
bool res = true;
int c = 0;
I itBegin = dsl.begin(first);
for (I it = itBegin, itEnd = dsl.end(last);
( (it != itEnd)&&(res)&&(c<100) );
++it, ++c)
{
trace.info() << "(" << it->operator[](0) << "," << it->operator[](1) << ") " << it.remainder() << ", ";
I it2 = ( itBegin + c );
if ( (it != it2) || ((it2 - itBegin) != c) )
res = false;
}
int n = c;
trace.info() << " : " << c << " points " << std::endl;
trace.info() << std::endl;

if (res)
nbok++;
nb++;

trace.info() << "(" << nbok << "/" << nb << ") "
<< std::endl;

--n;
c = 0;
for (I it = (itBegin+n), itEnd = itBegin;
( (it!=itEnd)&&(res)&&(c < 100) );
--it, ++c )
{
trace.info() << "(" << it->operator[](0) << "," << it->operator[](1) << ") " << it.remainder() << ", ";
I it2 = ( (itBegin+n) - c );
if ( (it != it2) || (((itBegin+n) - it2) != c) )
res = false;
}

if (res)
nbok++;
nb++;

trace.info() << "(" << nbok << "/" << nb << ") "
<< std::endl;
}


trace.endBlock();

return nbok == nb;
Expand Down Expand Up @@ -291,22 +338,22 @@ int main( int argc, char** argv )
typedef DGtal::ArithmeticalDSL<DGtal::int32_t> DSL;

res = res
&& rangeTest( DSL(5, 8, 0) )
&& rangeTest( DSL(8, 5, 0) )
&& rangeTest( DSL(5, -8, 0) )
&& rangeTest( DSL(8, -5, 0) )
&& rangeTest( DSL(-5, 8, 0) )
&& rangeTest( DSL(-8, 5, 0) )
&& rangeTest( DSL(-5, -8, 0) )
&& rangeTest( DSL(-8, -5, 0) )
&& rangeTest( DSL(1, 0, 0) )
&& rangeTest( DSL(0, -1, 0) )
&& rangeTest( DSL(0, 1, 0) )
&& rangeTest( DSL(-1, 0, 0) )
&& rangeTest( DSL(1, 1, 0) )
&& rangeTest( DSL(1, -1, 0) )
&& rangeTest( DSL(-1, 1, 0) )
&& rangeTest( DSL(-1, -1, 0) )
&& rangeTest( DSL(5, 8, 16) )
&& rangeTest( DSL(8, 5, 14) )
&& rangeTest( DSL(5, -8, 14) )
&& rangeTest( DSL(8, -5, 14) )
&& rangeTest( DSL(-5, 8, 14) )
&& rangeTest( DSL(-8, 5, 14) )
&& rangeTest( DSL(-5, -8, 14) )
&& rangeTest( DSL(-8, -5, 14) )
&& rangeTest( DSL(1, 0, 14) )
&& rangeTest( DSL(0, -1, 14) )
&& rangeTest( DSL(0, 1, 14) )
&& rangeTest( DSL(-1, 0, 14) )
&& rangeTest( DSL(1, 1, 14) )
&& rangeTest( DSL(1, -1, 14) )
&& rangeTest( DSL(-1, 1, 14) )
&& rangeTest( DSL(-1, -1, 14) )
;
}

Expand All @@ -315,18 +362,18 @@ int main( int argc, char** argv )
typedef DGtal::ArithmeticalDSL<DGtal::int32_t, DGtal::int32_t, 4> DSL;

res = res
&& rangeTest( DSL(5, 8, 0) )
&& rangeTest( DSL(8, 5, 0) )
&& rangeTest( DSL(5, -8, 0) )
&& rangeTest( DSL(8, -5, 0) )
&& rangeTest( DSL(-5, 8, 0) )
&& rangeTest( DSL(-8, 5, 0) )
&& rangeTest( DSL(-5, -8, 0) )
&& rangeTest( DSL(-8, -5, 0) )
&& rangeTest( DSL(1, 0, 0) )
&& rangeTest( DSL(0, -1, 0) )
&& rangeTest( DSL(0, 1, 0) )
&& rangeTest( DSL(-1, 0, 0) )
&& rangeTest( DSL(5, 8, -16) )
&& rangeTest( DSL(8, 5, -17) )
&& rangeTest( DSL(5, -8, -17) )
&& rangeTest( DSL(8, -5, -17) )
&& rangeTest( DSL(-5, 8, -17) )
&& rangeTest( DSL(-8, 5, -17) )
&& rangeTest( DSL(-5, -8, -17) )
&& rangeTest( DSL(-8, -5, -17) )
&& rangeTest( DSL(1, 0, -17) )
&& rangeTest( DSL(0, -1, -17) )
&& rangeTest( DSL(0, 1, -17) )
&& rangeTest( DSL(-1, 0, -17) )
;
}

Expand Down

0 comments on commit 9021574

Please sign in to comment.