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 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 
35 #include <math/math_util.h>
36 #include <math.h>
37 
38 #ifdef WX_COMPATIBILITY
39  #include <wx/gdicmn.h>
40 #endif
41 
46 template <class T>
47 struct VECTOR2_TRAITS
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:
78  typedef typename VECTOR2_TRAITS<T>::extended_type extended_type;
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 
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 
120  // virtual ~VECTOR2();
121 
128  T EuclideanNorm() const;
129 
136  extended_type SquaredEuclideanNorm() const;
137 
138 
145 
152  VECTOR2<T> Resize( T aNewLength ) const;
153 
159  double Angle() const;
160 
167  VECTOR2<T> Rotate( double aAngle ) const;
168 
174  const std::string Format() const;
175 
180  extended_type Cross( const VECTOR2<T>& aVector ) const;
181 
186  extended_type Dot( const VECTOR2<T>& aVector ) const;
187 
188 
189  // Operators
190 
192  VECTOR2<T>& operator=( const VECTOR2<T>& aVector );
193 
195  VECTOR2<T> operator+( const VECTOR2<T>& aVector ) const;
196 
198  VECTOR2<T> operator+( const T& aScalar ) const;
199 
201  VECTOR2<T>& operator+=( const VECTOR2<T>& aVector );
202 
204  VECTOR2<T>& operator+=( const T& aScalar );
205 
207  VECTOR2<T> operator-( const VECTOR2<T>& aVector ) const;
208 
210  VECTOR2<T> operator-( const T& aScalar ) const;
211 
213  VECTOR2<T>& operator-=( const VECTOR2<T>& aVector );
214 
216  VECTOR2<T>& operator-=( const T& aScalar );
217 
220 
222  extended_type operator*( const VECTOR2<T>& aVector ) const;
223 
225  VECTOR2<T> operator*( const T& aFactor ) const;
226 
228  VECTOR2<T> operator/( const T& aFactor ) const;
229 
231  bool operator==( const VECTOR2<T>& aVector ) const;
232 
234  bool operator!=( const VECTOR2<T>& aVector ) const;
235 
237  bool operator<( const VECTOR2<T>& aVector ) const;
238  bool operator<=( const VECTOR2<T>& aVector ) const;
239 
241  bool operator>( const VECTOR2<T>& aVector ) const;
242  bool operator>=( const VECTOR2<T>& aVector ) const;
243 };
244 
245 
246 // ----------------------
247 // --- Implementation ---
248 // ----------------------
249 
250 template <class T>
252 {
253  x = y = 0.0;
254 }
255 
256 
257 #ifdef WX_COMPATIBILITY
258 template <class T>
259 VECTOR2<T>::VECTOR2( wxPoint const& aPoint )
260 {
261  x = T( aPoint.x );
262  y = T( aPoint.y );
263 }
264 
265 
266 template <class T>
267 VECTOR2<T>::VECTOR2( wxSize const& aSize )
268 {
269  x = T( aSize.x );
270  y = T( aSize.y );
271 }
272 #endif
273 
274 template <class T>
275 VECTOR2<T>::VECTOR2( T aX, T aY )
276 {
277  x = aX;
278  y = aY;
279 }
280 
281 
282 template <class T>
284 {
285  return sqrt( (extended_type) x * x + (extended_type) y * y );
286 }
287 
288 
289 template <class T>
290 typename VECTOR2<T>::extended_type VECTOR2<T>::SquaredEuclideanNorm() const
291 {
292  return (extended_type) x * x + (extended_type) y * y;
293 }
294 
295 
296 template <class T>
297 double VECTOR2<T>::Angle() const
298 {
299  return atan2( (double) y, (double) x );
300 }
301 
302 
303 template <class T>
305 {
306  VECTOR2<T> perpendicular( -y, x );
307  return perpendicular;
308 }
309 
310 
311 template <class T>
313 {
314  x = aVector.x;
315  y = aVector.y;
316  return *this;
317 }
318 
319 
320 template <class T>
322 {
323  x += aVector.x;
324  y += aVector.y;
325  return *this;
326 }
327 
328 
329 template <class T>
330 VECTOR2<T>& VECTOR2<T>::operator+=( const T& aScalar )
331 {
332  x += aScalar;
333  y += aScalar;
334  return *this;
335 }
336 
337 
338 template <class T>
340 {
341  x -= aVector.x;
342  y -= aVector.y;
343  return *this;
344 }
345 
346 
347 template <class T>
348 VECTOR2<T>& VECTOR2<T>::operator-=( const T& aScalar )
349 {
350  x -= aScalar;
351  y -= aScalar;
352  return *this;
353 }
354 
355 
360 template <class T>
361 VECTOR2<T> VECTOR2<T>::Rotate( double aAngle ) const
362 {
363  // Avoid 0 radian rotation, case very frequently found
364  if( aAngle == 0.0 )
365  return VECTOR2<T> ( T( x ), T( y ) );
366 
367  double sa = sin( aAngle );
368  double ca = cos( aAngle );
369 
370  return VECTOR2<T> ( T( (double) x * ca - (double) y * sa ),
371  T( (double) x * sa + (double) y * ca ) );
372 }
373 
374 
375 template <class T>
376 VECTOR2<T> VECTOR2<T>::Resize( T aNewLength ) const
377 {
378  if( x == 0 && y == 0 )
379  return VECTOR2<T> ( 0, 0 );
380 
381  extended_type l_sq_current = (extended_type) x * x + (extended_type) y * y;
382  extended_type l_sq_new = (extended_type) aNewLength * aNewLength;
383 
384  return VECTOR2<T> (
385  ( x < 0 ? -1 : 1 ) * sqrt( rescale( l_sq_new, (extended_type) x * x, l_sq_current ) ),
386  ( y < 0 ? -1 : 1 ) * sqrt( rescale( l_sq_new, (extended_type) y * y, l_sq_current ) ) ) * sign( aNewLength );
387 }
388 
389 
390 template <class T>
391 const std::string VECTOR2<T>::Format() const
392 {
393  std::stringstream ss;
394 
395  ss << "( xy " << x << " " << y << " )";
396 
397  return ss.str();
398 }
399 
400 
401 template <class T>
402 VECTOR2<T> VECTOR2<T>::operator+( const VECTOR2<T>& aVector ) const
403 {
404  return VECTOR2<T> ( x + aVector.x, y + aVector.y );
405 }
406 
407 
408 template <class T>
409 VECTOR2<T> VECTOR2<T>::operator+( const T& aScalar ) const
410 {
411  return VECTOR2<T> ( x + aScalar, y + aScalar );
412 }
413 
414 
415 template <class T>
416 VECTOR2<T> VECTOR2<T>::operator-( const VECTOR2<T>& aVector ) const
417 {
418  return VECTOR2<T> ( x - aVector.x, y - aVector.y );
419 }
420 
421 
422 template <class T>
423 VECTOR2<T> VECTOR2<T>::operator-( const T& aScalar ) const
424 {
425  return VECTOR2<T> ( x - aScalar, y - aScalar );
426 }
427 
428 
429 template <class T>
431 {
432  return VECTOR2<T> ( -x, -y );
433 }
434 
435 
436 template <class T>
437 typename VECTOR2<T>::extended_type VECTOR2<T>::operator*( const VECTOR2<T>& aVector ) const
438 {
439  return (extended_type)aVector.x * x + (extended_type)aVector.y * y;
440 }
441 
442 
443 template <class T>
444 VECTOR2<T> VECTOR2<T>::operator*( const T& aFactor ) const
445 {
446  VECTOR2<T> vector( x * aFactor, y * aFactor );
447  return vector;
448 }
449 
450 
451 template <class T>
452 VECTOR2<T> VECTOR2<T>::operator/( const T& aFactor ) const
453 {
454  VECTOR2<T> vector( x / aFactor, y / aFactor );
455  return vector;
456 }
457 
458 
459 template <class T>
460 VECTOR2<T> operator*( const T& aFactor, const VECTOR2<T>& aVector )
461 {
462  VECTOR2<T> vector( aVector.x * aFactor, aVector.y * aFactor );
463  return vector;
464 }
465 
466 
467 template <class T>
468 typename VECTOR2<T>::extended_type VECTOR2<T>::Cross( const VECTOR2<T>& aVector ) const
469 {
470  return (extended_type) x * (extended_type) aVector.y -
471  (extended_type) y * (extended_type) aVector.x;
472 }
473 
474 
475 template <class T>
476 typename VECTOR2<T>::extended_type VECTOR2<T>::Dot( const VECTOR2<T>& aVector ) const
477 {
478  return (extended_type) x * (extended_type) aVector.x +
479  (extended_type) y * (extended_type) aVector.y;
480 }
481 
482 
483 template <class T>
484 bool VECTOR2<T>::operator<( const VECTOR2<T>& aVector ) const
485 {
486  return ( *this * *this ) < ( aVector * aVector );
487 }
488 
489 
490 template <class T>
491 bool VECTOR2<T>::operator<=( const VECTOR2<T>& aVector ) const
492 {
493  return ( *this * *this ) <= ( aVector * aVector );
494 }
495 
496 
497 template <class T>
498 bool VECTOR2<T>::operator>( const VECTOR2<T>& aVector ) const
499 {
500  return ( *this * *this ) > ( aVector * aVector );
501 }
502 
503 
504 template <class T>
505 bool VECTOR2<T>::operator>=( const VECTOR2<T>& aVector ) const
506 {
507  return ( *this * *this ) >= ( aVector * aVector );
508 }
509 
510 
511 template <class T>
512 bool VECTOR2<T>::operator==( VECTOR2<T> const& aVector ) const
513 {
514  return ( aVector.x == x ) && ( aVector.y == y );
515 }
516 
517 
518 template <class T>
519 bool VECTOR2<T>::operator!=( VECTOR2<T> const& aVector ) const
520 {
521  return ( aVector.x != x ) || ( aVector.y != y );
522 }
523 
524 
525 template <class T>
526 const VECTOR2<T> LexicographicalMax( const VECTOR2<T>& aA, const VECTOR2<T>& aB )
527 {
528  if( aA.x > aB.x )
529  return aA;
530  else if( aA.x == aB.x && aA.y > aB.y )
531  return aA;
532 
533  return aB;
534 }
535 
536 
537 template <class T>
538 const VECTOR2<T> LexicographicalMin( 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 int LexicographicalCompare( const VECTOR2<T>& aA, const VECTOR2<T>& aB )
551 {
552  if( aA.x < aB.x )
553  return -1;
554  else if( aA.x > aB.x )
555  return 1;
556  else // aA.x == aB.x
557  {
558  if( aA.y < aB.y )
559  return -1;
560  else if( aA.y > aB.y )
561  return 1;
562  else
563  return 0;
564  }
565 }
566 
567 
568 template <class T>
569 std::ostream& operator<<( std::ostream& aStream, const VECTOR2<T>& aVector )
570 {
571  aStream << "[ " << aVector.x << " | " << aVector.y << " ]";
572  return aStream;
573 }
574 
575 
576 /* Default specializations */
577 typedef VECTOR2<double> VECTOR2D;
578 typedef VECTOR2<int> VECTOR2I;
580 
581 /* Compatibility typedefs */
582 // FIXME should be removed to avoid multiple typedefs for the same type
583 typedef VECTOR2<double> DPOINT;
584 typedef DPOINT DSIZE;
585 
586 #endif // VECTOR2D_H_
VECTOR2::operator+
VECTOR2< T > operator+(const VECTOR2< T > &aVector) const
Vector addition operator.
VECTOR2::operator=
VECTOR2< T > & operator=(const VECTOR2< T > &aVector)
Assignment operator.
VECTOR2::operator!=
bool operator!=(const VECTOR2< T > &aVector) const
Not equality operator.
VECTOR2::SquaredEuclideanNorm
extended_type SquaredEuclideanNorm() const
Function Squared Euclidean Norm computes the squared euclidean norm of the vector,...
Definition: vector2d.h:290
VECTOR2::Rotate
VECTOR2< T > Rotate(double aAngle) const
Function Rotate rotates the vector by a given angle.
Definition: vector2d.h:361
VECTOR2::SquaredEuclideanNorm
extended_type SquaredEuclideanNorm() const
Function Squared Euclidean Norm computes the squared euclidean norm of the vector,...
VECTOR2::operator-
VECTOR2< T > operator-()
Negate Vector operator.
VECTOR2::operator-
VECTOR2< T > operator-(const T &aScalar) const
Scalar subtraction operator.
VECTOR2::operator+
VECTOR2< T > operator+(const T &aScalar) const
Scalar addition operator.
VECTOR2::operator>
bool operator>(const VECTOR2< T > &aVector) const
Greater than operator.
VECTOR2::operator()
VECTOR2< CastedType > operator()() const
Casts a vector to another specialized subclass.
Definition: vector2d.h:114
VECTOR2::Format
const std::string Format() const
Function Format returns the vector formatted as a string.
VECTOR2::operator<
bool operator<(const VECTOR2< T > &aVector) const
Smaller than operator.
VECTOR2::Rotate
VECTOR2< T > Rotate(double aAngle) const
Function Rotate rotates the vector by a given angle.
VECTOR2::Perpendicular
VECTOR2< T > Perpendicular() const
Function Perpendicular computes the perpendicular vector.
Definition: vector2d.h:304
VECTOR2
Class VECTOR2 defines a general 2D-vector/point.
Definition: vector2d.h:76
VECTOR2::EuclideanNorm
T EuclideanNorm() const
Destructor.
VECTOR2_TRAITS::extended_type
T extended_type
extended range/precision types used by operations involving multiple multiplications to prevent overf...
Definition: vector2d.h:51
VECTOR2::operator-=
VECTOR2< T > & operator-=(const VECTOR2< T > &aVector)
Compound assignment operator.
VECTOR2::VECTOR2
VECTOR2(T x, T y)
Construct a vector with given components x, y.
libzip::int64_t
zip_int64_t int64_t
zip_int64_t typedef.
Definition: zip.hpp:103
VECTOR2::Dot
extended_type Dot(const VECTOR2< T > &aVector) const
Function Dot() computes dot product of self with aVector.
VECTOR2::VECTOR2
VECTOR2()
Construct a 2D-vector with x, y = 0.
VECTOR2::operator*
extended_type operator*(const VECTOR2< T > &aVector) const
Scalar product operator.
VECTOR2::operator/
VECTOR2< T > operator/(const T &aFactor) const
Division with a factor.
Definition: vector2d.h:452
VECTOR2::Cross
extended_type Cross(const VECTOR2< T > &aVector) const
Function Cross() computes cross product of self with aVector.
Definition: vector2d.h:468
VECTOR2::operator==
bool operator==(const VECTOR2< T > &aVector) const
Equality operator.
VECTOR2::Resize
VECTOR2< T > Resize(T aNewLength) const
Function Resize returns a vector of the same direction, but length specified in aNewLength.
VECTOR2::VECTOR2
VECTOR2(const VECTOR2< CastingType > &aVec)
Initializes a vector from another specialization.
Definition: vector2d.h:105
VECTOR2::operator+=
VECTOR2< T > & operator+=(const VECTOR2< T > &aVector)
Compound assignment operator.
Definition: vector2d.h:321
VECTOR2::operator-=
VECTOR2< T > & operator-=(const T &aScalar)
Compound assignment operator.
VECTOR2_TRAITS
Class VECTOR2_TRAITS traits class for VECTOR2.
Definition: vector2d.h:48
VECTOR2::operator+=
VECTOR2< T > & operator+=(const VECTOR2< T > &aVector)
Compound assignment operator.
VECTOR2::operator=
VECTOR2< T > & operator=(const VECTOR2< T > &aVector)
Assignment operator.
Definition: vector2d.h:312
VECTOR2::operator+
VECTOR2< T > operator+(const VECTOR2< T > &aVector) const
Vector addition operator.
Definition: vector2d.h:402
VECTOR2::Cross
extended_type Cross(const VECTOR2< T > &aVector) const
Function Cross() computes cross product of self with aVector.
VECTOR2::operator*
VECTOR2< T > operator*(const T &aFactor) const
Multiplication with a factor.
VECTOR2::Perpendicular
VECTOR2< T > Perpendicular() const
Function Perpendicular computes the perpendicular vector.
VECTOR2::Resize
VECTOR2< T > Resize(T aNewLength) const
Function Resize returns a vector of the same direction, but length specified in aNewLength.
Definition: vector2d.h:376
VECTOR2::operator/
VECTOR2< T > operator/(const T &aFactor) const
Division with a factor.
VECTOR2::operator-
VECTOR2< T > operator-(const VECTOR2< T > &aVector) const
Vector subtraction operator.
VECTOR2::Angle
double Angle() const
Function Angle computes the angle of the vector.
VECTOR2::operator*
extended_type operator*(const VECTOR2< T > &aVector) const
Scalar product operator.
Definition: vector2d.h:437
p2t::operator*
Point operator*(double s, const Point &a)
Multiply point by scalar.
Definition: shapes.h:245
VECTOR2::operator-
VECTOR2< T > operator-()
Negate Vector operator.
Definition: vector2d.h:430
VECTOR2::operator-=
VECTOR2< T > & operator-=(const VECTOR2< T > &aVector)
Compound assignment operator.
Definition: vector2d.h:339
VECTOR2::operator+=
VECTOR2< T > & operator+=(const T &aScalar)
Compound assignment operator.
VECTOR2::Dot
extended_type Dot(const VECTOR2< T > &aVector) const
Function Dot() computes dot product of self with aVector.
Definition: vector2d.h:476