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