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 Kicad Developers, see change_log.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 
46 template <class T>
48 {
51  typedef T extended_type;
52 };
53 
54 template <>
55 struct VECTOR2_TRAITS<int>
56 {
57  typedef int64_t extended_type;
58 };
59 
60 // Forward declarations for template friends
61 template <class T>
62 class VECTOR2;
63 template <class T>
64 std::ostream& operator<<( std::ostream& aStream, const VECTOR2<T>& aVector );
65 
74 template <class T = int>
75 class VECTOR2
76 {
77 public:
79  typedef T coord_type;
80 
81  static constexpr extended_type ECOORD_MAX = std::numeric_limits<extended_type>::max();
82  static constexpr extended_type ECOORD_MIN = std::numeric_limits<extended_type>::min();
83 
84  T x, y;
85 
86  // Constructors
87 
89  VECTOR2();
90 
91 #ifdef WX_COMPATIBILITY
92  VECTOR2( const wxPoint& aPoint );
94 
96  VECTOR2( const wxSize& aSize );
97 #endif
98 
100  VECTOR2( T x, T y );
101 
104  template <typename CastingType>
106  {
107  x = (T) aVec.x;
108  y = (T) aVec.y;
109  }
110 
112  VECTOR2( const VECTOR2<T>& aVec )
113  {
114  x = aVec.x;
115  y = aVec.y;
116  }
117 
120  template <typename CastedType>
122  {
123  return VECTOR2<CastedType>( (CastedType) x, (CastedType) y );
124  }
125 
131  explicit operator wxPoint() const
132  {
133  return wxPoint( x, y );
134  }
135 
137  // virtual ~VECTOR2();
138 
145  T EuclideanNorm() const;
146 
154 
155 
161  VECTOR2<T> Perpendicular() const;
162 
169  VECTOR2<T> Resize( T aNewLength ) const;
170 
176  double Angle() const;
177 
184  VECTOR2<T> Rotate( double aAngle ) const;
185 
191  const std::string Format() const;
192 
197  extended_type Cross( const VECTOR2<T>& aVector ) const;
198 
203  extended_type Dot( const VECTOR2<T>& aVector ) const;
204 
205 
206  // Operators
207 
209  VECTOR2<T>& operator=( const VECTOR2<T>& aVector );
210 
212  VECTOR2<T> operator+( const VECTOR2<T>& aVector ) const;
213 
215  VECTOR2<T> operator+( const T& aScalar ) const;
216 
218  VECTOR2<T>& operator+=( const VECTOR2<T>& aVector );
219 
221  VECTOR2<T>& operator+=( const T& aScalar );
222 
224  VECTOR2<T> operator-( const VECTOR2<T>& aVector ) const;
225 
227  VECTOR2<T> operator-( const T& aScalar ) const;
228 
230  VECTOR2<T>& operator-=( const VECTOR2<T>& aVector );
231 
233  VECTOR2<T>& operator-=( const T& aScalar );
234 
237 
239  extended_type operator*( const VECTOR2<T>& aVector ) const;
240 
242  VECTOR2<T> operator*( const T& aFactor ) const;
243 
245  VECTOR2<T> operator/( const T& aFactor ) const;
246 
248  bool operator==( const VECTOR2<T>& aVector ) const;
249 
251  bool operator!=( const VECTOR2<T>& aVector ) const;
252 
254  bool operator<( const VECTOR2<T>& aVector ) const;
255  bool operator<=( const VECTOR2<T>& aVector ) const;
256 
258  bool operator>( const VECTOR2<T>& aVector ) const;
259  bool operator>=( const VECTOR2<T>& aVector ) const;
260 };
261 
262 
263 // ----------------------
264 // --- Implementation ---
265 // ----------------------
266 
267 template <class T>
269 {
270  x = y = 0.0;
271 }
272 
273 
274 #ifdef WX_COMPATIBILITY
275 template <class T>
276 VECTOR2<T>::VECTOR2( wxPoint const& aPoint )
277 {
278  x = T( aPoint.x );
279  y = T( aPoint.y );
280 }
281 
282 
283 template <class T>
284 VECTOR2<T>::VECTOR2( wxSize const& aSize )
285 {
286  x = T( aSize.x );
287  y = T( aSize.y );
288 }
289 #endif
290 
291 template <class T>
292 VECTOR2<T>::VECTOR2( T aX, T aY )
293 {
294  x = aX;
295  y = aY;
296 }
297 
298 
299 template <class T>
301 {
302  return sqrt( (extended_type) x * x + (extended_type) y * y );
303 }
304 
305 
306 template <class T>
308 {
309  return (extended_type) x * x + (extended_type) y * y;
310 }
311 
312 
313 template <class T>
314 double VECTOR2<T>::Angle() const
315 {
316  return atan2( (double) y, (double) x );
317 }
318 
319 
320 template <class T>
322 {
323  VECTOR2<T> perpendicular( -y, x );
324  return perpendicular;
325 }
326 
327 
328 template <class T>
330 {
331  x = aVector.x;
332  y = aVector.y;
333  return *this;
334 }
335 
336 
337 template <class T>
339 {
340  x += aVector.x;
341  y += aVector.y;
342  return *this;
343 }
344 
345 
346 template <class T>
347 VECTOR2<T>& VECTOR2<T>::operator+=( const T& aScalar )
348 {
349  x += aScalar;
350  y += aScalar;
351  return *this;
352 }
353 
354 
355 template <class T>
357 {
358  x -= aVector.x;
359  y -= aVector.y;
360  return *this;
361 }
362 
363 
364 template <class T>
365 VECTOR2<T>& VECTOR2<T>::operator-=( const T& aScalar )
366 {
367  x -= aScalar;
368  y -= aScalar;
369  return *this;
370 }
371 
372 
377 template <class T>
378 VECTOR2<T> VECTOR2<T>::Rotate( double aAngle ) const
379 {
380  // Avoid common radian rotations that may allow for angular error
381  if( aAngle == 0.0 || aAngle == 2 * M_PI )
382  return VECTOR2<T> ( T( x ), T( y ) );
383 
384  if( aAngle == M_PI_2 )
385  return VECTOR2<T>( -T( y ), T( x ) );
386 
387  if( aAngle == M_PI )
388  return VECTOR2<T>( -T(x), -T( y ) );
389 
390  if( aAngle == 3 * M_PI_2 )
391  return VECTOR2<T>( T( y ), -T( x ) );
392 
393  double sa = sin( aAngle );
394  double ca = cos( aAngle );
395 
396  if( std::is_integral<T>::value )
397  {
398  return VECTOR2<T> ( KiROUND( (double) x * ca - (double) y * sa ),
399  KiROUND( (double) x * sa + (double) y * ca ) );
400 
401  }
402  else
403  {
404  return VECTOR2<T> ( T( (double) x * ca - (double) y * sa ),
405  T( (double) x * sa + (double) y * ca ) );
406  }
407 }
408 
409 
410 template <class T>
411 VECTOR2<T> VECTOR2<T>::Resize( T aNewLength ) const
412 {
413  if( x == 0 && y == 0 )
414  return VECTOR2<T> ( 0, 0 );
415 
416  extended_type l_sq_current = (extended_type) x * x + (extended_type) y * y;
417  extended_type l_sq_new = (extended_type) aNewLength * aNewLength;
418 
419  if( std::is_integral<T>::value )
420  {
421  return VECTOR2<T> (
422  ( x < 0 ? -1 : 1 ) *
423  KiROUND( std::sqrt( rescale( l_sq_new, (extended_type) x * x, l_sq_current ) ) ),
424  ( y < 0 ? -1 : 1 ) *
425  KiROUND( std::sqrt( rescale( l_sq_new, (extended_type) y * y, l_sq_current ) ) ) )
426  * sign( aNewLength );
427  }
428  else
429  {
430  return VECTOR2<T> (
431  ( x < 0 ? -1 : 1 ) *
432  std::sqrt( rescale( l_sq_new, (extended_type) x * x, l_sq_current ) ),
433  ( y < 0 ? -1 : 1 ) *
434  std::sqrt( rescale( l_sq_new, (extended_type) y * y, l_sq_current ) ) )
435  * sign( aNewLength );
436  }
437 }
438 
439 
440 template <class T>
441 const std::string VECTOR2<T>::Format() const
442 {
443  std::stringstream ss;
444 
445  ss << "( xy " << x << " " << y << " )";
446 
447  return ss.str();
448 }
449 
450 
451 template <class T>
453 {
454  return VECTOR2<T> ( x + aVector.x, y + aVector.y );
455 }
456 
457 
458 template <class T>
459 VECTOR2<T> VECTOR2<T>::operator+( const T& aScalar ) const
460 {
461  return VECTOR2<T> ( x + aScalar, y + aScalar );
462 }
463 
464 
465 template <class T>
467 {
468  return VECTOR2<T> ( x - aVector.x, y - aVector.y );
469 }
470 
471 
472 template <class T>
473 VECTOR2<T> VECTOR2<T>::operator-( const T& aScalar ) const
474 {
475  return VECTOR2<T> ( x - aScalar, y - aScalar );
476 }
477 
478 
479 template <class T>
481 {
482  return VECTOR2<T> ( -x, -y );
483 }
484 
485 
486 template <class T>
488 {
489  return (extended_type)aVector.x * x + (extended_type)aVector.y * y;
490 }
491 
492 
493 template <class T>
494 VECTOR2<T> VECTOR2<T>::operator*( const T& aFactor ) const
495 {
496  VECTOR2<T> vector( x * aFactor, y * aFactor );
497  return vector;
498 }
499 
500 
501 template <class T>
502 VECTOR2<T> VECTOR2<T>::operator/( const T& aFactor ) const
503 {
504  if( std::is_integral<T>::value )
505  return VECTOR2<T>( KiROUND( x / aFactor ), KiROUND( y / aFactor ) );
506  else
507  return VECTOR2<T>( x / aFactor, y / aFactor );
508 }
509 
510 
511 template <class T>
512 VECTOR2<T> operator*( const T& aFactor, const VECTOR2<T>& aVector )
513 {
514  VECTOR2<T> vector( aVector.x * aFactor, aVector.y * aFactor );
515  return vector;
516 }
517 
518 
519 template <class T>
521 {
522  return (extended_type) x * (extended_type) aVector.y -
523  (extended_type) y * (extended_type) aVector.x;
524 }
525 
526 
527 template <class T>
528 typename VECTOR2<T>::extended_type VECTOR2<T>::Dot( const VECTOR2<T>& aVector ) const
529 {
530  return (extended_type) x * (extended_type) aVector.x +
531  (extended_type) y * (extended_type) aVector.y;
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>=( const VECTOR2<T>& aVector ) const
558 {
559  return ( *this * *this ) >= ( aVector * aVector );
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 bool VECTOR2<T>::operator!=( VECTOR2<T> const& aVector ) const
572 {
573  return ( aVector.x != x ) || ( aVector.y != y );
574 }
575 
576 
577 template <class T>
578 const VECTOR2<T> LexicographicalMax( const VECTOR2<T>& aA, const VECTOR2<T>& aB )
579 {
580  if( aA.x > aB.x )
581  return aA;
582  else if( aA.x == aB.x && aA.y > aB.y )
583  return aA;
584 
585  return aB;
586 }
587 
588 
589 template <class T>
590 const VECTOR2<T> LexicographicalMin( const VECTOR2<T>& aA, const VECTOR2<T>& aB )
591 {
592  if( aA.x < aB.x )
593  return aA;
594  else if( aA.x == aB.x && aA.y < aB.y )
595  return aA;
596 
597  return aB;
598 }
599 
600 
601 template <class T>
602 const int LexicographicalCompare( const VECTOR2<T>& aA, const VECTOR2<T>& aB )
603 {
604  if( aA.x < aB.x )
605  return -1;
606  else if( aA.x > aB.x )
607  return 1;
608  else // aA.x == aB.x
609  {
610  if( aA.y < aB.y )
611  return -1;
612  else if( aA.y > aB.y )
613  return 1;
614  else
615  return 0;
616  }
617 }
618 
619 
620 template <class T>
621 std::ostream& operator<<( std::ostream& aStream, const VECTOR2<T>& aVector )
622 {
623  aStream << "[ " << aVector.x << " | " << aVector.y << " ]";
624  return aStream;
625 }
626 
627 
628 /* Default specializations */
632 
633 /* Compatibility typedefs */
634 // FIXME should be removed to avoid multiple typedefs for the same type
636 typedef DPOINT DSIZE;
637 
638 #endif // VECTOR2D_H_
VECTOR2_TRAITS< T >::extended_type extended_type
Definition: vector2d.h:78
extended_type Cross(const VECTOR2< T > &aVector) const
Function Cross() computes cross product of self with aVector.
Definition: vector2d.h:520
int sign(T val)
Definition: util.h:101
VECTOR2_TRAITS traits class for VECTOR2.
Definition: vector2d.h:47
bool operator>=(const VECTOR2< T > &aVector) const
Definition: vector2d.h:557
int64_t extended_type
Definition: vector2d.h:57
VECTOR2< T > operator+(const VECTOR2< T > &aVector) const
Vector addition operator.
Definition: vector2d.h:452
VECTOR2< T > Perpendicular() const
Function Perpendicular computes the perpendicular vector.
Definition: vector2d.h:321
DPOINT DSIZE
Definition: vector2d.h:636
#define M_PI_2
Definition: transline.cpp:37
VECTOR2 defines a general 2D-vector/point.
Definition: vector2d.h:62
const VECTOR2< T > LexicographicalMin(const VECTOR2< T > &aA, const VECTOR2< T > &aB)
Definition: vector2d.h:590
extended_type SquaredEuclideanNorm() const
Function Squared Euclidean Norm computes the squared euclidean norm of the vector,...
Definition: vector2d.h:307
VECTOR2< T > operator *(const T &aFactor, const VECTOR2< T > &aVector)
Definition: vector2d.h:512
VECTOR2< int > VECTOR2I
Definition: vector2d.h:630
VECTOR2< CastedType > operator()() const
Casts a vector to another specialized subclass.
Definition: vector2d.h:121
bool operator!=(const VECTOR2< T > &aVector) const
Not equality operator.
Definition: vector2d.h:571
VECTOR2< T > & operator=(const VECTOR2< T > &aVector)
Assignment operator.
Definition: vector2d.h:329
T extended_type
extended range/precision types used by operations involving multiple multiplications to prevent overf...
Definition: vector2d.h:51
static constexpr extended_type ECOORD_MAX
Definition: vector2d.h:81
std::ostream & operator<<(std::ostream &aStream, const VECTOR2< T > &aVector)
Definition: vector2d.h:621
T coord_type
Definition: vector2d.h:79
VECTOR2< double > VECTOR2D
Definition: vector2d.h:629
VECTOR2()
Construct a 2D-vector with x, y = 0.
Definition: vector2d.h:268
const int LexicographicalCompare(const VECTOR2< T > &aA, const VECTOR2< T > &aB)
Definition: vector2d.h:602
const std::string Format() const
Function Format returns the vector formatted as a string.
Definition: vector2d.h:441
bool operator<(const VECTOR2< T > &aVector) const
Smaller than operator.
Definition: vector2d.h:536
VECTOR2< unsigned int > VECTOR2U
Definition: vector2d.h:631
extended_type operator *(const VECTOR2< T > &aVector) const
Scalar product operator.
Definition: vector2d.h:487
bool operator==(const VECTOR2< T > &aVector) const
Equality operator.
Definition: vector2d.h:564
double Angle() const
Function Angle computes the angle of the vector.
Definition: vector2d.h:314
bool operator<=(const VECTOR2< T > &aVector) const
Definition: vector2d.h:543
VECTOR2< T > Resize(T aNewLength) const
Function Resize returns a vector of the same direction, but length specified in aNewLength.
Definition: vector2d.h:411
VECTOR2< T > Rotate(double aAngle) const
Function Rotate rotates the vector by a given angle.
Definition: vector2d.h:378
VECTOR2< T > & operator-=(const VECTOR2< T > &aVector)
Compound assignment operator.
Definition: vector2d.h:356
VECTOR2< T > operator/(const T &aFactor) const
Division with a factor.
Definition: vector2d.h:502
extended_type Dot(const VECTOR2< T > &aVector) const
Function Dot() computes dot product of self with aVector.
Definition: vector2d.h:528
const VECTOR2< T > LexicographicalMax(const VECTOR2< T > &aA, const VECTOR2< T > &aB)
Definition: vector2d.h:578
T rescale(T aNumerator, T aValue, T aDenominator)
Function rescale()
Definition: util.h:95
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:68
static constexpr extended_type ECOORD_MIN
Definition: vector2d.h:82
VECTOR2< T > operator-()
Negate Vector operator.
Definition: vector2d.h:480
VECTOR2(const VECTOR2< CastingType > &aVec)
Initializes a vector from another specialization.
Definition: vector2d.h:105
T EuclideanNorm() const
Destructor.
Definition: vector2d.h:300
VECTOR2(const VECTOR2< T > &aVec)
Copy a vector.
Definition: vector2d.h:112
VECTOR2< double > DPOINT
Definition: vector2d.h:635
VECTOR2< T > & operator+=(const VECTOR2< T > &aVector)
Compound assignment operator.
Definition: vector2d.h:338
bool operator>(const VECTOR2< T > &aVector) const
Greater than operator.
Definition: vector2d.h:550