KiCad PCB EDA Suite
vector2d.h
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KICAD, a free EDA CAD application.
3  *
4  * Copyright (C) 2010 Virtenio GmbH, Torsten Hueter, torsten.hueter <at> virtenio.de
5  * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
6  * Copyright (C) 2012-2021 KiCad Developers, see AUTHORS.txt for contributors.
7  * Copyright (C) 2013 CERN
8  * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, you may find one here:
22  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
23  * or you may search the http://www.gnu.org website for the version 2 license,
24  * or you may write to the Free Software Foundation, Inc.,
25  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
26  */
27 
28 #ifndef VECTOR2D_H_
29 #define VECTOR2D_H_
30 
31 #include <limits>
32 #include <iostream>
33 #include <sstream>
34 #include <type_traits>
35 
36 #include <math/util.h>
37 
38 #ifdef WX_COMPATIBILITY
39 #include <wx/gdicmn.h>
40 #endif
41 
45 template <class T>
47 {
50  typedef T extended_type;
51 };
52 
53 template <>
54 struct VECTOR2_TRAITS<int>
55 {
56  typedef int64_t extended_type;
57 };
58 
59 // Forward declarations for template friends
60 template <class T>
61 class VECTOR2;
62 template <class T>
63 std::ostream& operator<<( std::ostream& aStream, const VECTOR2<T>& aVector );
64 
72 template <class T = int>
73 class VECTOR2
74 {
75 public:
77  typedef T coord_type;
78 
79  static constexpr extended_type ECOORD_MAX = std::numeric_limits<extended_type>::max();
80  static constexpr extended_type ECOORD_MIN = std::numeric_limits<extended_type>::min();
81 
82  T x, y;
83 
85  VECTOR2();
86 
87 #ifdef WX_COMPATIBILITY
88  VECTOR2( const wxPoint& aPoint );
90 
92  VECTOR2( const wxSize& aSize );
93 #endif
94 
96  VECTOR2( T x, T y );
97 
99  template <typename CastingType>
101  {
102  x = (T) aVec.x;
103  y = (T) aVec.y;
104  }
105 
107  VECTOR2( const VECTOR2<T>& aVec )
108  {
109  x = aVec.x;
110  y = aVec.y;
111  }
112 
114  template <typename CastedType>
116  {
117  return VECTOR2<CastedType>( (CastedType) x, (CastedType) y );
118  }
119 
125  explicit operator wxPoint() const
126  {
127  return wxPoint( x, y );
128  }
129 
130  // virtual ~VECTOR2();
131 
139  T EuclideanNorm() const;
140 
149 
150 
156  VECTOR2<T> Perpendicular() const;
157 
164  VECTOR2<T> Resize( T aNewLength ) const;
165 
171  double Angle() const;
172 
179  VECTOR2<T> Rotate( double aAngle ) const;
180 
186  const std::string Format() const;
187 
191  extended_type Cross( const VECTOR2<T>& aVector ) const;
192 
196  extended_type Dot( const VECTOR2<T>& aVector ) const;
197 
198 
199  // Operators
200 
202  VECTOR2<T>& operator=( const VECTOR2<T>& aVector );
203 
205  VECTOR2<T> operator+( const VECTOR2<T>& aVector ) const;
206 
208  VECTOR2<T> operator+( const T& aScalar ) const;
209 
211  VECTOR2<T>& operator+=( const VECTOR2<T>& aVector );
212 
214  VECTOR2<T>& operator+=( const T& aScalar );
215 
217  VECTOR2<T> operator-( const VECTOR2<T>& aVector ) const;
218 
220  VECTOR2<T> operator-( const T& aScalar ) const;
221 
223  VECTOR2<T>& operator-=( const VECTOR2<T>& aVector );
224 
226  VECTOR2<T>& operator-=( const T& aScalar );
227 
230 
232  extended_type operator*( const VECTOR2<T>& aVector ) const;
233 
235  VECTOR2<T> operator*( const T& aFactor ) const;
236 
238  VECTOR2<T> operator/( const T& aFactor ) const;
239 
241  bool operator==( const VECTOR2<T>& aVector ) const;
242 
244  bool operator!=( const VECTOR2<T>& aVector ) const;
245 
247  bool operator<( const VECTOR2<T>& aVector ) const;
248  bool operator<=( const VECTOR2<T>& aVector ) const;
249 
251  bool operator>( const VECTOR2<T>& aVector ) const;
252  bool operator>=( const VECTOR2<T>& aVector ) const;
253 };
254 
255 
256 // ----------------------
257 // --- Implementation ---
258 // ----------------------
259 
260 template <class T>
262 {
263  x = y = 0.0;
264 }
265 
266 
267 #ifdef WX_COMPATIBILITY
268 template <class T>
269 VECTOR2<T>::VECTOR2( const wxPoint& aPoint )
270 {
271  x = T( aPoint.x );
272  y = T( aPoint.y );
273 }
274 
275 
276 template <class T>
277 VECTOR2<T>::VECTOR2( const wxSize& aSize )
278 {
279  x = T( aSize.x );
280  y = T( aSize.y );
281 }
282 #endif
283 
284 template <class T>
285 VECTOR2<T>::VECTOR2( T aX, T aY )
286 {
287  x = aX;
288  y = aY;
289 }
290 
291 
292 template <class T>
294 {
295  return sqrt( (extended_type) x * x + (extended_type) y * y );
296 }
297 
298 
299 template <class T>
301 {
302  return (extended_type) x * x + (extended_type) y * y;
303 }
304 
305 
306 template <class T>
307 double VECTOR2<T>::Angle() const
308 {
309  return atan2( (double) y, (double) x );
310 }
311 
312 
313 template <class T>
315 {
316  VECTOR2<T> perpendicular( -y, x );
317  return perpendicular;
318 }
319 
320 
321 template <class T>
323 {
324  x = aVector.x;
325  y = aVector.y;
326  return *this;
327 }
328 
329 
330 template <class T>
332 {
333  x += aVector.x;
334  y += aVector.y;
335  return *this;
336 }
337 
338 
339 template <class T>
340 VECTOR2<T>& VECTOR2<T>::operator+=( const T& aScalar )
341 {
342  x += aScalar;
343  y += aScalar;
344  return *this;
345 }
346 
347 
348 template <class T>
350 {
351  x -= aVector.x;
352  y -= aVector.y;
353  return *this;
354 }
355 
356 
357 template <class T>
358 VECTOR2<T>& VECTOR2<T>::operator-=( const T& aScalar )
359 {
360  x -= aScalar;
361  y -= aScalar;
362  return *this;
363 }
364 
365 
370 template <class T>
371 VECTOR2<T> VECTOR2<T>::Rotate( double aAngle ) const
372 {
373  // Avoid common radian rotations that may allow for angular error
374  if( aAngle == 0.0 || aAngle == 2 * M_PI )
375  return VECTOR2<T> ( T( x ), T( y ) );
376 
377  if( aAngle == M_PI_2 )
378  return VECTOR2<T>( -T( y ), T( x ) );
379 
380  if( aAngle == M_PI )
381  return VECTOR2<T>( -T(x), -T( y ) );
382 
383  if( aAngle == 3 * M_PI_2 )
384  return VECTOR2<T>( T( y ), -T( x ) );
385 
386  double sa = sin( aAngle );
387  double ca = cos( aAngle );
388 
389  if( std::is_integral<T>::value )
390  {
391  return VECTOR2<T> ( KiROUND( (double) x * ca - (double) y * sa ),
392  KiROUND( (double) x * sa + (double) y * ca ) );
393 
394  }
395  else
396  {
397  return VECTOR2<T> ( T( (double) x * ca - (double) y * sa ),
398  T( (double) x * sa + (double) y * ca ) );
399  }
400 }
401 
402 
403 template <class T>
404 VECTOR2<T> VECTOR2<T>::Resize( T aNewLength ) const
405 {
406  if( x == 0 && y == 0 )
407  return VECTOR2<T> ( 0, 0 );
408 
409  extended_type l_sq_current = (extended_type) x * x + (extended_type) y * y;
410  extended_type l_sq_new = (extended_type) aNewLength * aNewLength;
411 
412  if( std::is_integral<T>::value )
413  {
414  return VECTOR2<T> (
415  ( x < 0 ? -1 : 1 ) *
416  KiROUND( std::sqrt( rescale( l_sq_new, (extended_type) x * x, l_sq_current ) ) ),
417  ( y < 0 ? -1 : 1 ) *
418  KiROUND( std::sqrt( rescale( l_sq_new, (extended_type) y * y, l_sq_current ) ) ) )
419  * sign( aNewLength );
420  }
421  else
422  {
423  return VECTOR2<T> (
424  ( x < 0 ? -1 : 1 ) *
425  std::sqrt( rescale( l_sq_new, (extended_type) x * x, l_sq_current ) ),
426  ( y < 0 ? -1 : 1 ) *
427  std::sqrt( rescale( l_sq_new, (extended_type) y * y, l_sq_current ) ) )
428  * sign( aNewLength );
429  }
430 }
431 
432 
433 template <class T>
434 const std::string VECTOR2<T>::Format() const
435 {
436  std::stringstream ss;
437 
438  ss << "( xy " << x << " " << y << " )";
439 
440  return ss.str();
441 }
442 
443 
444 template <class T>
446 {
447  return VECTOR2<T> ( x + aVector.x, y + aVector.y );
448 }
449 
450 
451 template <class T>
452 VECTOR2<T> VECTOR2<T>::operator+( const T& aScalar ) const
453 {
454  return VECTOR2<T> ( x + aScalar, y + aScalar );
455 }
456 
457 
458 template <class T>
460 {
461  return VECTOR2<T> ( x - aVector.x, y - aVector.y );
462 }
463 
464 
465 template <class T>
466 VECTOR2<T> VECTOR2<T>::operator-( const T& aScalar ) const
467 {
468  return VECTOR2<T> ( x - aScalar, y - aScalar );
469 }
470 
471 
472 template <class T>
474 {
475  return VECTOR2<T> ( -x, -y );
476 }
477 
478 
479 template <class T>
481 {
482  return (extended_type)aVector.x * x + (extended_type)aVector.y * y;
483 }
484 
485 
486 template <class T>
487 VECTOR2<T> VECTOR2<T>::operator*( const T& aFactor ) const
488 {
489  VECTOR2<T> vector( x * aFactor, y * aFactor );
490  return vector;
491 }
492 
493 
494 template <class T>
495 VECTOR2<T> VECTOR2<T>::operator/( const T& aFactor ) const
496 {
497  if( std::is_integral<T>::value )
498  return VECTOR2<T>( KiROUND( x / aFactor ), KiROUND( y / aFactor ) );
499  else
500  return VECTOR2<T>( x / aFactor, y / aFactor );
501 }
502 
503 
504 template <class T>
505 VECTOR2<T> operator*( const T& aFactor, const VECTOR2<T>& aVector )
506 {
507  VECTOR2<T> vector( aVector.x * aFactor, aVector.y * aFactor );
508  return vector;
509 }
510 
511 
512 template <class T>
514 {
515  return (extended_type) x * (extended_type) aVector.y -
516  (extended_type) y * (extended_type) aVector.x;
517 }
518 
519 
520 template <class T>
521 typename VECTOR2<T>::extended_type VECTOR2<T>::Dot( const VECTOR2<T>& aVector ) const
522 {
523  return (extended_type) x * (extended_type) aVector.x +
524  (extended_type) y * (extended_type) aVector.y;
525 }
526 
527 
528 template <class T>
529 bool VECTOR2<T>::operator<( const VECTOR2<T>& aVector ) const
530 {
531  return ( *this * *this ) < ( aVector * aVector );
532 }
533 
534 
535 template <class T>
536 bool VECTOR2<T>::operator<=( const VECTOR2<T>& aVector ) const
537 {
538  return ( *this * *this ) <= ( aVector * aVector );
539 }
540 
541 
542 template <class T>
543 bool VECTOR2<T>::operator>( const VECTOR2<T>& aVector ) const
544 {
545  return ( *this * *this ) > ( aVector * aVector );
546 }
547 
548 
549 template <class T>
550 bool VECTOR2<T>::operator>=( const VECTOR2<T>& aVector ) const
551 {
552  return ( *this * *this ) >= ( aVector * aVector );
553 }
554 
555 
556 template <class T>
557 bool VECTOR2<T>::operator==( VECTOR2<T> const& aVector ) const
558 {
559  return ( aVector.x == x ) && ( aVector.y == y );
560 }
561 
562 
563 template <class T>
564 bool VECTOR2<T>::operator!=( VECTOR2<T> const& aVector ) const
565 {
566  return ( aVector.x != x ) || ( aVector.y != y );
567 }
568 
569 
570 template <class T>
571 const VECTOR2<T> LexicographicalMax( const VECTOR2<T>& aA, const VECTOR2<T>& aB )
572 {
573  if( aA.x > aB.x )
574  return aA;
575  else if( aA.x == aB.x && aA.y > aB.y )
576  return aA;
577 
578  return aB;
579 }
580 
581 
582 template <class T>
583 const VECTOR2<T> LexicographicalMin( const VECTOR2<T>& aA, const VECTOR2<T>& aB )
584 {
585  if( aA.x < aB.x )
586  return aA;
587  else if( aA.x == aB.x && aA.y < aB.y )
588  return aA;
589 
590  return aB;
591 }
592 
593 
594 template <class T>
595 const int LexicographicalCompare( const VECTOR2<T>& aA, const VECTOR2<T>& aB )
596 {
597  if( aA.x < aB.x )
598  return -1;
599  else if( aA.x > aB.x )
600  return 1;
601  else // aA.x == aB.x
602  {
603  if( aA.y < aB.y )
604  return -1;
605  else if( aA.y > aB.y )
606  return 1;
607  else
608  return 0;
609  }
610 }
611 
612 
613 template <class T>
614 std::ostream& operator<<( std::ostream& aStream, const VECTOR2<T>& aVector )
615 {
616  aStream << "[ " << aVector.x << " | " << aVector.y << " ]";
617  return aStream;
618 }
619 
620 
621 /* Default specializations */
625 
626 /* Compatibility typedefs */
627 // FIXME should be removed to avoid multiple typedefs for the same type
629 typedef DPOINT DSIZE;
630 
631 #endif // VECTOR2D_H_
VECTOR2_TRAITS< T >::extended_type extended_type
Definition: vector2d.h:76
extended_type Cross(const VECTOR2< T > &aVector) const
Compute cross product of self with aVector.
Definition: vector2d.h:513
int sign(T val)
Definition: util.h:104
Traits class for VECTOR2.
Definition: vector2d.h:46
bool operator>=(const VECTOR2< T > &aVector) const
Definition: vector2d.h:550
int64_t extended_type
Definition: vector2d.h:56
VECTOR2< T > operator+(const VECTOR2< T > &aVector) const
Vector addition operator.
Definition: vector2d.h:445
VECTOR2< T > Perpendicular() const
Compute the perpendicular vector.
Definition: vector2d.h:314
DPOINT DSIZE
Definition: vector2d.h:629
#define M_PI_2
Definition: transline.cpp:40
Define a general 2D-vector/point.
Definition: vector2d.h:61
const VECTOR2< T > LexicographicalMin(const VECTOR2< T > &aA, const VECTOR2< T > &aB)
Definition: vector2d.h:583
extended_type SquaredEuclideanNorm() const
Compute the squared euclidean norm of the vector, which is defined as (x ** 2 + y ** 2).
Definition: vector2d.h:300
VECTOR2< T > operator *(const T &aFactor, const VECTOR2< T > &aVector)
Definition: vector2d.h:505
VECTOR2< int > VECTOR2I
Definition: vector2d.h:623
VECTOR2< CastedType > operator()() const
Cast a vector to another specialized subclass. Beware of rounding issues.
Definition: vector2d.h:115
bool operator!=(const VECTOR2< T > &aVector) const
Not equality operator.
Definition: vector2d.h:564
VECTOR2< T > & operator=(const VECTOR2< T > &aVector)
Assignment operator.
Definition: vector2d.h:322
T extended_type
< extended range/precision types used by operations involving multiple multiplications to prevent ove...
Definition: vector2d.h:50
static constexpr extended_type ECOORD_MAX
Definition: vector2d.h:79
std::ostream & operator<<(std::ostream &aStream, const VECTOR2< T > &aVector)
Definition: vector2d.h:614
T coord_type
Definition: vector2d.h:77
VECTOR2< double > VECTOR2D
Definition: vector2d.h:622
VECTOR2()
Construct a 2D-vector with x, y = 0.
Definition: vector2d.h:261
const int LexicographicalCompare(const VECTOR2< T > &aA, const VECTOR2< T > &aB)
Definition: vector2d.h:595
const std::string Format() const
Return the vector formatted as a string.
Definition: vector2d.h:434
bool operator<(const VECTOR2< T > &aVector) const
Smaller than operator.
Definition: vector2d.h:529
VECTOR2< unsigned int > VECTOR2U
Definition: vector2d.h:624
extended_type operator *(const VECTOR2< T > &aVector) const
Scalar product operator.
Definition: vector2d.h:480
bool operator==(const VECTOR2< T > &aVector) const
Equality operator.
Definition: vector2d.h:557
double Angle() const
Compute the angle of the vector.
Definition: vector2d.h:307
bool operator<=(const VECTOR2< T > &aVector) const
Definition: vector2d.h:536
VECTOR2< T > Resize(T aNewLength) const
Return a vector of the same direction, but length specified in aNewLength.
Definition: vector2d.h:404
VECTOR2< T > Rotate(double aAngle) const
Rotate the vector by a given angle.
Definition: vector2d.h:371
VECTOR2< T > & operator-=(const VECTOR2< T > &aVector)
Compound assignment operator.
Definition: vector2d.h:349
VECTOR2< T > operator/(const T &aFactor) const
Division with a factor.
Definition: vector2d.h:495
extended_type Dot(const VECTOR2< T > &aVector) const
Compute dot product of self with aVector.
Definition: vector2d.h:521
const VECTOR2< T > LexicographicalMax(const VECTOR2< T > &aA, const VECTOR2< T > &aB)
Definition: vector2d.h:571
T rescale(T aNumerator, T aValue, T aDenominator)
Scale a number (value) by rational (numerator/denominator).
Definition: util.h:98
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:73
static constexpr extended_type ECOORD_MIN
Definition: vector2d.h:80
VECTOR2< T > operator-()
Negate Vector operator.
Definition: vector2d.h:473
VECTOR2(const VECTOR2< CastingType > &aVec)
Initializes a vector from another specialization. Beware of rounding issues.
Definition: vector2d.h:100
T EuclideanNorm() const
Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
Definition: vector2d.h:293
VECTOR2(const VECTOR2< T > &aVec)
Copy a vector.
Definition: vector2d.h:107
VECTOR2< double > DPOINT
Definition: vector2d.h:628
VECTOR2< T > & operator+=(const VECTOR2< T > &aVector)
Compound assignment operator.
Definition: vector2d.h:331
bool operator>(const VECTOR2< T > &aVector) const
Greater than operator.
Definition: vector2d.h:543