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