Horizon
Loading...
Searching...
No Matches
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
43template <class T>
45{
48 typedef T extended_type;
49};
50
51template <>
52struct VECTOR2_TRAITS<int>
53{
54 typedef int64_t extended_type;
55};
56
57// Forward declarations for template friends
58template <class T>
59class VECTOR2;
60template <class T>
61std::ostream& operator<<( std::ostream& aStream, const VECTOR2<T>& aVector );
62
70template <class T = int>
72{
73public:
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
256template <class T>
258{
259 x = y = 0.0;
260}
261
262
263template <class T>
265{
266 x = T( aPoint.x );
267 y = T( aPoint.y );
268}
269
270
271template <class T>
273{
274 x = T( aSize.x );
275 y = T( aSize.y );
276}
277
278template <class T>
280{
281 x = aX;
282 y = aY;
283}
284
285
286template <class T>
288{
289 return sqrt( (extended_type) x * x + (extended_type) y * y );
290}
291
292
293template <class T>
294typename VECTOR2<T>::extended_type VECTOR2<T>::SquaredEuclideanNorm() const
295{
296 return (extended_type) x * x + (extended_type) y * y;
297}
298
299
300template <class T>
301double VECTOR2<T>::Angle() const
302{
303 return atan2( (double) y, (double) x );
304}
305
306
307template <class T>
309{
310 VECTOR2<T> perpendicular( -y, x );
311 return perpendicular;
312}
313
314
315template <class T>
317{
318 x = aVector.x;
319 y = aVector.y;
320 return *this;
321}
322
323
324template <class T>
326{
327 x += aVector.x;
328 y += aVector.y;
329 return *this;
330}
331
332
333template <class T>
335{
336 x += aScalar;
337 y += aScalar;
338 return *this;
339}
340
341
342template <class T>
344{
345 x -= aVector.x;
346 y -= aVector.y;
347 return *this;
348}
349
350
351template <class T>
353{
354 x -= aScalar;
355 y -= aScalar;
356 return *this;
357}
358
359
364template <class T>
365VECTOR2<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
397template <class T>
398VECTOR2<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
427template <class T>
428const 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
438template <class T>
440{
441 return VECTOR2<T> ( x + aVector.x, y + aVector.y );
442}
443
444
445template <class T>
446VECTOR2<T> VECTOR2<T>::operator+( const T& aScalar ) const
447{
448 return VECTOR2<T> ( x + aScalar, y + aScalar );
449}
450
451
452template <class T>
454{
455 return VECTOR2<T> ( x - aVector.x, y - aVector.y );
456}
457
458
459template <class T>
460VECTOR2<T> VECTOR2<T>::operator-( const T& aScalar ) const
461{
462 return VECTOR2<T> ( x - aScalar, y - aScalar );
463}
464
465
466template <class T>
468{
469 return VECTOR2<T> ( -x, -y );
470}
471
472
473template <class T>
474typename 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
480template <class T>
481VECTOR2<T> VECTOR2<T>::operator*( const T& aFactor ) const
482{
483 VECTOR2<T> vector( x * aFactor, y * aFactor );
484 return vector;
485}
486
487
488template <class T>
489VECTOR2<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
498template <class T>
499VECTOR2<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
506template <class T>
507typename 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
514template <class T>
515typename 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
522template <class T>
523bool VECTOR2<T>::operator<( const VECTOR2<T>& aVector ) const
524{
525 return ( *this * *this ) < ( aVector * aVector );
526}
527
528
529template <class T>
530bool VECTOR2<T>::operator<=( const VECTOR2<T>& aVector ) const
531{
532 return ( *this * *this ) <= ( aVector * aVector );
533}
534
535
536template <class T>
537bool VECTOR2<T>::operator>( const VECTOR2<T>& aVector ) const
538{
539 return ( *this * *this ) > ( aVector * aVector );
540}
541
542
543template <class T>
544bool VECTOR2<T>::operator>=( const VECTOR2<T>& aVector ) const
545{
546 return ( *this * *this ) >= ( aVector * aVector );
547}
548
549
550template <class T>
551bool VECTOR2<T>::operator==( VECTOR2<T> const& aVector ) const
552{
553 return ( aVector.x == x ) && ( aVector.y == y );
554}
555
556
557template <class T>
558bool VECTOR2<T>::operator!=( VECTOR2<T> const& aVector ) const
559{
560 return ( aVector.x != x ) || ( aVector.y != y );
561}
562
563
564template <class T>
565const 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
576template <class T>
577const 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
588template <class T>
589const 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
607template <class T>
608std::ostream& operator<<( std::ostream& aStream, const VECTOR2<T>& aVector )
609{
610 aStream << "[ " << aVector.x << " | " << aVector.y << " ]";
611 return aStream;
612}
613
614/* Default specializations */
616typedef VECTOR2<int> VECTOR2I;
618
619/* STL specializations */
620namespace 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
639typedef VECTOR2<double> DPOINT;
640typedef 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(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
VECTOR2< CastedType > operator()() const
Cast a vector to another specialized subclass. Beware of rounding issues.
Definition vector2d.h:111
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
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