h o m e d o c u m e n t a t i o n c l a s s h i e r a r c h y

CurveIterators.h

00001 //
00002 //  Filename         : CurveIterators.h
00003 //  Author(s)        : Stephane Grabli
00004 //  Purpose          : Iterators used to iterate over the elements of the Curve
00005 //  Date of creation : 01/08/2003
00006 //
00008 
00009 
00010 //
00011 //  Copyright (C) : Please refer to the COPYRIGHT file distributed 
00012 //   with this source distribution. 
00013 //
00014 //  This program is free software; you can redistribute it and/or
00015 //  modify it under the terms of the GNU General Public License
00016 //  as published by the Free Software Foundation; either version 2
00017 //  of the License, or (at your option) any later version.
00018 //
00019 //  This program is distributed in the hope that it will be useful,
00020 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00021 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00022 //  GNU General Public License for more details.
00023 //
00024 //  You should have received a copy of the GNU General Public License
00025 //  along with this program; if not, write to the Free Software
00026 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00027 //
00029 
00030 #ifndef  CURVEITERATORS_H
00031 # define CURVEITERATORS_H
00032 
00033 #include "Stroke.h"
00034 #include "Curve.h"
00035 
00036 namespace CurveInternal {
00037 
00043   class CurvePointIterator : public Interface0DIteratorNested
00044   { 
00045   public:
00046     friend class ::Curve; 
00047   public:
00048     float _CurvilinearLength;
00049     float _step;
00050     ::Curve::vertex_container::iterator __A;
00051     ::Curve::vertex_container::iterator __B;
00052     ::Curve::vertex_container::iterator _begin;
00053     ::Curve::vertex_container::iterator _end;
00054     int _n;
00055     int _currentn;
00056     float _t;
00057     mutable CurvePoint _Point;
00058     float _CurveLength;
00059 
00060   public:
00061     
00062   public:
00063     inline CurvePointIterator(float step = 0.f)
00064       : Interface0DIteratorNested()
00065     {
00066       _step = step;
00067       _CurvilinearLength = 0.f;
00068       _t = 0.f;
00069       //_Point = 0;
00070       _n = 0;
00071       _currentn = 0;
00072       _CurveLength=0;
00073     }
00074     
00075     inline CurvePointIterator(const CurvePointIterator& iBrother)
00076       : Interface0DIteratorNested()
00077     {
00078       __A = iBrother.__A;
00079       __B = iBrother.__B;
00080       _begin = iBrother._begin;
00081       _end = iBrother._end;
00082       _CurvilinearLength = iBrother._CurvilinearLength;
00083       _step = iBrother._step;
00084       _t = iBrother._t;
00085       _Point = iBrother._Point;
00086       _n = iBrother._n;
00087       _currentn = iBrother._currentn;
00088       _CurveLength = iBrother._CurveLength;
00089     }
00090     inline CurvePointIterator& operator=(const CurvePointIterator& iBrother)
00091     {
00092       __A = iBrother.__A;
00093       __B = iBrother.__B;
00094       _begin = iBrother._begin;
00095       _end = iBrother._end;
00096       _CurvilinearLength = iBrother._CurvilinearLength;
00097       _step = iBrother._step;
00098       _t = iBrother._t;
00099       _Point = iBrother._Point;
00100       _n = iBrother._n;
00101       _currentn = iBrother._currentn;
00102       _CurveLength = iBrother._CurveLength;
00103       return *this;
00104     }
00105     virtual ~CurvePointIterator()
00106     {
00107     }
00108   protected:
00109     inline CurvePointIterator(::Curve::vertex_container::iterator iA, 
00110                               ::Curve::vertex_container::iterator iB, 
00111                               ::Curve::vertex_container::iterator ibegin, 
00112                               ::Curve::vertex_container::iterator iend,
00113                               int currentn,
00114       int n,
00115       float iCurveLength,
00116       float step, float t=0.f, float iCurvilinearLength = 0.f)
00117       : Interface0DIteratorNested()
00118     {
00119       __A = iA;
00120       __B = iB;
00121       _begin = ibegin;
00122       _end = iend;
00123       _CurvilinearLength = iCurvilinearLength;
00124       _step = step;
00125       _t = t;
00126       _n = n;
00127       _currentn = currentn;
00128       _CurveLength = iCurveLength;
00129     }
00130  
00131   public:
00132 
00133     virtual CurvePointIterator* copy() const {
00134       return new CurvePointIterator(*this);
00135     }
00136 
00137     inline Interface0DIterator CastToInterface0DIterator() const{
00138       Interface0DIterator ret(new CurveInternal::CurvePointIterator(*this));
00139       return ret;
00140     }
00141     virtual string getExactTypeName() const {
00142       return "CurvePointIterator";
00143     }
00144     
00145     // operators
00146     inline CurvePointIterator& operator++()  // operator corresponding to ++i
00147     { 
00148       increment();
00149       return *this;
00150     }
00151    
00152     inline CurvePointIterator& operator--()  // operator corresponding to ++i
00153     { 
00154       decrement();
00155       return *this;
00156     }
00157     
00158     // comparibility
00159     virtual bool operator==(const Interface0DIteratorNested& b) const
00160     {
00161       const CurvePointIterator* it_exact = dynamic_cast<const CurvePointIterator*>(&b);
00162       if (!it_exact)
00163           return false;
00164       return ((__A==it_exact->__A) && (__B==it_exact->__B) && (_t == it_exact->_t));
00165     }
00166     
00167     // dereferencing
00168     virtual CurvePoint& operator*()  
00169     {
00170       return (_Point = CurvePoint(*__A,*__B,_t));
00171     }
00172     virtual CurvePoint* operator->() { return &(operator*());}
00173   public:
00174     virtual bool isBegin() const 
00175     {
00176       if((__A == _begin) && (_t < (float)M_EPSILON))
00177         return true;
00178       return false;
00179     }
00180     virtual bool isEnd() const 
00181     {
00182       if(__B == _end)
00183         return true;
00184       return false;
00185     }
00186   protected:
00187     virtual void increment() 
00188     {
00189       if((_currentn == _n-1) && (_t == 1.f))
00190       {
00191         // we're setting the iterator to end
00192         ++__A;
00193         ++__B;
00194         ++_currentn;
00195         _t = 0.f;
00196         return;
00197       }
00198       
00199       if(0 == _step) // means we iterate over initial vertices
00200       {
00201               Vec3r vec_tmp((*__B)->point2d() - (*__A)->point2d());
00202         _CurvilinearLength += (float)vec_tmp.norm();
00203         if(_currentn == _n-1)
00204         { 
00205           _t = 1.f;   
00206           return;
00207         }
00208         ++__B;
00209         ++__A;
00210         ++_currentn;
00211         return;
00212       }
00213       
00214       // compute the new position:
00215       Vec3r vec_tmp2((*__A)->point2d() - (*__B)->point2d());
00216       float normAB = (float)vec_tmp2.norm();
00217 
00218       if(normAB > M_EPSILON)
00219       {
00220         _CurvilinearLength += _step;
00221         _t = _t + _step/normAB;
00222       }
00223       else
00224         _t = 1.f; // AB is a null segment, we're directly at its end
00225         //if normAB ~= 0, we don't change these values
00226       if(_t >= 1)
00227       { 
00228         _CurvilinearLength -= normAB*(_t-1);
00229         if(_currentn == _n-1)
00230           _t=1.f;
00231         else
00232         {
00233           _t = 0.f;
00234           ++_currentn;
00235           ++__A;++__B;
00236         }
00237       }
00238     }
00239     virtual void decrement() 
00240     {
00241       if(_t == 0.f) //we're at the beginning of the edge
00242       {
00243         _t = 1.f;
00244         --_currentn;
00245         --__A; --__B;
00246         if(_currentn == _n-1)
00247           return;
00248       }
00249 
00250       if(0 == _step) // means we iterate over initial vertices
00251       {
00252               Vec3r vec_tmp((*__B)->point2d() - (*__A)->point2d());
00253         _CurvilinearLength -= (float)vec_tmp.norm();
00254         _t = 0;
00255         return;
00256       }
00257       
00258       // compute the new position:
00259       Vec3r vec_tmp2((*__A)->point2d() - (*__B)->point2d());
00260       float normAB = (float)vec_tmp2.norm();
00261       
00262       if(normAB >M_EPSILON)
00263       {
00264         _CurvilinearLength -= _step;
00265         _t = _t - _step/normAB;
00266       }
00267       else
00268         _t = -1.f; // We just need a negative value here
00269 
00270       // round value
00271       if(fabs(_t) < (float)M_EPSILON)
00272         _t = 0.0;
00273       if(_t < 0)
00274       { 
00275         if(_currentn == 0)
00276           _CurvilinearLength = 0.f;
00277         else
00278         _CurvilinearLength += normAB*(-_t);
00279         _t = 0.f;
00280       } 
00281     }
00282 
00283     virtual float t() const{
00284       return _CurvilinearLength;
00285     } 
00286     virtual float u() const{
00287       return _CurvilinearLength/_CurveLength;
00288     } 
00289   };
00290 
00291   
00292 
00293 } // end of namespace StrokeInternal
00294 
00295 #endif // CURVEITERATORS_H