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//////////////////////////////////////////////////////////////////////////////
41template<DGtal::Dimension dim, typename Container>
43std::bitset<dim> DGtal::setDimensionsIn( const Container &dimensions )
46 for ( typename Container::const_iterator it=dimensions.begin();
47 it!=dimensions.end(); ++it )
54//------------------------------------------------------------------------------
55template<DGtal::Dimension dim, typename Container>
57std::bitset<dim> DGtal::setDimensionsNotIn( const Container &dimensions )
59 std::bitset<dim> t1; t1.set();
60 for ( typename Container::const_iterator it=dimensions.begin();
61 it!=dimensions.end(); ++it )
68//------------------------------------------------------------------------------
71template<DGtal::Dimension dim, typename TComponent, typename TContainer>
73DGtal::PointVector<dim, TComponent, TContainer>::PointVector()
75 for ( Dimension i = 0; i < dim; ++i )
76 myArray[ i ] = NumberTraits<TComponent>::ZERO;
78//------------------------------------------------------------------------------
79template<DGtal::Dimension dim, typename TComponent, typename TContainer>
81 typename LeftComponent, typename LeftStorage,
82 typename RightComponent, typename RightStorage,
83 typename BinaryFunctor >
85DGtal::PointVector<dim, TComponent, TContainer>::PointVector(
86 const PointVector<dim, LeftComponent, LeftStorage> & apoint1,
87 const PointVector<dim, RightComponent, RightStorage> & apoint2,
88 const BinaryFunctor & f)
90 for ( Dimension i = 0; i < dim; ++i )
91 myArray[ i ] = static_cast<TComponent>( f(apoint1[i], apoint2[i]) );
93//------------------------------------------------------------------------------
94template <DGtal::Dimension dim, typename TComponent, typename TContainer>
95template <typename OtherComponent, typename OtherStorage, typename UnaryFunctor>
97DGtal::PointVector<dim, TComponent,TContainer>::
98PointVector(const PointVector<dim, OtherComponent, OtherStorage> & apoint1,
99 const UnaryFunctor& f)
101 for ( Dimension i = 0; i < dim; ++i )
102 myArray[ i ] = static_cast<TComponent>( f( apoint1[i] ) );
104//------------------------------------------------------------------------------
105template<DGtal::Dimension dim, typename TComponent, typename TContainer>
107DGtal::PointVector<dim, TComponent, TContainer>::PointVector( const Component * ptrValues )
109 // The problem here is that we have no guaranty on the size of init !!
110 for ( Dimension i = 0; i < dim; ++i )
111 myArray[ i ] = ptrValues[ i ];
113//------------------------------------------------------------------------------
114template<DGtal::Dimension dim, typename TComponent, typename TContainer>
116DGtal::PointVector<dim, TComponent, TContainer>::PointVector( const Component & x, const Component & y )
121 for ( Dimension i = 2; i < dim; ++i )
122 myArray[ i ] = NumberTraits<TComponent>::ZERO;
124//------------------------------------------------------------------------------
125template<DGtal::Dimension dim, typename TComponent, typename TContainer>
127DGtal::PointVector<dim, TComponent, TContainer>::PointVector( const Component & x,
129 const Component & z )
135 for ( Dimension i = 3; i < dim; ++i )
136 myArray[ i ] = NumberTraits<TComponent>::ZERO;
138//------------------------------------------------------------------------------
139template<DGtal::Dimension dim, typename TComponent, typename TContainer>
141DGtal::PointVector<dim, TComponent, TContainer>::PointVector( const Component & x,
144 const Component & t )
151 for ( Dimension i = 4; i < dim; ++i )
152 myArray[ i ] = NumberTraits<TComponent>::ZERO;
154//------------------------------------------------------------------------------
155template<DGtal::Dimension dim, typename TComponent, typename TContainer>
157DGtal::PointVector<dim, TComponent, TContainer>::PointVector(std::initializer_list<Component> init)
160 for (const Component *p = init.begin (); p != init.end () && i < dim; ++p, ++i)
162 for ( ; i < dim; ++i)
163 myArray[i] = NumberTraits<TComponent>::ZERO;
165//------------------------------------------------------------------------------
166template<DGtal::Dimension dim, typename TComponent, typename TContainer>
168DGtal::PointVector<dim, TComponent, TContainer>::PointVector ( const Self & other )
169 : myArray( other.myArray )
171//------------------------------------------------------------------------------
172template<DGtal::Dimension dim, typename TComponent, typename TContainer>
174 typename OtherComponent, typename OtherCont,
175 typename std::enable_if< std::is_same< TComponent, DGtal::ArithmeticConversionType<TComponent, OtherComponent> >::value, int >::type >
177DGtal::PointVector<dim, TComponent, TContainer>::PointVector (const PointVector<dim,OtherComponent,OtherCont> & other )
179 for ( DGtal::Dimension i = 0; i < dimension; ++i )
180 this->myArray[ i ] = static_cast<TComponent>(other[ i ]);
182//------------------------------------------------------------------------------
183template<DGtal::Dimension dim, typename TComponent, typename TContainer>
185 typename OtherComponent, typename OtherCont,
186 typename std::enable_if< ! std::is_same< TComponent, DGtal::ArithmeticConversionType<TComponent, OtherComponent> >::value, int >::type >
188DGtal::PointVector<dim, TComponent, TContainer>::PointVector (const PointVector<dim,OtherComponent,OtherCont> & other )
190 for ( DGtal::Dimension i = 0; i < dimension; ++i )
191 this->myArray[ i ] = static_cast<TComponent>(other[ i ]);
193//------------------------------------------------------------------------------
194template<DGtal::Dimension dim, typename TComponent, typename TContainer>
196typename DGtal::PointVector<dim, TComponent, TContainer>::Iterator
197DGtal::PointVector<dim, TComponent, TContainer>::begin()
199 return myArray.begin();
201//------------------------------------------------------------------------------
202template<DGtal::Dimension dim, typename TComponent, typename TContainer>
204typename DGtal::PointVector<dim, TComponent, TContainer>::Iterator
205DGtal::PointVector<dim, TComponent, TContainer>::end()
207 return myArray.end();
209//------------------------------------------------------------------------------
210template<DGtal::Dimension dim, typename TComponent, typename TContainer>
212typename DGtal::PointVector<dim, TComponent, TContainer>::ConstIterator
213DGtal::PointVector<dim, TComponent, TContainer>::begin() const
215 return myArray.begin();
217//------------------------------------------------------------------------------
218template<DGtal::Dimension dim, typename TComponent, typename TContainer>
220typename DGtal::PointVector<dim, TComponent, TContainer>::ConstIterator
221DGtal::PointVector<dim, TComponent, TContainer>::end() const
223 return myArray.end();
225//------------------------------------------------------------------------------
226template<DGtal::Dimension dim, typename TComponent, typename TContainer>
228typename DGtal::PointVector<dim, TComponent, TContainer>::ReverseIterator
229DGtal::PointVector<dim, TComponent, TContainer>::rbegin()
231 return myArray.rbegin();
233//------------------------------------------------------------------------------
234template<DGtal::Dimension dim, typename TComponent, typename TContainer>
236typename DGtal::PointVector<dim, TComponent, TContainer>::ReverseIterator
237DGtal::PointVector<dim, TComponent, TContainer>::rend()
239 return myArray.rend();
241//------------------------------------------------------------------------------
242template<DGtal::Dimension dim, typename TComponent, typename TContainer>
244typename DGtal::PointVector<dim, TComponent, TContainer>::ConstReverseIterator
245DGtal::PointVector<dim, TComponent, TContainer>::rbegin() const
247 return myArray.rbegin();
249//------------------------------------------------------------------------------
250template<DGtal::Dimension dim, typename TComponent, typename TContainer>
252typename DGtal::PointVector<dim, TComponent, TContainer>::ConstReverseIterator
253DGtal::PointVector<dim, TComponent, TContainer>::rend() const
255 return myArray.rend();
257//------------------------------------------------------------------------------
258template<DGtal::Dimension dim, typename TComponent, typename TContainer>
260typename DGtal::Dimension
261DGtal::PointVector<dim, TComponent, TContainer>::size()
265//------------------------------------------------------------------------------
266template<DGtal::Dimension dim, typename TComponent, typename TContainer>
268const typename DGtal::PointVector<dim, TComponent, TContainer>::Component *
269DGtal::PointVector<dim, TComponent, TContainer>::data() const noexcept
271 return myArray.data();
273//------------------------------------------------------------------------------
274template<DGtal::Dimension dim, typename TComponent, typename TContainer>
276typename DGtal::PointVector<dim, TComponent, TContainer>::Component *
277DGtal::PointVector<dim, TComponent, TContainer>::data() noexcept
279 return myArray.data();
281//------------------------------------------------------------------------------
282template<DGtal::Dimension dim, typename TComponent, typename TContainer>
284const typename DGtal::PointVector<dim, TComponent, TContainer>::Component &
285DGtal::PointVector<dim, TComponent, TContainer>::operator[]( Dimension i ) const
290//------------------------------------------------------------------------------
291template<DGtal::Dimension dim, typename TComponent, typename TContainer>
293typename DGtal::PointVector<dim, TComponent, TContainer>::Component &
294DGtal::PointVector<dim, TComponent, TContainer>::operator[]( Dimension i )
299//------------------------------------------------------------------------------
300template<DGtal::Dimension dim, typename TComponent, typename TContainer>
302DGtal::PointVector<dim, TComponent, TContainer>&
303DGtal::PointVector<dim, TComponent, TContainer>::operator= ( const Self & pv )
305 myArray = pv.myArray;
308//------------------------------------------------------------------------------
309template<DGtal::Dimension dim, typename TComponent, typename TContainer>
311 typename OtherComponent,
312 typename OtherContainer,
313 typename std::enable_if< std::is_same< TComponent, DGtal::ArithmeticConversionType<TComponent, OtherComponent> >::value, int >::type>
315DGtal::PointVector<dim, TComponent, TContainer> &
316DGtal::PointVector<dim, TComponent, TContainer>::operator= ( const DGtal::PointVector<dim, OtherComponent, OtherContainer> & v )
318 for ( DGtal::Dimension i = 0; i < dimension; ++i )
320 this->myArray[ i ] = static_cast<Component>( v[ i ] );
324//------------------------------------------------------------------------------
325template<DGtal::Dimension dim, typename TComponent, typename TContainer>
327 typename OtherComponent,
328 typename OtherContainer,
329 typename std::enable_if< std::is_same< TComponent, DGtal::ArithmeticConversionType<TComponent, OtherComponent> >::value, int >::type>
331DGtal::PointVector<dim, TComponent, TContainer>&
332DGtal::PointVector<dim, TComponent, TContainer>::partialCopy
333( const DGtal::PointVector<dim, OtherComponent, OtherContainer> & pv,
334 const std::vector<DGtal::Dimension> &dimensions)
336 std::bitset<dim> dims = setDimensionsIn<dim>(dimensions);
337 for ( DGtal::Dimension i = 0; i < dim; ++i )
339 if ( dims.test(i) ) myArray[i] = static_cast<TComponent>(pv.myArray[i]);
343//------------------------------------------------------------------------------
344template<DGtal::Dimension dim, typename TComponent, typename TContainer>
346 typename OtherComponent,
347 typename OtherContainer,
348 typename std::enable_if< std::is_same< TComponent, DGtal::ArithmeticConversionType<TComponent, OtherComponent> >::value, int >::type>
350DGtal::PointVector<dim, TComponent, TContainer>&
351DGtal::PointVector<dim, TComponent, TContainer>::partialCopyInv
352( const DGtal::PointVector<dim, OtherComponent, OtherContainer> & pv,
353 const std::vector<DGtal::Dimension> &dimensions)
355 std::bitset<dim> dims = setDimensionsIn<dim>(dimensions);
356 for ( DGtal::Dimension i = 0; i < dim; ++i )
358 if ( !dims.test(i) ) myArray[i] = static_cast<TComponent>(pv.myArray[i]);
362//------------------------------------------------------------------------------
363template<DGtal::Dimension dim, typename TComponent, typename TContainer>
365 typename OtherComponent,
366 typename OtherContainer,
367 typename UnaryFunctor >
369DGtal::PointVector<dim, TComponent, TContainer>&
370DGtal::PointVector<dim, TComponent, TContainer>::partialCopy
371( const DGtal::PointVector<dim, OtherComponent, OtherContainer> & pv,
372 const std::vector<DGtal::Dimension> &dimensions,
373 const UnaryFunctor &f)
375 std::bitset<dim> dims = setDimensionsIn<dim>(dimensions);
376 for ( DGtal::Dimension i = 0; i < dim; ++i )
378 if ( dims.test(i) ) myArray[i] = static_cast<TComponent>(f(pv.myArray[i]));
382//------------------------------------------------------------------------------
383template<DGtal::Dimension dim, typename TComponent, typename TContainer>
385 typename OtherComponent,
386 typename OtherContainer,
387 typename UnaryFunctor >
389DGtal::PointVector<dim, TComponent, TContainer>&
390DGtal::PointVector<dim, TComponent, TContainer>::partialCopyInv
391( const DGtal::PointVector<dim, OtherComponent, OtherContainer> & pv,
392 const std::vector<DGtal::Dimension> &dimensions,
393 const UnaryFunctor &f)
395 std::bitset<dim> dims = setDimensionsIn<dim>(dimensions);
396 for ( DGtal::Dimension i = 0; i < dim; ++i )
398 if ( !dims.test(i) ) myArray[i] = static_cast<TComponent>(f(pv.myArray[i]));
402//------------------------------------------------------------------------------
403template<DGtal::Dimension dim, typename TComponent, typename TContainer>
404template <typename TOtherComponent, typename TOtherContainer>
407DGtal::PointVector<dim, TComponent, TContainer>::partialEqual
408( const DGtal::PointVector<dim, TOtherComponent, TOtherContainer> & pv,
409 const std::vector<DGtal::Dimension> &dimensions ) const
411 std::bitset<dim> dims = setDimensionsIn<dim>(dimensions);
412 for ( DGtal::Dimension i = 0; i < dim; ++i )
414 if ( dims.test(i) && myArray[i] != pv.myArray[i]) return false;
418//------------------------------------------------------------------------------
419template<DGtal::Dimension dim, typename TComponent, typename TContainer>
420template <typename TOtherComponent, typename TOtherContainer>
423DGtal::PointVector<dim, TComponent, TContainer>::partialEqualInv
424( const DGtal::PointVector<dim, TOtherComponent, TOtherContainer> & pv,
425 const std::vector<DGtal::Dimension> &dimensions ) const
427 std::bitset<dim> dims = setDimensionsIn<dim>(dimensions);
428 for ( DGtal::Dimension i = 0; i < dim; ++i )
430 if ( !dims.test(i) && myArray[i] != pv.myArray[i]) return false;
434//------------------------------------------------------------------------------
435template < DGtal::Dimension ptDim,
436 typename LeftEuclideanRing, typename LeftContainer,
437 typename RightEuclideanRing, typename RightContainer >
439DGtal::operator== ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
440 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
442 return std::equal( lhs.begin(), lhs.end(), rhs.begin() );
444//------------------------------------------------------------------------------
445template < DGtal::Dimension ptDim,
446 typename LeftEuclideanRing, typename LeftContainer,
447 typename RightEuclideanRing, typename RightContainer >
449DGtal::operator!= ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
450 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
452 return ! (lhs == rhs);
454//------------------------------------------------------------------------------
455template < DGtal::Dimension ptDim,
456 typename LeftEuclideanRing, typename LeftContainer,
457 typename RightEuclideanRing, typename RightContainer >
459DGtal::operator< ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
460 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
462 return std::lexicographical_compare( lhs.begin(), lhs.end(), rhs.begin(), rhs.end() );
464//------------------------------------------------------------------------------
465template < DGtal::Dimension ptDim,
466 typename LeftEuclideanRing, typename LeftContainer,
467 typename RightEuclideanRing, typename RightContainer >
469DGtal::operator> ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
470 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
474//------------------------------------------------------------------------------
475template < DGtal::Dimension ptDim,
476 typename LeftEuclideanRing, typename LeftContainer,
477 typename RightEuclideanRing, typename RightContainer >
479DGtal::operator<= ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
480 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
482 return ! ( lhs > rhs );
484//------------------------------------------------------------------------------
485template < DGtal::Dimension ptDim,
486 typename LeftEuclideanRing, typename LeftContainer,
487 typename RightEuclideanRing, typename RightContainer >
489DGtal::operator>= ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
490 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
492 return ! ( lhs < rhs );
494//------------------------------------------------------------------------------
495template<DGtal::Dimension dim, typename TComponent, typename TContainer>
497 typename OtherComponent, typename OtherStorage,
498 typename std::enable_if< std::is_same< TComponent, DGtal::ArithmeticConversionType<TComponent, OtherComponent> >::value, int >::type >
500DGtal::PointVector<dim, TComponent, TContainer>&
501DGtal::PointVector<dim, TComponent, TContainer>::operator+= ( PointVector<dim, OtherComponent, OtherStorage> const& v )
503 for ( DGtal::Dimension i = 0; i < dim; ++i )
504 this->myArray[ i ] += v[ i ];
507//------------------------------------------------------------------------------
508template<DGtal::Dimension dim, typename TComponent, typename TContainer>
510 typename OtherComponent,
511 typename std::enable_if< std::is_same< TComponent, DGtal::ArithmeticConversionType<TComponent, OtherComponent> >::value, int >::type >
513DGtal::PointVector<dim, TComponent, TContainer>&
514DGtal::PointVector<dim, TComponent, TContainer>::operator+= ( OtherComponent coeff )
516 for ( DGtal::Dimension i = 0; i < dim; ++i )
517 this->myArray[ i ] += coeff;
520//------------------------------------------------------------------------------
521template<DGtal::Dimension dim, typename TComponent, typename TContainer>
523 typename OtherComponent, typename OtherStorage,
524 typename std::enable_if< std::is_same< TComponent, DGtal::ArithmeticConversionType<TComponent, OtherComponent> >::value, int >::type >
526DGtal::PointVector<dim, TComponent, TContainer>&
527DGtal::PointVector<dim, TComponent, TContainer>::operator-= ( PointVector<dim, OtherComponent, OtherStorage> const& v )
529 for ( DGtal::Dimension i = 0; i < dim; ++i )
530 this->myArray[ i ] -= v[ i ];
533//------------------------------------------------------------------------------
534template<DGtal::Dimension dim, typename TComponent, typename TContainer>
536 typename OtherComponent,
537 typename std::enable_if< std::is_same< TComponent, DGtal::ArithmeticConversionType<TComponent, OtherComponent> >::value, int >::type >
539DGtal::PointVector<dim, TComponent, TContainer>&
540DGtal::PointVector<dim, TComponent, TContainer>::operator-= ( OtherComponent coeff )
542 for ( DGtal::Dimension i = 0; i < dim; ++i )
543 this->myArray[ i ] -= coeff;
546//------------------------------------------------------------------------------
547template<DGtal::Dimension dim, typename TComponent, typename TContainer>
549 typename OtherComponent,
550 typename std::enable_if< std::is_same< TComponent, DGtal::ArithmeticConversionType<TComponent, OtherComponent> >::value, int >::type>
551DGtal::PointVector<dim, TComponent, TContainer>&
552DGtal::PointVector<dim, TComponent, TContainer>::operator*= ( OtherComponent coeff )
554 for ( DGtal::Dimension i = 0; i < myArray.size(); ++i )
555 myArray[ i ] *= coeff;
558//------------------------------------------------------------------------------
559template<DGtal::Dimension dim, typename TComponent, typename TContainer>
561 typename OtherComponent, typename OtherStorage,
562 typename std::enable_if< std::is_same< TComponent, DGtal::ArithmeticConversionType<TComponent, OtherComponent> >::value, int >::type>
563DGtal::PointVector<dim, TComponent, TContainer>&
564DGtal::PointVector<dim, TComponent, TContainer>::operator*= ( PointVector<dim, OtherComponent, OtherStorage> const& v )
566 for ( DGtal::Dimension i = 0; i < myArray.size(); ++i )
567 myArray[ i ] *= v[ i ];
570//------------------------------------------------------------------------------
571template<DGtal::Dimension dim, typename TComponent, typename TContainer>
573 typename OtherComponent,
574 typename std::enable_if< std::is_same< TComponent, DGtal::ArithmeticConversionType<TComponent, OtherComponent> >::value, int >::type>
575DGtal::PointVector<dim, TComponent, TContainer>&
576DGtal::PointVector<dim, TComponent, TContainer>::operator/= ( OtherComponent coeff )
578 for ( DGtal::Dimension i = 0; i < myArray.size(); ++i )
579 myArray[ i ] /= coeff;
582//------------------------------------------------------------------------------
583template<DGtal::Dimension dim, typename TComponent, typename TContainer>
585 typename OtherComponent, typename OtherStorage,
586 typename std::enable_if< std::is_same< TComponent, DGtal::ArithmeticConversionType<TComponent, OtherComponent> >::value, int >::type>
587DGtal::PointVector<dim, TComponent, TContainer>&
588DGtal::PointVector<dim, TComponent, TContainer>::operator/= ( PointVector<dim, OtherComponent, OtherStorage> const& v )
590 for ( DGtal::Dimension i = 0; i < myArray.size(); ++i )
591 myArray[ i ] /= v[ i ];
594//------------------------------------------------------------------------------
595template<DGtal::Dimension dim, typename TComponent, typename TContainer>
596template < typename OtherComponent, typename OtherStorage >
598DGtal::PointVector<dim, TComponent, TContainer>::dot( const DGtal::PointVector<dim, OtherComponent, OtherStorage>& v ) const
599 -> decltype( DGtal::dotProduct(*this, v) )
601 return DGtal::dotProduct(*this, v);
603//------------------------------------------------------------------------------
604template < DGtal::Dimension ptDim,
605 typename LeftEuclideanRing, typename LeftContainer,
606 typename RightEuclideanRing, typename RightContainer >
608DGtal::ArithmeticConversionType<LeftEuclideanRing, RightEuclideanRing>
609DGtal::dotProduct ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
610 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
612 using EuclideanRing = ArithmeticConversionType<LeftEuclideanRing, RightEuclideanRing>;
613 auto dotprod = NumberTraits<EuclideanRing>::ZERO;
614 for ( DGtal::Dimension i = 0; i < ptDim; ++i )
615 dotprod += lhs[ i ] * rhs[ i ];
618//------------------------------------------------------------------------------
619template < DGtal::Dimension ptDim,
620 typename LeftEuclideanRing, typename LeftContainer,
621 typename RightEuclideanRing, typename RightContainer >
623DGtal::cosineSimilarity ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
624 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
627 if ( lhs.norm() > 0. && rhs.norm() > 0. )
628 radians = rhs.dot ( lhs ) / ( lhs.norm() * rhs.norm() );
630 throw std::runtime_error ( "Operation involving a null vector is not defined!" );
631 return std::acos ( std::min ( std::max ( radians, -1. ), 1. ) );
634//------------------------------------------------------------------------------
635template<DGtal::Dimension dim, typename TComponent, typename TContainer>
636template < typename OtherComponent, typename OtherStorage >
638DGtal::PointVector<dim, TComponent, TContainer>::cosineSimilarity( const DGtal::PointVector<dim, OtherComponent, OtherStorage>& v ) const
640 return DGtal::cosineSimilarity(*this, v);
642//------------------------------------------------------------------------------
643template<DGtal::Dimension dim, typename TComponent, typename TContainer>
644template < typename OtherComponent, typename OtherStorage >
646DGtal::PointVector<dim, TComponent, TContainer>::crossProduct( const DGtal::PointVector<dim, OtherComponent, OtherStorage>& v ) const
647 -> decltype( DGtal::crossProduct(*this, v) )
649 return DGtal::crossProduct(*this, v);
651//------------------------------------------------------------------------------
653 typename LeftEuclideanRing, typename LeftContainer,
654 typename RightEuclideanRing, typename RightContainer >
656DGtal::crossProduct ( DGtal::PointVector<3, LeftEuclideanRing, LeftContainer> const& lhs,
657 DGtal::PointVector<3, RightEuclideanRing, RightContainer> const& rhs )
658 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
660 auto crossprod = constructFromArithmeticConversion(lhs, rhs);
661 for ( DGtal::Dimension i = 0; i < 3; ++i )
663 lhs[ (i+1)%3 ] * rhs[ (i+2)%3 ]
664 - lhs[ (i+2)%3 ] * rhs[ (i+1)%3 ];
667//------------------------------------------------------------------------------
669 typename LeftEuclideanRing, typename LeftContainer,
670 typename RightEuclideanRing, typename RightContainer >
672DGtal::PointVector<3, DGtal::ArithmeticConversionType<LeftEuclideanRing, RightEuclideanRing>>
673DGtal::crossProduct ( DGtal::PointVector<2, LeftEuclideanRing, LeftContainer> const& lhs,
674 DGtal::PointVector<2, RightEuclideanRing, RightContainer> const& rhs )
676 return PointVector<3, ArithmeticConversionType<LeftEuclideanRing, RightEuclideanRing>>(
679 lhs[0]*rhs[1] - lhs[1]*rhs[0]
682//------------------------------------------------------------------------------
683template < DGtal::Dimension ptDim,
684 typename LeftEuclideanRing, typename LeftContainer,
685 typename RightEuclideanRing, typename RightContainer >
687DGtal::operator+ ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
688 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
689 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
691 using EuclideanRing = ArithmeticConversionType<LeftEuclideanRing, RightEuclideanRing>;
692 return constructFromArithmeticConversion(lhs, rhs, lhs, rhs, std::plus<EuclideanRing>());
694//------------------------------------------------------------------------------
695template < DGtal::Dimension ptDim,
696 typename LeftEuclideanRing, typename LeftContainer,
697 typename RightEuclideanRing, typename RightContainer >
699DGtal::operator- ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
700 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
701 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
703 using EuclideanRing = ArithmeticConversionType<LeftEuclideanRing, RightEuclideanRing>;
704 return constructFromArithmeticConversion(lhs, rhs, lhs, rhs, std::minus<EuclideanRing>());
706//------------------------------------------------------------------------------
707template < DGtal::Dimension ptDim,
708 typename LeftEuclideanRing, typename LeftContainer,
709 typename RightEuclideanRing, typename RightContainer >
711DGtal::operator* ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
712 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
713 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
715 using EuclideanRing = ArithmeticConversionType<LeftEuclideanRing, RightEuclideanRing>;
716 return constructFromArithmeticConversion(lhs, rhs, lhs, rhs, std::multiplies<EuclideanRing>());
718//------------------------------------------------------------------------------
719template < DGtal::Dimension ptDim,
720 typename LeftEuclideanRing, typename LeftContainer,
721 typename RightEuclideanRing, typename RightContainer >
723DGtal::operator/ ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
724 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
725 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
727 using EuclideanRing = ArithmeticConversionType<LeftEuclideanRing, RightEuclideanRing>;
728 return constructFromArithmeticConversion(lhs, rhs, lhs, rhs, std::divides<EuclideanRing>());
730//------------------------------------------------------------------------------
731template < DGtal::Dimension ptDim,
732 typename LeftEuclideanRing, typename LeftContainer,
733 typename RightScalar >
735DGtal::operator+ ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
736 RightScalar const& rhs )
737 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
739 return constructFromArithmeticConversion(lhs, rhs, lhs, [&rhs] (LeftEuclideanRing v) { return v + rhs; });
741//------------------------------------------------------------------------------
742template < DGtal::Dimension ptDim,
744 typename RightEuclideanRing, typename RightContainer >
746DGtal::operator+ ( LeftScalar const& lhs,
747 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
748 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
750 return constructFromArithmeticConversion(lhs, rhs, rhs, [&lhs] (RightEuclideanRing v) { return lhs + v; });
752//------------------------------------------------------------------------------
753template < DGtal::Dimension ptDim,
754 typename LeftEuclideanRing, typename LeftContainer,
755 typename RightScalar >
757DGtal::operator- ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
758 RightScalar const& rhs )
759 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
761 return constructFromArithmeticConversion(lhs, rhs, lhs, [&rhs] (LeftEuclideanRing v) { return v - rhs; });
763//------------------------------------------------------------------------------
764template < DGtal::Dimension ptDim,
766 typename RightEuclideanRing, typename RightContainer >
768DGtal::operator- ( LeftScalar const& lhs,
769 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
770 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
772 return constructFromArithmeticConversion(lhs, rhs, rhs, [&lhs] (RightEuclideanRing v) { return lhs - v; });
774//------------------------------------------------------------------------------
775template < DGtal::Dimension ptDim,
776 typename LeftEuclideanRing, typename LeftContainer,
777 typename RightScalar >
779DGtal::operator* ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
780 RightScalar const& rhs )
781 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
783 return constructFromArithmeticConversion(lhs, rhs, lhs, [&rhs] (LeftEuclideanRing v) { return v * rhs; });
785//------------------------------------------------------------------------------
786template < DGtal::Dimension ptDim,
788 typename RightEuclideanRing, typename RightContainer >
790DGtal::operator* ( LeftScalar const& lhs,
791 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
792 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
794 return constructFromArithmeticConversion(lhs, rhs, rhs, [&lhs] (RightEuclideanRing v) { return lhs * v; });
796//------------------------------------------------------------------------------
797template < DGtal::Dimension ptDim,
798 typename LeftEuclideanRing, typename LeftContainer,
799 typename RightScalar >
801DGtal::operator/ ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
802 RightScalar const& rhs )
803 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
805 return constructFromArithmeticConversion(lhs, rhs, lhs, [&rhs] (LeftEuclideanRing v) { return v / rhs; });
807//------------------------------------------------------------------------------
808template < DGtal::Dimension ptDim,
810 typename RightEuclideanRing, typename RightContainer >
812DGtal::operator/ ( LeftScalar const& lhs,
813 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
814 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
816 return constructFromArithmeticConversion(lhs, rhs, rhs, [&lhs] (RightEuclideanRing v) { return lhs / v; });
818//------------------------------------------------------------------------------
819template<DGtal::Dimension dim, typename TComponent, typename TContainer>
821DGtal::PointVector<dim, TComponent,TContainer>
822DGtal::PointVector<dim, TComponent,TContainer>::operator-() const
824 return Self(*this, functors::UnaryMinus<Component>());
826//------------------------------------------------------------------------------
827template<DGtal::Dimension dim, typename TComponent, typename TContainer>
830DGtal::PointVector<dim, TComponent, TContainer>::reset()
832 for ( DGtal::Dimension i = 0; i < myArray.size(); ++i )
833 myArray[ i ] = NumberTraits< Component >::ZERO;
835//------------------------------------------------------------------------------
836template < DGtal::Dimension ptDim,
837 typename LeftEuclideanRing, typename LeftContainer,
838 typename RightEuclideanRing, typename RightContainer >
840DGtal::inf( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
841 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
842 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
844 using EuclideanRing = ArithmeticConversionType<LeftEuclideanRing, RightEuclideanRing>;
845 return DGtal::constructFromArithmeticConversion(lhs, rhs, lhs, rhs, functors::Min<EuclideanRing>());
847//------------------------------------------------------------------------------
848template<DGtal::Dimension dim, typename TComponent, typename TContainer>
849template < typename OtherComponent, typename OtherStorage >
851DGtal::PointVector<dim, TComponent, TContainer>::inf( const DGtal::PointVector<dim, OtherComponent, OtherStorage>& aPoint ) const
852 -> decltype( DGtal::inf(*this, aPoint) )
854 return DGtal::inf(*this, aPoint);
856//------------------------------------------------------------------------------
857template < DGtal::Dimension ptDim,
858 typename LeftEuclideanRing, typename LeftContainer,
859 typename RightEuclideanRing, typename RightContainer >
861DGtal::sup( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
862 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
863 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
865 using EuclideanRing = ArithmeticConversionType<LeftEuclideanRing, RightEuclideanRing>;
866 return DGtal::constructFromArithmeticConversion(lhs, rhs, lhs, rhs, functors::Max<EuclideanRing>());
868//------------------------------------------------------------------------------
869template<DGtal::Dimension dim, typename TComponent, typename TContainer>
870template < typename OtherComponent, typename OtherStorage >
872DGtal::PointVector<dim, TComponent, TContainer>::sup( const DGtal::PointVector<dim, OtherComponent, OtherStorage>& aPoint ) const
873 -> decltype( DGtal::sup(*this, aPoint) )
875 return DGtal::sup(*this, aPoint);
877//------------------------------------------------------------------------------
878template < DGtal::Dimension ptDim,
879 typename LeftEuclideanRing, typename LeftContainer,
880 typename RightEuclideanRing, typename RightContainer >
882DGtal::isLower( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
883 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
885 for ( DGtal::Dimension i = 0; i < ptDim; ++i )
886 if ( rhs[ i ] < lhs[ i ] )
890//------------------------------------------------------------------------------
891template<DGtal::Dimension dim, typename TComponent, typename TContainer>
892template < typename OtherComponent, typename OtherStorage >
894DGtal::PointVector<dim, TComponent, TContainer>::isLower( const DGtal::PointVector<dim, OtherComponent, OtherStorage> & p ) const
896 return DGtal::isLower(*this, p);
898//------------------------------------------------------------------------------
899template < DGtal::Dimension ptDim,
900 typename LeftEuclideanRing, typename LeftContainer,
901 typename RightEuclideanRing, typename RightContainer >
903DGtal::isUpper( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
904 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
906 for ( DGtal::Dimension i = 0; i < ptDim; ++i )
907 if ( rhs[ i ] > lhs[ i ] )
911//------------------------------------------------------------------------------
912template<DGtal::Dimension dim, typename TComponent, typename TContainer>
913template < typename OtherComponent, typename OtherStorage >
915DGtal::PointVector<dim, TComponent, TContainer>::isUpper( const DGtal::PointVector<dim, OtherComponent, OtherStorage> & p ) const
917 return DGtal::isUpper(*this, p);
919//------------------------------------------------------------------------------
920template<DGtal::Dimension dim, typename TComponent, typename TContainer>
922typename DGtal::PointVector<dim, TComponent, TContainer>::Component
923DGtal::PointVector<dim, TComponent, TContainer>::max( ) const
925 return *std::max_element(this->begin(), this->end());
927//------------------------------------------------------------------------------
928template<DGtal::Dimension dim, typename TComponent, typename TContainer>
930typename DGtal::PointVector<dim, TComponent, TContainer>::Component
931DGtal::PointVector<dim, TComponent, TContainer>::min( ) const
933 return *std::min_element(this->begin(), this->end());
935//------------------------------------------------------------------------------
936template<DGtal::Dimension dim, typename TComponent, typename TContainer>
938typename DGtal::PointVector<dim, TComponent, TContainer>::Iterator
939DGtal::PointVector<dim, TComponent, TContainer>::maxElement( )
941 return std::max_element(this->begin(), this->end());
943//------------------------------------------------------------------------------
944template<DGtal::Dimension dim, typename TComponent, typename TContainer>
946typename DGtal::PointVector<dim, TComponent, TContainer>::Iterator
947DGtal::PointVector<dim, TComponent, TContainer>::minElement( )
949 return std::min_element(this->begin(), this->end());
951//------------------------------------------------------------------------------
952template<DGtal::Dimension dim, typename TComponent, typename TContainer>
955DGtal::PointVector<dim, TComponent, TContainer>::
958 for ( DGtal::Dimension i = 0; i < dimension; ++i )
959 this->myArray[ i ] = - this->myArray[ i ];
961//------------------------------------------------------------------------------
962template<DGtal::Dimension dim, typename TComponent, typename TContainer>
965DGtal::PointVector<dim, TComponent, TContainer>::squaredNorm () const
969 for ( DGtal::Dimension i = 0; i < dimension; i++ )
970 tmp += std::pow(NumberTraits<Component>::castToDouble(myArray[ i ]), 2);
973//------------------------------------------------------------------------------
974template<DGtal::Dimension dim, typename TComponent, typename TContainer>
977DGtal::PointVector<dim, TComponent, TContainer>::norm (
978 const typename Self::NormType aType ) const
987 for ( DGtal::Dimension i = 0; i < dimension; i++ )
988 tmp += NumberTraits<Component>::castToDouble(myArray[ i ]) *
989 NumberTraits<Component>::castToDouble(myArray[ i ]);
990 tmp = ( double ) sqrt ( tmp );
993 for ( DGtal::Dimension i = 0; i < dimension; i++ )
994 tmp += fabs ( NumberTraits<Component>::castToDouble(myArray[ i ] ));
997 tmp = fabs( NumberTraits<Component>::castToDouble( myArray[ 0 ]));
998 for ( DGtal::Dimension i = 1; i < dimension; i++ )
999 if ( tmp < fabs ( NumberTraits<Component>::castToDouble(myArray[ i ] ) ))
1000 tmp = fabs ( NumberTraits<Component>::castToDouble(myArray[ i ] ));
1005//------------------------------------------------------------------------------
1006template<DGtal::Dimension dim, typename TComponent, typename TContainer>
1008typename DGtal::PointVector<dim, TComponent, TContainer>::UnsignedComponent
1009DGtal::PointVector<dim, TComponent, TContainer>::norm1() const
1011 ASSERT ( dimension > 0 );
1012 UnsignedComponent val
1013 ( ( myArray[ 0 ] >= 0 ) ? myArray[ 0 ] : UnsignedComponent(-myArray[ 0 ]) );
1014 for ( DGtal::Dimension i = 1; i < dimension; ++i )
1015 val += ( myArray[ i ] >= 0 )
1017 : UnsignedComponent(-myArray[ i ]);
1020//------------------------------------------------------------------------------
1021template<DGtal::Dimension dim, typename TComponent, typename TContainer>
1023typename DGtal::PointVector<dim, TComponent, TContainer>::UnsignedComponent
1024DGtal::PointVector<dim, TComponent, TContainer>::normInfinity() const
1026 ASSERT ( dimension > 0 );
1027 UnsignedComponent tmp;
1028 UnsignedComponent val( ( myArray[ 0 ] >= 0 ) ? myArray[ 0 ] : -myArray[ 0 ] );
1029 for ( DGtal::Dimension i = 1; i < dimension; ++i )
1031 tmp = ( myArray[ i ] >= 0 ) ? myArray[ i ] : -myArray[ i ] ;
1037//------------------------------------------------------------------------------
1039template<DGtal::Dimension dim, typename TComponent, typename TContainer>
1041typename DGtal::PointVector<dim, double, std::array<double,dim> >
1042DGtal::PointVector<dim, TComponent, TContainer>::getNormalized() const
1044 PointVector<dim,double,std::array<double,dim> > normalized(*this);
1045 normalized /= normalized.norm();
1048//------------------------------------------------------------------------------
1049template<DGtal::Dimension dim, typename TComponent, typename TContainer>
1051DGtal::PointVector<dim,TComponent, TContainer>
1052DGtal::PointVector<dim,TComponent, TContainer>::diagonal( Component val )
1055 for ( DGtal::Dimension i = 0; i < dim; ++i )
1056 p.myArray[ i ] = val;
1059//------------------------------------------------------------------------------
1060template<DGtal::Dimension dim,typename TComponent, typename TContainer>
1062DGtal::PointVector<dim,TComponent, TContainer>
1063DGtal::PointVector<dim,TComponent, TContainer>::base( Dimension k, Component val )
1066 p.myArray[ k ] = val;
1069//------------------------------------------------------------------------------
1070template<DGtal::Dimension dim,typename TComponent, typename TContainer>
1073DGtal::PointVector<dim,TComponent, TContainer>::selfDisplay( std::ostream & out ) const
1076 for (DGtal::Dimension i = 0; i < dimension ; ++i)
1077 out << myArray[ i ] << (i == dimension - 1 ? "" : ", ");
1081//------------------------------------------------------------------------------
1082template<DGtal::Dimension dim, typename TComponent, typename TContainer>
1085DGtal::PointVector<dim, TComponent, TContainer>::className() const
1087 return "PointVector";
1090//------------------------------------------------------------------------------
1091template<DGtal::Dimension dim, typename TComponent, typename TContainer>
1094DGtal::operator<<( std::ostream & out,
1095 const PointVector<dim, TComponent, TContainer>& object )
1097 object.selfDisplay( out );
1100//------------------------------------------------------------------------------
1101template<DGtal::Dimension dim, typename TComponent, typename TContainer>
1104DGtal::PointVector<dim, TComponent, TContainer>::isValid() const
1108//------------------------------------------------------------------------------