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( const Component * ptrValues )
110 // The problem here is that we have no guaranty on the size of init !!
111 for ( Dimension i = 0; i < dim; ++i )
112 myArray[ i ] = ptrValues[ i ];
114//------------------------------------------------------------------------------
115template<DGtal::Dimension dim, typename TComponent, typename TContainer>
117DGtal::PointVector<dim, TComponent, TContainer>::PointVector( const Component & x, const Component & y )
122 for ( Dimension i = 2; i < dim; ++i )
123 myArray[ i ] = NumberTraits<TComponent>::ZERO;
125//------------------------------------------------------------------------------
126template<DGtal::Dimension dim, typename TComponent, typename TContainer>
128DGtal::PointVector<dim, TComponent, TContainer>::PointVector( const Component & x,
130 const Component & z )
136 for ( Dimension i = 3; i < dim; ++i )
137 myArray[ i ] = NumberTraits<TComponent>::ZERO;
139//------------------------------------------------------------------------------
140template<DGtal::Dimension dim, typename TComponent, typename TContainer>
142DGtal::PointVector<dim, TComponent, TContainer>::PointVector( const Component & x,
145 const Component & t )
152 for ( Dimension i = 4; i < dim; ++i )
153 myArray[ i ] = NumberTraits<TComponent>::ZERO;
155//------------------------------------------------------------------------------
156template<DGtal::Dimension dim, typename TComponent, typename TContainer>
158DGtal::PointVector<dim, TComponent, TContainer>::PointVector(std::initializer_list<Component> init)
161 for (const Component *p = init.begin (); p != init.end () && i < dim; ++p, ++i)
163 for ( ; i < dim; ++i)
164 myArray[i] = NumberTraits<TComponent>::ZERO;
166//------------------------------------------------------------------------------
167template<DGtal::Dimension dim, typename TComponent, typename TContainer>
169DGtal::PointVector<dim, TComponent, TContainer>::PointVector ( const Self & other )
170 : myArray( other.myArray )
172//------------------------------------------------------------------------------
173template<DGtal::Dimension dim, typename TComponent, typename TContainer>
175 typename OtherComponent, typename OtherCont,
176 typename std::enable_if< std::is_same< TComponent, DGtal::ArithmeticConversionType<TComponent, OtherComponent> >::value, int >::type >
178DGtal::PointVector<dim, TComponent, TContainer>::PointVector (const PointVector<dim,OtherComponent,OtherCont> & other )
180 for ( DGtal::Dimension i = 0; i < dimension; ++i )
181 this->myArray[ i ] = static_cast<TComponent>(other[ i ]);
183//------------------------------------------------------------------------------
184template<DGtal::Dimension dim, typename TComponent, typename TContainer>
186 typename OtherComponent, typename OtherCont,
187 typename std::enable_if< ! std::is_same< TComponent, DGtal::ArithmeticConversionType<TComponent, OtherComponent> >::value, int >::type >
189DGtal::PointVector<dim, TComponent, TContainer>::PointVector (const PointVector<dim,OtherComponent,OtherCont> & other )
191 for ( DGtal::Dimension i = 0; i < dimension; ++i )
192 this->myArray[ i ] = static_cast<TComponent>(other[ i ]);
194//------------------------------------------------------------------------------
195template<DGtal::Dimension dim, typename TComponent, typename TContainer>
197typename DGtal::PointVector<dim, TComponent, TContainer>::Iterator
198DGtal::PointVector<dim, TComponent, TContainer>::begin()
200 return myArray.begin();
202//------------------------------------------------------------------------------
203template<DGtal::Dimension dim, typename TComponent, typename TContainer>
205typename DGtal::PointVector<dim, TComponent, TContainer>::Iterator
206DGtal::PointVector<dim, TComponent, TContainer>::end()
208 return myArray.end();
210//------------------------------------------------------------------------------
211template<DGtal::Dimension dim, typename TComponent, typename TContainer>
213typename DGtal::PointVector<dim, TComponent, TContainer>::ConstIterator
214DGtal::PointVector<dim, TComponent, TContainer>::begin() const
216 return myArray.begin();
218//------------------------------------------------------------------------------
219template<DGtal::Dimension dim, typename TComponent, typename TContainer>
221typename DGtal::PointVector<dim, TComponent, TContainer>::ConstIterator
222DGtal::PointVector<dim, TComponent, TContainer>::end() const
224 return myArray.end();
226//------------------------------------------------------------------------------
227template<DGtal::Dimension dim, typename TComponent, typename TContainer>
229typename DGtal::PointVector<dim, TComponent, TContainer>::ReverseIterator
230DGtal::PointVector<dim, TComponent, TContainer>::rbegin()
232 return myArray.rbegin();
234//------------------------------------------------------------------------------
235template<DGtal::Dimension dim, typename TComponent, typename TContainer>
237typename DGtal::PointVector<dim, TComponent, TContainer>::ReverseIterator
238DGtal::PointVector<dim, TComponent, TContainer>::rend()
240 return myArray.rend();
242//------------------------------------------------------------------------------
243template<DGtal::Dimension dim, typename TComponent, typename TContainer>
245typename DGtal::PointVector<dim, TComponent, TContainer>::ConstReverseIterator
246DGtal::PointVector<dim, TComponent, TContainer>::rbegin() const
248 return myArray.rbegin();
250//------------------------------------------------------------------------------
251template<DGtal::Dimension dim, typename TComponent, typename TContainer>
253typename DGtal::PointVector<dim, TComponent, TContainer>::ConstReverseIterator
254DGtal::PointVector<dim, TComponent, TContainer>::rend() const
256 return myArray.rend();
258//------------------------------------------------------------------------------
259template<DGtal::Dimension dim, typename TComponent, typename TContainer>
261typename DGtal::Dimension
262DGtal::PointVector<dim, TComponent, TContainer>::size()
266//------------------------------------------------------------------------------
267template<DGtal::Dimension dim, typename TComponent, typename TContainer>
269const typename DGtal::PointVector<dim, TComponent, TContainer>::Component *
270DGtal::PointVector<dim, TComponent, TContainer>::data() const noexcept
272 return myArray.data();
274//------------------------------------------------------------------------------
275template<DGtal::Dimension dim, typename TComponent, typename TContainer>
277typename DGtal::PointVector<dim, TComponent, TContainer>::Component *
278DGtal::PointVector<dim, TComponent, TContainer>::data() noexcept
280 return myArray.data();
282//------------------------------------------------------------------------------
283template<DGtal::Dimension dim, typename TComponent, typename TContainer>
285const typename DGtal::PointVector<dim, TComponent, TContainer>::Component &
286DGtal::PointVector<dim, TComponent, TContainer>::operator[]( Dimension i ) const
291//------------------------------------------------------------------------------
292template<DGtal::Dimension dim, typename TComponent, typename TContainer>
294typename DGtal::PointVector<dim, TComponent, TContainer>::Component &
295DGtal::PointVector<dim, TComponent, TContainer>::operator[]( Dimension i )
300//------------------------------------------------------------------------------
301template<DGtal::Dimension dim, typename TComponent, typename TContainer>
303DGtal::PointVector<dim, TComponent, TContainer>&
304DGtal::PointVector<dim, TComponent, TContainer>::operator= ( const Self & pv )
306 myArray = pv.myArray;
309//------------------------------------------------------------------------------
310template<DGtal::Dimension dim, typename TComponent, typename TContainer>
312 typename OtherComponent,
313 typename OtherContainer,
314 typename std::enable_if< std::is_same< TComponent, DGtal::ArithmeticConversionType<TComponent, OtherComponent> >::value, int >::type>
316DGtal::PointVector<dim, TComponent, TContainer> &
317DGtal::PointVector<dim, TComponent, TContainer>::operator= ( const DGtal::PointVector<dim, OtherComponent, OtherContainer> & v )
319 for ( DGtal::Dimension i = 0; i < dimension; ++i )
321 this->myArray[ i ] = static_cast<Component>( v[ i ] );
325//------------------------------------------------------------------------------
326template<DGtal::Dimension dim, typename TComponent, typename TContainer>
328 typename OtherComponent,
329 typename OtherContainer,
330 typename std::enable_if< std::is_same< TComponent, DGtal::ArithmeticConversionType<TComponent, OtherComponent> >::value, int >::type>
332DGtal::PointVector<dim, TComponent, TContainer>&
333DGtal::PointVector<dim, TComponent, TContainer>::partialCopy
334( const DGtal::PointVector<dim, OtherComponent, OtherContainer> & pv,
335 const std::vector<DGtal::Dimension> &dimensions)
337 std::bitset<dim> dims = setDimensionsIn<dim>(dimensions);
338 for ( DGtal::Dimension i = 0; i < dim; ++i )
340 if ( dims.test(i) ) myArray[i] = static_cast<TComponent>(pv.myArray[i]);
344//------------------------------------------------------------------------------
345template<DGtal::Dimension dim, typename TComponent, typename TContainer>
347 typename OtherComponent,
348 typename OtherContainer,
349 typename std::enable_if< std::is_same< TComponent, DGtal::ArithmeticConversionType<TComponent, OtherComponent> >::value, int >::type>
351DGtal::PointVector<dim, TComponent, TContainer>&
352DGtal::PointVector<dim, TComponent, TContainer>::partialCopyInv
353( const DGtal::PointVector<dim, OtherComponent, OtherContainer> & pv,
354 const std::vector<DGtal::Dimension> &dimensions)
356 std::bitset<dim> dims = setDimensionsIn<dim>(dimensions);
357 for ( DGtal::Dimension i = 0; i < dim; ++i )
359 if ( !dims.test(i) ) myArray[i] = static_cast<TComponent>(pv.myArray[i]);
363//------------------------------------------------------------------------------
364template<DGtal::Dimension dim, typename TComponent, typename TContainer>
366 typename OtherComponent,
367 typename OtherContainer,
368 typename UnaryFunctor >
370DGtal::PointVector<dim, TComponent, TContainer>&
371DGtal::PointVector<dim, TComponent, TContainer>::partialCopy
372( const DGtal::PointVector<dim, OtherComponent, OtherContainer> & pv,
373 const std::vector<DGtal::Dimension> &dimensions,
374 const UnaryFunctor &f)
376 std::bitset<dim> dims = setDimensionsIn<dim>(dimensions);
377 for ( DGtal::Dimension i = 0; i < dim; ++i )
379 if ( dims.test(i) ) myArray[i] = static_cast<TComponent>(f(pv.myArray[i]));
383//------------------------------------------------------------------------------
384template<DGtal::Dimension dim, typename TComponent, typename TContainer>
386 typename OtherComponent,
387 typename OtherContainer,
388 typename UnaryFunctor >
390DGtal::PointVector<dim, TComponent, TContainer>&
391DGtal::PointVector<dim, TComponent, TContainer>::partialCopyInv
392( const DGtal::PointVector<dim, OtherComponent, OtherContainer> & pv,
393 const std::vector<DGtal::Dimension> &dimensions,
394 const UnaryFunctor &f)
396 std::bitset<dim> dims = setDimensionsIn<dim>(dimensions);
397 for ( DGtal::Dimension i = 0; i < dim; ++i )
399 if ( !dims.test(i) ) myArray[i] = static_cast<TComponent>(f(pv.myArray[i]));
403//------------------------------------------------------------------------------
404template<DGtal::Dimension dim, typename TComponent, typename TContainer>
405template <typename TOtherComponent, typename TOtherContainer>
408DGtal::PointVector<dim, TComponent, TContainer>::partialEqual
409( const DGtal::PointVector<dim, TOtherComponent, TOtherContainer> & pv,
410 const std::vector<DGtal::Dimension> &dimensions ) const
412 std::bitset<dim> dims = setDimensionsIn<dim>(dimensions);
413 for ( DGtal::Dimension i = 0; i < dim; ++i )
415 if ( dims.test(i) && myArray[i] != pv.myArray[i]) return false;
419//------------------------------------------------------------------------------
420template<DGtal::Dimension dim, typename TComponent, typename TContainer>
421template <typename TOtherComponent, typename TOtherContainer>
424DGtal::PointVector<dim, TComponent, TContainer>::partialEqualInv
425( const DGtal::PointVector<dim, TOtherComponent, TOtherContainer> & pv,
426 const std::vector<DGtal::Dimension> &dimensions ) const
428 std::bitset<dim> dims = setDimensionsIn<dim>(dimensions);
429 for ( DGtal::Dimension i = 0; i < dim; ++i )
431 if ( !dims.test(i) && myArray[i] != pv.myArray[i]) return false;
435//------------------------------------------------------------------------------
436template < DGtal::Dimension ptDim,
437 typename LeftEuclideanRing, typename LeftContainer,
438 typename RightEuclideanRing, typename RightContainer >
440DGtal::operator== ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
441 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
443 return std::equal( lhs.begin(), lhs.end(), rhs.begin() );
445//------------------------------------------------------------------------------
446template < DGtal::Dimension ptDim,
447 typename LeftEuclideanRing, typename LeftContainer,
448 typename RightEuclideanRing, typename RightContainer >
450DGtal::operator!= ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
451 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
453 return ! (lhs == rhs);
455//------------------------------------------------------------------------------
456template < DGtal::Dimension ptDim,
457 typename LeftEuclideanRing, typename LeftContainer,
458 typename RightEuclideanRing, typename RightContainer >
460DGtal::operator< ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
461 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
463 return std::lexicographical_compare( lhs.begin(), lhs.end(), rhs.begin(), rhs.end() );
465//------------------------------------------------------------------------------
466template < DGtal::Dimension ptDim,
467 typename LeftEuclideanRing, typename LeftContainer,
468 typename RightEuclideanRing, typename RightContainer >
470DGtal::operator> ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
471 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
475//------------------------------------------------------------------------------
476template < DGtal::Dimension ptDim,
477 typename LeftEuclideanRing, typename LeftContainer,
478 typename RightEuclideanRing, typename RightContainer >
480DGtal::operator<= ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
481 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
483 return ! ( lhs > rhs );
485//------------------------------------------------------------------------------
486template < DGtal::Dimension ptDim,
487 typename LeftEuclideanRing, typename LeftContainer,
488 typename RightEuclideanRing, typename RightContainer >
490DGtal::operator>= ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
491 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
493 return ! ( lhs < rhs );
495//------------------------------------------------------------------------------
496template<DGtal::Dimension dim, typename TComponent, typename TContainer>
498 typename OtherComponent, typename OtherStorage,
499 typename std::enable_if< std::is_same< TComponent, DGtal::ArithmeticConversionType<TComponent, OtherComponent> >::value, int >::type >
501DGtal::PointVector<dim, TComponent, TContainer>&
502DGtal::PointVector<dim, TComponent, TContainer>::operator+= ( PointVector<dim, OtherComponent, OtherStorage> const& v )
504 for ( DGtal::Dimension i = 0; i < dim; ++i )
505 this->myArray[ i ] += v[ i ];
508//------------------------------------------------------------------------------
509template<DGtal::Dimension dim, typename TComponent, typename TContainer>
511 typename OtherComponent,
512 typename std::enable_if< std::is_same< TComponent, DGtal::ArithmeticConversionType<TComponent, OtherComponent> >::value, int >::type >
514DGtal::PointVector<dim, TComponent, TContainer>&
515DGtal::PointVector<dim, TComponent, TContainer>::operator+= ( OtherComponent coeff )
517 for ( DGtal::Dimension i = 0; i < dim; ++i )
518 this->myArray[ i ] += coeff;
521//------------------------------------------------------------------------------
522template<DGtal::Dimension dim, typename TComponent, typename TContainer>
524 typename OtherComponent, typename OtherStorage,
525 typename std::enable_if< std::is_same< TComponent, DGtal::ArithmeticConversionType<TComponent, OtherComponent> >::value, int >::type >
527DGtal::PointVector<dim, TComponent, TContainer>&
528DGtal::PointVector<dim, TComponent, TContainer>::operator-= ( PointVector<dim, OtherComponent, OtherStorage> const& v )
530 for ( DGtal::Dimension i = 0; i < dim; ++i )
531 this->myArray[ i ] -= v[ i ];
534//------------------------------------------------------------------------------
535template<DGtal::Dimension dim, typename TComponent, typename TContainer>
537 typename OtherComponent,
538 typename std::enable_if< std::is_same< TComponent, DGtal::ArithmeticConversionType<TComponent, OtherComponent> >::value, int >::type >
540DGtal::PointVector<dim, TComponent, TContainer>&
541DGtal::PointVector<dim, TComponent, TContainer>::operator-= ( OtherComponent coeff )
543 for ( DGtal::Dimension i = 0; i < dim; ++i )
544 this->myArray[ i ] -= coeff;
547//------------------------------------------------------------------------------
548template<DGtal::Dimension dim, typename TComponent, typename TContainer>
550 typename OtherComponent,
551 typename std::enable_if< std::is_same< TComponent, DGtal::ArithmeticConversionType<TComponent, OtherComponent> >::value, int >::type>
552DGtal::PointVector<dim, TComponent, TContainer>&
553DGtal::PointVector<dim, TComponent, TContainer>::operator*= ( OtherComponent coeff )
555 for ( DGtal::Dimension i = 0; i < myArray.size(); ++i )
556 myArray[ i ] *= coeff;
559//------------------------------------------------------------------------------
560template<DGtal::Dimension dim, typename TComponent, typename TContainer>
562 typename OtherComponent, typename OtherStorage,
563 typename std::enable_if< std::is_same< TComponent, DGtal::ArithmeticConversionType<TComponent, OtherComponent> >::value, int >::type>
564DGtal::PointVector<dim, TComponent, TContainer>&
565DGtal::PointVector<dim, TComponent, TContainer>::operator*= ( PointVector<dim, OtherComponent, OtherStorage> const& v )
567 for ( DGtal::Dimension i = 0; i < myArray.size(); ++i )
568 myArray[ i ] *= v[ i ];
571//------------------------------------------------------------------------------
572template<DGtal::Dimension dim, typename TComponent, typename TContainer>
574 typename OtherComponent,
575 typename std::enable_if< std::is_same< TComponent, DGtal::ArithmeticConversionType<TComponent, OtherComponent> >::value, int >::type>
576DGtal::PointVector<dim, TComponent, TContainer>&
577DGtal::PointVector<dim, TComponent, TContainer>::operator/= ( OtherComponent coeff )
579 for ( DGtal::Dimension i = 0; i < myArray.size(); ++i )
580 myArray[ i ] /= coeff;
583//------------------------------------------------------------------------------
584template<DGtal::Dimension dim, typename TComponent, typename TContainer>
586 typename OtherComponent, typename OtherStorage,
587 typename std::enable_if< std::is_same< TComponent, DGtal::ArithmeticConversionType<TComponent, OtherComponent> >::value, int >::type>
588DGtal::PointVector<dim, TComponent, TContainer>&
589DGtal::PointVector<dim, TComponent, TContainer>::operator/= ( PointVector<dim, OtherComponent, OtherStorage> const& v )
591 for ( DGtal::Dimension i = 0; i < myArray.size(); ++i )
592 myArray[ i ] /= v[ i ];
595//------------------------------------------------------------------------------
596template<DGtal::Dimension dim, typename TComponent, typename TContainer>
597template < typename OtherComponent, typename OtherStorage >
599DGtal::PointVector<dim, TComponent, TContainer>::dot( const DGtal::PointVector<dim, OtherComponent, OtherStorage>& v ) const
600 -> decltype( DGtal::dotProduct(*this, v) )
602 return DGtal::dotProduct(*this, v);
604//------------------------------------------------------------------------------
605template < DGtal::Dimension ptDim,
606 typename LeftEuclideanRing, typename LeftContainer,
607 typename RightEuclideanRing, typename RightContainer >
609DGtal::ArithmeticConversionType<LeftEuclideanRing, RightEuclideanRing>
610DGtal::dotProduct ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
611 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
613 using EuclideanRing = ArithmeticConversionType<LeftEuclideanRing, RightEuclideanRing>;
614 auto dotprod = NumberTraits<EuclideanRing>::ZERO;
615 for ( DGtal::Dimension i = 0; i < ptDim; ++i )
616 dotprod += lhs[ i ] * rhs[ i ];
619//------------------------------------------------------------------------------
620template < DGtal::Dimension ptDim,
621 typename LeftEuclideanRing, typename LeftContainer,
622 typename RightEuclideanRing, typename RightContainer >
624DGtal::cosineSimilarity ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
625 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
628 if ( lhs.norm() > 0. && rhs.norm() > 0. )
629 radians = rhs.dot ( lhs ) / ( lhs.norm() * rhs.norm() );
631 throw std::runtime_error ( "Operation involving a null vector is not defined!" );
632 return std::acos ( std::min ( std::max ( radians, -1. ), 1. ) );
635//------------------------------------------------------------------------------
636template<DGtal::Dimension dim, typename TComponent, typename TContainer>
637template < typename OtherComponent, typename OtherStorage >
639DGtal::PointVector<dim, TComponent, TContainer>::cosineSimilarity( const DGtal::PointVector<dim, OtherComponent, OtherStorage>& v ) const
641 return DGtal::cosineSimilarity(*this, v);
643//------------------------------------------------------------------------------
644template<DGtal::Dimension dim, typename TComponent, typename TContainer>
645template < typename OtherComponent, typename OtherStorage >
647DGtal::PointVector<dim, TComponent, TContainer>::crossProduct( const DGtal::PointVector<dim, OtherComponent, OtherStorage>& v ) const
648 -> decltype( DGtal::crossProduct(*this, v) )
650 return DGtal::crossProduct(*this, v);
652//------------------------------------------------------------------------------
654 typename LeftEuclideanRing, typename LeftContainer,
655 typename RightEuclideanRing, typename RightContainer >
657DGtal::crossProduct ( DGtal::PointVector<3, LeftEuclideanRing, LeftContainer> const& lhs,
658 DGtal::PointVector<3, RightEuclideanRing, RightContainer> const& rhs )
659 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
661 auto crossprod = constructFromArithmeticConversion(lhs, rhs);
662 for ( DGtal::Dimension i = 0; i < 3; ++i )
664 lhs[ (i+1)%3 ] * rhs[ (i+2)%3 ]
665 - lhs[ (i+2)%3 ] * rhs[ (i+1)%3 ];
668//------------------------------------------------------------------------------
670 typename LeftEuclideanRing, typename LeftContainer,
671 typename RightEuclideanRing, typename RightContainer >
673DGtal::PointVector<3, DGtal::ArithmeticConversionType<LeftEuclideanRing, RightEuclideanRing>>
674DGtal::crossProduct ( DGtal::PointVector<2, LeftEuclideanRing, LeftContainer> const& lhs,
675 DGtal::PointVector<2, RightEuclideanRing, RightContainer> const& rhs )
677 return PointVector<3, ArithmeticConversionType<LeftEuclideanRing, RightEuclideanRing>>(
680 lhs[0]*rhs[1] - lhs[1]*rhs[0]
683//------------------------------------------------------------------------------
684template < DGtal::Dimension ptDim,
685 typename LeftEuclideanRing, typename LeftContainer,
686 typename RightEuclideanRing, typename RightContainer >
688DGtal::operator+ ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
689 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
690 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
692 using EuclideanRing = ArithmeticConversionType<LeftEuclideanRing, RightEuclideanRing>;
693 return constructFromArithmeticConversion(lhs, rhs, lhs, rhs, std::plus<EuclideanRing>());
695//------------------------------------------------------------------------------
696template < DGtal::Dimension ptDim,
697 typename LeftEuclideanRing, typename LeftContainer,
698 typename RightEuclideanRing, typename RightContainer >
700DGtal::operator- ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
701 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
702 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
704 using EuclideanRing = ArithmeticConversionType<LeftEuclideanRing, RightEuclideanRing>;
705 return constructFromArithmeticConversion(lhs, rhs, lhs, rhs, std::minus<EuclideanRing>());
707//------------------------------------------------------------------------------
708template < DGtal::Dimension ptDim,
709 typename LeftEuclideanRing, typename LeftContainer,
710 typename RightEuclideanRing, typename RightContainer >
712DGtal::operator* ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
713 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
714 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
716 using EuclideanRing = ArithmeticConversionType<LeftEuclideanRing, RightEuclideanRing>;
717 return constructFromArithmeticConversion(lhs, rhs, lhs, rhs, std::multiplies<EuclideanRing>());
719//------------------------------------------------------------------------------
720template < DGtal::Dimension ptDim,
721 typename LeftEuclideanRing, typename LeftContainer,
722 typename RightEuclideanRing, typename RightContainer >
724DGtal::operator/ ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
725 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
726 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
728 using EuclideanRing = ArithmeticConversionType<LeftEuclideanRing, RightEuclideanRing>;
729 return constructFromArithmeticConversion(lhs, rhs, lhs, rhs, std::divides<EuclideanRing>());
731//------------------------------------------------------------------------------
732template < DGtal::Dimension ptDim,
733 typename LeftEuclideanRing, typename LeftContainer,
734 typename RightScalar >
736DGtal::operator+ ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
737 RightScalar const& rhs )
738 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
740 return constructFromArithmeticConversion(lhs, rhs, lhs, [&rhs] (LeftEuclideanRing v) { return v + rhs; });
742//------------------------------------------------------------------------------
743template < DGtal::Dimension ptDim,
745 typename RightEuclideanRing, typename RightContainer >
747DGtal::operator+ ( LeftScalar const& lhs,
748 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
749 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
751 return constructFromArithmeticConversion(lhs, rhs, rhs, [&lhs] (RightEuclideanRing v) { return lhs + v; });
753//------------------------------------------------------------------------------
754template < DGtal::Dimension ptDim,
755 typename LeftEuclideanRing, typename LeftContainer,
756 typename RightScalar >
758DGtal::operator- ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
759 RightScalar const& rhs )
760 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
762 return constructFromArithmeticConversion(lhs, rhs, lhs, [&rhs] (LeftEuclideanRing v) { return v - rhs; });
764//------------------------------------------------------------------------------
765template < DGtal::Dimension ptDim,
767 typename RightEuclideanRing, typename RightContainer >
769DGtal::operator- ( LeftScalar const& lhs,
770 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
771 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
773 return constructFromArithmeticConversion(lhs, rhs, rhs, [&lhs] (RightEuclideanRing v) { return lhs - v; });
775//------------------------------------------------------------------------------
776template < DGtal::Dimension ptDim,
777 typename LeftEuclideanRing, typename LeftContainer,
778 typename RightScalar >
780DGtal::operator* ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
781 RightScalar const& rhs )
782 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
784 return constructFromArithmeticConversion(lhs, rhs, lhs, [&rhs] (LeftEuclideanRing v) { return v * rhs; });
786//------------------------------------------------------------------------------
787template < DGtal::Dimension ptDim,
789 typename RightEuclideanRing, typename RightContainer >
791DGtal::operator* ( LeftScalar const& lhs,
792 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
793 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
795 return constructFromArithmeticConversion(lhs, rhs, rhs, [&lhs] (RightEuclideanRing v) { return lhs * v; });
797//------------------------------------------------------------------------------
798template < DGtal::Dimension ptDim,
799 typename LeftEuclideanRing, typename LeftContainer,
800 typename RightScalar >
802DGtal::operator/ ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
803 RightScalar const& rhs )
804 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
806 return constructFromArithmeticConversion(lhs, rhs, lhs, [&rhs] (LeftEuclideanRing v) { return v / rhs; });
808//------------------------------------------------------------------------------
809template < DGtal::Dimension ptDim,
811 typename RightEuclideanRing, typename RightContainer >
813DGtal::operator/ ( LeftScalar const& lhs,
814 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
815 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
817 return constructFromArithmeticConversion(lhs, rhs, rhs, [&lhs] (RightEuclideanRing v) { return lhs / v; });
819//------------------------------------------------------------------------------
820template<DGtal::Dimension dim, typename TComponent, typename TContainer>
822DGtal::PointVector<dim, TComponent,TContainer>
823DGtal::PointVector<dim, TComponent,TContainer>::operator-() const
825 return Self(*this, functors::UnaryMinus<Component>());
827//------------------------------------------------------------------------------
828template<DGtal::Dimension dim, typename TComponent, typename TContainer>
831DGtal::PointVector<dim, TComponent, TContainer>::reset()
833 for ( DGtal::Dimension i = 0; i < myArray.size(); ++i )
834 myArray[ i ] = NumberTraits< Component >::ZERO;
836//------------------------------------------------------------------------------
837template < DGtal::Dimension ptDim,
838 typename LeftEuclideanRing, typename LeftContainer,
839 typename RightEuclideanRing, typename RightContainer >
841DGtal::inf( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
842 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
843 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
845 using EuclideanRing = ArithmeticConversionType<LeftEuclideanRing, RightEuclideanRing>;
846 return DGtal::constructFromArithmeticConversion(lhs, rhs, lhs, rhs, functors::Min<EuclideanRing>());
848//------------------------------------------------------------------------------
849template<DGtal::Dimension dim, typename TComponent, typename TContainer>
850template < typename OtherComponent, typename OtherStorage >
852DGtal::PointVector<dim, TComponent, TContainer>::inf( const DGtal::PointVector<dim, OtherComponent, OtherStorage>& aPoint ) const
853 -> decltype( DGtal::inf(*this, aPoint) )
855 return DGtal::inf(*this, aPoint);
857//------------------------------------------------------------------------------
858template < DGtal::Dimension ptDim,
859 typename LeftEuclideanRing, typename LeftContainer,
860 typename RightEuclideanRing, typename RightContainer >
862DGtal::sup( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
863 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
864 -> decltype( DGtal::constructFromArithmeticConversion(lhs, rhs) )
866 using EuclideanRing = ArithmeticConversionType<LeftEuclideanRing, RightEuclideanRing>;
867 return DGtal::constructFromArithmeticConversion(lhs, rhs, lhs, rhs, functors::Max<EuclideanRing>());
869//------------------------------------------------------------------------------
870template<DGtal::Dimension dim, typename TComponent, typename TContainer>
871template < typename OtherComponent, typename OtherStorage >
873DGtal::PointVector<dim, TComponent, TContainer>::sup( const DGtal::PointVector<dim, OtherComponent, OtherStorage>& aPoint ) const
874 -> decltype( DGtal::sup(*this, aPoint) )
876 return DGtal::sup(*this, aPoint);
878//------------------------------------------------------------------------------
879template < DGtal::Dimension ptDim,
880 typename LeftEuclideanRing, typename LeftContainer,
881 typename RightEuclideanRing, typename RightContainer >
883DGtal::isLower( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
884 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
886 for ( DGtal::Dimension i = 0; i < ptDim; ++i )
887 if ( rhs[ i ] < lhs[ i ] )
891//------------------------------------------------------------------------------
892template<DGtal::Dimension dim, typename TComponent, typename TContainer>
893template < typename OtherComponent, typename OtherStorage >
895DGtal::PointVector<dim, TComponent, TContainer>::isLower( const DGtal::PointVector<dim, OtherComponent, OtherStorage> & p ) const
897 return DGtal::isLower(*this, p);
899//------------------------------------------------------------------------------
900template < DGtal::Dimension ptDim,
901 typename LeftEuclideanRing, typename LeftContainer,
902 typename RightEuclideanRing, typename RightContainer >
904DGtal::isUpper( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
905 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
907 for ( DGtal::Dimension i = 0; i < ptDim; ++i )
908 if ( rhs[ i ] > lhs[ i ] )
912//------------------------------------------------------------------------------
913template<DGtal::Dimension dim, typename TComponent, typename TContainer>
914template < typename OtherComponent, typename OtherStorage >
916DGtal::PointVector<dim, TComponent, TContainer>::isUpper( const DGtal::PointVector<dim, OtherComponent, OtherStorage> & p ) const
918 return DGtal::isUpper(*this, p);
920//------------------------------------------------------------------------------
921template<DGtal::Dimension dim, typename TComponent, typename TContainer>
923typename DGtal::PointVector<dim, TComponent, TContainer>::Component
924DGtal::PointVector<dim, TComponent, TContainer>::max( ) const
926 return *std::max_element(this->begin(), this->end());
928//------------------------------------------------------------------------------
929template<DGtal::Dimension dim, typename TComponent, typename TContainer>
931typename DGtal::PointVector<dim, TComponent, TContainer>::Component
932DGtal::PointVector<dim, TComponent, TContainer>::min( ) const
934 return *std::min_element(this->begin(), this->end());
936//------------------------------------------------------------------------------
937template<DGtal::Dimension dim, typename TComponent, typename TContainer>
939typename DGtal::PointVector<dim, TComponent, TContainer>::Iterator
940DGtal::PointVector<dim, TComponent, TContainer>::maxElement( )
942 return std::max_element(this->begin(), this->end());
944//------------------------------------------------------------------------------
945template<DGtal::Dimension dim, typename TComponent, typename TContainer>
947typename DGtal::PointVector<dim, TComponent, TContainer>::Iterator
948DGtal::PointVector<dim, TComponent, TContainer>::minElement( )
950 return std::min_element(this->begin(), this->end());
952//------------------------------------------------------------------------------
953template<DGtal::Dimension dim, typename TComponent, typename TContainer>
956DGtal::PointVector<dim, TComponent, TContainer>::
959 for ( DGtal::Dimension i = 0; i < dimension; ++i )
960 this->myArray[ i ] = - this->myArray[ i ];
962//------------------------------------------------------------------------------
963template<DGtal::Dimension dim, typename TComponent, typename TContainer>
966DGtal::PointVector<dim, TComponent, TContainer>::squaredNorm () const
970 for ( DGtal::Dimension i = 0; i < dimension; i++ )
971 tmp += std::pow(NumberTraits<Component>::castToDouble(myArray[ i ]), 2);
974//------------------------------------------------------------------------------
975template<DGtal::Dimension dim, typename TComponent, typename TContainer>
978DGtal::PointVector<dim, TComponent, TContainer>::norm (
979 const typename Self::NormType aType ) const
988 for ( DGtal::Dimension i = 0; i < dimension; i++ )
989 tmp += NumberTraits<Component>::castToDouble(myArray[ i ]) *
990 NumberTraits<Component>::castToDouble(myArray[ i ]);
991 tmp = ( double ) sqrt ( tmp );
994 for ( DGtal::Dimension i = 0; i < dimension; i++ )
995 tmp += fabs ( NumberTraits<Component>::castToDouble(myArray[ i ] ));
998 tmp = fabs( NumberTraits<Component>::castToDouble( myArray[ 0 ]));
999 for ( DGtal::Dimension i = 1; i < dimension; i++ )
1000 if ( tmp < fabs ( NumberTraits<Component>::castToDouble(myArray[ i ] ) ))
1001 tmp = fabs ( NumberTraits<Component>::castToDouble(myArray[ i ] ));
1006//------------------------------------------------------------------------------
1007template<DGtal::Dimension dim, typename TComponent, typename TContainer>
1009typename DGtal::PointVector<dim, TComponent, TContainer>::UnsignedComponent
1010DGtal::PointVector<dim, TComponent, TContainer>::norm1() const
1012 ASSERT ( dimension > 0 );
1013 UnsignedComponent val
1014 ( ( myArray[ 0 ] >= 0 ) ? myArray[ 0 ] : UnsignedComponent(-myArray[ 0 ]) );
1015 for ( DGtal::Dimension i = 1; i < dimension; ++i )
1016 val += ( myArray[ i ] >= 0 )
1018 : UnsignedComponent(-myArray[ i ]);
1021//------------------------------------------------------------------------------
1022template<DGtal::Dimension dim, typename TComponent, typename TContainer>
1024typename DGtal::PointVector<dim, TComponent, TContainer>::UnsignedComponent
1025DGtal::PointVector<dim, TComponent, TContainer>::normInfinity() const
1027 ASSERT ( dimension > 0 );
1028 UnsignedComponent tmp;
1029 UnsignedComponent val( ( myArray[ 0 ] >= 0 ) ? myArray[ 0 ] : -myArray[ 0 ] );
1030 for ( DGtal::Dimension i = 1; i < dimension; ++i )
1032 tmp = ( myArray[ i ] >= 0 ) ? myArray[ i ] : -myArray[ i ] ;
1038//------------------------------------------------------------------------------
1040template<DGtal::Dimension dim, typename TComponent, typename TContainer>
1042typename DGtal::PointVector<dim, double, std::array<double,dim> >
1043DGtal::PointVector<dim, TComponent, TContainer>::getNormalized() const
1045 PointVector<dim,double,std::array<double,dim> > normalized =(*this);
1046 normalized /= normalized.norm();
1049//------------------------------------------------------------------------------
1050template<DGtal::Dimension dim, typename TComponent, typename TContainer>
1052DGtal::PointVector<dim,TComponent, TContainer>
1053DGtal::PointVector<dim,TComponent, TContainer>::diagonal( Component val )
1056 for ( DGtal::Dimension i = 0; i < dim; ++i )
1057 p.myArray[ i ] = val;
1060//------------------------------------------------------------------------------
1061template<DGtal::Dimension dim,typename TComponent, typename TContainer>
1063DGtal::PointVector<dim,TComponent, TContainer>
1064DGtal::PointVector<dim,TComponent, TContainer>::base( Dimension k, Component val )
1067 p.myArray[ k ] = val;
1070//------------------------------------------------------------------------------
1071template<DGtal::Dimension dim,typename TComponent, typename TContainer>
1074DGtal::PointVector<dim,TComponent, TContainer>::selfDisplay( std::ostream & out ) const
1077 for (DGtal::Dimension i = 0; i < dimension ; ++i)
1078 out << myArray[ i ] << (i == dimension - 1 ? "" : ", ");
1082//------------------------------------------------------------------------------
1083template<DGtal::Dimension dim, typename TComponent, typename TContainer>
1086DGtal::PointVector<dim, TComponent, TContainer>::className() const
1088 return "PointVector";
1091//------------------------------------------------------------------------------
1092template<DGtal::Dimension dim, typename TComponent, typename TContainer>
1095DGtal::operator<<( std::ostream & out,
1096 const PointVector<dim, TComponent, TContainer>& object )
1098 object.selfDisplay( out );
1101//------------------------------------------------------------------------------
1102template<DGtal::Dimension dim, typename TComponent, typename TContainer>
1105DGtal::PointVector<dim, TComponent, TContainer>::isValid() const
1109//------------------------------------------------------------------------------