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 <cmath>
32 #include <climits>
33 #include <iostream>
34 #include <sstream>
35 #include <cmath>
36 
37 #include <math/math_util.h>
38 
39 #ifdef WX_COMPATIBILITY
40  #include <wx/gdicmn.h>
41 #endif
42 
47 template <class T>
49 {
52  typedef T extended_type;
53 };
54 
55 template <>
56 struct VECTOR2_TRAITS<int>
57 {
58  typedef int64_t extended_type;
59  static const extended_type ECOORD_MAX = 0x7fffffffffffffffULL;
60  static const extended_type ECOORD_MIN = 0x8000000000000000ULL;
61 };
62 
63 // Forward declarations for template friends
64 template <class T>
65 class VECTOR2;
66 template <class T>
67 std::ostream& operator<<( std::ostream& aStream, const VECTOR2<T>& aVector );
68 
77 template <class T = int>
78 class VECTOR2 : public VECTOR2_TRAITS<T>
79 {
80 public:
82  typedef T coord_type;
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 
113  template <typename CastedType>
115  {
116  return VECTOR2<CastedType>( (CastedType) x, (CastedType) y );
117  }
118 
124  explicit operator wxPoint() const
125  {
126  return wxPoint( x, y );
127  }
128 
130  // virtual ~VECTOR2();
131 
138  T EuclideanNorm() const;
139 
146  extended_type SquaredEuclideanNorm() const;
147 
148 
154  VECTOR2<T> Perpendicular() const;
155 
162  VECTOR2<T> Resize( T aNewLength ) const;
163 
169  double Angle() const;
170 
177  VECTOR2<T> Rotate( double aAngle ) const;
178 
184  const std::string Format() const;
185 
190  extended_type Cross( const VECTOR2<T>& aVector ) const;
191 
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  friend std::ostream & operator<< <T> ( std::ostream & stream, const VECTOR2<T> &vector );
255 };
256 
257 
258 // ----------------------
259 // --- Implementation ---
260 // ----------------------
261 
262 template <class T>
264 {
265  x = y = 0.0;
266 }
267 
268 
269 #ifdef WX_COMPATIBILITY
270 template <class T>
271 VECTOR2<T>::VECTOR2( wxPoint const& aPoint )
272 {
273  x = T( aPoint.x );
274  y = T( aPoint.y );
275 }
276 
277 
278 template <class T>
279 VECTOR2<T>::VECTOR2( wxSize const& aSize )
280 {
281  x = T( aSize.x );
282  y = T( aSize.y );
283 }
284 #endif
285 
286 template <class T>
288 {
289  x = aX;
290  y = aY;
291 }
292 
293 
294 template <class T>
296 {
297  return sqrt( (extended_type) x * x + (extended_type) y * y );
298 }
299 
300 
301 template <class T>
303 {
304  return (extended_type) x * x + (extended_type) y * y;
305 }
306 
307 
308 template <class T>
309 double VECTOR2<T>::Angle() const
310 {
311  return atan2( (double) y, (double) x );
312 }
313 
314 
315 template <class T>
317 {
318  VECTOR2<T> perpendicular( -y, x );
319  return perpendicular;
320 }
321 
322 
323 template <class T>
325 {
326  x = aVector.x;
327  y = aVector.y;
328  return *this;
329 }
330 
331 
332 template <class T>
334 {
335  x += aVector.x;
336  y += aVector.y;
337  return *this;
338 }
339 
340 
341 template <class T>
343 {
344  x += aScalar;
345  y += aScalar;
346  return *this;
347 }
348 
349 
350 template <class T>
352 {
353  x -= aVector.x;
354  y -= aVector.y;
355  return *this;
356 }
357 
358 
359 template <class T>
361 {
362  x -= aScalar;
363  y -= aScalar;
364  return *this;
365 }
366 
367 
372 template <class T>
373 VECTOR2<T> VECTOR2<T>::Rotate( double aAngle ) const
374 {
375  // Avoid 0 radian rotation, case very frequently found
376  if( aAngle == 0.0 )
377  return VECTOR2<T> ( T( x ), T( y ) );
378 
379  double sa = sin( aAngle );
380  double ca = cos( aAngle );
381 
382  return VECTOR2<T> ( T( (double) x * ca - (double) y * sa ),
383  T( (double) x * sa + (double) y * ca ) );
384 }
385 
386 
387 template <class T>
388 VECTOR2<T> VECTOR2<T>::Resize( T aNewLength ) const
389 {
390  if( x == 0 && y == 0 )
391  return VECTOR2<T> ( 0, 0 );
392 
393  extended_type l_sq_current = (extended_type) x * x + (extended_type) y * y;
394  extended_type l_sq_new = (extended_type) aNewLength * aNewLength;
395 
396  return VECTOR2<T> (
397  ( x < 0 ? -1 : 1 ) * sqrt( rescale( l_sq_new, (extended_type) x * x, l_sq_current ) ),
398  ( y < 0 ? -1 : 1 ) * sqrt( rescale( l_sq_new, (extended_type) y * y, l_sq_current ) ) ) * sign( aNewLength );
399 }
400 
401 
402 template <class T>
403 const std::string VECTOR2<T>::Format() const
404 {
405  std::stringstream ss;
406 
407  ss << "( xy " << x << " " << y << " )";
408 
409  return ss.str();
410 }
411 
412 
413 template <class T>
415 {
416  return VECTOR2<T> ( x + aVector.x, y + aVector.y );
417 }
418 
419 
420 template <class T>
421 VECTOR2<T> VECTOR2<T>::operator+( const T& aScalar ) const
422 {
423  return VECTOR2<T> ( x + aScalar, y + aScalar );
424 }
425 
426 
427 template <class T>
429 {
430  return VECTOR2<T> ( x - aVector.x, y - aVector.y );
431 }
432 
433 
434 template <class T>
435 VECTOR2<T> VECTOR2<T>::operator-( const T& aScalar ) const
436 {
437  return VECTOR2<T> ( x - aScalar, y - aScalar );
438 }
439 
440 
441 template <class T>
443 {
444  return VECTOR2<T> ( -x, -y );
445 }
446 
447 
448 template <class T>
450 {
451  return (extended_type)aVector.x * x + (extended_type)aVector.y * y;
452 }
453 
454 
455 template <class T>
456 VECTOR2<T> VECTOR2<T>::operator*( const T& aFactor ) const
457 {
458  VECTOR2<T> vector( x * aFactor, y * aFactor );
459  return vector;
460 }
461 
462 
463 template <class T>
464 VECTOR2<T> VECTOR2<T>::operator/( const T& aFactor ) const
465 {
466  VECTOR2<T> vector( x / aFactor, y / aFactor );
467  return vector;
468 }
469 
470 
471 template <class T>
472 VECTOR2<T> operator*( const T& aFactor, const VECTOR2<T>& aVector )
473 {
474  VECTOR2<T> vector( aVector.x * aFactor, aVector.y * aFactor );
475  return vector;
476 }
477 
478 
479 template <class T>
481 {
482  return (extended_type) x * (extended_type) aVector.y -
483  (extended_type) y * (extended_type) aVector.x;
484 }
485 
486 
487 template <class T>
488 typename VECTOR2<T>::extended_type VECTOR2<T>::Dot( const VECTOR2<T>& aVector ) const
489 {
490  return (extended_type) x * (extended_type) aVector.x +
491  (extended_type) y * (extended_type) aVector.y;
492 }
493 
494 
495 template <class T>
496 bool VECTOR2<T>::operator<( const VECTOR2<T>& aVector ) const
497 {
498  return ( *this * *this ) < ( aVector * aVector );
499 }
500 
501 
502 template <class T>
503 bool VECTOR2<T>::operator<=( const VECTOR2<T>& aVector ) const
504 {
505  return ( *this * *this ) <= ( aVector * aVector );
506 }
507 
508 
509 template <class T>
510 bool VECTOR2<T>::operator>( const VECTOR2<T>& aVector ) const
511 {
512  return ( *this * *this ) > ( aVector * aVector );
513 }
514 
515 
516 template <class T>
517 bool VECTOR2<T>::operator>=( const VECTOR2<T>& aVector ) const
518 {
519  return ( *this * *this ) >= ( aVector * aVector );
520 }
521 
522 
523 template <class T>
524 bool VECTOR2<T>::operator==( VECTOR2<T> const& aVector ) const
525 {
526  return ( aVector.x == x ) && ( aVector.y == y );
527 }
528 
529 
530 template <class T>
531 bool VECTOR2<T>::operator!=( VECTOR2<T> const& aVector ) const
532 {
533  return ( aVector.x != x ) || ( aVector.y != y );
534 }
535 
536 
537 template <class T>
538 const VECTOR2<T> LexicographicalMax( const VECTOR2<T>& aA, const VECTOR2<T>& aB )
539 {
540  if( aA.x > aB.x )
541  return aA;
542  else if( aA.x == aB.x && aA.y > aB.y )
543  return aA;
544 
545  return aB;
546 }
547 
548 
549 template <class T>
550 const VECTOR2<T> LexicographicalMin( const VECTOR2<T>& aA, const VECTOR2<T>& aB )
551 {
552  if( aA.x < aB.x )
553  return aA;
554  else if( aA.x == aB.x && aA.y < aB.y )
555  return aA;
556 
557  return aB;
558 }
559 
560 
561 template <class T>
562 const int LexicographicalCompare( const VECTOR2<T>& aA, const VECTOR2<T>& aB )
563 {
564  if( aA.x < aB.x )
565  return -1;
566  else if( aA.x > aB.x )
567  return 1;
568  else // aA.x == aB.x
569  {
570  if( aA.y < aB.y )
571  return -1;
572  else if( aA.y > aB.y )
573  return 1;
574  else
575  return 0;
576  }
577 }
578 
579 
580 template <class T>
581 std::ostream& operator<<( std::ostream& aStream, const VECTOR2<T>& aVector )
582 {
583  aStream << "[ " << aVector.x << " | " << aVector.y << " ]";
584  return aStream;
585 }
586 
587 
588 /* Default specializations */
592 
593 /* Compatibility typedefs */
594 // FIXME should be removed to avoid multiple typedefs for the same type
596 typedef DPOINT DSIZE;
597 
598 #endif // VECTOR2D_H_
VECTOR2_TRAITS< T >::extended_type extended_type
Definition: vector2d.h:81
Class VECTOR2_TRAITS traits class for VECTOR2.
Definition: vector2d.h:48
VECTOR2< T > operator+(const VECTOR2< T > &aVector) const
Vector addition operator.
Definition: vector2d.h:414
int64_t extended_type
Definition: vector2d.h:58
extended_type Dot(const VECTOR2< T > &aVector) const
Function Dot() computes dot product of self with aVector.
Definition: vector2d.h:488
bool operator<=(const VECTOR2< T > &aVector) const
Definition: vector2d.h:503
bool operator>(const VECTOR2< T > &aVector) const
Greater than operator.
Definition: vector2d.h:510
T
enum T contains all this lexer's tokens.
VECTOR2< T > Resize(T aNewLength) const
Function Resize returns a vector of the same direction, but length specified in aNewLength.
Definition: vector2d.h:388
VECTOR2< CastedType > operator()() const
Casts a vector to another specialized subclass.
Definition: vector2d.h:114
DPOINT DSIZE
Definition: vector2d.h:596
Class VECTOR2 defines a general 2D-vector/point.
Definition: vector2d.h:65
VECTOR2< T > Rotate(double aAngle) const
Function Rotate rotates the vector by a given angle.
Definition: vector2d.h:373
const VECTOR2< T > LexicographicalMin(const VECTOR2< T > &aA, const VECTOR2< T > &aB)
Definition: vector2d.h:550
VECTOR2< T > operator/(const T &aFactor) const
Division with a factor.
Definition: vector2d.h:464
VECTOR2< int > VECTOR2I
Definition: vector2d.h:590
VECTOR2< T > & operator=(const VECTOR2< T > &aVector)
Assignment operator.
Definition: vector2d.h:324
T extended_type
extended range/precision types used by operations involving multiple multiplications to prevent overf...
Definition: vector2d.h:52
double Angle() const
Function Angle computes the angle of the vector.
Definition: vector2d.h:309
T coord_type
Definition: vector2d.h:82
T EuclideanNorm() const
Destructor.
Definition: vector2d.h:295
VECTOR2< double > VECTOR2D
Definition: vector2d.h:589
VECTOR2()
Construct a 2D-vector with x, y = 0.
Definition: vector2d.h:263
const int LexicographicalCompare(const VECTOR2< T > &aA, const VECTOR2< T > &aB)
Definition: vector2d.h:562
VECTOR2< unsigned int > VECTOR2U
Definition: vector2d.h:591
bool operator>=(const VECTOR2< T > &aVector) const
Definition: vector2d.h:517
int rescale(int aNumerator, int aValue, int aDenominator)
Definition: math_util.cpp:32
extended_type Cross(const VECTOR2< T > &aVector) const
Function Cross() computes cross product of self with aVector.
Definition: vector2d.h:480
extended_type SquaredEuclideanNorm() const
Function Squared Euclidean Norm computes the squared euclidean norm of the vector, which is defined as (x ** 2 + y ** 2).
Definition: vector2d.h:302
VECTOR2< T > & operator-=(const VECTOR2< T > &aVector)
Compound assignment operator.
Definition: vector2d.h:351
bool operator<(const VECTOR2< T > &aVector) const
Smaller than operator.
Definition: vector2d.h:496
const VECTOR2< T > LexicographicalMax(const VECTOR2< T > &aA, const VECTOR2< T > &aB)
Definition: vector2d.h:538
extended_type operator*(const VECTOR2< T > &aVector) const
Scalar product operator.
Definition: vector2d.h:449
bool operator==(const VECTOR2< T > &aVector) const
Equality operator.
Definition: vector2d.h:524
VECTOR2< T > operator-()
Negate Vector operator.
Definition: vector2d.h:442
VECTOR2< T > Perpendicular() const
Function Perpendicular computes the perpendicular vector.
Definition: vector2d.h:316
VECTOR2(const VECTOR2< CastingType > &aVec)
Initializes a vector from another specialization.
Definition: vector2d.h:105
bool operator!=(const VECTOR2< T > &aVector) const
Not equality operator.
Definition: vector2d.h:531
VECTOR2< double > DPOINT
Definition: vector2d.h:595
VECTOR2< T > & operator+=(const VECTOR2< T > &aVector)
Compound assignment operator.
Definition: vector2d.h:333
const std::string Format() const
Function Format returns the vector formatted as a string.
Definition: vector2d.h:403
VECTOR2< T > operator*(const T &aFactor, const VECTOR2< T > &aVector)
Definition: vector2d.h:472
int sign(T val)
Definition: math_util.h:44