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 <cmath>
32 #include <limits>
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 };
60 
61 // Forward declarations for template friends
62 template <class T>
63 class VECTOR2;
64 template <class T>
65 std::ostream& operator<<( std::ostream& aStream, const VECTOR2<T>& aVector );
66 
75 template <class T = int>
76 class VECTOR2
77 {
78 public:
79  typedef typename VECTOR2_TRAITS<T>::extended_type extended_type;
80  typedef T coord_type;
81 
82  static constexpr extended_type ECOORD_MAX = std::numeric_limits<extended_type>::max();
83  static constexpr extended_type ECOORD_MIN = std::numeric_limits<extended_type>::min();
84 
85  T x, y;
86 
87  // Constructors
88 
90  VECTOR2();
91 
92 #ifdef WX_COMPATIBILITY
93  VECTOR2( const wxPoint& aPoint );
95 
97  VECTOR2( const wxSize& aSize );
98 #endif
99 
101  VECTOR2( T x, T y );
102 
105  template <typename CastingType>
107  {
108  x = (T) aVec.x;
109  y = (T) aVec.y;
110  }
111 
114  template <typename CastedType>
116  {
117  return VECTOR2<CastedType>( (CastedType) x, (CastedType) y );
118  }
119 
121  // virtual ~VECTOR2();
122 
129  T EuclideanNorm() const;
130 
137  extended_type SquaredEuclideanNorm() const;
138 
139 
145  VECTOR2<T> Perpendicular() const;
146 
153  VECTOR2<T> Resize( T aNewLength ) const;
154 
160  double Angle() const;
161 
168  VECTOR2<T> Rotate( double aAngle ) const;
169 
175  const std::string Format() const;
176 
181  extended_type Cross( const VECTOR2<T>& aVector ) const;
182 
187  extended_type Dot( const VECTOR2<T>& aVector ) const;
188 
189 
190  // Operators
191 
193  VECTOR2<T>& operator=( const VECTOR2<T>& aVector );
194 
196  VECTOR2<T> operator+( const VECTOR2<T>& aVector ) const;
197 
199  VECTOR2<T> operator+( const T& aScalar ) const;
200 
202  VECTOR2<T>& operator+=( const VECTOR2<T>& aVector );
203 
205  VECTOR2<T>& operator+=( const T& aScalar );
206 
208  VECTOR2<T> operator-( const VECTOR2<T>& aVector ) const;
209 
211  VECTOR2<T> operator-( const T& aScalar ) const;
212 
214  VECTOR2<T>& operator-=( const VECTOR2<T>& aVector );
215 
217  VECTOR2<T>& operator-=( const T& aScalar );
218 
221 
223  extended_type operator*( const VECTOR2<T>& aVector ) const;
224 
226  VECTOR2<T> operator*( const T& aFactor ) const;
227 
229  VECTOR2<T> operator/( const T& aFactor ) const;
230 
232  bool operator==( const VECTOR2<T>& aVector ) const;
233 
235  bool operator!=( const VECTOR2<T>& aVector ) const;
236 
238  bool operator<( const VECTOR2<T>& aVector ) const;
239  bool operator<=( const VECTOR2<T>& aVector ) const;
240 
242  bool operator>( const VECTOR2<T>& aVector ) const;
243  bool operator>=( const VECTOR2<T>& aVector ) const;
244 
245  friend std::ostream & operator<< <T> ( std::ostream & stream, const VECTOR2<T> &vector );
246 };
247 
248 
249 // ----------------------
250 // --- Implementation ---
251 // ----------------------
252 
253 template <class T>
255 {
256  x = y = 0.0;
257 }
258 
259 
260 #ifdef WX_COMPATIBILITY
261 template <class T>
262 VECTOR2<T>::VECTOR2( wxPoint const& aPoint )
263 {
264  x = T( aPoint.x );
265  y = T( aPoint.y );
266 }
267 
268 
269 template <class T>
270 VECTOR2<T>::VECTOR2( wxSize const& aSize )
271 {
272  x = T( aSize.x );
273  y = T( aSize.y );
274 }
275 #endif
276 
277 template <class T>
278 VECTOR2<T>::VECTOR2( T aX, T aY )
279 {
280  x = aX;
281  y = aY;
282 }
283 
284 
285 template <class T>
287 {
288  return sqrt( (extended_type) x * x + (extended_type) y * y );
289 }
290 
291 
292 template <class T>
293 typename VECTOR2<T>::extended_type VECTOR2<T>::SquaredEuclideanNorm() const
294 {
295  return (extended_type) x * x + (extended_type) y * y;
296 }
297 
298 
299 template <class T>
300 double VECTOR2<T>::Angle() const
301 {
302  return atan2( (double) y, (double) x );
303 }
304 
305 
306 template <class T>
308 {
309  VECTOR2<T> perpendicular( -y, x );
310  return perpendicular;
311 }
312 
313 
314 template <class T>
316 {
317  x = aVector.x;
318  y = aVector.y;
319  return *this;
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>
333 VECTOR2<T>& VECTOR2<T>::operator+=( const T& aScalar )
334 {
335  x += aScalar;
336  y += aScalar;
337  return *this;
338 }
339 
340 
341 template <class T>
343 {
344  x -= aVector.x;
345  y -= aVector.y;
346  return *this;
347 }
348 
349 
350 template <class T>
351 VECTOR2<T>& VECTOR2<T>::operator-=( const T& aScalar )
352 {
353  x -= aScalar;
354  y -= aScalar;
355  return *this;
356 }
357 
358 
363 template <class T>
364 VECTOR2<T> VECTOR2<T>::Rotate( double aAngle ) const
365 {
366  // Avoid 0 radian rotation, case very frequently found
367  if( aAngle == 0.0 )
368  return VECTOR2<T> ( T( x ), T( y ) );
369 
370  double sa = sin( aAngle );
371  double ca = cos( aAngle );
372 
373  return VECTOR2<T> ( T( (double) x * ca - (double) y * sa ),
374  T( (double) x * sa + (double) y * ca ) );
375 }
376 
377 
378 template <class T>
379 VECTOR2<T> VECTOR2<T>::Resize( T aNewLength ) const
380 {
381  if( x == 0 && y == 0 )
382  return VECTOR2<T> ( 0, 0 );
383 
384  extended_type l_sq_current = (extended_type) x * x + (extended_type) y * y;
385  extended_type l_sq_new = (extended_type) aNewLength * aNewLength;
386 
387  return VECTOR2<T> (
388  ( x < 0 ? -1 : 1 ) * sqrt( rescale( l_sq_new, (extended_type) x * x, l_sq_current ) ),
389  ( y < 0 ? -1 : 1 ) * sqrt( rescale( l_sq_new, (extended_type) y * y, l_sq_current ) ) ) * sign( aNewLength );
390 }
391 
392 
393 template <class T>
394 const std::string VECTOR2<T>::Format() const
395 {
396  std::stringstream ss;
397 
398  ss << "( xy " << x << " " << y << " )";
399 
400  return ss.str();
401 }
402 
403 
404 template <class T>
406 {
407  return VECTOR2<T> ( x + aVector.x, y + aVector.y );
408 }
409 
410 
411 template <class T>
412 VECTOR2<T> VECTOR2<T>::operator+( const T& aScalar ) const
413 {
414  return VECTOR2<T> ( x + aScalar, y + aScalar );
415 }
416 
417 
418 template <class T>
420 {
421  return VECTOR2<T> ( x - aVector.x, y - aVector.y );
422 }
423 
424 
425 template <class T>
426 VECTOR2<T> VECTOR2<T>::operator-( const T& aScalar ) const
427 {
428  return VECTOR2<T> ( x - aScalar, y - aScalar );
429 }
430 
431 
432 template <class T>
434 {
435  return VECTOR2<T> ( -x, -y );
436 }
437 
438 
439 template <class T>
440 typename VECTOR2<T>::extended_type VECTOR2<T>::operator*( const VECTOR2<T>& aVector ) const
441 {
442  return (extended_type)aVector.x * x + (extended_type)aVector.y * y;
443 }
444 
445 
446 template <class T>
447 VECTOR2<T> VECTOR2<T>::operator*( const T& aFactor ) const
448 {
449  VECTOR2<T> vector( x * aFactor, y * aFactor );
450  return vector;
451 }
452 
453 
454 template <class T>
455 VECTOR2<T> VECTOR2<T>::operator/( const T& aFactor ) const
456 {
457  VECTOR2<T> vector( x / aFactor, y / aFactor );
458  return vector;
459 }
460 
461 
462 template <class T>
463 VECTOR2<T> operator*( const T& aFactor, const VECTOR2<T>& aVector )
464 {
465  VECTOR2<T> vector( aVector.x * aFactor, aVector.y * aFactor );
466  return vector;
467 }
468 
469 
470 template <class T>
471 typename VECTOR2<T>::extended_type VECTOR2<T>::Cross( const VECTOR2<T>& aVector ) const
472 {
473  return (extended_type) x * (extended_type) aVector.y -
474  (extended_type) y * (extended_type) aVector.x;
475 }
476 
477 
478 template <class T>
479 typename VECTOR2<T>::extended_type VECTOR2<T>::Dot( const VECTOR2<T>& aVector ) const
480 {
481  return (extended_type) x * (extended_type) aVector.x +
482  (extended_type) y * (extended_type) aVector.y;
483 }
484 
485 
486 template <class T>
487 bool VECTOR2<T>::operator<( const VECTOR2<T>& aVector ) const
488 {
489  return ( *this * *this ) < ( aVector * aVector );
490 }
491 
492 
493 template <class T>
494 bool VECTOR2<T>::operator<=( const VECTOR2<T>& aVector ) const
495 {
496  return ( *this * *this ) <= ( aVector * aVector );
497 }
498 
499 
500 template <class T>
501 bool VECTOR2<T>::operator>( const VECTOR2<T>& aVector ) const
502 {
503  return ( *this * *this ) > ( aVector * aVector );
504 }
505 
506 
507 template <class T>
508 bool VECTOR2<T>::operator>=( const VECTOR2<T>& aVector ) const
509 {
510  return ( *this * *this ) >= ( aVector * aVector );
511 }
512 
513 
514 template <class T>
515 bool VECTOR2<T>::operator==( VECTOR2<T> const& aVector ) const
516 {
517  return ( aVector.x == x ) && ( aVector.y == y );
518 }
519 
520 
521 template <class T>
522 bool VECTOR2<T>::operator!=( VECTOR2<T> const& aVector ) const
523 {
524  return ( aVector.x != x ) || ( aVector.y != y );
525 }
526 
527 
528 template <class T>
529 const VECTOR2<T> LexicographicalMax( const VECTOR2<T>& aA, const VECTOR2<T>& aB )
530 {
531  if( aA.x > aB.x )
532  return aA;
533  else if( aA.x == aB.x && aA.y > aB.y )
534  return aA;
535 
536  return aB;
537 }
538 
539 
540 template <class T>
541 const VECTOR2<T> LexicographicalMin( const VECTOR2<T>& aA, const VECTOR2<T>& aB )
542 {
543  if( aA.x < aB.x )
544  return aA;
545  else if( aA.x == aB.x && aA.y < aB.y )
546  return aA;
547 
548  return aB;
549 }
550 
551 
552 template <class T>
553 const int LexicographicalCompare( const VECTOR2<T>& aA, const VECTOR2<T>& aB )
554 {
555  if( aA.x < aB.x )
556  return -1;
557  else if( aA.x > aB.x )
558  return 1;
559  else // aA.x == aB.x
560  {
561  if( aA.y < aB.y )
562  return -1;
563  else if( aA.y > aB.y )
564  return 1;
565  else
566  return 0;
567  }
568 }
569 
570 
571 template <class T>
572 std::ostream& operator<<( std::ostream& aStream, const VECTOR2<T>& aVector )
573 {
574  aStream << "[ " << aVector.x << " | " << aVector.y << " ]";
575  return aStream;
576 }
577 
578 
579 /* Default specializations */
580 typedef VECTOR2<double> VECTOR2D;
581 typedef VECTOR2<int> VECTOR2I;
583 
584 /* Compatibility typedefs */
585 // FIXME should be removed to avoid multiple typedefs for the same type
586 typedef VECTOR2<double> DPOINT;
587 typedef DPOINT DSIZE;
588 
589 #endif // VECTOR2D_H_
VECTOR2::operator!=
bool operator!=(const VECTOR2< T > &aVector) const
Not equality operator.
Definition: vector2d.h:522
VECTOR2::SquaredEuclideanNorm
extended_type SquaredEuclideanNorm() const
Function Squared Euclidean Norm computes the squared euclidean norm of the vector,...
Definition: vector2d.h:293
VECTOR2::Rotate
VECTOR2< T > Rotate(double aAngle) const
Function Rotate rotates the vector by a given angle.
Definition: vector2d.h:364
VECTOR2::operator>
bool operator>(const VECTOR2< T > &aVector) const
Greater than operator.
Definition: vector2d.h:501
VECTOR2::operator()
VECTOR2< CastedType > operator()() const
Casts a vector to another specialized subclass.
Definition: vector2d.h:115
VECTOR2::Format
const std::string Format() const
Function Format returns the vector formatted as a string.
Definition: vector2d.h:394
VECTOR2::operator<
bool operator<(const VECTOR2< T > &aVector) const
Smaller than operator.
Definition: vector2d.h:487
VECTOR2::Perpendicular
VECTOR2< T > Perpendicular() const
Function Perpendicular computes the perpendicular vector.
Definition: vector2d.h:307
VECTOR2
Class VECTOR2 defines a general 2D-vector/point.
Definition: vector2d.h:63
VECTOR2::EuclideanNorm
T EuclideanNorm() const
Destructor.
Definition: vector2d.h:286
VECTOR2_TRAITS::extended_type
T extended_type
extended range/precision types used by operations involving multiple multiplications to prevent overf...
Definition: vector2d.h:52
VECTOR2::VECTOR2
VECTOR2()
Construct a 2D-vector with x, y = 0.
Definition: vector2d.h:254
VECTOR2::operator/
VECTOR2< T > operator/(const T &aFactor) const
Division with a factor.
Definition: vector2d.h:455
VECTOR2::Cross
extended_type Cross(const VECTOR2< T > &aVector) const
Function Cross() computes cross product of self with aVector.
Definition: vector2d.h:471
VECTOR2::operator==
bool operator==(const VECTOR2< T > &aVector) const
Equality operator.
Definition: vector2d.h:515
VECTOR2::VECTOR2
VECTOR2(const VECTOR2< CastingType > &aVec)
Initializes a vector from another specialization.
Definition: vector2d.h:106
VECTOR2::operator+=
VECTOR2< T > & operator+=(const VECTOR2< T > &aVector)
Compound assignment operator.
Definition: vector2d.h:324
VECTOR2_TRAITS
Class VECTOR2_TRAITS traits class for VECTOR2.
Definition: vector2d.h:48
libzip::int64_t
zip_int64_t int64_t
zip_int64_t typedef.
Definition: zip.hpp:103
VECTOR2::operator=
VECTOR2< T > & operator=(const VECTOR2< T > &aVector)
Assignment operator.
Definition: vector2d.h:315
VECTOR2::operator+
VECTOR2< T > operator+(const VECTOR2< T > &aVector) const
Vector addition operator.
Definition: vector2d.h:405
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:379
VECTOR2::Angle
double Angle() const
Function Angle computes the angle of the vector.
Definition: vector2d.h:300
VECTOR2::operator*
extended_type operator*(const VECTOR2< T > &aVector) const
Scalar product operator.
Definition: vector2d.h:440
VECTOR2::operator-
VECTOR2< T > operator-()
Negate Vector operator.
Definition: vector2d.h:433
VECTOR2::operator-=
VECTOR2< T > & operator-=(const VECTOR2< T > &aVector)
Compound assignment operator.
Definition: vector2d.h:342
VECTOR2::Dot
extended_type Dot(const VECTOR2< T > &aVector) const
Function Dot() computes dot product of self with aVector.
Definition: vector2d.h:479