Horizon
vector2d.h
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 #include "wx_compat.h"
39 
43 template <class T>
45 {
48  typedef T extended_type;
49 };
50 
51 template <>
52 struct VECTOR2_TRAITS<int>
53 {
54  typedef int64_t extended_type;
55 };
56 
57 // Forward declarations for template friends
58 template <class T>
59 class VECTOR2;
60 template <class T>
61 std::ostream& operator<<( std::ostream& aStream, const VECTOR2<T>& aVector );
62 
70 template <class T = int>
71 class VECTOR2
72 {
73 public:
74  typedef typename VECTOR2_TRAITS<T>::extended_type extended_type;
75  typedef T coord_type;
76 
77  static constexpr extended_type ECOORD_MAX = std::numeric_limits<extended_type>::max();
78  static constexpr extended_type ECOORD_MIN = std::numeric_limits<extended_type>::min();
79 
80  T x, y;
81 
84 
86  VECTOR2( const wxPoint& aPoint );
87 
89  VECTOR2( const wxSize& aSize );
90 
92  VECTOR2( T x, T y );
93 
95  template <typename CastingType>
97  {
98  x = (T) aVec.x;
99  y = (T) aVec.y;
100  }
101 
103  VECTOR2( const VECTOR2<T>& aVec )
104  {
105  x = aVec.x;
106  y = aVec.y;
107  }
108 
110  template <typename CastedType>
112  {
113  return VECTOR2<CastedType>( (CastedType) x, (CastedType) y );
114  }
115 
121  explicit operator wxPoint() const
122  {
123  return wxPoint( x, y );
124  }
125 
126  // virtual ~VECTOR2();
127 
135  T EuclideanNorm() const;
136 
144  extended_type SquaredEuclideanNorm() const;
145 
146 
153 
160  VECTOR2<T> Resize( T aNewLength ) const;
161 
167  double Angle() const;
168 
175  VECTOR2<T> Rotate( double aAngle ) const;
176 
182  const std::string Format() const;
183 
187  extended_type Cross( const VECTOR2<T>& aVector ) const;
188 
192  extended_type Dot( const VECTOR2<T>& aVector ) const;
193 
194 
195  // Operators
196 
198  VECTOR2<T>& operator=( const VECTOR2<T>& aVector );
199 
201  VECTOR2<T> operator+( const VECTOR2<T>& aVector ) const;
202 
204  VECTOR2<T> operator+( const T& aScalar ) const;
205 
207  VECTOR2<T>& operator+=( const VECTOR2<T>& aVector );
208 
210  VECTOR2<T>& operator+=( const T& aScalar );
211 
213  VECTOR2<T> operator-( const VECTOR2<T>& aVector ) const;
214 
216  VECTOR2<T> operator-( const T& aScalar ) const;
217 
219  VECTOR2<T>& operator-=( const VECTOR2<T>& aVector );
220 
222  VECTOR2<T>& operator-=( const T& aScalar );
223 
226 
228  extended_type operator*( const VECTOR2<T>& aVector ) const;
229 
231  VECTOR2<T> operator*( const T& aFactor ) const;
232 
234  VECTOR2<T> operator/( const T& aFactor ) const;
235 
237  bool operator==( const VECTOR2<T>& aVector ) const;
238 
240  bool operator!=( const VECTOR2<T>& aVector ) const;
241 
243  bool operator<( const VECTOR2<T>& aVector ) const;
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 };
250 
251 
252 // ----------------------
253 // --- Implementation ---
254 // ----------------------
255 
256 template <class T>
258 {
259  x = y = 0.0;
260 }
261 
262 
263 template <class T>
264 VECTOR2<T>::VECTOR2( const wxPoint& aPoint )
265 {
266  x = T( aPoint.x );
267  y = T( aPoint.y );
268 }
269 
270 
271 template <class T>
273 {
274  x = T( aSize.x );
275  y = T( aSize.y );
276 }
277 
278 template <class T>
279 VECTOR2<T>::VECTOR2( T aX, T aY )
280 {
281  x = aX;
282  y = aY;
283 }
284 
285 
286 template <class T>
288 {
289  return sqrt( (extended_type) x * x + (extended_type) y * y );
290 }
291 
292 
293 template <class T>
294 typename VECTOR2<T>::extended_type VECTOR2<T>::SquaredEuclideanNorm() const
295 {
296  return (extended_type) x * x + (extended_type) y * y;
297 }
298 
299 
300 template <class T>
301 double VECTOR2<T>::Angle() const
302 {
303  return atan2( (double) y, (double) x );
304 }
305 
306 
307 template <class T>
309 {
310  VECTOR2<T> perpendicular( -y, x );
311  return perpendicular;
312 }
313 
314 
315 template <class T>
317 {
318  x = aVector.x;
319  y = aVector.y;
320  return *this;
321 }
322 
323 
324 template <class T>
326 {
327  x += aVector.x;
328  y += aVector.y;
329  return *this;
330 }
331 
332 
333 template <class T>
334 VECTOR2<T>& VECTOR2<T>::operator+=( const T& aScalar )
335 {
336  x += aScalar;
337  y += aScalar;
338  return *this;
339 }
340 
341 
342 template <class T>
344 {
345  x -= aVector.x;
346  y -= aVector.y;
347  return *this;
348 }
349 
350 
351 template <class T>
352 VECTOR2<T>& VECTOR2<T>::operator-=( const T& aScalar )
353 {
354  x -= aScalar;
355  y -= aScalar;
356  return *this;
357 }
358 
359 
364 template <class T>
365 VECTOR2<T> VECTOR2<T>::Rotate( double aAngle ) const
366 {
367  // Avoid common radian rotations that may allow for angular error
368  if( aAngle == 0.0 || aAngle == 2 * M_PI )
369  return VECTOR2<T> ( T( x ), T( y ) );
370 
371  if( aAngle == M_PI_2 )
372  return VECTOR2<T>( -T( y ), T( x ) );
373 
374  if( aAngle == M_PI )
375  return VECTOR2<T>( -T(x), -T( y ) );
376 
377  if( aAngle == 3 * M_PI_2 )
378  return VECTOR2<T>( T( y ), -T( x ) );
379 
380  double sa = sin( aAngle );
381  double ca = cos( aAngle );
382 
383  if( std::is_integral<T>::value )
384  {
385  return VECTOR2<T> ( KiROUND( (double) x * ca - (double) y * sa ),
386  KiROUND( (double) x * sa + (double) y * ca ) );
387 
388  }
389  else
390  {
391  return VECTOR2<T> ( T( (double) x * ca - (double) y * sa ),
392  T( (double) x * sa + (double) y * ca ) );
393  }
394 }
395 
396 
397 template <class T>
398 VECTOR2<T> VECTOR2<T>::Resize( T aNewLength ) const
399 {
400  if( x == 0 && y == 0 )
401  return VECTOR2<T> ( 0, 0 );
402 
403  extended_type l_sq_current = (extended_type) x * x + (extended_type) y * y;
404  extended_type l_sq_new = (extended_type) aNewLength * aNewLength;
405 
406  if( std::is_integral<T>::value )
407  {
408  return VECTOR2<T> (
409  ( x < 0 ? -1 : 1 ) *
410  KiROUND( std::sqrt( rescale( l_sq_new, (extended_type) x * x, l_sq_current ) ) ),
411  ( y < 0 ? -1 : 1 ) *
412  KiROUND( std::sqrt( rescale( l_sq_new, (extended_type) y * y, l_sq_current ) ) ) )
413  * sign( aNewLength );
414  }
415  else
416  {
417  return VECTOR2<T> (
418  ( x < 0 ? -1 : 1 ) *
419  std::sqrt( rescale( l_sq_new, (extended_type) x * x, l_sq_current ) ),
420  ( y < 0 ? -1 : 1 ) *
421  std::sqrt( rescale( l_sq_new, (extended_type) y * y, l_sq_current ) ) )
422  * sign( aNewLength );
423  }
424 }
425 
426 
427 template <class T>
428 const std::string VECTOR2<T>::Format() const
429 {
430  std::stringstream ss;
431 
432  ss << "( xy " << x << " " << y << " )";
433 
434  return ss.str();
435 }
436 
437 
438 template <class T>
440 {
441  return VECTOR2<T> ( x + aVector.x, y + aVector.y );
442 }
443 
444 
445 template <class T>
446 VECTOR2<T> VECTOR2<T>::operator+( const T& aScalar ) const
447 {
448  return VECTOR2<T> ( x + aScalar, y + aScalar );
449 }
450 
451 
452 template <class T>
454 {
455  return VECTOR2<T> ( x - aVector.x, y - aVector.y );
456 }
457 
458 
459 template <class T>
460 VECTOR2<T> VECTOR2<T>::operator-( const T& aScalar ) const
461 {
462  return VECTOR2<T> ( x - aScalar, y - aScalar );
463 }
464 
465 
466 template <class T>
468 {
469  return VECTOR2<T> ( -x, -y );
470 }
471 
472 
473 template <class T>
474 typename VECTOR2<T>::extended_type VECTOR2<T>::operator*( const VECTOR2<T>& aVector ) const
475 {
476  return (extended_type)aVector.x * x + (extended_type)aVector.y * y;
477 }
478 
479 
480 template <class T>
481 VECTOR2<T> VECTOR2<T>::operator*( const T& aFactor ) const
482 {
483  VECTOR2<T> vector( x * aFactor, y * aFactor );
484  return vector;
485 }
486 
487 
488 template <class T>
489 VECTOR2<T> VECTOR2<T>::operator/( const T& aFactor ) const
490 {
491  if( std::is_integral<T>::value )
492  return VECTOR2<T>( KiROUND( x / aFactor ), KiROUND( y / aFactor ) );
493  else
494  return VECTOR2<T>( x / aFactor, y / aFactor );
495 }
496 
497 
498 template <class T>
499 VECTOR2<T> operator*( const T& aFactor, const VECTOR2<T>& aVector )
500 {
501  VECTOR2<T> vector( aVector.x * aFactor, aVector.y * aFactor );
502  return vector;
503 }
504 
505 
506 template <class T>
507 typename VECTOR2<T>::extended_type VECTOR2<T>::Cross( const VECTOR2<T>& aVector ) const
508 {
509  return (extended_type) x * (extended_type) aVector.y -
510  (extended_type) y * (extended_type) aVector.x;
511 }
512 
513 
514 template <class T>
515 typename VECTOR2<T>::extended_type VECTOR2<T>::Dot( const VECTOR2<T>& aVector ) const
516 {
517  return (extended_type) x * (extended_type) aVector.x +
518  (extended_type) y * (extended_type) aVector.y;
519 }
520 
521 
522 template <class T>
523 bool VECTOR2<T>::operator<( const VECTOR2<T>& aVector ) const
524 {
525  return ( *this * *this ) < ( aVector * aVector );
526 }
527 
528 
529 template <class T>
530 bool VECTOR2<T>::operator<=( const VECTOR2<T>& aVector ) const
531 {
532  return ( *this * *this ) <= ( aVector * aVector );
533 }
534 
535 
536 template <class T>
537 bool VECTOR2<T>::operator>( const VECTOR2<T>& aVector ) const
538 {
539  return ( *this * *this ) > ( aVector * aVector );
540 }
541 
542 
543 template <class T>
544 bool VECTOR2<T>::operator>=( const VECTOR2<T>& aVector ) const
545 {
546  return ( *this * *this ) >= ( aVector * aVector );
547 }
548 
549 
550 template <class T>
551 bool VECTOR2<T>::operator==( VECTOR2<T> const& aVector ) const
552 {
553  return ( aVector.x == x ) && ( aVector.y == y );
554 }
555 
556 
557 template <class T>
558 bool VECTOR2<T>::operator!=( VECTOR2<T> const& aVector ) const
559 {
560  return ( aVector.x != x ) || ( aVector.y != y );
561 }
562 
563 
564 template <class T>
565 const VECTOR2<T> LexicographicalMax( const VECTOR2<T>& aA, const VECTOR2<T>& aB )
566 {
567  if( aA.x > aB.x )
568  return aA;
569  else if( aA.x == aB.x && aA.y > aB.y )
570  return aA;
571 
572  return aB;
573 }
574 
575 
576 template <class T>
577 const VECTOR2<T> LexicographicalMin( const VECTOR2<T>& aA, const VECTOR2<T>& aB )
578 {
579  if( aA.x < aB.x )
580  return aA;
581  else if( aA.x == aB.x && aA.y < aB.y )
582  return aA;
583 
584  return aB;
585 }
586 
587 
588 template <class T>
589 const int LexicographicalCompare( const VECTOR2<T>& aA, const VECTOR2<T>& aB )
590 {
591  if( aA.x < aB.x )
592  return -1;
593  else if( aA.x > aB.x )
594  return 1;
595  else // aA.x == aB.x
596  {
597  if( aA.y < aB.y )
598  return -1;
599  else if( aA.y > aB.y )
600  return 1;
601  else
602  return 0;
603  }
604 }
605 
606 
607 template <class T>
608 std::ostream& operator<<( std::ostream& aStream, const VECTOR2<T>& aVector )
609 {
610  aStream << "[ " << aVector.x << " | " << aVector.y << " ]";
611  return aStream;
612 }
613 
614 /* Default specializations */
615 typedef VECTOR2<double> VECTOR2D;
616 typedef VECTOR2<int> VECTOR2I;
618 
619 /* STL specializations */
620 namespace std
621 {
622  // Required to enable correct use in std::map/unordered_map
623  template <>
624  struct hash<VECTOR2I>
625  {
626  size_t operator()( const VECTOR2I& k ) const;
627  };
628 
629  // Required to enable use of std::hash with maps
630  template <>
631  struct less<VECTOR2I>
632  {
633  bool operator()( const VECTOR2I& aA, const VECTOR2I& aB ) const;
634  };
635 }
636 
637 /* Compatibility typedefs */
638 // FIXME should be removed to avoid multiple typedefs for the same type
639 typedef VECTOR2<double> DPOINT;
640 typedef DPOINT DSIZE;
641 
642 #endif // VECTOR2D_H_
Define a general 2D-vector/point.
Definition: vector2d.h:72
VECTOR2< T > operator-(const T &aScalar) const
Scalar subtraction operator.
Definition: vector2d.h:460
VECTOR2< T > & operator+=(const T &aScalar)
Compound assignment operator.
Definition: vector2d.h:334
VECTOR2(const VECTOR2< CastingType > &aVec)
Initializes a vector from another specialization. Beware of rounding issues.
Definition: vector2d.h:96
VECTOR2(const wxPoint &aPoint)
Constructor with a wxPoint as argument.
Definition: vector2d.h:264
extended_type SquaredEuclideanNorm() const
Compute the squared euclidean norm of the vector, which is defined as (x ** 2 + y ** 2).
Definition: vector2d.h:294
const std::string Format() const
Return the vector formatted as a string.
Definition: vector2d.h:428
VECTOR2()
Construct a 2D-vector with x, y = 0.
Definition: vector2d.h:257
VECTOR2< CastedType > operator()() const
Cast a vector to another specialized subclass. Beware of rounding issues.
Definition: vector2d.h:111
VECTOR2(T x, T y)
Construct a vector with given components x, y.
Definition: vector2d.h:279
VECTOR2< T > & operator+=(const VECTOR2< T > &aVector)
Compound assignment operator.
Definition: vector2d.h:325
VECTOR2(const VECTOR2< T > &aVec)
Copy a vector.
Definition: vector2d.h:103
VECTOR2< T > Rotate(double aAngle) const
Rotate the vector by a given angle.
Definition: vector2d.h:365
T EuclideanNorm() const
Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
Definition: vector2d.h:287
bool operator==(const VECTOR2< T > &aVector) const
Equality operator.
Definition: vector2d.h:551
VECTOR2< T > Perpendicular() const
Compute the perpendicular vector.
Definition: vector2d.h:308
VECTOR2< T > & operator=(const VECTOR2< T > &aVector)
Assignment operator.
Definition: vector2d.h:316
VECTOR2< T > & operator-=(const T &aScalar)
Compound assignment operator.
Definition: vector2d.h:352
bool operator!=(const VECTOR2< T > &aVector) const
Not equality operator.
Definition: vector2d.h:558
double Angle() const
Compute the angle of the vector.
Definition: vector2d.h:301
extended_type Cross(const VECTOR2< T > &aVector) const
Compute cross product of self with aVector.
Definition: vector2d.h:507
bool operator>(const VECTOR2< T > &aVector) const
Greater than operator.
Definition: vector2d.h:537
extended_type Dot(const VECTOR2< T > &aVector) const
Compute dot product of self with aVector.
Definition: vector2d.h:515
extended_type operator*(const VECTOR2< T > &aVector) const
Scalar product operator.
Definition: vector2d.h:474
VECTOR2< T > operator+(const VECTOR2< T > &aVector) const
Vector addition operator.
Definition: vector2d.h:439
VECTOR2< T > operator-(const VECTOR2< T > &aVector) const
Vector subtraction operator.
Definition: vector2d.h:453
VECTOR2(const wxSize &aSize)
Constructor with a wxSize as argument.
Definition: vector2d.h:272
VECTOR2< T > operator*(const T &aFactor) const
Multiplication with a factor.
Definition: vector2d.h:481
VECTOR2< T > operator+(const T &aScalar) const
Scalar addition operator.
Definition: vector2d.h:446
VECTOR2< T > & operator-=(const VECTOR2< T > &aVector)
Compound assignment operator.
Definition: vector2d.h:343
bool operator<(const VECTOR2< T > &aVector) const
Smaller than operator.
Definition: vector2d.h:523
VECTOR2< T > Resize(T aNewLength) const
Return a vector of the same direction, but length specified in aNewLength.
Definition: vector2d.h:398
VECTOR2< T > operator-()
Negate Vector operator.
Definition: vector2d.h:467
VECTOR2< T > operator/(const T &aFactor) const
Division with a factor.
Definition: vector2d.h:489
Definition: wx_compat.h:40
Definition: wx_compat.h:64
bool_<(T::type::value< U::type::value)> less
A Boolean integral constant wrapper around true if T::type::value is less than U::type::value; false,...
Definition: meta.hpp:255
Traits class for VECTOR2.
Definition: vector2d.h:45
T extended_type
< extended range/precision types used by operations involving multiple multiplications to prevent ove...
Definition: vector2d.h:48