2 * This program is free software: you can redistribute it and/or modify
3 * it under the terms of the GNU Lesser General Public License as
4 * published by the Free Software Foundation, either version 3 of the
5 * License, or (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 * @file PointVector.ih
19 * @author David Coeurjolly (\c david.coeurjolly@liris.cnrs.fr )
20 * @author Guillaume Damiand
21 * Laboratoire d'InfoRmatique en Image et Systèmes d'information - LIRIS (CNRS, UMR 5205), CNRS, France
25 * Implementation of inline methods defined in PointVector.h
27 * This file is part of the DGtal library.
30 ///////////////////////////////////////////////////////////////////////////////
31 // IMPLEMENTATION of inline methods.
32 ///////////////////////////////////////////////////////////////////////////////
34 //////////////////////////////////////////////////////////////////////////////
37 #include <DGtal/base/BasicFunctors.h>
38 #include "DGtal/io/Color.h"
39 //////////////////////////////////////////////////////////////////////////////
42 template<DGtal::Dimension dim, typename Container>
44 std::bitset<dim> DGtal::setDimensionsIn( const Container &dimensions )
47 for ( typename Container::const_iterator it=dimensions.begin();
48 it!=dimensions.end(); ++it )
55 //------------------------------------------------------------------------------
56 template<DGtal::Dimension dim, typename Container>
58 std::bitset<dim> DGtal::setDimensionsNotIn( const Container &dimensions )
60 std::bitset<dim> t1; t1.set();
61 for ( typename Container::const_iterator it=dimensions.begin();
62 it!=dimensions.end(); ++it )
69 //------------------------------------------------------------------------------
72 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
74 DGtal::PointVector<dim, TComponent, TContainer>::PointVector()
76 for ( Dimension i = 0; i < dim; ++i )
77 myArray[ i ] = NumberTraits<TComponent>::ZERO;
79 //------------------------------------------------------------------------------
80 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
82 typename LeftComponent, typename LeftStorage,
83 typename RightComponent, typename RightStorage,
84 typename BinaryFunctor >
86 DGtal::PointVector<dim, TComponent, TContainer>::PointVector(
87 const PointVector<dim, LeftComponent, LeftStorage> & apoint1,
88 const PointVector<dim, RightComponent, RightStorage> & apoint2,
89 const BinaryFunctor & f)
91 for ( Dimension i = 0; i < dim; ++i )
92 myArray[ i ] = static_cast<TComponent>( f(apoint1[i], apoint2[i]) );
94 //------------------------------------------------------------------------------
95 template <DGtal::Dimension dim, typename TComponent, typename TContainer>
96 template <typename OtherComponent, typename OtherStorage, typename UnaryFunctor>
98 DGtal::PointVector<dim, TComponent,TContainer>::
99 PointVector(const PointVector<dim, OtherComponent, OtherStorage> & apoint1,
100 const UnaryFunctor& f)
102 for ( Dimension i = 0; i < dim; ++i )
103 myArray[ i ] = static_cast<TComponent>( f( apoint1[i] ) );
105 //------------------------------------------------------------------------------
106 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
108 DGtal::PointVector<dim, TComponent, TContainer>::PointVector( 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 //------------------------------------------------------------------------------
115 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
117 DGtal::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 //------------------------------------------------------------------------------
126 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
128 DGtal::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 //------------------------------------------------------------------------------
140 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
142 DGtal::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 //------------------------------------------------------------------------------
156 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
158 DGtal::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 //------------------------------------------------------------------------------
167 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
169 DGtal::PointVector<dim, TComponent, TContainer>::PointVector ( const Self & other )
170 : myArray( other.myArray )
172 //------------------------------------------------------------------------------
173 template<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 >
178 DGtal::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 //------------------------------------------------------------------------------
184 template<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 >
189 DGtal::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 //------------------------------------------------------------------------------
195 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
197 typename DGtal::PointVector<dim, TComponent, TContainer>::Iterator
198 DGtal::PointVector<dim, TComponent, TContainer>::begin()
200 return myArray.begin();
202 //------------------------------------------------------------------------------
203 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
205 typename DGtal::PointVector<dim, TComponent, TContainer>::Iterator
206 DGtal::PointVector<dim, TComponent, TContainer>::end()
208 return myArray.end();
210 //------------------------------------------------------------------------------
211 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
213 typename DGtal::PointVector<dim, TComponent, TContainer>::ConstIterator
214 DGtal::PointVector<dim, TComponent, TContainer>::begin() const
216 return myArray.begin();
218 //------------------------------------------------------------------------------
219 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
221 typename DGtal::PointVector<dim, TComponent, TContainer>::ConstIterator
222 DGtal::PointVector<dim, TComponent, TContainer>::end() const
224 return myArray.end();
226 //------------------------------------------------------------------------------
227 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
229 typename DGtal::PointVector<dim, TComponent, TContainer>::ReverseIterator
230 DGtal::PointVector<dim, TComponent, TContainer>::rbegin()
232 return myArray.rbegin();
234 //------------------------------------------------------------------------------
235 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
237 typename DGtal::PointVector<dim, TComponent, TContainer>::ReverseIterator
238 DGtal::PointVector<dim, TComponent, TContainer>::rend()
240 return myArray.rend();
242 //------------------------------------------------------------------------------
243 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
245 typename DGtal::PointVector<dim, TComponent, TContainer>::ConstReverseIterator
246 DGtal::PointVector<dim, TComponent, TContainer>::rbegin() const
248 return myArray.rbegin();
250 //------------------------------------------------------------------------------
251 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
253 typename DGtal::PointVector<dim, TComponent, TContainer>::ConstReverseIterator
254 DGtal::PointVector<dim, TComponent, TContainer>::rend() const
256 return myArray.rend();
258 //------------------------------------------------------------------------------
259 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
261 typename DGtal::Dimension
262 DGtal::PointVector<dim, TComponent, TContainer>::size()
266 //------------------------------------------------------------------------------
267 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
269 const typename DGtal::PointVector<dim, TComponent, TContainer>::Component *
270 DGtal::PointVector<dim, TComponent, TContainer>::data() const noexcept
272 return myArray.data();
274 //------------------------------------------------------------------------------
275 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
277 typename DGtal::PointVector<dim, TComponent, TContainer>::Component *
278 DGtal::PointVector<dim, TComponent, TContainer>::data() noexcept
280 return myArray.data();
282 //------------------------------------------------------------------------------
283 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
285 const typename DGtal::PointVector<dim, TComponent, TContainer>::Component &
286 DGtal::PointVector<dim, TComponent, TContainer>::operator[]( Dimension i ) const
291 //------------------------------------------------------------------------------
292 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
294 typename DGtal::PointVector<dim, TComponent, TContainer>::Component &
295 DGtal::PointVector<dim, TComponent, TContainer>::operator[]( Dimension i )
300 //------------------------------------------------------------------------------
301 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
303 DGtal::PointVector<dim, TComponent, TContainer>&
304 DGtal::PointVector<dim, TComponent, TContainer>::operator= ( const Self & pv )
306 myArray = pv.myArray;
309 //------------------------------------------------------------------------------
310 template<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>
316 DGtal::PointVector<dim, TComponent, TContainer> &
317 DGtal::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 //------------------------------------------------------------------------------
326 template<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>
332 DGtal::PointVector<dim, TComponent, TContainer>&
333 DGtal::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 //------------------------------------------------------------------------------
345 template<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>
351 DGtal::PointVector<dim, TComponent, TContainer>&
352 DGtal::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 //------------------------------------------------------------------------------
364 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
366 typename OtherComponent,
367 typename OtherContainer,
368 typename UnaryFunctor >
370 DGtal::PointVector<dim, TComponent, TContainer>&
371 DGtal::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 //------------------------------------------------------------------------------
384 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
386 typename OtherComponent,
387 typename OtherContainer,
388 typename UnaryFunctor >
390 DGtal::PointVector<dim, TComponent, TContainer>&
391 DGtal::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 //------------------------------------------------------------------------------
404 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
405 template <typename TOtherComponent, typename TOtherContainer>
408 DGtal::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 //------------------------------------------------------------------------------
420 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
421 template <typename TOtherComponent, typename TOtherContainer>
424 DGtal::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 //------------------------------------------------------------------------------
436 template < DGtal::Dimension ptDim,
437 typename LeftEuclideanRing, typename LeftContainer,
438 typename RightEuclideanRing, typename RightContainer >
440 DGtal::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 //------------------------------------------------------------------------------
446 template < DGtal::Dimension ptDim,
447 typename LeftEuclideanRing, typename LeftContainer,
448 typename RightEuclideanRing, typename RightContainer >
450 DGtal::operator!= ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
451 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
453 return ! (lhs == rhs);
455 //------------------------------------------------------------------------------
456 template < DGtal::Dimension ptDim,
457 typename LeftEuclideanRing, typename LeftContainer,
458 typename RightEuclideanRing, typename RightContainer >
460 DGtal::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 //------------------------------------------------------------------------------
466 template < DGtal::Dimension ptDim,
467 typename LeftEuclideanRing, typename LeftContainer,
468 typename RightEuclideanRing, typename RightContainer >
470 DGtal::operator> ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
471 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
475 //------------------------------------------------------------------------------
476 template < DGtal::Dimension ptDim,
477 typename LeftEuclideanRing, typename LeftContainer,
478 typename RightEuclideanRing, typename RightContainer >
480 DGtal::operator<= ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
481 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
483 return ! ( lhs > rhs );
485 //------------------------------------------------------------------------------
486 template < DGtal::Dimension ptDim,
487 typename LeftEuclideanRing, typename LeftContainer,
488 typename RightEuclideanRing, typename RightContainer >
490 DGtal::operator>= ( DGtal::PointVector<ptDim, LeftEuclideanRing, LeftContainer> const& lhs,
491 DGtal::PointVector<ptDim, RightEuclideanRing, RightContainer> const& rhs )
493 return ! ( lhs < rhs );
495 //------------------------------------------------------------------------------
496 template<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 >
501 DGtal::PointVector<dim, TComponent, TContainer>&
502 DGtal::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 //------------------------------------------------------------------------------
509 template<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 >
514 DGtal::PointVector<dim, TComponent, TContainer>&
515 DGtal::PointVector<dim, TComponent, TContainer>::operator+= ( OtherComponent coeff )
517 for ( DGtal::Dimension i = 0; i < dim; ++i )
518 this->myArray[ i ] += coeff;
521 //------------------------------------------------------------------------------
522 template<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 >
527 DGtal::PointVector<dim, TComponent, TContainer>&
528 DGtal::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 //------------------------------------------------------------------------------
535 template<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 >
540 DGtal::PointVector<dim, TComponent, TContainer>&
541 DGtal::PointVector<dim, TComponent, TContainer>::operator-= ( OtherComponent coeff )
543 for ( DGtal::Dimension i = 0; i < dim; ++i )
544 this->myArray[ i ] -= coeff;
547 //------------------------------------------------------------------------------
548 template<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>
552 DGtal::PointVector<dim, TComponent, TContainer>&
553 DGtal::PointVector<dim, TComponent, TContainer>::operator*= ( OtherComponent coeff )
555 for ( DGtal::Dimension i = 0; i < myArray.size(); ++i )
556 myArray[ i ] *= coeff;
559 //------------------------------------------------------------------------------
560 template<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>
564 DGtal::PointVector<dim, TComponent, TContainer>&
565 DGtal::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 //------------------------------------------------------------------------------
572 template<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>
576 DGtal::PointVector<dim, TComponent, TContainer>&
577 DGtal::PointVector<dim, TComponent, TContainer>::operator/= ( OtherComponent coeff )
579 for ( DGtal::Dimension i = 0; i < myArray.size(); ++i )
580 myArray[ i ] /= coeff;
583 //------------------------------------------------------------------------------
584 template<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>
588 DGtal::PointVector<dim, TComponent, TContainer>&
589 DGtal::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 //------------------------------------------------------------------------------
596 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
597 template < typename OtherComponent, typename OtherStorage >
599 DGtal::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 //------------------------------------------------------------------------------
605 template < DGtal::Dimension ptDim,
606 typename LeftEuclideanRing, typename LeftContainer,
607 typename RightEuclideanRing, typename RightContainer >
609 DGtal::ArithmeticConversionType<LeftEuclideanRing, RightEuclideanRing>
610 DGtal::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 //------------------------------------------------------------------------------
620 template < DGtal::Dimension ptDim,
621 typename LeftEuclideanRing, typename LeftContainer,
622 typename RightEuclideanRing, typename RightContainer >
624 DGtal::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 //------------------------------------------------------------------------------
636 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
637 template < typename OtherComponent, typename OtherStorage >
639 DGtal::PointVector<dim, TComponent, TContainer>::cosineSimilarity( const DGtal::PointVector<dim, OtherComponent, OtherStorage>& v ) const
641 return DGtal::cosineSimilarity(*this, v);
643 //------------------------------------------------------------------------------
644 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
645 template < typename OtherComponent, typename OtherStorage >
647 DGtal::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 >
657 DGtal::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 >
673 DGtal::PointVector<3, DGtal::ArithmeticConversionType<LeftEuclideanRing, RightEuclideanRing>>
674 DGtal::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 //------------------------------------------------------------------------------
684 template < DGtal::Dimension ptDim,
685 typename LeftEuclideanRing, typename LeftContainer,
686 typename RightEuclideanRing, typename RightContainer >
688 DGtal::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 //------------------------------------------------------------------------------
696 template < DGtal::Dimension ptDim,
697 typename LeftEuclideanRing, typename LeftContainer,
698 typename RightEuclideanRing, typename RightContainer >
700 DGtal::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 //------------------------------------------------------------------------------
708 template < DGtal::Dimension ptDim,
709 typename LeftEuclideanRing, typename LeftContainer,
710 typename RightEuclideanRing, typename RightContainer >
712 DGtal::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 //------------------------------------------------------------------------------
720 template < DGtal::Dimension ptDim,
721 typename LeftEuclideanRing, typename LeftContainer,
722 typename RightEuclideanRing, typename RightContainer >
724 DGtal::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 //------------------------------------------------------------------------------
732 template < DGtal::Dimension ptDim,
733 typename LeftEuclideanRing, typename LeftContainer,
734 typename RightScalar >
736 DGtal::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 //------------------------------------------------------------------------------
743 template < DGtal::Dimension ptDim,
745 typename RightEuclideanRing, typename RightContainer >
747 DGtal::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 //------------------------------------------------------------------------------
754 template < DGtal::Dimension ptDim,
755 typename LeftEuclideanRing, typename LeftContainer,
756 typename RightScalar >
758 DGtal::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 //------------------------------------------------------------------------------
765 template < DGtal::Dimension ptDim,
767 typename RightEuclideanRing, typename RightContainer >
769 DGtal::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 //------------------------------------------------------------------------------
776 template < DGtal::Dimension ptDim,
777 typename LeftEuclideanRing, typename LeftContainer,
778 typename RightScalar >
780 DGtal::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 //------------------------------------------------------------------------------
787 template < DGtal::Dimension ptDim,
789 typename RightEuclideanRing, typename RightContainer >
791 DGtal::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 //------------------------------------------------------------------------------
798 template < DGtal::Dimension ptDim,
799 typename LeftEuclideanRing, typename LeftContainer,
800 typename RightScalar >
802 DGtal::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 //------------------------------------------------------------------------------
809 template < DGtal::Dimension ptDim,
811 typename RightEuclideanRing, typename RightContainer >
813 DGtal::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 //------------------------------------------------------------------------------
820 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
822 DGtal::PointVector<dim, TComponent,TContainer>
823 DGtal::PointVector<dim, TComponent,TContainer>::operator-() const
825 return Self(*this, functors::UnaryMinus<Component>());
827 //------------------------------------------------------------------------------
828 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
831 DGtal::PointVector<dim, TComponent, TContainer>::reset()
833 for ( DGtal::Dimension i = 0; i < myArray.size(); ++i )
834 myArray[ i ] = NumberTraits< Component >::ZERO;
836 //------------------------------------------------------------------------------
837 template < DGtal::Dimension ptDim,
838 typename LeftEuclideanRing, typename LeftContainer,
839 typename RightEuclideanRing, typename RightContainer >
841 DGtal::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 //------------------------------------------------------------------------------
849 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
850 template < typename OtherComponent, typename OtherStorage >
852 DGtal::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 //------------------------------------------------------------------------------
858 template < DGtal::Dimension ptDim,
859 typename LeftEuclideanRing, typename LeftContainer,
860 typename RightEuclideanRing, typename RightContainer >
862 DGtal::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 //------------------------------------------------------------------------------
870 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
871 template < typename OtherComponent, typename OtherStorage >
873 DGtal::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 //------------------------------------------------------------------------------
879 template < DGtal::Dimension ptDim,
880 typename LeftEuclideanRing, typename LeftContainer,
881 typename RightEuclideanRing, typename RightContainer >
883 DGtal::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 //------------------------------------------------------------------------------
892 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
893 template < typename OtherComponent, typename OtherStorage >
895 DGtal::PointVector<dim, TComponent, TContainer>::isLower( const DGtal::PointVector<dim, OtherComponent, OtherStorage> & p ) const
897 return DGtal::isLower(*this, p);
899 //------------------------------------------------------------------------------
900 template < DGtal::Dimension ptDim,
901 typename LeftEuclideanRing, typename LeftContainer,
902 typename RightEuclideanRing, typename RightContainer >
904 DGtal::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 //------------------------------------------------------------------------------
913 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
914 template < typename OtherComponent, typename OtherStorage >
916 DGtal::PointVector<dim, TComponent, TContainer>::isUpper( const DGtal::PointVector<dim, OtherComponent, OtherStorage> & p ) const
918 return DGtal::isUpper(*this, p);
920 //------------------------------------------------------------------------------
921 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
923 typename DGtal::PointVector<dim, TComponent, TContainer>::Component
924 DGtal::PointVector<dim, TComponent, TContainer>::max( ) const
926 return *std::max_element(this->begin(), this->end());
928 //------------------------------------------------------------------------------
929 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
931 typename DGtal::PointVector<dim, TComponent, TContainer>::Component
932 DGtal::PointVector<dim, TComponent, TContainer>::min( ) const
934 return *std::min_element(this->begin(), this->end());
936 //------------------------------------------------------------------------------
937 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
939 typename DGtal::PointVector<dim, TComponent, TContainer>::Iterator
940 DGtal::PointVector<dim, TComponent, TContainer>::maxElement( )
942 return std::max_element(this->begin(), this->end());
944 //------------------------------------------------------------------------------
945 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
947 typename DGtal::PointVector<dim, TComponent, TContainer>::Iterator
948 DGtal::PointVector<dim, TComponent, TContainer>::minElement( )
950 return std::min_element(this->begin(), this->end());
952 //------------------------------------------------------------------------------
953 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
956 DGtal::PointVector<dim, TComponent, TContainer>::
959 for ( DGtal::Dimension i = 0; i < dimension; ++i )
960 this->myArray[ i ] = - this->myArray[ i ];
962 //------------------------------------------------------------------------------
963 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
966 DGtal::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 //------------------------------------------------------------------------------
975 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
978 DGtal::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 //------------------------------------------------------------------------------
1007 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
1009 typename DGtal::PointVector<dim, TComponent, TContainer>::UnsignedComponent
1010 DGtal::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 //------------------------------------------------------------------------------
1022 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
1024 typename DGtal::PointVector<dim, TComponent, TContainer>::UnsignedComponent
1025 DGtal::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 //------------------------------------------------------------------------------
1040 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
1042 typename DGtal::PointVector<dim, double, std::array<double,dim> >
1043 DGtal::PointVector<dim, TComponent, TContainer>::getNormalized() const
1045 PointVector<dim,double,std::array<double,dim> > normalized =(*this);
1046 normalized /= normalized.norm();
1049 //------------------------------------------------------------------------------
1050 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
1052 DGtal::PointVector<dim,TComponent, TContainer>
1053 DGtal::PointVector<dim,TComponent, TContainer>::diagonal( Component val )
1056 for ( DGtal::Dimension i = 0; i < dim; ++i )
1057 p.myArray[ i ] = val;
1060 //------------------------------------------------------------------------------
1061 template<DGtal::Dimension dim,typename TComponent, typename TContainer>
1063 DGtal::PointVector<dim,TComponent, TContainer>
1064 DGtal::PointVector<dim,TComponent, TContainer>::base( Dimension k, Component val )
1067 p.myArray[ k ] = val;
1070 //------------------------------------------------------------------------------
1071 template<DGtal::Dimension dim,typename TComponent, typename TContainer>
1074 DGtal::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 //------------------------------------------------------------------------------
1083 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
1086 DGtal::PointVector<dim, TComponent, TContainer>::className() const
1088 return "PointVector";
1091 //------------------------------------------------------------------------------
1092 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
1095 DGtal::operator<<( std::ostream & out,
1096 const PointVector<dim, TComponent, TContainer>& object )
1098 object.selfDisplay( out );
1101 //------------------------------------------------------------------------------
1102 template<DGtal::Dimension dim, typename TComponent, typename TContainer>
1105 DGtal::PointVector<dim, TComponent, TContainer>::isValid() const
1109 //------------------------------------------------------------------------------