2 * This program is free software: you can redistribute it and/or modify
3 * it under the terms of the GNU Lesser General Public License as
4 * published by the Free Software Foundation, either version 3 of the
5 * License, or (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 * @file NaiveParametricCurveDigitizer3D.ih
19 * @author Kacper Pluta (\c kacper.pluta@esiee.fr )
20 * Laboratoire d'Informatique Gaspard-Monge - LIGM, A3SI, France
24 * Implementation of inline methods defined in NaiveParametricCurveDigitizer3D.h
26 * This file is part of the DGtal library.
29 ///////////////////////////////////////////////////////////////////////////////
30 // IMPLEMENTATION of inline methods.
31 ///////////////////////////////////////////////////////////////////////////////
33 //////////////////////////////////////////////////////////////////////////////
39 #include "DGtal/kernel/BasicPointFunctors.h"
40 //////////////////////////////////////////////////////////////////////////////
43 template <typename T> int sgn(T val) {
44 return ( T ( 0 ) < val ) - ( val < T( 0 ) );
53 bool NaiveParametricCurveDigitizer3D<T>::is26Connected ( const Point &x, const Point &y )
55 return std::abs ( x[0] - y[0] ) < 2 && std::abs ( x[1] - y[1] ) < 2 && std::abs ( x[2] - y[2] ) < 2 && x != y;
58 ///////////////////////////////////////////////////////////////////////////////
59 // Implementation of inline methods //
62 NaiveParametricCurveDigitizer3D<T>::NaiveParametricCurveDigitizer3D ()
68 BUFFER_SIZE = K_NEXT * 3;
73 void NaiveParametricCurveDigitizer3D<T>::attach ( ConstAlias<T> p_curve )
81 void NaiveParametricCurveDigitizer3D<T>::init ( long double tmin, long double tmax, long double timeStep )
84 throw std::runtime_error ( "Starting time is bigger than the end time!" );
86 if ( timeStep > ( tmax - tmin ) )
87 throw std::runtime_error ( "The step is too big!" );
98 unsigned int NaiveParametricCurveDigitizer3D<T>::setKNext ( unsigned int knext )
102 unsigned int tmp = K_NEXT;
104 BUFFER_SIZE = K_NEXT * 3;
107 throw std::runtime_error ( "The value of k-next cannot be 0!" );
111 template <typename T>
113 bool NaiveParametricCurveDigitizer3D<T>::isValid ( ) const
115 return initOK && K_NEXT > 0 && curve != nullptr;
119 template <typename T>
121 void NaiveParametricCurveDigitizer3D<T>::syncData ( ConstIterator bbegin, ConstIterator bend, DataInfo & weights )
123 if ( bbegin == bend )
126 if ( digitalCurve.size() == 0 )
128 digitalCurve.push_back ( *bbegin );
131 metaDataContainter.push_back ( weights[*bbegin] );
134 for (; it != bend; it++ )
136 // search for better candidates i.e. search for 26-connected points of higher scores in the k-neighborhood.
137 for ( KConstIter s = { it + 1, 0 }; s.jt != bend && s.k < K_NEXT; s.jt++ )
139 if ( is26Connected ( digitalCurve.back(), *s.jt ) && weights[*s.jt].second >= weights[*it].second )
144 else if ( ! is26Connected ( digitalCurve.back(), *s.jt ) )
148 digitalCurve.push_back ( *it );
150 metaDataContainter.push_back( weights[*it] );
155 template <typename T>
157 void NaiveParametricCurveDigitizer3D<T>::flashBuffers ( Buffer & buffer, DataInfo & weights )
159 syncData ( buffer.begin(), buffer.end() - K_NEXT, weights );
160 // keep the last few points for re-evaluation or because they may not be well evaluated yet.
161 for ( auto it = buffer.begin(); it != buffer.end() - K_NEXT; it++ )
162 weights.erase ( *it );
163 buffer.erase ( buffer.begin(), buffer.end() - K_NEXT );
166 template <typename T>
168 void NaiveParametricCurveDigitizer3D<T>::updateMetaData ( const Point & p, const RealPoint & pc,
169 DataInfo & weights, long double t )
173 if ( weights[p].second == 1 )
174 weights[p].first = t;
175 else if ( (p - pc).norm() < (curve->x ( weights[p].first ) - p).norm() )
176 weights[p].first = t;
180 template <typename T>
182 void NaiveParametricCurveDigitizer3D<T>::cleanClosedPart ( )
184 bool isClosed = false;
185 auto it = digitalCurve.end () - K_NEXT;
186 auto jt = digitalCurve.begin () + K_NEXT;
187 for ( ; it != digitalCurve.end (); it++ )
188 for (; jt != digitalCurve.begin(); jt--)
189 if ( is26Connected ( *jt, *it ) )
194 if ( isClosed && std::distance ( it, digitalCurve.end () ) > 1 )
197 metaDataContainter.erase ( metaDataContainter.end ( ) + std::distance ( it, digitalCurve.end ( ) ) + 1, metaDataContainter.end ( ) );
198 digitalCurve.erase ( it + 1, digitalCurve.end ( ) );
200 if ( isClosed && jt != digitalCurve.begin() )
203 metaDataContainter.erase ( metaDataContainter.begin (), metaDataContainter.begin () + std::distance ( digitalCurve.begin (), jt ) );
204 digitalCurve.erase ( digitalCurve.begin ( ), jt );
208 template <typename T>
210 void NaiveParametricCurveDigitizer3D<T>::cleanCurve ( )
213 for ( auto it = digitalCurve.begin (); it != digitalCurve.end (); )
216 for ( KIter s = { tmp, 0 }; s.jt != digitalCurve.end () && s.k < K_NEXT; s.jt++ )
217 if ( is26Connected ( *it, *s.jt ) )
227 metaDataContainter.erase ( metaDataContainter.begin () + std::distance ( digitalCurve.begin ( ), it ) + 1,
228 metaDataContainter.begin () + std::distance ( digitalCurve.begin(), tmp ) );
229 it = digitalCurve.erase ( it + 1, tmp );
237 template <typename T>
239 void NaiveParametricCurveDigitizer3D<T>::digitize ( std::back_insert_iterator < DigitalCurve > inserter )
241 assert ( isValid() );
246 for ( double t = timeMin; t < timeMax + step; t += step )
248 RealPoint pc = curve->x ( t );
249 Point p ( std::round ( pc[0] ), std::round ( pc[1] ), std::round ( pc[2] ) );
252 updateMetaData ( p, pc, weights, t );
253 if ( std::find ( buffer.begin (), buffer.end (), p ) == buffer.end ( ) )
254 buffer.push_back ( p );
256 if ( buffer.size() == BUFFER_SIZE )
257 flashBuffers(buffer, weights);
259 syncData ( buffer.begin (), buffer.end (), weights );
262 std::move ( digitalCurve.begin (), digitalCurve.end (), inserter );
263 digitalCurve.clear ();
266 template <typename T>
268 void NaiveParametricCurveDigitizer3D<T>::digitize ( std::back_insert_iterator < DigitalCurve > inserter,
269 std::back_insert_iterator < MetaData > meta_inserter )
272 digitize ( inserter );
273 std::move ( metaDataContainter.begin (), metaDataContainter.end (), meta_inserter );
274 metaDataContainter.clear ();
278 template <typename T>
280 void NaiveParametricCurveDigitizer3D<T>::selfDisplay ( std::ostream & out ) const
282 out << "[NaiveParametricCurveDigitizer3D]";
287 ///////////////////////////////////////////////////////////////////////////////
288 // Implementation of inline functions and external operators //
291 * Overloads 'operator<<' for displaying objects of class 'NaiveParametricCurveDigitizer3D'.
292 * @param out the output stream where the object is written.
293 * @param object the object of class 'NaiveParametricCurveDigitizer3D' to write.
294 * @return the output stream after the writing.
296 template <typename T>
299 operator<< ( std::ostream & out, const DGtal::NaiveParametricCurveDigitizer3D<T> & object )
301 object.selfDisplay ( out );
306 ///////////////////////////////////////////////////////////////////////////////