2 * This program is free software: you can redistribute it and/or modify
3 * it under the terms of the GNU Lesser General Public License as
4 * published by the Free Software Foundation, either version 3 of the
5 * License, or (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 * @file 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
25 * Implementation of inline methods defined in PointVector.h
27 * This file is part of the DGtal library.
30 ///////////////////////////////////////////////////////////////////////////////
31 // IMPLEMENTATION of inline methods.
32 ///////////////////////////////////////////////////////////////////////////////
34 //////////////////////////////////////////////////////////////////////////////
37 #include <DGtal/base/BasicFunctors.h>
38 #include "DGtal/io/Color.h"
39 //////////////////////////////////////////////////////////////////////////////
42 template<DGtal::Dimension dim, typename Container>
44 std::bitset<dim> DGtal::setDimensionsIn( const Container &dimensions )
47 for ( typename Container::const_iterator it=dimensions.begin();
48 it!=dimensions.end(); ++it )
55 //------------------------------------------------------------------------------
56 template<DGtal::Dimension dim, typename Container>
58 std::bitset<dim> DGtal::setDimensionsNotIn( const Container &dimensions )
60 std::bitset<dim> t1; t1.set();
61 for ( typename Container::const_iterator it=dimensions.begin();
62 it!=dimensions.end(); ++it )
69 //------------------------------------------------------------------------------
72 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
74 DGtal::PointVector<dim, TComponent, TContainer>::PointVector()
76 for ( Dimension i = 0; i < dim; ++i )
77 myArray[ i ] = NumberTraits<TComponent>::ZERO;
79 //------------------------------------------------------------------------------
80 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
82 typename LeftComponent, typename LeftStorage,
83 typename RightComponent, typename RightStorage,
84 typename BinaryFunctor >
86 DGtal::PointVector<dim, TComponent, TContainer>::PointVector(
87 const PointVector<dim, LeftComponent, LeftStorage> & apoint1,
88 const PointVector<dim, RightComponent, RightStorage> & apoint2,
89 const BinaryFunctor & f)
91 for ( Dimension i = 0; i < dim; ++i )
92 myArray[ i ] = static_cast<TComponent>( f(apoint1[i], apoint2[i]) );
94 //------------------------------------------------------------------------------
95 template <DGtal::Dimension dim, typename TComponent, typename TContainer>
96 template <typename OtherComponent, typename OtherStorage, typename UnaryFunctor>
98 DGtal::PointVector<dim, TComponent,TContainer>::
99 PointVector(const PointVector<dim, OtherComponent, OtherStorage> & apoint1,
100 const UnaryFunctor& f)
102 for ( Dimension i = 0; i < dim; ++i )
103 myArray[ i ] = static_cast<TComponent>( f( apoint1[i] ) );
105 //------------------------------------------------------------------------------
106 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
108 DGtal::PointVector<dim, TComponent, TContainer>::~PointVector()
110 //------------------------------------------------------------------------------
111 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
113 DGtal::PointVector<dim, TComponent, TContainer>::PointVector( const Component * ptrValues )
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 ];
119 //------------------------------------------------------------------------------
120 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
122 DGtal::PointVector<dim, TComponent, TContainer>::PointVector( const Component & x, const Component & y )
127 for ( Dimension i = 2; i < dim; ++i )
128 myArray[ i ] = NumberTraits<TComponent>::ZERO;
130 //------------------------------------------------------------------------------
131 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
133 DGtal::PointVector<dim, TComponent, TContainer>::PointVector( const Component & x,
135 const Component & z )
141 for ( Dimension i = 3; i < dim; ++i )
142 myArray[ i ] = NumberTraits<TComponent>::ZERO;
144 //------------------------------------------------------------------------------
145 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
147 DGtal::PointVector<dim, TComponent, TContainer>::PointVector( const Component & x,
150 const Component & t )
157 for ( Dimension i = 4; i < dim; ++i )
158 myArray[ i ] = NumberTraits<TComponent>::ZERO;
160 //------------------------------------------------------------------------------
161 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
163 DGtal::PointVector<dim, TComponent, TContainer>::PointVector(std::initializer_list<Component> init)
166 for (const Component *p = init.begin (); p != init.end () && i < dim; ++p, ++i)
168 for ( ; i < dim; ++i)
169 myArray[i] = NumberTraits<TComponent>::ZERO;
171 //------------------------------------------------------------------------------
172 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
174 DGtal::PointVector<dim, TComponent, TContainer>::PointVector ( const Self & other )
175 : myArray( other.myArray )
177 //------------------------------------------------------------------------------
178 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
180 typename OtherComponent, typename OtherCont,
181 typename std::enable_if< std::is_same< TComponent, DGtal::ArithmeticConversionType<TComponent, OtherComponent> >::value, int >::type >
183 DGtal::PointVector<dim, TComponent, TContainer>::PointVector (const PointVector<dim,OtherComponent,OtherCont> & other )
185 for ( DGtal::Dimension i = 0; i < dimension; ++i )
186 this->myArray[ i ] = static_cast<TComponent>(other[ i ]);
188 //------------------------------------------------------------------------------
189 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
191 typename OtherComponent, typename OtherCont,
192 typename std::enable_if< ! std::is_same< TComponent, DGtal::ArithmeticConversionType<TComponent, OtherComponent> >::value, int >::type >
194 DGtal::PointVector<dim, TComponent, TContainer>::PointVector (const PointVector<dim,OtherComponent,OtherCont> & other )
196 for ( DGtal::Dimension i = 0; i < dimension; ++i )
197 this->myArray[ i ] = static_cast<TComponent>(other[ i ]);
199 //------------------------------------------------------------------------------
200 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
202 typename DGtal::PointVector<dim, TComponent, TContainer>::Iterator
203 DGtal::PointVector<dim, TComponent, TContainer>::begin()
205 return myArray.begin();
207 //------------------------------------------------------------------------------
208 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
210 typename DGtal::PointVector<dim, TComponent, TContainer>::Iterator
211 DGtal::PointVector<dim, TComponent, TContainer>::end()
213 return myArray.end();
215 //------------------------------------------------------------------------------
216 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
218 typename DGtal::PointVector<dim, TComponent, TContainer>::ConstIterator
219 DGtal::PointVector<dim, TComponent, TContainer>::begin() const
221 return myArray.begin();
223 //------------------------------------------------------------------------------
224 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
226 typename DGtal::PointVector<dim, TComponent, TContainer>::ConstIterator
227 DGtal::PointVector<dim, TComponent, TContainer>::end() const
229 return myArray.end();
231 //------------------------------------------------------------------------------
232 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
234 typename DGtal::PointVector<dim, TComponent, TContainer>::ReverseIterator
235 DGtal::PointVector<dim, TComponent, TContainer>::rbegin()
237 return myArray.rbegin();
239 //------------------------------------------------------------------------------
240 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
242 typename DGtal::PointVector<dim, TComponent, TContainer>::ReverseIterator
243 DGtal::PointVector<dim, TComponent, TContainer>::rend()
245 return myArray.rend();
247 //------------------------------------------------------------------------------
248 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
250 typename DGtal::PointVector<dim, TComponent, TContainer>::ConstReverseIterator
251 DGtal::PointVector<dim, TComponent, TContainer>::rbegin() const
253 return myArray.rbegin();
255 //------------------------------------------------------------------------------
256 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
258 typename DGtal::PointVector<dim, TComponent, TContainer>::ConstReverseIterator
259 DGtal::PointVector<dim, TComponent, TContainer>::rend() const
261 return myArray.rend();
263 //------------------------------------------------------------------------------
264 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
266 typename DGtal::Dimension
267 DGtal::PointVector<dim, TComponent, TContainer>::size()
271 //------------------------------------------------------------------------------
272 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
274 const typename DGtal::PointVector<dim, TComponent, TContainer>::Component *
275 DGtal::PointVector<dim, TComponent, TContainer>::data() const noexcept
277 return myArray.data();
279 //------------------------------------------------------------------------------
280 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
282 typename DGtal::PointVector<dim, TComponent, TContainer>::Component *
283 DGtal::PointVector<dim, TComponent, TContainer>::data() noexcept
285 return myArray.data();
287 //------------------------------------------------------------------------------
288 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
290 const typename DGtal::PointVector<dim, TComponent, TContainer>::Component &
291 DGtal::PointVector<dim, TComponent, TContainer>::operator[]( Dimension i ) const
296 //------------------------------------------------------------------------------
297 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
299 typename DGtal::PointVector<dim, TComponent, TContainer>::Component &
300 DGtal::PointVector<dim, TComponent, TContainer>::operator[]( Dimension i )
305 //------------------------------------------------------------------------------
306 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
308 DGtal::PointVector<dim, TComponent, TContainer>&
309 DGtal::PointVector<dim, TComponent, TContainer>::operator= ( const Self & pv )
311 myArray = pv.myArray;
314 //------------------------------------------------------------------------------
315 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
317 typename OtherComponent,
318 typename OtherContainer,
319 typename std::enable_if< std::is_same< TComponent, DGtal::ArithmeticConversionType<TComponent, OtherComponent> >::value, int >::type>
321 DGtal::PointVector<dim, TComponent, TContainer> &
322 DGtal::PointVector<dim, TComponent, TContainer>::operator= ( const DGtal::PointVector<dim, OtherComponent, OtherContainer> & v )
324 for ( DGtal::Dimension i = 0; i < dimension; ++i )
326 this->myArray[ i ] = static_cast<Component>( v[ i ] );
330 //------------------------------------------------------------------------------
331 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
333 typename OtherComponent,
334 typename OtherContainer,
335 typename std::enable_if< std::is_same< TComponent, DGtal::ArithmeticConversionType<TComponent, OtherComponent> >::value, int >::type>
337 DGtal::PointVector<dim, TComponent, TContainer>&
338 DGtal::PointVector<dim, TComponent, TContainer>::partialCopy
339 ( const DGtal::PointVector<dim, OtherComponent, OtherContainer> & pv,
340 const std::vector<DGtal::Dimension> &dimensions)
342 std::bitset<dim> dims = setDimensionsIn<dim>(dimensions);
343 for ( DGtal::Dimension i = 0; i < dim; ++i )
345 if ( dims.test(i) ) myArray[i] = static_cast<TComponent>(pv.myArray[i]);
349 //------------------------------------------------------------------------------
350 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
352 typename OtherComponent,
353 typename OtherContainer,
354 typename std::enable_if< std::is_same< TComponent, DGtal::ArithmeticConversionType<TComponent, OtherComponent> >::value, int >::type>
356 DGtal::PointVector<dim, TComponent, TContainer>&
357 DGtal::PointVector<dim, TComponent, TContainer>::partialCopyInv
358 ( const DGtal::PointVector<dim, OtherComponent, OtherContainer> & pv,
359 const std::vector<DGtal::Dimension> &dimensions)
361 std::bitset<dim> dims = setDimensionsIn<dim>(dimensions);
362 for ( DGtal::Dimension i = 0; i < dim; ++i )
364 if ( !dims.test(i) ) myArray[i] = static_cast<TComponent>(pv.myArray[i]);
368 //------------------------------------------------------------------------------
369 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
371 typename OtherComponent,
372 typename OtherContainer,
373 typename UnaryFunctor >
375 DGtal::PointVector<dim, TComponent, TContainer>&
376 DGtal::PointVector<dim, TComponent, TContainer>::partialCopy
377 ( const DGtal::PointVector<dim, OtherComponent, OtherContainer> & pv,
378 const std::vector<DGtal::Dimension> &dimensions,
379 const UnaryFunctor &f)
381 std::bitset<dim> dims = setDimensionsIn<dim>(dimensions);
382 for ( DGtal::Dimension i = 0; i < dim; ++i )
384 if ( dims.test(i) ) myArray[i] = static_cast<TComponent>(f(pv.myArray[i]));
388 //------------------------------------------------------------------------------
389 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
391 typename OtherComponent,
392 typename OtherContainer,
393 typename UnaryFunctor >
395 DGtal::PointVector<dim, TComponent, TContainer>&
396 DGtal::PointVector<dim, TComponent, TContainer>::partialCopyInv
397 ( const DGtal::PointVector<dim, OtherComponent, OtherContainer> & pv,
398 const std::vector<DGtal::Dimension> &dimensions,
399 const UnaryFunctor &f)
401 std::bitset<dim> dims = setDimensionsIn<dim>(dimensions);
402 for ( DGtal::Dimension i = 0; i < dim; ++i )
404 if ( !dims.test(i) ) myArray[i] = static_cast<TComponent>(f(pv.myArray[i]));
408 //------------------------------------------------------------------------------
409 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
410 template <typename TOtherComponent, typename TOtherContainer>
413 DGtal::PointVector<dim, TComponent, TContainer>::partialEqual
414 ( const DGtal::PointVector<dim, TOtherComponent, TOtherContainer> & pv,
415 const std::vector<DGtal::Dimension> &dimensions ) const
417 std::bitset<dim> dims = setDimensionsIn<dim>(dimensions);
418 for ( DGtal::Dimension i = 0; i < dim; ++i )
420 if ( dims.test(i) && myArray[i] != pv.myArray[i]) return false;
424 //------------------------------------------------------------------------------
425 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
426 template <typename TOtherComponent, typename TOtherContainer>
429 DGtal::PointVector<dim, TComponent, TContainer>::partialEqualInv
430 ( const DGtal::PointVector<dim, TOtherComponent, TOtherContainer> & pv,
431 const std::vector<DGtal::Dimension> &dimensions ) const
433 std::bitset<dim> dims = setDimensionsIn<dim>(dimensions);
434 for ( DGtal::Dimension i = 0; i < dim; ++i )
436 if ( !dims.test(i) && myArray[i] != pv.myArray[i]) return false;
440 //------------------------------------------------------------------------------
441 template < DGtal::Dimension ptDim,
442 typename LeftEuclideanRing, typename LeftContainer,
443 typename RightEuclideanRing, typename RightContainer >
445 DGtal::operator== ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
446 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
448 return std::equal( lhs.begin(), lhs.end(), rhs.begin() );
450 //------------------------------------------------------------------------------
451 template < DGtal::Dimension ptDim,
452 typename LeftEuclideanRing, typename LeftContainer,
453 typename RightEuclideanRing, typename RightContainer >
455 DGtal::operator!= ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
456 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
458 return ! (lhs == rhs);
460 //------------------------------------------------------------------------------
461 template < DGtal::Dimension ptDim,
462 typename LeftEuclideanRing, typename LeftContainer,
463 typename RightEuclideanRing, typename RightContainer >
465 DGtal::operator< ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
466 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
468 return std::lexicographical_compare( lhs.begin(), lhs.end(), rhs.begin(), rhs.end() );
470 //------------------------------------------------------------------------------
471 template < DGtal::Dimension ptDim,
472 typename LeftEuclideanRing, typename LeftContainer,
473 typename RightEuclideanRing, typename RightContainer >
475 DGtal::operator> ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
476 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
480 //------------------------------------------------------------------------------
481 template < DGtal::Dimension ptDim,
482 typename LeftEuclideanRing, typename LeftContainer,
483 typename RightEuclideanRing, typename RightContainer >
485 DGtal::operator<= ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
486 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
488 return ! ( lhs > rhs );
490 //------------------------------------------------------------------------------
491 template < DGtal::Dimension ptDim,
492 typename LeftEuclideanRing, typename LeftContainer,
493 typename RightEuclideanRing, typename RightContainer >
495 DGtal::operator>= ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
496 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
498 return ! ( lhs < rhs );
500 //------------------------------------------------------------------------------
501 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
503 typename OtherComponent, typename OtherStorage,
504 typename std::enable_if< std::is_same< TComponent, DGtal::ArithmeticConversionType<TComponent, OtherComponent> >::value, int >::type >
506 DGtal::PointVector<dim, TComponent, TContainer>&
507 DGtal::PointVector<dim, TComponent, TContainer>::operator+= ( PointVector<dim, OtherComponent, OtherStorage> const& v )
509 for ( DGtal::Dimension i = 0; i < dim; ++i )
510 this->myArray[ i ] += v[ i ];
513 //------------------------------------------------------------------------------
514 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
516 typename OtherComponent,
517 typename std::enable_if< std::is_same< TComponent, DGtal::ArithmeticConversionType<TComponent, OtherComponent> >::value, int >::type >
519 DGtal::PointVector<dim, TComponent, TContainer>&
520 DGtal::PointVector<dim, TComponent, TContainer>::operator+= ( OtherComponent coeff )
522 for ( DGtal::Dimension i = 0; i < dim; ++i )
523 this->myArray[ i ] += coeff;
526 //------------------------------------------------------------------------------
527 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
529 typename OtherComponent, typename OtherStorage,
530 typename std::enable_if< std::is_same< TComponent, DGtal::ArithmeticConversionType<TComponent, OtherComponent> >::value, int >::type >
532 DGtal::PointVector<dim, TComponent, TContainer>&
533 DGtal::PointVector<dim, TComponent, TContainer>::operator-= ( PointVector<dim, OtherComponent, OtherStorage> const& v )
535 for ( DGtal::Dimension i = 0; i < dim; ++i )
536 this->myArray[ i ] -= v[ i ];
539 //------------------------------------------------------------------------------
540 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
542 typename OtherComponent,
543 typename std::enable_if< std::is_same< TComponent, DGtal::ArithmeticConversionType<TComponent, OtherComponent> >::value, int >::type >
545 DGtal::PointVector<dim, TComponent, TContainer>&
546 DGtal::PointVector<dim, TComponent, TContainer>::operator-= ( OtherComponent coeff )
548 for ( DGtal::Dimension i = 0; i < dim; ++i )
549 this->myArray[ i ] -= coeff;
552 //------------------------------------------------------------------------------
553 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
555 typename OtherComponent,
556 typename std::enable_if< std::is_same< TComponent, DGtal::ArithmeticConversionType<TComponent, OtherComponent> >::value, int >::type>
557 DGtal::PointVector<dim, TComponent, TContainer>&
558 DGtal::PointVector<dim, TComponent, TContainer>::operator*= ( OtherComponent coeff )
560 for ( DGtal::Dimension i = 0; i < myArray.size(); ++i )
561 myArray[ i ] *= coeff;
564 //------------------------------------------------------------------------------
565 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
567 typename OtherComponent, typename OtherStorage,
568 typename std::enable_if< std::is_same< TComponent, DGtal::ArithmeticConversionType<TComponent, OtherComponent> >::value, int >::type>
569 DGtal::PointVector<dim, TComponent, TContainer>&
570 DGtal::PointVector<dim, TComponent, TContainer>::operator*= ( PointVector<dim, OtherComponent, OtherStorage> const& v )
572 for ( DGtal::Dimension i = 0; i < myArray.size(); ++i )
573 myArray[ i ] *= v[ i ];
576 //------------------------------------------------------------------------------
577 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
579 typename OtherComponent,
580 typename std::enable_if< std::is_same< TComponent, DGtal::ArithmeticConversionType<TComponent, OtherComponent> >::value, int >::type>
581 DGtal::PointVector<dim, TComponent, TContainer>&
582 DGtal::PointVector<dim, TComponent, TContainer>::operator/= ( OtherComponent coeff )
584 for ( DGtal::Dimension i = 0; i < myArray.size(); ++i )
585 myArray[ i ] /= coeff;
588 //------------------------------------------------------------------------------
589 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
591 typename OtherComponent, typename OtherStorage,
592 typename std::enable_if< std::is_same< TComponent, DGtal::ArithmeticConversionType<TComponent, OtherComponent> >::value, int >::type>
593 DGtal::PointVector<dim, TComponent, TContainer>&
594 DGtal::PointVector<dim, TComponent, TContainer>::operator/= ( PointVector<dim, OtherComponent, OtherStorage> const& v )
596 for ( DGtal::Dimension i = 0; i < myArray.size(); ++i )
597 myArray[ i ] /= v[ i ];
600 //------------------------------------------------------------------------------
601 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
602 template < typename OtherComponent, typename OtherStorage >
604 DGtal::PointVector<dim, TComponent, TContainer>::dot( const DGtal::PointVector<dim, OtherComponent, OtherStorage>& v ) const
605 -> decltype( DGtal::dotProduct(*this, v) )
607 return DGtal::dotProduct(*this, v);
609 //------------------------------------------------------------------------------
610 template < DGtal::Dimension ptDim,
611 typename LeftEuclideanRing, typename LeftContainer,
612 typename RightEuclideanRing, typename RightContainer >
614 DGtal::ArithmeticConversionType<LeftEuclideanRing, RightEuclideanRing>
615 DGtal::dotProduct ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
616 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
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 ];
624 //------------------------------------------------------------------------------
625 template < DGtal::Dimension ptDim,
626 typename LeftEuclideanRing, typename LeftContainer,
627 typename RightEuclideanRing, typename RightContainer >
629 DGtal::cosineSimilarity ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
630 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
633 if ( lhs.norm() > 0. && rhs.norm() > 0. )
634 radians = rhs.dot ( lhs ) / ( lhs.norm() * rhs.norm() );
636 throw std::runtime_error ( "Operation involving a null vector is not defined!" );
637 return std::acos ( std::min ( std::max ( radians, -1. ), 1. ) );
640 //------------------------------------------------------------------------------
641 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
642 template < typename OtherComponent, typename OtherStorage >
644 DGtal::PointVector<dim, TComponent, TContainer>::cosineSimilarity( const DGtal::PointVector<dim, OtherComponent, OtherStorage>& v ) const
646 return DGtal::cosineSimilarity(*this, v);
648 //------------------------------------------------------------------------------
649 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
650 template < typename OtherComponent, typename OtherStorage >
652 DGtal::PointVector<dim, TComponent, TContainer>::crossProduct( const DGtal::PointVector<dim, OtherComponent, OtherStorage>& v ) const
653 -> decltype( DGtal::crossProduct(*this, v) )
655 return DGtal::crossProduct(*this, v);
657 //------------------------------------------------------------------------------
659 typename LeftEuclideanRing, typename LeftContainer,
660 typename RightEuclideanRing, typename RightContainer >
662 DGtal::crossProduct ( DGtal::PointVector<3, LeftEuclideanRing, LeftContainer> const& lhs,
663 DGtal::PointVector<3, RightEuclideanRing, RightContainer> const& rhs )
664 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
666 auto crossprod = constructFromArithmeticConversion(lhs, rhs);
667 for ( DGtal::Dimension i = 0; i < 3; ++i )
669 lhs[ (i+1)%3 ] * rhs[ (i+2)%3 ]
670 - lhs[ (i+2)%3 ] * rhs[ (i+1)%3 ];
673 //------------------------------------------------------------------------------
675 typename LeftEuclideanRing, typename LeftContainer,
676 typename RightEuclideanRing, typename RightContainer >
678 DGtal::PointVector<3, DGtal::ArithmeticConversionType<LeftEuclideanRing, RightEuclideanRing>>
679 DGtal::crossProduct ( DGtal::PointVector<2, LeftEuclideanRing, LeftContainer> const& lhs,
680 DGtal::PointVector<2, RightEuclideanRing, RightContainer> const& rhs )
682 return PointVector<3, ArithmeticConversionType<LeftEuclideanRing, RightEuclideanRing>>(
685 lhs[0]*rhs[1] - lhs[1]*rhs[0]
688 //------------------------------------------------------------------------------
689 template < DGtal::Dimension ptDim,
690 typename LeftEuclideanRing, typename LeftContainer,
691 typename RightEuclideanRing, typename RightContainer >
693 DGtal::operator+ ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
694 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
695 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
697 using EuclideanRing = ArithmeticConversionType<LeftEuclideanRing, RightEuclideanRing>;
698 return constructFromArithmeticConversion(lhs, rhs, lhs, rhs, std::plus<EuclideanRing>());
700 //------------------------------------------------------------------------------
701 template < DGtal::Dimension ptDim,
702 typename LeftEuclideanRing, typename LeftContainer,
703 typename RightEuclideanRing, typename RightContainer >
705 DGtal::operator- ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
706 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
707 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
709 using EuclideanRing = ArithmeticConversionType<LeftEuclideanRing, RightEuclideanRing>;
710 return constructFromArithmeticConversion(lhs, rhs, lhs, rhs, std::minus<EuclideanRing>());
712 //------------------------------------------------------------------------------
713 template < DGtal::Dimension ptDim,
714 typename LeftEuclideanRing, typename LeftContainer,
715 typename RightEuclideanRing, typename RightContainer >
717 DGtal::operator* ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
718 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
719 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
721 using EuclideanRing = ArithmeticConversionType<LeftEuclideanRing, RightEuclideanRing>;
722 return constructFromArithmeticConversion(lhs, rhs, lhs, rhs, std::multiplies<EuclideanRing>());
724 //------------------------------------------------------------------------------
725 template < DGtal::Dimension ptDim,
726 typename LeftEuclideanRing, typename LeftContainer,
727 typename RightEuclideanRing, typename RightContainer >
729 DGtal::operator/ ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
730 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
731 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
733 using EuclideanRing = ArithmeticConversionType<LeftEuclideanRing, RightEuclideanRing>;
734 return constructFromArithmeticConversion(lhs, rhs, lhs, rhs, std::divides<EuclideanRing>());
736 //------------------------------------------------------------------------------
737 template < DGtal::Dimension ptDim,
738 typename LeftEuclideanRing, typename LeftContainer,
739 typename RightScalar >
741 DGtal::operator+ ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
742 RightScalar const& rhs )
743 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
745 return constructFromArithmeticConversion(lhs, rhs, lhs, [&rhs] (LeftEuclideanRing v) { return v + rhs; });
747 //------------------------------------------------------------------------------
748 template < DGtal::Dimension ptDim,
750 typename RightEuclideanRing, typename RightContainer >
752 DGtal::operator+ ( LeftScalar const& lhs,
753 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
754 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
756 return constructFromArithmeticConversion(lhs, rhs, rhs, [&lhs] (RightEuclideanRing v) { return lhs + v; });
758 //------------------------------------------------------------------------------
759 template < DGtal::Dimension ptDim,
760 typename LeftEuclideanRing, typename LeftContainer,
761 typename RightScalar >
763 DGtal::operator- ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
764 RightScalar const& rhs )
765 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
767 return constructFromArithmeticConversion(lhs, rhs, lhs, [&rhs] (LeftEuclideanRing v) { return v - rhs; });
769 //------------------------------------------------------------------------------
770 template < DGtal::Dimension ptDim,
772 typename RightEuclideanRing, typename RightContainer >
774 DGtal::operator- ( LeftScalar const& lhs,
775 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
776 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
778 return constructFromArithmeticConversion(lhs, rhs, rhs, [&lhs] (RightEuclideanRing v) { return lhs - v; });
780 //------------------------------------------------------------------------------
781 template < DGtal::Dimension ptDim,
782 typename LeftEuclideanRing, typename LeftContainer,
783 typename RightScalar >
785 DGtal::operator* ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
786 RightScalar const& rhs )
787 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
789 return constructFromArithmeticConversion(lhs, rhs, lhs, [&rhs] (LeftEuclideanRing v) { return v * rhs; });
791 //------------------------------------------------------------------------------
792 template < DGtal::Dimension ptDim,
794 typename RightEuclideanRing, typename RightContainer >
796 DGtal::operator* ( LeftScalar const& lhs,
797 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
798 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
800 return constructFromArithmeticConversion(lhs, rhs, rhs, [&lhs] (RightEuclideanRing v) { return lhs * v; });
802 //------------------------------------------------------------------------------
803 template < DGtal::Dimension ptDim,
804 typename LeftEuclideanRing, typename LeftContainer,
805 typename RightScalar >
807 DGtal::operator/ ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
808 RightScalar const& rhs )
809 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
811 return constructFromArithmeticConversion(lhs, rhs, lhs, [&rhs] (LeftEuclideanRing v) { return v / rhs; });
813 //------------------------------------------------------------------------------
814 template < DGtal::Dimension ptDim,
816 typename RightEuclideanRing, typename RightContainer >
818 DGtal::operator/ ( LeftScalar const& lhs,
819 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
820 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
822 return constructFromArithmeticConversion(lhs, rhs, rhs, [&lhs] (RightEuclideanRing v) { return lhs / v; });
824 //------------------------------------------------------------------------------
825 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
827 DGtal::PointVector<dim, TComponent,TContainer>
828 DGtal::PointVector<dim, TComponent,TContainer>::operator-() const
830 return Self(*this, functors::UnaryMinus<Component>());
832 //------------------------------------------------------------------------------
833 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
836 DGtal::PointVector<dim, TComponent, TContainer>::reset()
838 for ( DGtal::Dimension i = 0; i < myArray.size(); ++i )
839 myArray[ i ] = NumberTraits< Component >::ZERO;
841 //------------------------------------------------------------------------------
842 template < DGtal::Dimension ptDim,
843 typename LeftEuclideanRing, typename LeftContainer,
844 typename RightEuclideanRing, typename RightContainer >
846 DGtal::inf( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
847 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
848 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
850 using EuclideanRing = ArithmeticConversionType<LeftEuclideanRing, RightEuclideanRing>;
851 return DGtal::constructFromArithmeticConversion(lhs, rhs, lhs, rhs, functors::Min<EuclideanRing>());
853 //------------------------------------------------------------------------------
854 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
855 template < typename OtherComponent, typename OtherStorage >
857 DGtal::PointVector<dim, TComponent, TContainer>::inf( const DGtal::PointVector<dim, OtherComponent, OtherStorage>& aPoint ) const
858 -> decltype( DGtal::inf(*this, aPoint) )
860 return DGtal::inf(*this, aPoint);
862 //------------------------------------------------------------------------------
863 template < DGtal::Dimension ptDim,
864 typename LeftEuclideanRing, typename LeftContainer,
865 typename RightEuclideanRing, typename RightContainer >
867 DGtal::sup( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
868 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
869 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
871 using EuclideanRing = ArithmeticConversionType<LeftEuclideanRing, RightEuclideanRing>;
872 return DGtal::constructFromArithmeticConversion(lhs, rhs, lhs, rhs, functors::Max<EuclideanRing>());
874 //------------------------------------------------------------------------------
875 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
876 template < typename OtherComponent, typename OtherStorage >
878 DGtal::PointVector<dim, TComponent, TContainer>::sup( const DGtal::PointVector<dim, OtherComponent, OtherStorage>& aPoint ) const
879 -> decltype( DGtal::sup(*this, aPoint) )
881 return DGtal::sup(*this, aPoint);
883 //------------------------------------------------------------------------------
884 template < DGtal::Dimension ptDim,
885 typename LeftEuclideanRing, typename LeftContainer,
886 typename RightEuclideanRing, typename RightContainer >
888 DGtal::isLower( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
889 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
891 for ( DGtal::Dimension i = 0; i < ptDim; ++i )
892 if ( rhs[ i ] < lhs[ i ] )
896 //------------------------------------------------------------------------------
897 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
898 template < typename OtherComponent, typename OtherStorage >
900 DGtal::PointVector<dim, TComponent, TContainer>::isLower( const DGtal::PointVector<dim, OtherComponent, OtherStorage> & p ) const
902 return DGtal::isLower(*this, p);
904 //------------------------------------------------------------------------------
905 template < DGtal::Dimension ptDim,
906 typename LeftEuclideanRing, typename LeftContainer,
907 typename RightEuclideanRing, typename RightContainer >
909 DGtal::isUpper( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
910 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
912 for ( DGtal::Dimension i = 0; i < ptDim; ++i )
913 if ( rhs[ i ] > lhs[ i ] )
917 //------------------------------------------------------------------------------
918 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
919 template < typename OtherComponent, typename OtherStorage >
921 DGtal::PointVector<dim, TComponent, TContainer>::isUpper( const DGtal::PointVector<dim, OtherComponent, OtherStorage> & p ) const
923 return DGtal::isUpper(*this, p);
925 //------------------------------------------------------------------------------
926 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
928 typename DGtal::PointVector<dim, TComponent, TContainer>::Component
929 DGtal::PointVector<dim, TComponent, TContainer>::max( ) const
931 return *std::max_element(this->begin(), this->end());
933 //------------------------------------------------------------------------------
934 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
936 typename DGtal::PointVector<dim, TComponent, TContainer>::Component
937 DGtal::PointVector<dim, TComponent, TContainer>::min( ) const
939 return *std::min_element(this->begin(), this->end());
941 //------------------------------------------------------------------------------
942 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
944 typename DGtal::PointVector<dim, TComponent, TContainer>::Iterator
945 DGtal::PointVector<dim, TComponent, TContainer>::maxElement( )
947 return std::max_element(this->begin(), this->end());
949 //------------------------------------------------------------------------------
950 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
952 typename DGtal::PointVector<dim, TComponent, TContainer>::Iterator
953 DGtal::PointVector<dim, TComponent, TContainer>::minElement( )
955 return std::min_element(this->begin(), this->end());
957 //------------------------------------------------------------------------------
958 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
961 DGtal::PointVector<dim, TComponent, TContainer>::
964 for ( DGtal::Dimension i = 0; i < dimension; ++i )
965 this->myArray[ i ] = - this->myArray[ i ];
967 //------------------------------------------------------------------------------
968 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
971 DGtal::PointVector<dim, TComponent, TContainer>::squaredNorm () const
975 for ( DGtal::Dimension i = 0; i < dimension; i++ )
976 tmp += std::pow(NumberTraits<Component>::castToDouble(myArray[ i ]), 2);
979 //------------------------------------------------------------------------------
980 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
983 DGtal::PointVector<dim, TComponent, TContainer>::norm (
984 const typename Self::NormType aType ) const
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 );
999 for ( DGtal::Dimension i = 0; i < dimension; i++ )
1000 tmp += fabs ( NumberTraits<Component>::castToDouble(myArray[ i ] ));
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 ] ));
1011 //------------------------------------------------------------------------------
1012 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
1014 typename DGtal::PointVector<dim, TComponent, TContainer>::UnsignedComponent
1015 DGtal::PointVector<dim, TComponent, TContainer>::norm1() const
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 )
1023 : UnsignedComponent(-myArray[ i ]);
1026 //------------------------------------------------------------------------------
1027 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
1029 typename DGtal::PointVector<dim, TComponent, TContainer>::UnsignedComponent
1030 DGtal::PointVector<dim, TComponent, TContainer>::normInfinity() const
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 )
1037 tmp = ( myArray[ i ] >= 0 ) ? myArray[ i ] : -myArray[ i ] ;
1043 //------------------------------------------------------------------------------
1045 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
1047 typename DGtal::PointVector<dim, double, std::array<double,dim> >
1048 DGtal::PointVector<dim, TComponent, TContainer>::getNormalized() const
1050 PointVector<dim,double,std::array<double,dim> > normalized =(*this);
1051 normalized /= normalized.norm();
1054 //------------------------------------------------------------------------------
1055 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
1057 DGtal::PointVector<dim,TComponent, TContainer>
1058 DGtal::PointVector<dim,TComponent, TContainer>::diagonal( Component val )
1061 for ( DGtal::Dimension i = 0; i < dim; ++i )
1062 p.myArray[ i ] = val;
1065 //------------------------------------------------------------------------------
1066 template<DGtal::Dimension dim,typename TComponent, typename TContainer>
1068 DGtal::PointVector<dim,TComponent, TContainer>
1069 DGtal::PointVector<dim,TComponent, TContainer>::base( Dimension k, Component val )
1072 p.myArray[ k ] = val;
1075 //------------------------------------------------------------------------------
1076 template<DGtal::Dimension dim,typename TComponent, typename TContainer>
1079 DGtal::PointVector<dim,TComponent, TContainer>::selfDisplay( std::ostream & out ) const
1081 out << "[PointVector] {";
1082 for (DGtal::Dimension i = 0; i < dimension ; ++i)
1083 out << myArray[ i ] << (i == dimension - 1 ? "" : ", ");
1087 //------------------------------------------------------------------------------
1088 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
1091 DGtal::PointVector<dim, TComponent, TContainer>::className() const
1093 return "PointVector";
1096 //------------------------------------------------------------------------------
1097 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
1100 DGtal::operator<<( std::ostream & out,
1101 const PointVector<dim, TComponent, TContainer>& object )
1103 object.selfDisplay( out );
1106 //------------------------------------------------------------------------------
1107 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
1110 DGtal::PointVector<dim, TComponent, TContainer>::isValid() const
1114 //------------------------------------------------------------------------------