Loading [MathJax]/extensions/TeX/AMSsymbols.js
DGtal 2.0.0
PointVector.ih
1/**
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.
6 *
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.
11 *
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/>.
14 *
15 **/
16
17/**
18 * @file PointVector.ih
19 * @author David Coeurjolly (\c david.coeurjolly@liris.cnrs.fr )
20 * @author Guillaume Damiand
21 * Laboratoire d'InfoRmatique en Image et Systèmes d'information - LIRIS (CNRS, UMR 5205), CNRS, France
22 *
23 * @date 2010/05/14
24 *
25 * Implementation of inline methods defined in PointVector.h
26 *
27 * This file is part of the DGtal library.
28 */
29
30///////////////////////////////////////////////////////////////////////////////
31// IMPLEMENTATION of inline methods.
32///////////////////////////////////////////////////////////////////////////////
33
34//////////////////////////////////////////////////////////////////////////////
35#include <cstdlib>
36#include <cmath>
37#include <DGtal/base/BasicFunctors.h>
38//////////////////////////////////////////////////////////////////////////////
39
40
41template<DGtal::Dimension dim, typename Container>
42inline
43std::bitset<dim> DGtal::setDimensionsIn( const Container &dimensions )
44{
45 std::bitset<dim> t1;
46 for ( typename Container::const_iterator it=dimensions.begin();
47 it!=dimensions.end(); ++it )
48 {
49 ASSERT( *it<dim );
50 t1.set(*it);
51 }
52 return t1;
53}
54//------------------------------------------------------------------------------
55template<DGtal::Dimension dim, typename Container>
56inline
57std::bitset<dim> DGtal::setDimensionsNotIn( const Container &dimensions )
58{
59 std::bitset<dim> t1; t1.set();
60 for ( typename Container::const_iterator it=dimensions.begin();
61 it!=dimensions.end(); ++it )
62 {
63 ASSERT( *it<dim );
64 t1.reset(*it);
65 }
66 return t1;
67}
68//------------------------------------------------------------------------------
69
70
71template<DGtal::Dimension dim, typename TComponent, typename TContainer>
72inline
73DGtal::PointVector<dim, TComponent, TContainer>::PointVector()
74{
75 for ( Dimension i = 0; i < dim; ++i )
76 myArray[ i ] = NumberTraits<TComponent>::ZERO;
77}
78//------------------------------------------------------------------------------
79template<DGtal::Dimension dim, typename TComponent, typename TContainer>
80template <
81 typename LeftComponent, typename LeftStorage,
82 typename RightComponent, typename RightStorage,
83 typename BinaryFunctor >
84inline
85DGtal::PointVector<dim, TComponent, TContainer>::PointVector(
86 const PointVector<dim, LeftComponent, LeftStorage> & apoint1,
87 const PointVector<dim, RightComponent, RightStorage> & apoint2,
88 const BinaryFunctor & f)
89{
90 for ( Dimension i = 0; i < dim; ++i )
91 myArray[ i ] = static_cast<TComponent>( f(apoint1[i], apoint2[i]) );
92}
93//------------------------------------------------------------------------------
94template <DGtal::Dimension dim, typename TComponent, typename TContainer>
95template <typename OtherComponent, typename OtherStorage, typename UnaryFunctor>
96inline
97DGtal::PointVector<dim, TComponent,TContainer>::
98PointVector(const PointVector<dim, OtherComponent, OtherStorage> & apoint1,
99 const UnaryFunctor& f)
100{
101 for ( Dimension i = 0; i < dim; ++i )
102 myArray[ i ] = static_cast<TComponent>( f( apoint1[i] ) );
103}
104//------------------------------------------------------------------------------
105template<DGtal::Dimension dim, typename TComponent, typename TContainer>
106inline
107DGtal::PointVector<dim, TComponent, TContainer>::PointVector( const Component * ptrValues )
108{
109 // The problem here is that we have no guaranty on the size of init !!
110 for ( Dimension i = 0; i < dim; ++i )
111 myArray[ i ] = ptrValues[ i ];
112}
113//------------------------------------------------------------------------------
114template<DGtal::Dimension dim, typename TComponent, typename TContainer>
115inline
116DGtal::PointVector<dim, TComponent, TContainer>::PointVector( const Component & x, const Component & y )
117{
118 ASSERT( dim >= 2 );
119 myArray[ 0 ] = x;
120 myArray[ 1 ] = y;
121 for ( Dimension i = 2; i < dim; ++i )
122 myArray[ i ] = NumberTraits<TComponent>::ZERO;
123}
124//------------------------------------------------------------------------------
125template<DGtal::Dimension dim, typename TComponent, typename TContainer>
126inline
127DGtal::PointVector<dim, TComponent, TContainer>::PointVector( const Component & x,
128 const Component & y,
129 const Component & z )
130{
131 ASSERT( dim >= 3 );
132 myArray[ 0 ] = x;
133 myArray[ 1 ] = y;
134 myArray[ 2 ] = z;
135 for ( Dimension i = 3; i < dim; ++i )
136 myArray[ i ] = NumberTraits<TComponent>::ZERO;
137}
138//------------------------------------------------------------------------------
139template<DGtal::Dimension dim, typename TComponent, typename TContainer>
140inline
141DGtal::PointVector<dim, TComponent, TContainer>::PointVector( const Component & x,
142 const Component & y,
143 const Component & z,
144 const Component & t )
145{
146 ASSERT( dim >= 4 );
147 myArray[ 0 ] = x;
148 myArray[ 1 ] = y;
149 myArray[ 2 ] = z;
150 myArray[ 3 ] = t;
151 for ( Dimension i = 4; i < dim; ++i )
152 myArray[ i ] = NumberTraits<TComponent>::ZERO;
153}
154//------------------------------------------------------------------------------
155template<DGtal::Dimension dim, typename TComponent, typename TContainer>
156inline
157DGtal::PointVector<dim, TComponent, TContainer>::PointVector(std::initializer_list<Component> init)
158{
159 unsigned int i = 0;
160 for (const Component *p = init.begin (); p != init.end () && i < dim; ++p, ++i)
161 myArray[ i ] = *p;
162 for ( ; i < dim; ++i)
163 myArray[i] = NumberTraits<TComponent>::ZERO;
164}
165//------------------------------------------------------------------------------
166template<DGtal::Dimension dim, typename TComponent, typename TContainer>
167inline
168DGtal::PointVector<dim, TComponent, TContainer>::PointVector ( const Self & other )
169 : myArray( other.myArray )
170{}
171//------------------------------------------------------------------------------
172template<DGtal::Dimension dim, typename TComponent, typename TContainer>
173template <
174 typename OtherComponent, typename OtherCont,
175 typename std::enable_if< std::is_same< TComponent, DGtal::ArithmeticConversionType<TComponent, OtherComponent> >::value, int >::type >
176inline
177DGtal::PointVector<dim, TComponent, TContainer>::PointVector (const PointVector<dim,OtherComponent,OtherCont> & other )
178{
179 for ( DGtal::Dimension i = 0; i < dimension; ++i )
180 this->myArray[ i ] = static_cast<TComponent>(other[ i ]);
181}
182//------------------------------------------------------------------------------
183template<DGtal::Dimension dim, typename TComponent, typename TContainer>
184template <
185 typename OtherComponent, typename OtherCont,
186 typename std::enable_if< ! std::is_same< TComponent, DGtal::ArithmeticConversionType<TComponent, OtherComponent> >::value, int >::type >
187inline
188DGtal::PointVector<dim, TComponent, TContainer>::PointVector (const PointVector<dim,OtherComponent,OtherCont> & other )
189{
190 for ( DGtal::Dimension i = 0; i < dimension; ++i )
191 this->myArray[ i ] = static_cast<TComponent>(other[ i ]);
192}
193//------------------------------------------------------------------------------
194template<DGtal::Dimension dim, typename TComponent, typename TContainer>
195inline
196typename DGtal::PointVector<dim, TComponent, TContainer>::Iterator
197DGtal::PointVector<dim, TComponent, TContainer>::begin()
198{
199 return myArray.begin();
200}
201//------------------------------------------------------------------------------
202template<DGtal::Dimension dim, typename TComponent, typename TContainer>
203inline
204typename DGtal::PointVector<dim, TComponent, TContainer>::Iterator
205DGtal::PointVector<dim, TComponent, TContainer>::end()
206{
207 return myArray.end();
208}
209//------------------------------------------------------------------------------
210template<DGtal::Dimension dim, typename TComponent, typename TContainer>
211inline
212typename DGtal::PointVector<dim, TComponent, TContainer>::ConstIterator
213DGtal::PointVector<dim, TComponent, TContainer>::begin() const
214{
215 return myArray.begin();
216}
217//------------------------------------------------------------------------------
218template<DGtal::Dimension dim, typename TComponent, typename TContainer>
219inline
220typename DGtal::PointVector<dim, TComponent, TContainer>::ConstIterator
221DGtal::PointVector<dim, TComponent, TContainer>::end() const
222{
223 return myArray.end();
224}
225//------------------------------------------------------------------------------
226template<DGtal::Dimension dim, typename TComponent, typename TContainer>
227inline
228typename DGtal::PointVector<dim, TComponent, TContainer>::ReverseIterator
229DGtal::PointVector<dim, TComponent, TContainer>::rbegin()
230{
231 return myArray.rbegin();
232}
233//------------------------------------------------------------------------------
234template<DGtal::Dimension dim, typename TComponent, typename TContainer>
235inline
236typename DGtal::PointVector<dim, TComponent, TContainer>::ReverseIterator
237DGtal::PointVector<dim, TComponent, TContainer>::rend()
238{
239 return myArray.rend();
240}
241//------------------------------------------------------------------------------
242template<DGtal::Dimension dim, typename TComponent, typename TContainer>
243inline
244typename DGtal::PointVector<dim, TComponent, TContainer>::ConstReverseIterator
245DGtal::PointVector<dim, TComponent, TContainer>::rbegin() const
246{
247 return myArray.rbegin();
248}
249//------------------------------------------------------------------------------
250template<DGtal::Dimension dim, typename TComponent, typename TContainer>
251inline
252typename DGtal::PointVector<dim, TComponent, TContainer>::ConstReverseIterator
253DGtal::PointVector<dim, TComponent, TContainer>::rend() const
254{
255 return myArray.rend();
256}
257//------------------------------------------------------------------------------
258template<DGtal::Dimension dim, typename TComponent, typename TContainer>
259inline
260typename DGtal::Dimension
261DGtal::PointVector<dim, TComponent, TContainer>::size()
262{
263 return dim;
264}
265//------------------------------------------------------------------------------
266template<DGtal::Dimension dim, typename TComponent, typename TContainer>
267inline
268const typename DGtal::PointVector<dim, TComponent, TContainer>::Component *
269DGtal::PointVector<dim, TComponent, TContainer>::data() const noexcept
270{
271 return myArray.data();
272}
273//------------------------------------------------------------------------------
274template<DGtal::Dimension dim, typename TComponent, typename TContainer>
275inline
276typename DGtal::PointVector<dim, TComponent, TContainer>::Component *
277DGtal::PointVector<dim, TComponent, TContainer>::data() noexcept
278{
279 return myArray.data();
280}
281//------------------------------------------------------------------------------
282template<DGtal::Dimension dim, typename TComponent, typename TContainer>
283inline
284const typename DGtal::PointVector<dim, TComponent, TContainer>::Component &
285DGtal::PointVector<dim, TComponent, TContainer>::operator[]( Dimension i ) const
286{
287 ASSERT ( i < dim );
288 return myArray[i];
289}
290//------------------------------------------------------------------------------
291template<DGtal::Dimension dim, typename TComponent, typename TContainer>
292inline
293typename DGtal::PointVector<dim, TComponent, TContainer>::Component &
294DGtal::PointVector<dim, TComponent, TContainer>::operator[]( Dimension i )
295{
296 ASSERT ( i < dim );
297 return myArray[i];
298}
299//------------------------------------------------------------------------------
300template<DGtal::Dimension dim, typename TComponent, typename TContainer>
301inline
302DGtal::PointVector<dim, TComponent, TContainer>&
303DGtal::PointVector<dim, TComponent, TContainer>::operator= ( const Self & pv )
304{
305 myArray = pv.myArray;
306 return *this;
307}
308//------------------------------------------------------------------------------
309template<DGtal::Dimension dim, typename TComponent, typename TContainer>
310template <
311 typename OtherComponent,
312 typename OtherContainer,
313 typename std::enable_if< std::is_same< TComponent, DGtal::ArithmeticConversionType<TComponent, OtherComponent> >::value, int >::type>
314inline
315DGtal::PointVector<dim, TComponent, TContainer> &
316DGtal::PointVector<dim, TComponent, TContainer>::operator= ( const DGtal::PointVector<dim, OtherComponent, OtherContainer> & v )
317{
318 for ( DGtal::Dimension i = 0; i < dimension; ++i )
319 {
320 this->myArray[ i ] = static_cast<Component>( v[ i ] );
321 }
322 return *this;
323}
324//------------------------------------------------------------------------------
325template<DGtal::Dimension dim, typename TComponent, typename TContainer>
326template <
327 typename OtherComponent,
328 typename OtherContainer,
329 typename std::enable_if< std::is_same< TComponent, DGtal::ArithmeticConversionType<TComponent, OtherComponent> >::value, int >::type>
330inline
331DGtal::PointVector<dim, TComponent, TContainer>&
332DGtal::PointVector<dim, TComponent, TContainer>::partialCopy
333( const DGtal::PointVector<dim, OtherComponent, OtherContainer> & pv,
334 const std::vector<DGtal::Dimension> &dimensions)
335{
336 std::bitset<dim> dims = setDimensionsIn<dim>(dimensions);
337 for ( DGtal::Dimension i = 0; i < dim; ++i )
338 {
339 if ( dims.test(i) ) myArray[i] = static_cast<TComponent>(pv.myArray[i]);
340 }
341 return *this;
342}
343//------------------------------------------------------------------------------
344template<DGtal::Dimension dim, typename TComponent, typename TContainer>
345template <
346 typename OtherComponent,
347 typename OtherContainer,
348 typename std::enable_if< std::is_same< TComponent, DGtal::ArithmeticConversionType<TComponent, OtherComponent> >::value, int >::type>
349inline
350DGtal::PointVector<dim, TComponent, TContainer>&
351DGtal::PointVector<dim, TComponent, TContainer>::partialCopyInv
352( const DGtal::PointVector<dim, OtherComponent, OtherContainer> & pv,
353 const std::vector<DGtal::Dimension> &dimensions)
354{
355 std::bitset<dim> dims = setDimensionsIn<dim>(dimensions);
356 for ( DGtal::Dimension i = 0; i < dim; ++i )
357 {
358 if ( !dims.test(i) ) myArray[i] = static_cast<TComponent>(pv.myArray[i]);
359 }
360 return *this;
361}
362//------------------------------------------------------------------------------
363template<DGtal::Dimension dim, typename TComponent, typename TContainer>
364template <
365 typename OtherComponent,
366 typename OtherContainer,
367 typename UnaryFunctor >
368inline
369DGtal::PointVector<dim, TComponent, TContainer>&
370DGtal::PointVector<dim, TComponent, TContainer>::partialCopy
371( const DGtal::PointVector<dim, OtherComponent, OtherContainer> & pv,
372 const std::vector<DGtal::Dimension> &dimensions,
373 const UnaryFunctor &f)
374{
375 std::bitset<dim> dims = setDimensionsIn<dim>(dimensions);
376 for ( DGtal::Dimension i = 0; i < dim; ++i )
377 {
378 if ( dims.test(i) ) myArray[i] = static_cast<TComponent>(f(pv.myArray[i]));
379 }
380 return *this;
381}
382//------------------------------------------------------------------------------
383template<DGtal::Dimension dim, typename TComponent, typename TContainer>
384template <
385 typename OtherComponent,
386 typename OtherContainer,
387 typename UnaryFunctor >
388inline
389DGtal::PointVector<dim, TComponent, TContainer>&
390DGtal::PointVector<dim, TComponent, TContainer>::partialCopyInv
391( const DGtal::PointVector<dim, OtherComponent, OtherContainer> & pv,
392 const std::vector<DGtal::Dimension> &dimensions,
393 const UnaryFunctor &f)
394{
395 std::bitset<dim> dims = setDimensionsIn<dim>(dimensions);
396 for ( DGtal::Dimension i = 0; i < dim; ++i )
397 {
398 if ( !dims.test(i) ) myArray[i] = static_cast<TComponent>(f(pv.myArray[i]));
399 }
400 return *this;
401}
402//------------------------------------------------------------------------------
403template<DGtal::Dimension dim, typename TComponent, typename TContainer>
404template <typename TOtherComponent, typename TOtherContainer>
405inline
406bool
407DGtal::PointVector<dim, TComponent, TContainer>::partialEqual
408( const DGtal::PointVector<dim, TOtherComponent, TOtherContainer> & pv,
409 const std::vector<DGtal::Dimension> &dimensions ) const
410{
411 std::bitset<dim> dims = setDimensionsIn<dim>(dimensions);
412 for ( DGtal::Dimension i = 0; i < dim; ++i )
413 {
414 if ( dims.test(i) && myArray[i] != pv.myArray[i]) return false;
415 }
416 return true;
417}
418//------------------------------------------------------------------------------
419template<DGtal::Dimension dim, typename TComponent, typename TContainer>
420template <typename TOtherComponent, typename TOtherContainer>
421inline
422bool
423DGtal::PointVector<dim, TComponent, TContainer>::partialEqualInv
424( const DGtal::PointVector<dim, TOtherComponent, TOtherContainer> & pv,
425 const std::vector<DGtal::Dimension> &dimensions ) const
426{
427 std::bitset<dim> dims = setDimensionsIn<dim>(dimensions);
428 for ( DGtal::Dimension i = 0; i < dim; ++i )
429 {
430 if ( !dims.test(i) && myArray[i] != pv.myArray[i]) return false;
431 }
432 return true;
433}
434//------------------------------------------------------------------------------
435template < DGtal::Dimension ptDim,
436 typename LeftEuclideanRing, typename LeftContainer,
437 typename RightEuclideanRing, typename RightContainer >
438inline bool
439DGtal::operator== ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
440 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
441 {
442 return std::equal( lhs.begin(), lhs.end(), rhs.begin() );
443 }
444//------------------------------------------------------------------------------
445template < DGtal::Dimension ptDim,
446 typename LeftEuclideanRing, typename LeftContainer,
447 typename RightEuclideanRing, typename RightContainer >
448inline bool
449DGtal::operator!= ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
450 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
451 {
452 return ! (lhs == rhs);
453 }
454//------------------------------------------------------------------------------
455template < DGtal::Dimension ptDim,
456 typename LeftEuclideanRing, typename LeftContainer,
457 typename RightEuclideanRing, typename RightContainer >
458inline bool
459DGtal::operator< ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
460 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
461 {
462 return std::lexicographical_compare( lhs.begin(), lhs.end(), rhs.begin(), rhs.end() );
463 }
464//------------------------------------------------------------------------------
465template < DGtal::Dimension ptDim,
466 typename LeftEuclideanRing, typename LeftContainer,
467 typename RightEuclideanRing, typename RightContainer >
468inline bool
469DGtal::operator> ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
470 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
471 {
472 return rhs < lhs;
473 }
474//------------------------------------------------------------------------------
475template < DGtal::Dimension ptDim,
476 typename LeftEuclideanRing, typename LeftContainer,
477 typename RightEuclideanRing, typename RightContainer >
478inline bool
479DGtal::operator<= ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
480 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
481 {
482 return ! ( lhs > rhs );
483 }
484//------------------------------------------------------------------------------
485template < DGtal::Dimension ptDim,
486 typename LeftEuclideanRing, typename LeftContainer,
487 typename RightEuclideanRing, typename RightContainer >
488inline bool
489DGtal::operator>= ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
490 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
491 {
492 return ! ( lhs < rhs );
493 }
494//------------------------------------------------------------------------------
495template<DGtal::Dimension dim, typename TComponent, typename TContainer>
496template <
497 typename OtherComponent, typename OtherStorage,
498 typename std::enable_if< std::is_same< TComponent, DGtal::ArithmeticConversionType<TComponent, OtherComponent> >::value, int >::type >
499inline
500DGtal::PointVector<dim, TComponent, TContainer>&
501DGtal::PointVector<dim, TComponent, TContainer>::operator+= ( PointVector<dim, OtherComponent, OtherStorage> const& v )
502{
503 for ( DGtal::Dimension i = 0; i < dim; ++i )
504 this->myArray[ i ] += v[ i ];
505 return *this;
506}
507//------------------------------------------------------------------------------
508template<DGtal::Dimension dim, typename TComponent, typename TContainer>
509template <
510 typename OtherComponent,
511 typename std::enable_if< std::is_same< TComponent, DGtal::ArithmeticConversionType<TComponent, OtherComponent> >::value, int >::type >
512inline
513DGtal::PointVector<dim, TComponent, TContainer>&
514DGtal::PointVector<dim, TComponent, TContainer>::operator+= ( OtherComponent coeff )
515{
516 for ( DGtal::Dimension i = 0; i < dim; ++i )
517 this->myArray[ i ] += coeff;
518 return *this;
519}
520//------------------------------------------------------------------------------
521template<DGtal::Dimension dim, typename TComponent, typename TContainer>
522template <
523 typename OtherComponent, typename OtherStorage,
524 typename std::enable_if< std::is_same< TComponent, DGtal::ArithmeticConversionType<TComponent, OtherComponent> >::value, int >::type >
525inline
526DGtal::PointVector<dim, TComponent, TContainer>&
527DGtal::PointVector<dim, TComponent, TContainer>::operator-= ( PointVector<dim, OtherComponent, OtherStorage> const& v )
528{
529 for ( DGtal::Dimension i = 0; i < dim; ++i )
530 this->myArray[ i ] -= v[ i ];
531 return *this;
532}
533//------------------------------------------------------------------------------
534template<DGtal::Dimension dim, typename TComponent, typename TContainer>
535template <
536 typename OtherComponent,
537 typename std::enable_if< std::is_same< TComponent, DGtal::ArithmeticConversionType<TComponent, OtherComponent> >::value, int >::type >
538inline
539DGtal::PointVector<dim, TComponent, TContainer>&
540DGtal::PointVector<dim, TComponent, TContainer>::operator-= ( OtherComponent coeff )
541{
542 for ( DGtal::Dimension i = 0; i < dim; ++i )
543 this->myArray[ i ] -= coeff;
544 return *this;
545}
546//------------------------------------------------------------------------------
547template<DGtal::Dimension dim, typename TComponent, typename TContainer>
548template <
549 typename OtherComponent,
550 typename std::enable_if< std::is_same< TComponent, DGtal::ArithmeticConversionType<TComponent, OtherComponent> >::value, int >::type>
551DGtal::PointVector<dim, TComponent, TContainer>&
552DGtal::PointVector<dim, TComponent, TContainer>::operator*= ( OtherComponent coeff )
553{
554 for ( DGtal::Dimension i = 0; i < myArray.size(); ++i )
555 myArray[ i ] *= coeff;
556 return *this;
557}
558//------------------------------------------------------------------------------
559template<DGtal::Dimension dim, typename TComponent, typename TContainer>
560template <
561 typename OtherComponent, typename OtherStorage,
562 typename std::enable_if< std::is_same< TComponent, DGtal::ArithmeticConversionType<TComponent, OtherComponent> >::value, int >::type>
563DGtal::PointVector<dim, TComponent, TContainer>&
564DGtal::PointVector<dim, TComponent, TContainer>::operator*= ( PointVector<dim, OtherComponent, OtherStorage> const& v )
565{
566 for ( DGtal::Dimension i = 0; i < myArray.size(); ++i )
567 myArray[ i ] *= v[ i ];
568 return *this;
569}
570//------------------------------------------------------------------------------
571template<DGtal::Dimension dim, typename TComponent, typename TContainer>
572template <
573 typename OtherComponent,
574 typename std::enable_if< std::is_same< TComponent, DGtal::ArithmeticConversionType<TComponent, OtherComponent> >::value, int >::type>
575DGtal::PointVector<dim, TComponent, TContainer>&
576DGtal::PointVector<dim, TComponent, TContainer>::operator/= ( OtherComponent coeff )
577{
578 for ( DGtal::Dimension i = 0; i < myArray.size(); ++i )
579 myArray[ i ] /= coeff;
580 return *this;
581}
582//------------------------------------------------------------------------------
583template<DGtal::Dimension dim, typename TComponent, typename TContainer>
584template <
585 typename OtherComponent, typename OtherStorage,
586 typename std::enable_if< std::is_same< TComponent, DGtal::ArithmeticConversionType<TComponent, OtherComponent> >::value, int >::type>
587DGtal::PointVector<dim, TComponent, TContainer>&
588DGtal::PointVector<dim, TComponent, TContainer>::operator/= ( PointVector<dim, OtherComponent, OtherStorage> const& v )
589{
590 for ( DGtal::Dimension i = 0; i < myArray.size(); ++i )
591 myArray[ i ] /= v[ i ];
592 return *this;
593}
594//------------------------------------------------------------------------------
595template<DGtal::Dimension dim, typename TComponent, typename TContainer>
596template < typename OtherComponent, typename OtherStorage >
597inline auto
598DGtal::PointVector<dim, TComponent, TContainer>::dot( const DGtal::PointVector<dim, OtherComponent, OtherStorage>& v ) const
599 -> decltype( DGtal::dotProduct(*this, v) )
600{
601 return DGtal::dotProduct(*this, v);
602}
603//------------------------------------------------------------------------------
604template < DGtal::Dimension ptDim,
605 typename LeftEuclideanRing, typename LeftContainer,
606 typename RightEuclideanRing, typename RightContainer >
607inline
608DGtal::ArithmeticConversionType<LeftEuclideanRing, RightEuclideanRing>
609DGtal::dotProduct ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
610 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
611 {
612 using EuclideanRing = ArithmeticConversionType<LeftEuclideanRing, RightEuclideanRing>;
613 auto dotprod = NumberTraits<EuclideanRing>::ZERO;
614 for ( DGtal::Dimension i = 0; i < ptDim; ++i )
615 dotprod += lhs[ i ] * rhs[ i ];
616 return dotprod;
617 }
618//------------------------------------------------------------------------------
619template < DGtal::Dimension ptDim,
620 typename LeftEuclideanRing, typename LeftContainer,
621 typename RightEuclideanRing, typename RightContainer >
622inline double
623DGtal::cosineSimilarity ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
624 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
625 {
626 double radians = 0.;
627 if ( lhs.norm() > 0. && rhs.norm() > 0. )
628 radians = rhs.dot ( lhs ) / ( lhs.norm() * rhs.norm() );
629 else
630 throw std::runtime_error ( "Operation involving a null vector is not defined!" );
631 return std::acos ( std::min ( std::max ( radians, -1. ), 1. ) );
632}
633
634//------------------------------------------------------------------------------
635template<DGtal::Dimension dim, typename TComponent, typename TContainer>
636template < typename OtherComponent, typename OtherStorage >
637inline double
638DGtal::PointVector<dim, TComponent, TContainer>::cosineSimilarity( const DGtal::PointVector<dim, OtherComponent, OtherStorage>& v ) const
639 {
640 return DGtal::cosineSimilarity(*this, v);
641 }
642//------------------------------------------------------------------------------
643template<DGtal::Dimension dim, typename TComponent, typename TContainer>
644template < typename OtherComponent, typename OtherStorage >
645inline auto
646DGtal::PointVector<dim, TComponent, TContainer>::crossProduct( const DGtal::PointVector<dim, OtherComponent, OtherStorage>& v ) const
647 -> decltype( DGtal::crossProduct(*this, v) )
648{
649 return DGtal::crossProduct(*this, v);
650}
651//------------------------------------------------------------------------------
652template <
653 typename LeftEuclideanRing, typename LeftContainer,
654 typename RightEuclideanRing, typename RightContainer >
655inline auto
656DGtal::crossProduct ( DGtal::PointVector<3, LeftEuclideanRing, LeftContainer> const& lhs,
657 DGtal::PointVector<3, RightEuclideanRing, RightContainer> const& rhs )
658 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
659 {
660 auto crossprod = constructFromArithmeticConversion(lhs, rhs);
661 for ( DGtal::Dimension i = 0; i < 3; ++i )
662 crossprod[i] =
663 lhs[ (i+1)%3 ] * rhs[ (i+2)%3 ]
664 - lhs[ (i+2)%3 ] * rhs[ (i+1)%3 ];
665 return crossprod;
666 }
667//------------------------------------------------------------------------------
668template <
669 typename LeftEuclideanRing, typename LeftContainer,
670 typename RightEuclideanRing, typename RightContainer >
671inline
672DGtal::PointVector<3, DGtal::ArithmeticConversionType<LeftEuclideanRing, RightEuclideanRing>>
673DGtal::crossProduct ( DGtal::PointVector<2, LeftEuclideanRing, LeftContainer> const& lhs,
674 DGtal::PointVector<2, RightEuclideanRing, RightContainer> const& rhs )
675 {
676 return PointVector<3, ArithmeticConversionType<LeftEuclideanRing, RightEuclideanRing>>(
677 0,
678 0,
679 lhs[0]*rhs[1] - lhs[1]*rhs[0]
680 );
681 }
682//------------------------------------------------------------------------------
683template < DGtal::Dimension ptDim,
684 typename LeftEuclideanRing, typename LeftContainer,
685 typename RightEuclideanRing, typename RightContainer >
686inline auto
687DGtal::operator+ ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
688 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
689 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
690 {
691 using EuclideanRing = ArithmeticConversionType<LeftEuclideanRing, RightEuclideanRing>;
692 return constructFromArithmeticConversion(lhs, rhs, lhs, rhs, std::plus<EuclideanRing>());
693 }
694//------------------------------------------------------------------------------
695template < DGtal::Dimension ptDim,
696 typename LeftEuclideanRing, typename LeftContainer,
697 typename RightEuclideanRing, typename RightContainer >
698inline auto
699DGtal::operator- ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
700 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
701 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
702 {
703 using EuclideanRing = ArithmeticConversionType<LeftEuclideanRing, RightEuclideanRing>;
704 return constructFromArithmeticConversion(lhs, rhs, lhs, rhs, std::minus<EuclideanRing>());
705 }
706//------------------------------------------------------------------------------
707template < DGtal::Dimension ptDim,
708 typename LeftEuclideanRing, typename LeftContainer,
709 typename RightEuclideanRing, typename RightContainer >
710inline auto
711DGtal::operator* ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
712 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
713 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
714 {
715 using EuclideanRing = ArithmeticConversionType<LeftEuclideanRing, RightEuclideanRing>;
716 return constructFromArithmeticConversion(lhs, rhs, lhs, rhs, std::multiplies<EuclideanRing>());
717 }
718//------------------------------------------------------------------------------
719template < DGtal::Dimension ptDim,
720 typename LeftEuclideanRing, typename LeftContainer,
721 typename RightEuclideanRing, typename RightContainer >
722inline auto
723DGtal::operator/ ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
724 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
725 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
726 {
727 using EuclideanRing = ArithmeticConversionType<LeftEuclideanRing, RightEuclideanRing>;
728 return constructFromArithmeticConversion(lhs, rhs, lhs, rhs, std::divides<EuclideanRing>());
729 }
730//------------------------------------------------------------------------------
731template < DGtal::Dimension ptDim,
732 typename LeftEuclideanRing, typename LeftContainer,
733 typename RightScalar >
734inline auto
735DGtal::operator+ ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
736 RightScalar const& rhs )
737 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
738 {
739 return constructFromArithmeticConversion(lhs, rhs, lhs, [&rhs] (LeftEuclideanRing v) { return v + rhs; });
740 }
741//------------------------------------------------------------------------------
742template < DGtal::Dimension ptDim,
743 typename LeftScalar,
744 typename RightEuclideanRing, typename RightContainer >
745inline auto
746DGtal::operator+ ( LeftScalar const& lhs,
747 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
748 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
749 {
750 return constructFromArithmeticConversion(lhs, rhs, rhs, [&lhs] (RightEuclideanRing v) { return lhs + v; });
751 }
752//------------------------------------------------------------------------------
753template < DGtal::Dimension ptDim,
754 typename LeftEuclideanRing, typename LeftContainer,
755 typename RightScalar >
756inline auto
757DGtal::operator- ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
758 RightScalar const& rhs )
759 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
760 {
761 return constructFromArithmeticConversion(lhs, rhs, lhs, [&rhs] (LeftEuclideanRing v) { return v - rhs; });
762 }
763//------------------------------------------------------------------------------
764template < DGtal::Dimension ptDim,
765 typename LeftScalar,
766 typename RightEuclideanRing, typename RightContainer >
767inline auto
768DGtal::operator- ( LeftScalar const& lhs,
769 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
770 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
771 {
772 return constructFromArithmeticConversion(lhs, rhs, rhs, [&lhs] (RightEuclideanRing v) { return lhs - v; });
773 }
774//------------------------------------------------------------------------------
775template < DGtal::Dimension ptDim,
776 typename LeftEuclideanRing, typename LeftContainer,
777 typename RightScalar >
778inline auto
779DGtal::operator* ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
780 RightScalar const& rhs )
781 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
782 {
783 return constructFromArithmeticConversion(lhs, rhs, lhs, [&rhs] (LeftEuclideanRing v) { return v * rhs; });
784 }
785//------------------------------------------------------------------------------
786template < DGtal::Dimension ptDim,
787 typename LeftScalar,
788 typename RightEuclideanRing, typename RightContainer >
789inline auto
790DGtal::operator* ( LeftScalar const& lhs,
791 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
792 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
793 {
794 return constructFromArithmeticConversion(lhs, rhs, rhs, [&lhs] (RightEuclideanRing v) { return lhs * v; });
795 }
796//------------------------------------------------------------------------------
797template < DGtal::Dimension ptDim,
798 typename LeftEuclideanRing, typename LeftContainer,
799 typename RightScalar >
800inline auto
801DGtal::operator/ ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
802 RightScalar const& rhs )
803 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
804 {
805 return constructFromArithmeticConversion(lhs, rhs, lhs, [&rhs] (LeftEuclideanRing v) { return v / rhs; });
806 }
807//------------------------------------------------------------------------------
808template < DGtal::Dimension ptDim,
809 typename LeftScalar,
810 typename RightEuclideanRing, typename RightContainer >
811inline auto
812DGtal::operator/ ( LeftScalar const& lhs,
813 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
814 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
815 {
816 return constructFromArithmeticConversion(lhs, rhs, rhs, [&lhs] (RightEuclideanRing v) { return lhs / v; });
817 }
818//------------------------------------------------------------------------------
819template<DGtal::Dimension dim, typename TComponent, typename TContainer>
820inline
821DGtal::PointVector<dim, TComponent,TContainer>
822DGtal::PointVector<dim, TComponent,TContainer>::operator-() const
823{
824 return Self(*this, functors::UnaryMinus<Component>());
825}
826//------------------------------------------------------------------------------
827template<DGtal::Dimension dim, typename TComponent, typename TContainer>
828inline
829void
830DGtal::PointVector<dim, TComponent, TContainer>::reset()
831{
832 for ( DGtal::Dimension i = 0; i < myArray.size(); ++i )
833 myArray[ i ] = NumberTraits< Component >::ZERO;
834}
835//------------------------------------------------------------------------------
836template < DGtal::Dimension ptDim,
837 typename LeftEuclideanRing, typename LeftContainer,
838 typename RightEuclideanRing, typename RightContainer >
839inline auto
840DGtal::inf( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
841 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
842 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
843{
844 using EuclideanRing = ArithmeticConversionType<LeftEuclideanRing, RightEuclideanRing>;
845 return DGtal::constructFromArithmeticConversion(lhs, rhs, lhs, rhs, functors::Min<EuclideanRing>());
846}
847//------------------------------------------------------------------------------
848template<DGtal::Dimension dim, typename TComponent, typename TContainer>
849template < typename OtherComponent, typename OtherStorage >
850inline auto
851DGtal::PointVector<dim, TComponent, TContainer>::inf( const DGtal::PointVector<dim, OtherComponent, OtherStorage>& aPoint ) const
852 -> decltype( DGtal::inf(*this, aPoint) )
853{
854 return DGtal::inf(*this, aPoint);
855}
856//------------------------------------------------------------------------------
857template < DGtal::Dimension ptDim,
858 typename LeftEuclideanRing, typename LeftContainer,
859 typename RightEuclideanRing, typename RightContainer >
860inline auto
861DGtal::sup( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
862 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
863 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
864{
865 using EuclideanRing = ArithmeticConversionType<LeftEuclideanRing, RightEuclideanRing>;
866 return DGtal::constructFromArithmeticConversion(lhs, rhs, lhs, rhs, functors::Max<EuclideanRing>());
867}
868//------------------------------------------------------------------------------
869template<DGtal::Dimension dim, typename TComponent, typename TContainer>
870template < typename OtherComponent, typename OtherStorage >
871inline auto
872DGtal::PointVector<dim, TComponent, TContainer>::sup( const DGtal::PointVector<dim, OtherComponent, OtherStorage>& aPoint ) const
873 -> decltype( DGtal::sup(*this, aPoint) )
874{
875 return DGtal::sup(*this, aPoint);
876}
877//------------------------------------------------------------------------------
878template < DGtal::Dimension ptDim,
879 typename LeftEuclideanRing, typename LeftContainer,
880 typename RightEuclideanRing, typename RightContainer >
881inline bool
882DGtal::isLower( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
883 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
884{
885 for ( DGtal::Dimension i = 0; i < ptDim; ++i )
886 if ( rhs[ i ] < lhs[ i ] )
887 return false;
888 return true;
889}
890//------------------------------------------------------------------------------
891template<DGtal::Dimension dim, typename TComponent, typename TContainer>
892template < typename OtherComponent, typename OtherStorage >
893inline bool
894DGtal::PointVector<dim, TComponent, TContainer>::isLower( const DGtal::PointVector<dim, OtherComponent, OtherStorage> & p ) const
895{
896 return DGtal::isLower(*this, p);
897}
898//------------------------------------------------------------------------------
899template < DGtal::Dimension ptDim,
900 typename LeftEuclideanRing, typename LeftContainer,
901 typename RightEuclideanRing, typename RightContainer >
902inline bool
903DGtal::isUpper( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
904 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
905{
906 for ( DGtal::Dimension i = 0; i < ptDim; ++i )
907 if ( rhs[ i ] > lhs[ i ] )
908 return false;
909 return true;
910}
911//------------------------------------------------------------------------------
912template<DGtal::Dimension dim, typename TComponent, typename TContainer>
913template < typename OtherComponent, typename OtherStorage >
914inline bool
915DGtal::PointVector<dim, TComponent, TContainer>::isUpper( const DGtal::PointVector<dim, OtherComponent, OtherStorage> & p ) const
916{
917 return DGtal::isUpper(*this, p);
918}
919//------------------------------------------------------------------------------
920template<DGtal::Dimension dim, typename TComponent, typename TContainer>
921inline
922typename DGtal::PointVector<dim, TComponent, TContainer>::Component
923DGtal::PointVector<dim, TComponent, TContainer>::max( ) const
924{
925 return *std::max_element(this->begin(), this->end());
926}
927//------------------------------------------------------------------------------
928template<DGtal::Dimension dim, typename TComponent, typename TContainer>
929inline
930typename DGtal::PointVector<dim, TComponent, TContainer>::Component
931DGtal::PointVector<dim, TComponent, TContainer>::min( ) const
932{
933 return *std::min_element(this->begin(), this->end());
934}
935//------------------------------------------------------------------------------
936template<DGtal::Dimension dim, typename TComponent, typename TContainer>
937inline
938typename DGtal::PointVector<dim, TComponent, TContainer>::Iterator
939DGtal::PointVector<dim, TComponent, TContainer>::maxElement( )
940{
941 return std::max_element(this->begin(), this->end());
942}
943//------------------------------------------------------------------------------
944template<DGtal::Dimension dim, typename TComponent, typename TContainer>
945inline
946typename DGtal::PointVector<dim, TComponent, TContainer>::Iterator
947DGtal::PointVector<dim, TComponent, TContainer>::minElement( )
948{
949 return std::min_element(this->begin(), this->end());
950}
951//------------------------------------------------------------------------------
952template<DGtal::Dimension dim, typename TComponent, typename TContainer>
953inline
954void
955DGtal::PointVector<dim, TComponent, TContainer>::
956negate()
957{
958 for ( DGtal::Dimension i = 0; i < dimension; ++i )
959 this->myArray[ i ] = - this->myArray[ i ];
960}
961//------------------------------------------------------------------------------
962template<DGtal::Dimension dim, typename TComponent, typename TContainer>
963inline
964double
965DGtal::PointVector<dim, TComponent, TContainer>::squaredNorm () const
966{
967 ASSERT ( dim > 0 );
968 double tmp = 0.0;
969 for ( DGtal::Dimension i = 0; i < dimension; i++ )
970 tmp += std::pow(NumberTraits<Component>::castToDouble(myArray[ i ]), 2);
971 return tmp;
972}
973//------------------------------------------------------------------------------
974template<DGtal::Dimension dim, typename TComponent, typename TContainer>
975inline
976double
977DGtal::PointVector<dim, TComponent, TContainer>::norm (
978 const typename Self::NormType aType ) const
979{
980 double tmp = 0.0;
981
982 ASSERT ( dim > 0 );
983
984 switch ( aType )
985 {
986 case L_2:
987 for ( DGtal::Dimension i = 0; i < dimension; i++ )
988 tmp += NumberTraits<Component>::castToDouble(myArray[ i ]) *
989 NumberTraits<Component>::castToDouble(myArray[ i ]);
990 tmp = ( double ) sqrt ( tmp );
991 break;
992 case L_1:
993 for ( DGtal::Dimension i = 0; i < dimension; i++ )
994 tmp += fabs ( NumberTraits<Component>::castToDouble(myArray[ i ] ));
995 break;
996 case L_infty:
997 tmp = fabs( NumberTraits<Component>::castToDouble( myArray[ 0 ]));
998 for ( DGtal::Dimension i = 1; i < dimension; i++ )
999 if ( tmp < fabs ( NumberTraits<Component>::castToDouble(myArray[ i ] ) ))
1000 tmp = fabs ( NumberTraits<Component>::castToDouble(myArray[ i ] ));
1001 break;
1002 }
1003 return tmp;
1004}
1005//------------------------------------------------------------------------------
1006template<DGtal::Dimension dim, typename TComponent, typename TContainer>
1007inline
1008typename DGtal::PointVector<dim, TComponent, TContainer>::UnsignedComponent
1009DGtal::PointVector<dim, TComponent, TContainer>::norm1() const
1010{
1011 ASSERT ( dimension > 0 );
1012 UnsignedComponent val
1013 ( ( myArray[ 0 ] >= 0 ) ? myArray[ 0 ] : UnsignedComponent(-myArray[ 0 ]) );
1014 for ( DGtal::Dimension i = 1; i < dimension; ++i )
1015 val += ( myArray[ i ] >= 0 )
1016 ? myArray[ i ]
1017 : UnsignedComponent(-myArray[ i ]);
1018 return val;
1019}
1020//------------------------------------------------------------------------------
1021template<DGtal::Dimension dim, typename TComponent, typename TContainer>
1022inline
1023typename DGtal::PointVector<dim, TComponent, TContainer>::UnsignedComponent
1024DGtal::PointVector<dim, TComponent, TContainer>::normInfinity() const
1025{
1026 ASSERT ( dimension > 0 );
1027 UnsignedComponent tmp;
1028 UnsignedComponent val( ( myArray[ 0 ] >= 0 ) ? myArray[ 0 ] : -myArray[ 0 ] );
1029 for ( DGtal::Dimension i = 1; i < dimension; ++i )
1030 {
1031 tmp = ( myArray[ i ] >= 0 ) ? myArray[ i ] : -myArray[ i ] ;
1032 if ( tmp > val )
1033 val = tmp;
1034 }
1035 return val;
1036}
1037//------------------------------------------------------------------------------
1038
1039template<DGtal::Dimension dim, typename TComponent, typename TContainer>
1040inline
1041typename DGtal::PointVector<dim, double, std::array<double,dim> >
1042DGtal::PointVector<dim, TComponent, TContainer>::getNormalized() const
1043{
1044 PointVector<dim,double,std::array<double,dim> > normalized(*this);
1045 normalized /= normalized.norm();
1046 return normalized;
1047}
1048//------------------------------------------------------------------------------
1049template<DGtal::Dimension dim, typename TComponent, typename TContainer>
1050inline
1051DGtal::PointVector<dim,TComponent, TContainer>
1052DGtal::PointVector<dim,TComponent, TContainer>::diagonal( Component val )
1053{
1054 Self p;
1055 for ( DGtal::Dimension i = 0; i < dim; ++i )
1056 p.myArray[ i ] = val;
1057 return p;
1058}
1059//------------------------------------------------------------------------------
1060template<DGtal::Dimension dim,typename TComponent, typename TContainer>
1061inline
1062DGtal::PointVector<dim,TComponent, TContainer>
1063DGtal::PointVector<dim,TComponent, TContainer>::base( Dimension k, Component val )
1064{
1065 Self p;
1066 p.myArray[ k ] = val;
1067 return p;
1068}
1069//------------------------------------------------------------------------------
1070template<DGtal::Dimension dim,typename TComponent, typename TContainer>
1071inline
1072void
1073DGtal::PointVector<dim,TComponent, TContainer>::selfDisplay( std::ostream & out ) const
1074{
1075 out << "(";
1076 for (DGtal::Dimension i = 0; i < dimension ; ++i)
1077 out << myArray[ i ] << (i == dimension - 1 ? "" : ", ");
1078 out << ")";
1079}
1080
1081//------------------------------------------------------------------------------
1082template<DGtal::Dimension dim, typename TComponent, typename TContainer>
1083inline
1084std::string
1085DGtal::PointVector<dim, TComponent, TContainer>::className() const
1086{
1087 return "PointVector";
1088}
1089
1090//------------------------------------------------------------------------------
1091template<DGtal::Dimension dim, typename TComponent, typename TContainer>
1092inline
1093std::ostream&
1094DGtal::operator<<( std::ostream & out,
1095 const PointVector<dim, TComponent, TContainer>& object )
1096{
1097 object.selfDisplay( out );
1098 return out;
1099}
1100//------------------------------------------------------------------------------
1101template<DGtal::Dimension dim, typename TComponent, typename TContainer>
1102inline
1103bool
1104DGtal::PointVector<dim, TComponent, TContainer>::isValid() const
1105{
1106 return true;
1107}
1108//------------------------------------------------------------------------------