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
46template <class T>
48{
51 typedef T extended_type;
52};
53
54template <>
55struct VECTOR2_TRAITS<int>
56{
57 typedef int64_t extended_type;
58};
59
60// Forward declarations for template friends
61template <class T>
62class VECTOR2;
63template <class T>
64std::ostream& operator<<( std::ostream& aStream, const VECTOR2<T>& aVector );
65
74template <class T = int>
76{
77public:
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
93 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
250template <class T>
252{
253 x = y = 0.0;
254}
255
256
257#ifdef WX_COMPATIBILITY
258template <class T>
259VECTOR2<T>::VECTOR2( wxPoint const& aPoint )
260{
261 x = T( aPoint.x );
262 y = T( aPoint.y );
263}
264
265
266template <class T>
267VECTOR2<T>::VECTOR2( wxSize const& aSize )
268{
269 x = T( aSize.x );
270 y = T( aSize.y );
271}
272#endif
273
274template <class T>
276{
277 x = aX;
278 y = aY;
279}
280
281
282template <class T>
284{
285 return sqrt( (extended_type) x * x + (extended_type) y * y );
286}
287
288
289template <class T>
290typename VECTOR2<T>::extended_type VECTOR2<T>::SquaredEuclideanNorm() const
291{
292 return (extended_type) x * x + (extended_type) y * y;
293}
294
295
296template <class T>
297double VECTOR2<T>::Angle() const
298{
299 return atan2( (double) y, (double) x );
300}
301
302
303template <class T>
305{
306 VECTOR2<T> perpendicular( -y, x );
307 return perpendicular;
308}
309
310
311template <class T>
313{
314 x = aVector.x;
315 y = aVector.y;
316 return *this;
317}
318
319
320template <class T>
322{
323 x += aVector.x;
324 y += aVector.y;
325 return *this;
326}
327
328
329template <class T>
331{
332 x += aScalar;
333 y += aScalar;
334 return *this;
335}
336
337
338template <class T>
340{
341 x -= aVector.x;
342 y -= aVector.y;
343 return *this;
344}
345
346
347template <class T>
349{
350 x -= aScalar;
351 y -= aScalar;
352 return *this;
353}
354
355
360template <class T>
361VECTOR2<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
375template <class T>
376VECTOR2<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
390template <class T>
391const 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
401template <class T>
403{
404 return VECTOR2<T> ( x + aVector.x, y + aVector.y );
405}
406
407
408template <class T>
409VECTOR2<T> VECTOR2<T>::operator+( const T& aScalar ) const
410{
411 return VECTOR2<T> ( x + aScalar, y + aScalar );
412}
413
414
415template <class T>
417{
418 return VECTOR2<T> ( x - aVector.x, y - aVector.y );
419}
420
421
422template <class T>
423VECTOR2<T> VECTOR2<T>::operator-( const T& aScalar ) const
424{
425 return VECTOR2<T> ( x - aScalar, y - aScalar );
426}
427
428
429template <class T>
431{
432 return VECTOR2<T> ( -x, -y );
433}
434
435
436template <class T>
437typename 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
443template <class T>
444VECTOR2<T> VECTOR2<T>::operator*( const T& aFactor ) const
445{
446 VECTOR2<T> vector( x * aFactor, y * aFactor );
447 return vector;
448}
449
450
451template <class T>
452VECTOR2<T> VECTOR2<T>::operator/( const T& aFactor ) const
453{
454 VECTOR2<T> vector( x / aFactor, y / aFactor );
455 return vector;
456}
457
458
459template <class T>
460VECTOR2<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
467template <class T>
468typename 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
475template <class T>
476typename 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
483template <class T>
484bool VECTOR2<T>::operator<( const VECTOR2<T>& aVector ) const
485{
486 return ( *this * *this ) < ( aVector * aVector );
487}
488
489
490template <class T>
491bool VECTOR2<T>::operator<=( const VECTOR2<T>& aVector ) const
492{
493 return ( *this * *this ) <= ( aVector * aVector );
494}
495
496
497template <class T>
498bool VECTOR2<T>::operator>( const VECTOR2<T>& aVector ) const
499{
500 return ( *this * *this ) > ( aVector * aVector );
501}
502
503
504template <class T>
505bool VECTOR2<T>::operator>=( const VECTOR2<T>& aVector ) const
506{
507 return ( *this * *this ) >= ( aVector * aVector );
508}
509
510
511template <class T>
512bool VECTOR2<T>::operator==( VECTOR2<T> const& aVector ) const
513{
514 return ( aVector.x == x ) && ( aVector.y == y );
515}
516
517
518template <class T>
519bool VECTOR2<T>::operator!=( VECTOR2<T> const& aVector ) const
520{
521 return ( aVector.x != x ) || ( aVector.y != y );
522}
523
524
525template <class T>
526const 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
537template <class T>
538const 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
549template <class T>
550const 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
568template <class T>
569std::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 */
578typedef VECTOR2<int> VECTOR2I;
580
581/* Compatibility typedefs */
582// FIXME should be removed to avoid multiple typedefs for the same type
583typedef VECTOR2<double> DPOINT;
584typedef DPOINT DSIZE;
585
586#endif // VECTOR2D_H_
Class VECTOR2 defines a general 2D-vector/point.
Definition: vector2d.h:76
VECTOR2< T > operator-(const T &aScalar) const
Scalar subtraction operator.
Definition: vector2d.h:423
VECTOR2< T > & operator+=(const T &aScalar)
Compound assignment operator.
Definition: vector2d.h:330
VECTOR2(const VECTOR2< CastingType > &aVec)
Initializes a vector from another specialization.
Definition: vector2d.h:105
extended_type SquaredEuclideanNorm() const
Function Squared Euclidean Norm computes the squared euclidean norm of the vector,...
Definition: vector2d.h:290
const std::string Format() const
Function Format returns the vector formatted as a string.
Definition: vector2d.h:391
VECTOR2()
Construct a 2D-vector with x, y = 0.
Definition: vector2d.h:251
VECTOR2(T x, T y)
Construct a vector with given components x, y.
Definition: vector2d.h:275
VECTOR2< T > & operator+=(const VECTOR2< T > &aVector)
Compound assignment operator.
Definition: vector2d.h:321
VECTOR2< T > Rotate(double aAngle) const
Function Rotate rotates the vector by a given angle.
Definition: vector2d.h:361
T EuclideanNorm() const
Destructor.
Definition: vector2d.h:283
bool operator==(const VECTOR2< T > &aVector) const
Equality operator.
Definition: vector2d.h:512
VECTOR2< T > Perpendicular() const
Function Perpendicular computes the perpendicular vector.
Definition: vector2d.h:304
VECTOR2< T > & operator=(const VECTOR2< T > &aVector)
Assignment operator.
Definition: vector2d.h:312
VECTOR2< T > & operator-=(const T &aScalar)
Compound assignment operator.
Definition: vector2d.h:348
bool operator!=(const VECTOR2< T > &aVector) const
Not equality operator.
Definition: vector2d.h:519
double Angle() const
Function Angle computes the angle of the vector.
Definition: vector2d.h:297
extended_type Cross(const VECTOR2< T > &aVector) const
Function Cross() computes cross product of self with aVector.
Definition: vector2d.h:468
VECTOR2< CastedType > operator()() const
Casts a vector to another specialized subclass.
Definition: vector2d.h:114
bool operator>(const VECTOR2< T > &aVector) const
Greater than operator.
Definition: vector2d.h:498
extended_type Dot(const VECTOR2< T > &aVector) const
Function Dot() computes dot product of self with aVector.
Definition: vector2d.h:476
extended_type operator*(const VECTOR2< T > &aVector) const
Scalar product operator.
Definition: vector2d.h:437
VECTOR2< T > operator+(const VECTOR2< T > &aVector) const
Vector addition operator.
Definition: vector2d.h:402
VECTOR2< T > operator-(const VECTOR2< T > &aVector) const
Vector subtraction operator.
Definition: vector2d.h:416
VECTOR2< T > operator*(const T &aFactor) const
Multiplication with a factor.
Definition: vector2d.h:444
VECTOR2< T > operator+(const T &aScalar) const
Scalar addition operator.
Definition: vector2d.h:409
VECTOR2< T > & operator-=(const VECTOR2< T > &aVector)
Compound assignment operator.
Definition: vector2d.h:339
bool operator<(const VECTOR2< T > &aVector) const
Smaller than operator.
Definition: vector2d.h:484
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< T > operator-()
Negate Vector operator.
Definition: vector2d.h:430
VECTOR2< T > operator/(const T &aFactor) const
Division with a factor.
Definition: vector2d.h:452
Class VECTOR2_TRAITS traits class for VECTOR2.
Definition: vector2d.h:48
T extended_type
‍extended range/precision types used by operations involving multiple multiplications to prevent over...
Definition: vector2d.h:51