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//////////////////////////////////////////////////////////////////////////////
42template<DGtal::Dimension dim, typename Container>
44std::bitset<dim> DGtal::setDimensionsIn( const Container &dimensions )
47 for ( typename Container::const_iterator it=dimensions.begin();
48 it!=dimensions.end(); ++it )
55//------------------------------------------------------------------------------
56template<DGtal::Dimension dim, typename Container>
58std::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//------------------------------------------------------------------------------
72template<DGtal::Dimension dim, typename TComponent, typename TContainer>
74DGtal::PointVector<dim, TComponent, TContainer>::PointVector()
76 for ( Dimension i = 0; i < dim; ++i )
77 myArray[ i ] = NumberTraits<TComponent>::ZERO;
79//------------------------------------------------------------------------------
80template<DGtal::Dimension dim, typename TComponent, typename TContainer>
82 typename LeftComponent, typename LeftStorage,
83 typename RightComponent, typename RightStorage,
84 typename BinaryFunctor >
86DGtal::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//------------------------------------------------------------------------------
95template <DGtal::Dimension dim, typename TComponent, typename TContainer>
96template <typename OtherComponent, typename OtherStorage, typename UnaryFunctor>
98DGtal::PointVector<dim, TComponent,TContainer>::
99PointVector(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//------------------------------------------------------------------------------
106template<DGtal::Dimension dim, typename TComponent, typename TContainer>
108DGtal::PointVector<dim, TComponent, TContainer>::~PointVector()
110//------------------------------------------------------------------------------
111template<DGtal::Dimension dim, typename TComponent, typename TContainer>
113DGtal::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//------------------------------------------------------------------------------
120template<DGtal::Dimension dim, typename TComponent, typename TContainer>
122DGtal::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//------------------------------------------------------------------------------
131template<DGtal::Dimension dim, typename TComponent, typename TContainer>
133DGtal::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//------------------------------------------------------------------------------
145template<DGtal::Dimension dim, typename TComponent, typename TContainer>
147DGtal::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//------------------------------------------------------------------------------
161template<DGtal::Dimension dim, typename TComponent, typename TContainer>
163DGtal::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//------------------------------------------------------------------------------
172template<DGtal::Dimension dim, typename TComponent, typename TContainer>
174DGtal::PointVector<dim, TComponent, TContainer>::PointVector ( const Self & other )
175 : myArray( other.myArray )
177//------------------------------------------------------------------------------
178template<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 >
183DGtal::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//------------------------------------------------------------------------------
189template<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 >
194DGtal::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//------------------------------------------------------------------------------
200template<DGtal::Dimension dim, typename TComponent, typename TContainer>
202typename DGtal::PointVector<dim, TComponent, TContainer>::Iterator
203DGtal::PointVector<dim, TComponent, TContainer>::begin()
205 return myArray.begin();
207//------------------------------------------------------------------------------
208template<DGtal::Dimension dim, typename TComponent, typename TContainer>
210typename DGtal::PointVector<dim, TComponent, TContainer>::Iterator
211DGtal::PointVector<dim, TComponent, TContainer>::end()
213 return myArray.end();
215//------------------------------------------------------------------------------
216template<DGtal::Dimension dim, typename TComponent, typename TContainer>
218typename DGtal::PointVector<dim, TComponent, TContainer>::ConstIterator
219DGtal::PointVector<dim, TComponent, TContainer>::begin() const
221 return myArray.begin();
223//------------------------------------------------------------------------------
224template<DGtal::Dimension dim, typename TComponent, typename TContainer>
226typename DGtal::PointVector<dim, TComponent, TContainer>::ConstIterator
227DGtal::PointVector<dim, TComponent, TContainer>::end() const
229 return myArray.end();
231//------------------------------------------------------------------------------
232template<DGtal::Dimension dim, typename TComponent, typename TContainer>
234typename DGtal::PointVector<dim, TComponent, TContainer>::ReverseIterator
235DGtal::PointVector<dim, TComponent, TContainer>::rbegin()
237 return myArray.rbegin();
239//------------------------------------------------------------------------------
240template<DGtal::Dimension dim, typename TComponent, typename TContainer>
242typename DGtal::PointVector<dim, TComponent, TContainer>::ReverseIterator
243DGtal::PointVector<dim, TComponent, TContainer>::rend()
245 return myArray.rend();
247//------------------------------------------------------------------------------
248template<DGtal::Dimension dim, typename TComponent, typename TContainer>
250typename DGtal::PointVector<dim, TComponent, TContainer>::ConstReverseIterator
251DGtal::PointVector<dim, TComponent, TContainer>::rbegin() const
253 return myArray.rbegin();
255//------------------------------------------------------------------------------
256template<DGtal::Dimension dim, typename TComponent, typename TContainer>
258typename DGtal::PointVector<dim, TComponent, TContainer>::ConstReverseIterator
259DGtal::PointVector<dim, TComponent, TContainer>::rend() const
261 return myArray.rend();
263//------------------------------------------------------------------------------
264template<DGtal::Dimension dim, typename TComponent, typename TContainer>
266typename DGtal::Dimension
267DGtal::PointVector<dim, TComponent, TContainer>::size()
271//------------------------------------------------------------------------------
272template<DGtal::Dimension dim, typename TComponent, typename TContainer>
274const typename DGtal::PointVector<dim, TComponent, TContainer>::Component *
275DGtal::PointVector<dim, TComponent, TContainer>::data() const noexcept
277 return myArray.data();
279//------------------------------------------------------------------------------
280template<DGtal::Dimension dim, typename TComponent, typename TContainer>
282typename DGtal::PointVector<dim, TComponent, TContainer>::Component *
283DGtal::PointVector<dim, TComponent, TContainer>::data() noexcept
285 return myArray.data();
287//------------------------------------------------------------------------------
288template<DGtal::Dimension dim, typename TComponent, typename TContainer>
290const typename DGtal::PointVector<dim, TComponent, TContainer>::Component &
291DGtal::PointVector<dim, TComponent, TContainer>::operator[]( Dimension i ) const
296//------------------------------------------------------------------------------
297template<DGtal::Dimension dim, typename TComponent, typename TContainer>
299typename DGtal::PointVector<dim, TComponent, TContainer>::Component &
300DGtal::PointVector<dim, TComponent, TContainer>::operator[]( Dimension i )
305//------------------------------------------------------------------------------
306template<DGtal::Dimension dim, typename TComponent, typename TContainer>
308DGtal::PointVector<dim, TComponent, TContainer>&
309DGtal::PointVector<dim, TComponent, TContainer>::operator= ( const Self & pv )
311 myArray = pv.myArray;
314//------------------------------------------------------------------------------
315template<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>
321DGtal::PointVector<dim, TComponent, TContainer> &
322DGtal::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//------------------------------------------------------------------------------
331template<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>
337DGtal::PointVector<dim, TComponent, TContainer>&
338DGtal::PointVector<dim, TComponent, TContainer>::partialCopy
339( const DGtal::PointVector<dim, OtherComponent, OtherContainer> & pv,
340 const std::vector<DGtal::Dimension> &dimensions)
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//------------------------------------------------------------------------------
350template<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>
356DGtal::PointVector<dim, TComponent, TContainer>&
357DGtal::PointVector<dim, TComponent, TContainer>::partialCopyInv
358( const DGtal::PointVector<dim, OtherComponent, OtherContainer> & pv,
359 const std::vector<DGtal::Dimension> &dimensions)
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//------------------------------------------------------------------------------
369template<DGtal::Dimension dim, typename TComponent, typename TContainer>
371 typename OtherComponent,
372 typename OtherContainer,
373 typename UnaryFunctor >
375DGtal::PointVector<dim, TComponent, TContainer>&
376DGtal::PointVector<dim, TComponent, TContainer>::partialCopy
377( const DGtal::PointVector<dim, OtherComponent, OtherContainer> & pv,
378 const std::vector<DGtal::Dimension> &dimensions,
379 const UnaryFunctor &f)
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//------------------------------------------------------------------------------
389template<DGtal::Dimension dim, typename TComponent, typename TContainer>
391 typename OtherComponent,
392 typename OtherContainer,
393 typename UnaryFunctor >
395DGtal::PointVector<dim, TComponent, TContainer>&
396DGtal::PointVector<dim, TComponent, TContainer>::partialCopyInv
397( const DGtal::PointVector<dim, OtherComponent, OtherContainer> & pv,
398 const std::vector<DGtal::Dimension> &dimensions,
399 const UnaryFunctor &f)
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//------------------------------------------------------------------------------
409template<DGtal::Dimension dim, typename TComponent, typename TContainer>
410template <typename TOtherComponent, typename TOtherContainer>
413DGtal::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//------------------------------------------------------------------------------
425template<DGtal::Dimension dim, typename TComponent, typename TContainer>
426template <typename TOtherComponent, typename TOtherContainer>
429DGtal::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//------------------------------------------------------------------------------
441template < DGtal::Dimension ptDim,
442 typename LeftEuclideanRing, typename LeftContainer,
443 typename RightEuclideanRing, typename RightContainer >
445DGtal::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//------------------------------------------------------------------------------
451template < DGtal::Dimension ptDim,
452 typename LeftEuclideanRing, typename LeftContainer,
453 typename RightEuclideanRing, typename RightContainer >
455DGtal::operator!= ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
456 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
458 return ! (lhs == rhs);
460//------------------------------------------------------------------------------
461template < DGtal::Dimension ptDim,
462 typename LeftEuclideanRing, typename LeftContainer,
463 typename RightEuclideanRing, typename RightContainer >
465DGtal::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//------------------------------------------------------------------------------
471template < DGtal::Dimension ptDim,
472 typename LeftEuclideanRing, typename LeftContainer,
473 typename RightEuclideanRing, typename RightContainer >
475DGtal::operator> ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
476 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
480//------------------------------------------------------------------------------
481template < DGtal::Dimension ptDim,
482 typename LeftEuclideanRing, typename LeftContainer,
483 typename RightEuclideanRing, typename RightContainer >
485DGtal::operator<= ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
486 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
488 return ! ( lhs > rhs );
490//------------------------------------------------------------------------------
491template < DGtal::Dimension ptDim,
492 typename LeftEuclideanRing, typename LeftContainer,
493 typename RightEuclideanRing, typename RightContainer >
495DGtal::operator>= ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
496 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
498 return ! ( lhs < rhs );
500//------------------------------------------------------------------------------
501template<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 >
506DGtal::PointVector<dim, TComponent, TContainer>&
507DGtal::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//------------------------------------------------------------------------------
514template<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 >
519DGtal::PointVector<dim, TComponent, TContainer>&
520DGtal::PointVector<dim, TComponent, TContainer>::operator+= ( OtherComponent coeff )
522 for ( DGtal::Dimension i = 0; i < dim; ++i )
523 this->myArray[ i ] += coeff;
526//------------------------------------------------------------------------------
527template<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 >
532DGtal::PointVector<dim, TComponent, TContainer>&
533DGtal::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//------------------------------------------------------------------------------
540template<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 >
545DGtal::PointVector<dim, TComponent, TContainer>&
546DGtal::PointVector<dim, TComponent, TContainer>::operator-= ( OtherComponent coeff )
548 for ( DGtal::Dimension i = 0; i < dim; ++i )
549 this->myArray[ i ] -= coeff;
552//------------------------------------------------------------------------------
553template<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>
557DGtal::PointVector<dim, TComponent, TContainer>&
558DGtal::PointVector<dim, TComponent, TContainer>::operator*= ( OtherComponent coeff )
560 for ( DGtal::Dimension i = 0; i < myArray.size(); ++i )
561 myArray[ i ] *= coeff;
564//------------------------------------------------------------------------------
565template<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>
569DGtal::PointVector<dim, TComponent, TContainer>&
570DGtal::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//------------------------------------------------------------------------------
577template<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>
581DGtal::PointVector<dim, TComponent, TContainer>&
582DGtal::PointVector<dim, TComponent, TContainer>::operator/= ( OtherComponent coeff )
584 for ( DGtal::Dimension i = 0; i < myArray.size(); ++i )
585 myArray[ i ] /= coeff;
588//------------------------------------------------------------------------------
589template<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>
593DGtal::PointVector<dim, TComponent, TContainer>&
594DGtal::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//------------------------------------------------------------------------------
601template<DGtal::Dimension dim, typename TComponent, typename TContainer>
602template < typename OtherComponent, typename OtherStorage >
604DGtal::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//------------------------------------------------------------------------------
610template < DGtal::Dimension ptDim,
611 typename LeftEuclideanRing, typename LeftContainer,
612 typename RightEuclideanRing, typename RightContainer >
614DGtal::ArithmeticConversionType<LeftEuclideanRing, RightEuclideanRing>
615DGtal::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//------------------------------------------------------------------------------
625template < DGtal::Dimension ptDim,
626 typename LeftEuclideanRing, typename LeftContainer,
627 typename RightEuclideanRing, typename RightContainer >
629DGtal::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//------------------------------------------------------------------------------
641template<DGtal::Dimension dim, typename TComponent, typename TContainer>
642template < typename OtherComponent, typename OtherStorage >
644DGtal::PointVector<dim, TComponent, TContainer>::cosineSimilarity( const DGtal::PointVector<dim, OtherComponent, OtherStorage>& v ) const
646 return DGtal::cosineSimilarity(*this, v);
648//------------------------------------------------------------------------------
649template<DGtal::Dimension dim, typename TComponent, typename TContainer>
650template < typename OtherComponent, typename OtherStorage >
652DGtal::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 >
662DGtal::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 >
678DGtal::PointVector<3, DGtal::ArithmeticConversionType<LeftEuclideanRing, RightEuclideanRing>>
679DGtal::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//------------------------------------------------------------------------------
689template < DGtal::Dimension ptDim,
690 typename LeftEuclideanRing, typename LeftContainer,
691 typename RightEuclideanRing, typename RightContainer >
693DGtal::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//------------------------------------------------------------------------------
701template < DGtal::Dimension ptDim,
702 typename LeftEuclideanRing, typename LeftContainer,
703 typename RightEuclideanRing, typename RightContainer >
705DGtal::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//------------------------------------------------------------------------------
713template < DGtal::Dimension ptDim,
714 typename LeftEuclideanRing, typename LeftContainer,
715 typename RightEuclideanRing, typename RightContainer >
717DGtal::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//------------------------------------------------------------------------------
725template < DGtal::Dimension ptDim,
726 typename LeftEuclideanRing, typename LeftContainer,
727 typename RightEuclideanRing, typename RightContainer >
729DGtal::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//------------------------------------------------------------------------------
737template < DGtal::Dimension ptDim,
738 typename LeftEuclideanRing, typename LeftContainer,
739 typename RightScalar >
741DGtal::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//------------------------------------------------------------------------------
748template < DGtal::Dimension ptDim,
750 typename RightEuclideanRing, typename RightContainer >
752DGtal::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//------------------------------------------------------------------------------
759template < DGtal::Dimension ptDim,
760 typename LeftEuclideanRing, typename LeftContainer,
761 typename RightScalar >
763DGtal::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//------------------------------------------------------------------------------
770template < DGtal::Dimension ptDim,
772 typename RightEuclideanRing, typename RightContainer >
774DGtal::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//------------------------------------------------------------------------------
781template < DGtal::Dimension ptDim,
782 typename LeftEuclideanRing, typename LeftContainer,
783 typename RightScalar >
785DGtal::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//------------------------------------------------------------------------------
792template < DGtal::Dimension ptDim,
794 typename RightEuclideanRing, typename RightContainer >
796DGtal::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//------------------------------------------------------------------------------
803template < DGtal::Dimension ptDim,
804 typename LeftEuclideanRing, typename LeftContainer,
805 typename RightScalar >
807DGtal::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//------------------------------------------------------------------------------
814template < DGtal::Dimension ptDim,
816 typename RightEuclideanRing, typename RightContainer >
818DGtal::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//------------------------------------------------------------------------------
825template<DGtal::Dimension dim, typename TComponent, typename TContainer>
827DGtal::PointVector<dim, TComponent,TContainer>
828DGtal::PointVector<dim, TComponent,TContainer>::operator-() const
830 return Self(*this, functors::UnaryMinus<Component>());
832//------------------------------------------------------------------------------
833template<DGtal::Dimension dim, typename TComponent, typename TContainer>
836DGtal::PointVector<dim, TComponent, TContainer>::reset()
838 for ( DGtal::Dimension i = 0; i < myArray.size(); ++i )
839 myArray[ i ] = NumberTraits< Component >::ZERO;
841//------------------------------------------------------------------------------
842template < DGtal::Dimension ptDim,
843 typename LeftEuclideanRing, typename LeftContainer,
844 typename RightEuclideanRing, typename RightContainer >
846DGtal::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//------------------------------------------------------------------------------
854template<DGtal::Dimension dim, typename TComponent, typename TContainer>
855template < typename OtherComponent, typename OtherStorage >
857DGtal::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//------------------------------------------------------------------------------
863template < DGtal::Dimension ptDim,
864 typename LeftEuclideanRing, typename LeftContainer,
865 typename RightEuclideanRing, typename RightContainer >
867DGtal::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//------------------------------------------------------------------------------
875template<DGtal::Dimension dim, typename TComponent, typename TContainer>
876template < typename OtherComponent, typename OtherStorage >
878DGtal::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//------------------------------------------------------------------------------
884template < DGtal::Dimension ptDim,
885 typename LeftEuclideanRing, typename LeftContainer,
886 typename RightEuclideanRing, typename RightContainer >
888DGtal::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//------------------------------------------------------------------------------
897template<DGtal::Dimension dim, typename TComponent, typename TContainer>
898template < typename OtherComponent, typename OtherStorage >
900DGtal::PointVector<dim, TComponent, TContainer>::isLower( const DGtal::PointVector<dim, OtherComponent, OtherStorage> & p ) const
902 return DGtal::isLower(*this, p);
904//------------------------------------------------------------------------------
905template < DGtal::Dimension ptDim,
906 typename LeftEuclideanRing, typename LeftContainer,
907 typename RightEuclideanRing, typename RightContainer >
909DGtal::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//------------------------------------------------------------------------------
918template<DGtal::Dimension dim, typename TComponent, typename TContainer>
919template < typename OtherComponent, typename OtherStorage >
921DGtal::PointVector<dim, TComponent, TContainer>::isUpper( const DGtal::PointVector<dim, OtherComponent, OtherStorage> & p ) const
923 return DGtal::isUpper(*this, p);
925//------------------------------------------------------------------------------
926template<DGtal::Dimension dim, typename TComponent, typename TContainer>
928typename DGtal::PointVector<dim, TComponent, TContainer>::Component
929DGtal::PointVector<dim, TComponent, TContainer>::max( ) const
931 return *std::max_element(this->begin(), this->end());
933//------------------------------------------------------------------------------
934template<DGtal::Dimension dim, typename TComponent, typename TContainer>
936typename DGtal::PointVector<dim, TComponent, TContainer>::Component
937DGtal::PointVector<dim, TComponent, TContainer>::min( ) const
939 return *std::min_element(this->begin(), this->end());
941//------------------------------------------------------------------------------
942template<DGtal::Dimension dim, typename TComponent, typename TContainer>
944typename DGtal::PointVector<dim, TComponent, TContainer>::Iterator
945DGtal::PointVector<dim, TComponent, TContainer>::maxElement( )
947 return std::max_element(this->begin(), this->end());
949//------------------------------------------------------------------------------
950template<DGtal::Dimension dim, typename TComponent, typename TContainer>
952typename DGtal::PointVector<dim, TComponent, TContainer>::Iterator
953DGtal::PointVector<dim, TComponent, TContainer>::minElement( )
955 return std::min_element(this->begin(), this->end());
957//------------------------------------------------------------------------------
958template<DGtal::Dimension dim, typename TComponent, typename TContainer>
961DGtal::PointVector<dim, TComponent, TContainer>::
964 for ( DGtal::Dimension i = 0; i < dimension; ++i )
965 this->myArray[ i ] = - this->myArray[ i ];
967//------------------------------------------------------------------------------
968template<DGtal::Dimension dim, typename TComponent, typename TContainer>
971DGtal::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//------------------------------------------------------------------------------
980template<DGtal::Dimension dim, typename TComponent, typename TContainer>
983DGtal::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//------------------------------------------------------------------------------
1012template<DGtal::Dimension dim, typename TComponent, typename TContainer>
1014typename DGtal::PointVector<dim, TComponent, TContainer>::UnsignedComponent
1015DGtal::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//------------------------------------------------------------------------------
1027template<DGtal::Dimension dim, typename TComponent, typename TContainer>
1029typename DGtal::PointVector<dim, TComponent, TContainer>::UnsignedComponent
1030DGtal::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//------------------------------------------------------------------------------
1045template<DGtal::Dimension dim, typename TComponent, typename TContainer>
1047typename DGtal::PointVector<dim, double, std::array<double,dim> >
1048DGtal::PointVector<dim, TComponent, TContainer>::getNormalized() const
1050 PointVector<dim,double,std::array<double,dim> > normalized =(*this);
1051 normalized /= normalized.norm();
1054//------------------------------------------------------------------------------
1055template<DGtal::Dimension dim, typename TComponent, typename TContainer>
1057DGtal::PointVector<dim,TComponent, TContainer>
1058DGtal::PointVector<dim,TComponent, TContainer>::diagonal( Component val )
1061 for ( DGtal::Dimension i = 0; i < dim; ++i )
1062 p.myArray[ i ] = val;
1065//------------------------------------------------------------------------------
1066template<DGtal::Dimension dim,typename TComponent, typename TContainer>
1068DGtal::PointVector<dim,TComponent, TContainer>
1069DGtal::PointVector<dim,TComponent, TContainer>::base( Dimension k, Component val )
1072 p.myArray[ k ] = val;
1075//------------------------------------------------------------------------------
1076template<DGtal::Dimension dim,typename TComponent, typename TContainer>
1079DGtal::PointVector<dim,TComponent, TContainer>::selfDisplay( std::ostream & out ) const
1082 for (DGtal::Dimension i = 0; i < dimension ; ++i)
1083 out << myArray[ i ] << (i == dimension - 1 ? "" : ", ");
1087//------------------------------------------------------------------------------
1088template<DGtal::Dimension dim, typename TComponent, typename TContainer>
1091DGtal::PointVector<dim, TComponent, TContainer>::className() const
1093 return "PointVector";
1096//------------------------------------------------------------------------------
1097template<DGtal::Dimension dim, typename TComponent, typename TContainer>
1100DGtal::operator<<( std::ostream & out,
1101 const PointVector<dim, TComponent, TContainer>& object )
1103 object.selfDisplay( out );
1106//------------------------------------------------------------------------------
1107template<DGtal::Dimension dim, typename TComponent, typename TContainer>
1110DGtal::PointVector<dim, TComponent, TContainer>::isValid() const
1114//------------------------------------------------------------------------------