DGtal  0.9.2
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 
42 template<DGtal::Dimension dim, typename Container>
43 inline
44 std::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 //------------------------------------------------------------------------------
56 template<DGtal::Dimension dim, typename Container>
57 inline
58 std::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 
72 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
73 inline
74 DGtal::PointVector<dim, TComponent, TContainer>::PointVector()
75 {
76  for ( Dimension i = 0; i < dim; ++i )
77  myArray[ i ] = NumberTraits<TComponent>::ZERO;
78 }
79 //------------------------------------------------------------------------------
80 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
81 template<typename BinaryFunctor>
82 inline
83 DGtal::PointVector<dim, TComponent, TContainer>::PointVector(const Self& apoint1,
84  const Self& apoint2,
85  const BinaryFunctor& f)
86 {
87  for ( Dimension i = 0; i < dim; ++i )
88  myArray[ i ] = f.operator() (apoint1[i], apoint2[i]);
89 }
90 //------------------------------------------------------------------------------
91 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
92 template<typename UnaryFunctor>
93 inline
94 DGtal::PointVector<dim, TComponent,TContainer>::
95 PointVector(const Self& apoint1,
96  const UnaryFunctor& f)
97 {
98  for ( Dimension i = 0; i < dim; ++i )
99  myArray[ i ] = f.operator()( apoint1[i] );
100 }
101 //------------------------------------------------------------------------------
102 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
103 inline
104 DGtal::PointVector<dim, TComponent, TContainer>::~PointVector()
105 {}
106 //------------------------------------------------------------------------------
107 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
108 inline
109 DGtal::PointVector<dim, TComponent, TContainer>::PointVector( const Component * ptrValues )
110 {
111  // The problem here is that we have no guaranty on the size of init !!
112  for ( Dimension i = 0; i < dim; ++i )
113  myArray[ i ] = ptrValues[ i ];
114 }
115 //------------------------------------------------------------------------------
116 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
117 inline
118 DGtal::PointVector<dim, TComponent, TContainer>::PointVector( const Component & x, const Component & y )
119 {
120  ASSERT( dim >= 2 );
121  myArray[ 0 ] = x;
122  myArray[ 1 ] = y;
123  for ( Dimension i = 2; i < dim; ++i )
124  myArray[ i ] = NumberTraits<TComponent>::ZERO;
125 }
126 //------------------------------------------------------------------------------
127 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
128 inline
129 DGtal::PointVector<dim, TComponent, TContainer>::PointVector( const Component & x,
130  const Component & y,
131  const Component & z )
132 {
133  ASSERT( dim >= 3 );
134  myArray[ 0 ] = x;
135  myArray[ 1 ] = y;
136  myArray[ 2 ] = z;
137  for ( Dimension i = 3; i < dim; ++i )
138  myArray[ i ] = NumberTraits<TComponent>::ZERO;
139 }
140 //------------------------------------------------------------------------------
141 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
142 inline
143 DGtal::PointVector<dim, TComponent, TContainer>::PointVector( const Component & x,
144  const Component & y,
145  const Component & z,
146  const Component & t )
147 {
148  ASSERT( dim >= 4 );
149  myArray[ 0 ] = x;
150  myArray[ 1 ] = y;
151  myArray[ 2 ] = z;
152  myArray[ 3 ] = t;
153  for ( Dimension i = 4; i < dim; ++i )
154  myArray[ i ] = NumberTraits<TComponent>::ZERO;
155 }
156 //------------------------------------------------------------------------------
157 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
158 inline
159 DGtal::PointVector<dim, TComponent, TContainer>::PointVector(std::initializer_list<Component> init)
160 {
161  unsigned int i = 0;
162  for (const Component *p = init.begin (); p != init.end () && i < dim; ++p, ++i)
163  myArray[ i ] = *p;
164  for ( ; i < dim; ++i)
165  myArray[i] = NumberTraits<TComponent>::ZERO;
166 }
167 //------------------------------------------------------------------------------
168 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
169 inline
170 DGtal::PointVector<dim, TComponent, TContainer>::PointVector ( const Self & other )
171  : myArray( other.myArray )
172 {}
173 //------------------------------------------------------------------------------
174 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
175 template<typename OtherComponent, typename OtherCont>
176 inline
177 DGtal::PointVector<dim, TComponent, TContainer>::PointVector (const PointVector<dim,OtherComponent,OtherCont> & other )
178 {
179  for ( DGtal::Dimension i = 0; i < dimension; ++i )
180  this->myArray[ i ] = (int)(static_cast<OtherComponent>(other[ i ]));
181 }
182 //------------------------------------------------------------------------------
183 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
184 inline
185 typename DGtal::PointVector<dim, TComponent, TContainer>::Iterator
186 DGtal::PointVector<dim, TComponent, TContainer>::begin()
187 {
188  return myArray.begin();
189 }
190 //------------------------------------------------------------------------------
191 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
192 inline
193 typename DGtal::PointVector<dim, TComponent, TContainer>::Iterator
194 DGtal::PointVector<dim, TComponent, TContainer>::end()
195 {
196  return myArray.end();
197 }
198 //------------------------------------------------------------------------------
199 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
200 inline
201 typename DGtal::PointVector<dim, TComponent, TContainer>::ConstIterator
202 DGtal::PointVector<dim, TComponent, TContainer>::begin() const
203 {
204  return myArray.begin();
205 }
206 //------------------------------------------------------------------------------
207 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
208 inline
209 typename DGtal::PointVector<dim, TComponent, TContainer>::ConstIterator
210 DGtal::PointVector<dim, TComponent, TContainer>::end() const
211 {
212  return myArray.end();
213 }
214 //------------------------------------------------------------------------------
215 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
216 inline
217 typename DGtal::PointVector<dim, TComponent, TContainer>::ReverseIterator
218 DGtal::PointVector<dim, TComponent, TContainer>::rbegin()
219 {
220  return myArray.rbegin();
221 }
222 //------------------------------------------------------------------------------
223 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
224 inline
225 typename DGtal::PointVector<dim, TComponent, TContainer>::ReverseIterator
226 DGtal::PointVector<dim, TComponent, TContainer>::rend()
227 {
228  return myArray.rend();
229 }
230 //------------------------------------------------------------------------------
231 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
232 inline
233 typename DGtal::PointVector<dim, TComponent, TContainer>::ConstReverseIterator
234 DGtal::PointVector<dim, TComponent, TContainer>::rbegin() const
235 {
236  return myArray.rbegin();
237 }
238 //------------------------------------------------------------------------------
239 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
240 inline
241 typename DGtal::PointVector<dim, TComponent, TContainer>::ConstReverseIterator
242 DGtal::PointVector<dim, TComponent, TContainer>::rend() const
243 {
244  return myArray.rend();
245 }
246 //------------------------------------------------------------------------------
247 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
248 inline
249 typename DGtal::Dimension
250 DGtal::PointVector<dim, TComponent, TContainer>::size()
251 {
252  return dim;
253 }
254 //------------------------------------------------------------------------------
255 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
256 inline
257 const typename DGtal::PointVector<dim, TComponent, TContainer>::Component &
258 DGtal::PointVector<dim, TComponent, TContainer>::operator[]( Dimension i ) const
259 {
260  ASSERT ( i < dim );
261  return myArray[i];
262 }
263 //------------------------------------------------------------------------------
264 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
265 inline
266 typename DGtal::PointVector<dim, TComponent, TContainer>::Component &
267 DGtal::PointVector<dim, TComponent, TContainer>::operator[]( Dimension i )
268 {
269  ASSERT ( i < dim );
270  return myArray[i];
271 }
272 //------------------------------------------------------------------------------
273 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
274 DGtal::PointVector<dim, TComponent, TContainer>&
275 DGtal::PointVector<dim, TComponent, TContainer>::operator*= ( Component coeff )
276 {
277  for ( DGtal::Dimension i = 0; i < myArray.size(); ++i )
278  myArray[ i ] *= coeff;
279  return *this;
280 }
281 //------------------------------------------------------------------------------
282 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
283 DGtal::PointVector<dim, TComponent, TContainer>
284 DGtal::PointVector<dim, TComponent, TContainer>::operator* ( Component coeff ) const
285 {
286  Self v = *this;
287  v *= coeff;
288  return v;
289 }
290 //------------------------------------------------------------------------------
291 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
292 inline
293 DGtal::PointVector<dim, TComponent, TContainer>
294 DGtal::operator*( TComponent coeff,
295  const PointVector<dim, TComponent,TContainer> & aVector )
296 {
297  return PointVector<dim, TComponent,TContainer>
298  ( aVector, functors::MultiplicationByScalar<TComponent>( coeff ) );
299 }
300 //------------------------------------------------------------------------------
301 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
302 inline
303 DGtal::PointVector<dim, TComponent, TContainer>&
304 DGtal::PointVector<dim, TComponent, TContainer>::operator= ( const Self & pv )
305 {
306  myArray = pv.myArray;
307  return *this;
308 }
309 //------------------------------------------------------------------------------
310 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
311 template<typename Component2>
312 inline
313 DGtal::PointVector<dim,TComponent, TContainer>&
314 DGtal::PointVector<dim, TComponent, TContainer>::operator= ( const DGtal::PointVector<dim,Component2,TContainer> & v )
315 {
316  for ( DGtal::Dimension i = 0; i < dimension; ++i )
317  {
318  this->myArray[ i ] = static_cast<Component>(v[ i ]);
319  }
320  return *this;
321 }
322 //------------------------------------------------------------------------------
323 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
324 inline
325 DGtal::PointVector<dim, TComponent, TContainer>&
326 DGtal::PointVector<dim, TComponent, TContainer>::partialCopy
327  ( const Self & pv,
328  std::initializer_list<DGtal::Dimension> dimensions )
329 {
330  std::vector<DGtal::Dimension> dims;
331  dims.reserve(dimensions.size());
332  for (const DGtal::Dimension *c = dimensions.begin (); c != dimensions.end (); ++c)
333  dims.push_back(*c);
334  return partialCopy(pv, dims);
335 }
336 //------------------------------------------------------------------------------
337 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
338 inline
339 DGtal::PointVector<dim, TComponent, TContainer>&
340 DGtal::PointVector<dim, TComponent, TContainer>::partialCopyInv
341 ( const Self & pv,
342  std::initializer_list<DGtal::Dimension> dimensions )
343 {
344  std::vector<DGtal::Dimension> dims;
345  dims.reserve(dimensions.size());
346  for (const DGtal::Dimension *c = dimensions.begin (); c != dimensions.end (); ++c)
347  dims.push_back(*c);
348  return partialCopyInv(pv, dims);
349 }
350 //------------------------------------------------------------------------------
351 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
352 inline
353 DGtal::PointVector<dim, TComponent, TContainer>&
354 DGtal::PointVector<dim, TComponent, TContainer>::partialCopy
355 ( const Self & pv,
356  const std::vector<DGtal::Dimension> &dimensions)
357 {
358  std::bitset<dim> dims = setDimensionsIn<dim>(dimensions);
359  for ( DGtal::Dimension i = 0; i < dim; ++i )
360  {
361  if ( dims.test(i) ) myArray[i] = pv.myArray[i];
362  }
363  return *this;
364 }
365 //------------------------------------------------------------------------------
366 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
367 inline
368 DGtal::PointVector<dim, TComponent, TContainer>&
369 DGtal::PointVector<dim, TComponent, TContainer>::partialCopyInv
370 ( const Self & pv,
371  const std::vector<DGtal::Dimension> &dimensions)
372 {
373  std::bitset<dim> dims = setDimensionsIn<dim>(dimensions);
374  for ( DGtal::Dimension i = 0; i < dim; ++i )
375  {
376  if ( !dims.test(i) ) myArray[i] = pv.myArray[i];
377  }
378  return *this;
379 }
380 //------------------------------------------------------------------------------
381 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
382 inline
383 bool
384 DGtal::PointVector<dim, TComponent, TContainer>::partialEqual
385 ( const Self & pv,
386  const std::vector<DGtal::Dimension> &dimensions ) const
387 {
388  std::bitset<dim> dims = setDimensionsIn<dim>(dimensions);
389  for ( DGtal::Dimension i = 0; i < dim; ++i )
390  {
391  if ( dims.test(i) && myArray[i] != pv.myArray[i]) return false;
392  }
393  return true;
394 }
395 //------------------------------------------------------------------------------
396 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
397 inline
398 bool
399 DGtal::PointVector<dim, TComponent, TContainer>::partialEqualInv
400 ( const Self & pv,
401  const std::vector<DGtal::Dimension> &dimensions ) const
402 {
403  std::bitset<dim> dims = setDimensionsIn<dim>(dimensions);
404  for ( DGtal::Dimension i = 0; i < dim; ++i )
405  {
406  if ( !dims.test(i) && myArray[i] != pv.myArray[i]) return false;
407  }
408  return true;
409 }
410 //------------------------------------------------------------------------------
411 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
412 inline
413 bool
414 DGtal::PointVector<dim, TComponent, TContainer>::operator==( const Self & pv ) const
415 {
416  return (myArray == pv.myArray);
417 }
418 //------------------------------------------------------------------------------
419 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
420 inline
421 bool
422 DGtal::PointVector<dim, TComponent, TContainer>::operator!= ( const Self & pv ) const
423 {
424  return (myArray != pv.myArray);
425 }
426 //------------------------------------------------------------------------------
427 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
428 inline
429 bool
430 DGtal::PointVector<dim, TComponent, TContainer>::operator< ( const Self & pv ) const
431 {
432  return (myArray < pv.myArray);
433 }
434 //------------------------------------------------------------------------------
435 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
436 inline
437 bool
438 DGtal::PointVector<dim, TComponent, TContainer>::operator<= ( const Self & pv ) const
439 {
440  return (myArray <= pv.myArray);
441 }
442 //------------------------------------------------------------------------------
443 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
444 inline
445 bool
446 DGtal::PointVector<dim, TComponent, TContainer>::operator> ( const Self & pv ) const
447 {
448  return (myArray > pv.myArray);
449 }
450 //------------------------------------------------------------------------------
451 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
452 inline
453 bool
454 DGtal::PointVector<dim, TComponent, TContainer>::operator>= ( const Self & pv ) const
455 {
456  return (myArray >= pv.myArray);
457 }
458 //------------------------------------------------------------------------------
459 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
460 inline
461 DGtal::PointVector<dim, TComponent, TContainer>&
462 DGtal::PointVector<dim, TComponent, TContainer>::operator+= ( const Self& v )
463 {
464  for ( DGtal::Dimension i = 0; i < dim; ++i )
465  this->myArray[ i ] += v[ i ];
466  return *this;
467 }
468 //------------------------------------------------------------------------------
469 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
470 inline
471 DGtal::PointVector<dim, TComponent, TContainer>
472 DGtal::PointVector<dim, TComponent, TContainer>::operator+ ( const Self& v ) const
473 {
474  return Self(*this, v, std::plus<Component>());
475 }
476 //------------------------------------------------------------------------------
477 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
478 inline
479 DGtal::PointVector<dim, TComponent, TContainer>&
480 DGtal::PointVector<dim, TComponent, TContainer>::operator-= ( const Self& v )
481 {
482  for ( DGtal::Dimension i = 0; i < dim; ++i )
483  this->myArray[ i ] -= v[ i ];
484  return *this;
485 }
486 //------------------------------------------------------------------------------
487 template<DGtal::Dimension dim,typename TComponent, typename TContainer>
488 inline
489 DGtal::PointVector<dim,TComponent, TContainer>&
490 DGtal::PointVector<dim,TComponent, TContainer>::operator/= ( const Self& v )
491 {
492  for ( DGtal::Dimension i = 0; i < dim; ++i )
493  this->myArray[ i ] /= v[ i ];
494  return *this;
495 }
496 //------------------------------------------------------------------------------
497 template<DGtal::Dimension dim,typename TComponent, typename TContainer>
498 inline
499 DGtal::PointVector<dim,TComponent, TContainer>
500 DGtal::PointVector<dim,TComponent, TContainer>::operator/ ( const Self& v ) const
501 {
502  return Self(*this, v, std::divides<Component>());
503 }
504 //------------------------------------------------------------------------------
505 template<DGtal::Dimension dim,typename TComponent, typename TContainer>
506 inline
507 DGtal::PointVector<dim,TComponent, TContainer> &
508 DGtal::PointVector<dim,TComponent, TContainer>::operator/= ( const Component coeff )
509 {
510  for ( DGtal::Dimension i = 0; i < dimension; ++i )
511  this->myArray[ i ] /= coeff;
512  return *this;
513 }
514 //------------------------------------------------------------------------------
515 template<DGtal::Dimension dim,typename TComponent, typename TContainer>
516 inline
517 DGtal::PointVector<dim,TComponent, TContainer>
518 DGtal::PointVector<dim,TComponent, TContainer>::operator/ ( const Component coeff ) const
519 {
520  Self p;
521  for ( DGtal::Dimension i = 0; i < dimension; ++i )
522  p[i] = this->myArray[ i ] / coeff;
523  return p;
524 }
525 //------------------------------------------------------------------------------
526 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
527 inline
528 typename DGtal::PointVector<dim, TComponent, TContainer>::Component
529 DGtal::PointVector<dim, TComponent, TContainer>::dot( const Self& v ) const
530 {
531  Component dotprod= NumberTraits<Component>::ZERO;
532  for ( DGtal::Dimension i = 0; i < dim; ++i )
533  dotprod += this->myArray[ i ]*v[ i ];
534  return dotprod;
535 }
536 //------------------------------------------------------------------------------
537 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
538 inline
539 double
540 DGtal::PointVector<dim, TComponent, TContainer>::cosineSimilarity( const Self& v ) const
541 {
542  double angle = std::acos ( this->dot ( v ) / ( this->norm() * v.norm() ) );
543  if ( std::isnan ( angle ) )
544  angle = 0.0;
545  return angle;
546 }
547 //------------------------------------------------------------------------------
548 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
549 inline
550 typename DGtal::PointVector<dim, TComponent, TContainer>
551 DGtal::PointVector<dim, TComponent, TContainer>::crossProduct( const Self& v ) const
552 {
553  Self crossprod;
554  for ( DGtal::Dimension i = 0; i < dim; ++i )
555  crossprod[i] = this->myArray[ (i+1)%dim ]*v[ (i+2)%dim ] -
556  this->myArray[ (i+2)%dim ]*v[ (i+1)%dim ];
557  return crossprod;
558 }
559 //------------------------------------------------------------------------------
560 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
561 inline
562 DGtal::PointVector<dim, TComponent, TContainer>
563 DGtal::PointVector<dim, TComponent, TContainer>::operator- ( const Self& v ) const
564 {
565  return Self(*this, v, functors::Minus<Component>());
566 }
567 //------------------------------------------------------------------------------
568 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
569 inline
570 DGtal::PointVector<dim, TComponent,TContainer>
571 DGtal::PointVector<dim, TComponent,TContainer>::operator-() const
572 {
573  return Self(*this, functors::UnaryMinus<Component>());
574 }
575 //------------------------------------------------------------------------------
576 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
577 inline
578 void
579 DGtal::PointVector<dim, TComponent, TContainer>::reset()
580 {
581  for ( DGtal::Dimension i = 0; i < myArray.size(); ++i )
582  myArray[ i ] = NumberTraits< Component >::ZERO;
583 }
584 //------------------------------------------------------------------------------
585 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
586 inline
587 DGtal::PointVector<dim, TComponent, TContainer>
588 DGtal::PointVector<dim, TComponent, TContainer>::inf( const Self& apoint ) const
589 {
590  return Self(*this, apoint, functors::Min<Component>());
591 }
592 //------------------------------------------------------------------------------
593 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
594 inline
595 DGtal::PointVector<dim, TComponent, TContainer>
596 DGtal::PointVector<dim, TComponent, TContainer>::sup( const Self& apoint ) const
597 {
598  return Self(*this, apoint, functors::Max<Component>());
599 }
600 //------------------------------------------------------------------------------
601 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
602 inline
603 bool
604 DGtal::PointVector<dim, TComponent, TContainer>::isLower( const Self& p ) const
605 {
606  for ( DGtal::Dimension i = 0; i < myArray.size(); ++i )
607  if ( p[ i ] < myArray[ i ] )
608  return false;
609  return true;
610 }
611 //------------------------------------------------------------------------------
612 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
613 inline
614 bool
615 DGtal::PointVector<dim, TComponent, TContainer>::isUpper( const Self& p ) const
616 {
617  for ( DGtal::Dimension i = 0; i < myArray.size(); ++i )
618  if ( p[ i ] > myArray[ i ] )
619  return false;
620  return true;
621 }
622 //------------------------------------------------------------------------------
623 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
624 inline
625 typename DGtal::PointVector<dim, TComponent, TContainer>::Component
626 DGtal::PointVector<dim, TComponent, TContainer>::max( ) const
627 {
628  return *std::max_element(this->begin(), this->end());
629 }
630 //------------------------------------------------------------------------------
631 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
632 inline
633 typename DGtal::PointVector<dim, TComponent, TContainer>::Component
634 DGtal::PointVector<dim, TComponent, TContainer>::min( ) const
635 {
636  return *std::min_element(this->begin(), this->end());
637 }
638 //------------------------------------------------------------------------------
639 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
640 inline
641 typename DGtal::PointVector<dim, TComponent, TContainer>::Iterator
642 DGtal::PointVector<dim, TComponent, TContainer>::maxElement( )
643 {
644  return std::max_element(this->begin(), this->end());
645 }
646 //------------------------------------------------------------------------------
647 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
648 inline
649 typename DGtal::PointVector<dim, TComponent, TContainer>::Iterator
650 DGtal::PointVector<dim, TComponent, TContainer>::minElement( )
651 {
652  return std::min_element(this->begin(), this->end());
653 }
654 //------------------------------------------------------------------------------
655 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
656 inline
657 void
658 DGtal::PointVector<dim, TComponent, TContainer>::
659 negate()
660 {
661  for ( DGtal::Dimension i = 0; i < dimension; ++i )
662  this->myArray[ i ] = - this->myArray[ i ];
663 }
664 //------------------------------------------------------------------------------
665 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
666 inline
667 double
668 DGtal::PointVector<dim, TComponent, TContainer>::norm (const
669  typename Self::NormType aType ) const
670 {
671  double tmp = 0.0;
672 
673  ASSERT ( dim > 0 );
674 
675  switch ( aType )
676  {
677  case L_2:
678  for ( DGtal::Dimension i = 0; i < dimension; i++ )
679  tmp += NumberTraits<Component>::castToDouble(myArray[ i ]) *
680  NumberTraits<Component>::castToDouble(myArray[ i ]);
681  tmp = ( double ) sqrt ( tmp );
682  break;
683  case L_1:
684  for ( DGtal::Dimension i = 0; i < dimension; i++ )
685  tmp += fabs ( NumberTraits<Component>::castToDouble(myArray[ i ] ));
686  break;
687  case L_infty:
688  tmp = fabs( NumberTraits<Component>::castToDouble( myArray[ 0 ]));
689  for ( DGtal::Dimension i = 1; i < dimension; i++ )
690  if ( tmp < fabs ( NumberTraits<Component>::castToDouble(myArray[ i ] ) ))
691  tmp = fabs ( NumberTraits<Component>::castToDouble(myArray[ i ] ));
692  break;
693  }
694  return tmp;
695 }
696 //------------------------------------------------------------------------------
697 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
698 inline
699 typename DGtal::PointVector<dim, TComponent, TContainer>::UnsignedComponent
700 DGtal::PointVector<dim, TComponent, TContainer>::norm1() const
701 {
702  ASSERT ( dimension > 0 );
703  UnsignedComponent val
704  ( ( myArray[ 0 ] >= 0 ) ? myArray[ 0 ] : UnsignedComponent(-myArray[ 0 ]) );
705  for ( DGtal::Dimension i = 1; i < dimension; ++i )
706  val += ( myArray[ i ] >= 0 )
707  ? myArray[ i ]
708  : UnsignedComponent(-myArray[ i ]);
709  return val;
710 }
711 //------------------------------------------------------------------------------
712 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
713 inline
714 typename DGtal::PointVector<dim, TComponent, TContainer>::UnsignedComponent
715 DGtal::PointVector<dim, TComponent, TContainer>::normInfinity() const
716 {
717  ASSERT ( dimension > 0 );
718  UnsignedComponent tmp;
719  UnsignedComponent val( ( myArray[ 0 ] >= 0 ) ? myArray[ 0 ] : -myArray[ 0 ] );
720  for ( DGtal::Dimension i = 1; i < dimension; ++i )
721  {
722  tmp = ( myArray[ i ] >= 0 ) ? myArray[ i ] : -myArray[ i ] ;
723  if ( tmp > val )
724  val = tmp;
725  }
726  return val;
727 }
728 //------------------------------------------------------------------------------
729 
730 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
731 inline
732 typename DGtal::PointVector<dim, double, std::array<double,dim> >
733 DGtal::PointVector<dim, TComponent, TContainer>::getNormalized() const
734 {
735  PointVector<dim,double,std::array<double,dim> > normalized =(*this);
736  normalized /= normalized.norm();
737  return normalized;
738 }
739 //------------------------------------------------------------------------------
740 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
741 inline
742 DGtal::PointVector<dim,TComponent, TContainer>
743 DGtal::PointVector<dim,TComponent, TContainer>::diagonal( Component val )
744 {
745  Self p;
746  for ( DGtal::Dimension i = 0; i < dim; ++i )
747  p.myArray[ i ] = val;
748  return p;
749 }
750 //------------------------------------------------------------------------------
751 template<DGtal::Dimension dim,typename TComponent, typename TContainer>
752 inline
753 DGtal::PointVector<dim,TComponent, TContainer>
754 DGtal::PointVector<dim,TComponent, TContainer>::base( Dimension k, Component val )
755 {
756  Self p;
757  p.myArray[ k ] = val;
758  return p;
759 }
760 //------------------------------------------------------------------------------
761 template<DGtal::Dimension dim,typename TComponent, typename TContainer>
762 inline
763 void
764 DGtal::PointVector<dim,TComponent, TContainer>::selfDisplay( std::ostream & out ) const
765 {
766  out << "[PointVector] {";
767  for (DGtal::Dimension i = 0; i < dimension ; ++i)
768  out << myArray[ i ] << (i == dimension - 1 ? "" : ", ");
769  out << "}";
770 }
771 
772 //------------------------------------------------------------------------------
773 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
774 inline
775 std::string
776 DGtal::PointVector<dim, TComponent, TContainer>::className() const
777 {
778  return "PointVector";
779 }
780 
781 //------------------------------------------------------------------------------
782 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
783 inline
784 std::ostream&
785 DGtal::operator<<( std::ostream & out,
786  const PointVector<dim, TComponent, TContainer>& object )
787 {
788  object.selfDisplay( out );
789  return out;
790 }
791 //------------------------------------------------------------------------------
792 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
793 inline
794 bool
795 DGtal::PointVector<dim, TComponent, TContainer>::isValid() const
796 {
797  return true;
798 }
799 //------------------------------------------------------------------------------