KiCad PCB EDA Suite
vector2d.h
Go to the documentation of this file.
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 <[email protected]>
6 * Copyright (C) 2012-2021 KiCad Developers, see AUTHORS.txt for contributors.
7 * Copyright (C) 2013 CERN
8 * @author Tomasz Wlostowski <[email protected]>
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#ifdef WX_COMPATIBILITY
39#include <wx/gdicmn.h>
40#endif
41
45template <class T>
47{
50 typedef T extended_type;
51};
52
53template <>
54struct VECTOR2_TRAITS<int>
55{
56 typedef int64_t extended_type;
57};
58
59// Forward declarations for template friends
60template <class T>
61class VECTOR2;
62template <class T>
63std::ostream& operator<<( std::ostream& aStream, const VECTOR2<T>& aVector );
64
72template <class T = int>
74{
75public:
77 typedef T coord_type;
78
79 static constexpr extended_type ECOORD_MAX = std::numeric_limits<extended_type>::max();
80 static constexpr extended_type ECOORD_MIN = std::numeric_limits<extended_type>::min();
81
82 T x, y;
83
86
87#ifdef WX_COMPATIBILITY
89 VECTOR2( const wxPoint& aPoint );
90
92 VECTOR2( const wxSize& aSize );
93#endif
94
96 VECTOR2( T x, T y );
97
99 template <typename CastingType>
101 {
102 x = (T) aVec.x;
103 y = (T) aVec.y;
104 }
105
107 VECTOR2( const VECTOR2<T>& aVec )
108 {
109 x = aVec.x;
110 y = aVec.y;
111 }
112
114 template <typename CastedType>
116 {
117 return VECTOR2<CastedType>( (CastedType) x, (CastedType) y );
118 }
119
125 explicit operator wxPoint() const
126 {
127 return wxPoint( x, y );
128 }
129
135 explicit operator wxSize() const
136 {
137 return wxSize( x, y );
138 }
139
140 // virtual ~VECTOR2();
141
149 T EuclideanNorm() const;
150
159
160
167
174 VECTOR2<T> Resize( T aNewLength ) const;
175
181 const std::string Format() const;
182
186 extended_type Cross( const VECTOR2<T>& aVector ) const;
187
191 extended_type Dot( const VECTOR2<T>& aVector ) const;
192
193
194 // Operators
195
197 VECTOR2<T>& operator=( const VECTOR2<T>& aVector );
198
200 VECTOR2<T> operator+( const VECTOR2<T>& aVector ) const;
201
203 VECTOR2<T> operator+( const T& aScalar ) const;
204
206 VECTOR2<T>& operator+=( const VECTOR2<T>& aVector );
207
209 VECTOR2<T>& operator*=( const VECTOR2<T>& aVector );
210
211 VECTOR2<T>& operator*=( const T& aScalar );
212
214 VECTOR2<T>& operator+=( const T& aScalar );
215
217 VECTOR2<T> operator-( const VECTOR2<T>& aVector ) const;
218
220 VECTOR2<T> operator-( const T& aScalar ) const;
221
223 VECTOR2<T>& operator-=( const VECTOR2<T>& aVector );
224
226 VECTOR2<T>& operator-=( const T& aScalar );
227
230
232 extended_type operator*( const VECTOR2<T>& aVector ) const;
233
235 VECTOR2<T> operator*( const T& aFactor ) const;
236
238 VECTOR2<T> operator/( const T& aFactor ) const;
239
241 bool operator==( const VECTOR2<T>& aVector ) const;
242
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
251 bool operator>( const VECTOR2<T>& aVector ) const;
252 bool operator>=( const VECTOR2<T>& aVector ) const;
253};
254
255
256// ----------------------
257// --- Implementation ---
258// ----------------------
259
260template <class T>
262{
263 x = y = 0.0;
264}
265
266
267#ifdef WX_COMPATIBILITY
268template <class T>
269VECTOR2<T>::VECTOR2( const wxPoint& aPoint )
270{
271 x = T( aPoint.x );
272 y = T( aPoint.y );
273}
274
275
276template <class T>
277VECTOR2<T>::VECTOR2( const wxSize& aSize )
278{
279 x = T( aSize.x );
280 y = T( aSize.y );
281}
282#endif
283
284template <class T>
286{
287 x = aX;
288 y = aY;
289}
290
291
292template <class T>
294{
295 return sqrt( (extended_type) x * x + (extended_type) y * y );
296}
297
298
299template <class T>
301{
302 return (extended_type) x * x + (extended_type) y * y;
303}
304
305
306template <class T>
308{
309 VECTOR2<T> perpendicular( -y, x );
310 return perpendicular;
311}
312
313
314template <class T>
316{
317 x = aVector.x;
318 y = aVector.y;
319 return *this;
320}
321
322
323template <class T>
325{
326 x += aVector.x;
327 y += aVector.y;
328 return *this;
329}
330
331
332template <class T>
334{
335 x *= aVector.x;
336 y *= aVector.y;
337 return *this;
338}
339
340
341template <class T>
343{
344 x *= aScalar;
345 y *= aScalar;
346 return *this;
347}
348
349
350template <class T>
352{
353 x += aScalar;
354 y += aScalar;
355 return *this;
356}
357
358
359template <class T>
361{
362 x -= aVector.x;
363 y -= aVector.y;
364 return *this;
365}
366
367
368template <class T>
370{
371 x -= aScalar;
372 y -= aScalar;
373 return *this;
374}
375
376
377template <class T>
378VECTOR2<T> VECTOR2<T>::Resize( T aNewLength ) const
379{
380 if( x == 0 && y == 0 )
381 return VECTOR2<T> ( 0, 0 );
382
383 extended_type l_sq_current = (extended_type) x * x + (extended_type) y * y;
384 extended_type l_sq_new = (extended_type) aNewLength * aNewLength;
385
386 if( std::is_integral<T>::value )
387 {
388 return VECTOR2<T> (
389 ( x < 0 ? -1 : 1 ) *
390 KiROUND( std::sqrt( rescale( l_sq_new, (extended_type) x * x, l_sq_current ) ) ),
391 ( y < 0 ? -1 : 1 ) *
392 KiROUND( std::sqrt( rescale( l_sq_new, (extended_type) y * y, l_sq_current ) ) ) )
393 * sign( aNewLength );
394 }
395 else
396 {
397 return VECTOR2<T> (
398 ( x < 0 ? -1 : 1 ) *
399 std::sqrt( rescale( l_sq_new, (extended_type) x * x, l_sq_current ) ),
400 ( y < 0 ? -1 : 1 ) *
401 std::sqrt( rescale( l_sq_new, (extended_type) y * y, l_sq_current ) ) )
402 * sign( aNewLength );
403 }
404}
405
406
407template <class T>
408const std::string VECTOR2<T>::Format() const
409{
410 std::stringstream ss;
411
412 ss << "( xy " << x << " " << y << " )";
413
414 return ss.str();
415}
416
417
418template <class T>
420{
421 return VECTOR2<T> ( x + aVector.x, y + aVector.y );
422}
423
424
425template <class T>
426VECTOR2<T> VECTOR2<T>::operator+( const T& aScalar ) const
427{
428 return VECTOR2<T> ( x + aScalar, y + aScalar );
429}
430
431
432template <class T>
434{
435 return VECTOR2<T> ( x - aVector.x, y - aVector.y );
436}
437
438
439template <class T>
440VECTOR2<T> VECTOR2<T>::operator-( const T& aScalar ) const
441{
442 return VECTOR2<T> ( x - aScalar, y - aScalar );
443}
444
445
446template <class T>
448{
449 return VECTOR2<T> ( -x, -y );
450}
451
452
453template <class T>
455{
456 return (extended_type)aVector.x * x + (extended_type)aVector.y * y;
457}
458
459
460template <class T>
461VECTOR2<T> VECTOR2<T>::operator*( const T& aFactor ) const
462{
463 VECTOR2<T> vector( x * aFactor, y * aFactor );
464 return vector;
465}
466
467
468template <class T>
469VECTOR2<T> VECTOR2<T>::operator/( const T& aFactor ) const
470{
471 if( std::is_integral<T>::value )
472 return VECTOR2<T>( KiROUND( x / aFactor ), KiROUND( y / aFactor ) );
473 else
474 return VECTOR2<T>( x / aFactor, y / aFactor );
475}
476
477
478template <class T>
479VECTOR2<T> operator*( const T& aFactor, const VECTOR2<T>& aVector )
480{
481 VECTOR2<T> vector( aVector.x * aFactor, aVector.y * aFactor );
482 return vector;
483}
484
485
486template <class T>
488{
489 return (extended_type) x * (extended_type) aVector.y -
490 (extended_type) y * (extended_type) aVector.x;
491}
492
493
494template <class T>
496{
497 return (extended_type) x * (extended_type) aVector.x +
498 (extended_type) y * (extended_type) aVector.y;
499}
500
501
502template <class T>
503bool VECTOR2<T>::operator<( const VECTOR2<T>& aVector ) const
504{
505 return ( *this * *this ) < ( aVector * aVector );
506}
507
508
509template <class T>
510bool VECTOR2<T>::operator<=( const VECTOR2<T>& aVector ) const
511{
512 return ( *this * *this ) <= ( aVector * aVector );
513}
514
515
516template <class T>
517bool VECTOR2<T>::operator>( const VECTOR2<T>& aVector ) const
518{
519 return ( *this * *this ) > ( aVector * aVector );
520}
521
522
523template <class T>
524bool VECTOR2<T>::operator>=( const VECTOR2<T>& aVector ) const
525{
526 return ( *this * *this ) >= ( aVector * aVector );
527}
528
529
530template <class T>
531bool VECTOR2<T>::operator==( VECTOR2<T> const& aVector ) const
532{
533 return ( aVector.x == x ) && ( aVector.y == y );
534}
535
536
537template <class T>
538bool VECTOR2<T>::operator!=( VECTOR2<T> const& aVector ) const
539{
540 return ( aVector.x != x ) || ( aVector.y != y );
541}
542
543
544template <class T>
546{
547 if( aA.x > aB.x )
548 return aA;
549 else if( aA.x == aB.x && aA.y > aB.y )
550 return aA;
551
552 return aB;
553}
554
555
556template <class T>
558{
559 if( aA.x < aB.x )
560 return aA;
561 else if( aA.x == aB.x && aA.y < aB.y )
562 return aA;
563
564 return aB;
565}
566
567
568template <class T>
569const int LexicographicalCompare( const VECTOR2<T>& aA, const VECTOR2<T>& aB )
570{
571 if( aA.x < aB.x )
572 return -1;
573 else if( aA.x > aB.x )
574 return 1;
575 else // aA.x == aB.x
576 {
577 if( aA.y < aB.y )
578 return -1;
579 else if( aA.y > aB.y )
580 return 1;
581 else
582 return 0;
583 }
584}
585
586
595template <class T>
596typename std::enable_if<!std::numeric_limits<T>::is_integer, bool>::type
597equals( VECTOR2<T> const& aFirst, VECTOR2<T> const& aSecond,
598 T aEpsilon = std::numeric_limits<T>::epsilon() )
599{
600 if( !equals( aFirst.x, aSecond.x, aEpsilon ) )
601 {
602 return false;
603 }
604
605 return equals( aFirst.y, aSecond.y, aEpsilon );
606}
607
608
609template <class T>
610std::ostream& operator<<( std::ostream& aStream, const VECTOR2<T>& aVector )
611{
612 aStream << "[ " << aVector.x << " | " << aVector.y << " ]";
613 return aStream;
614}
615
616/* Default specializations */
620
621/* STL specializations */
622namespace std
623{
624 // Required to enable correct use in std::map/unordered_map
625 // DO NOT USE hash tables with VECTOR2 elements. It is inefficient
626 // and degenerates to a linear search. Use the std::map/std::set
627 // trees instead that utilize the less operator below
628 // This function is purposely deleted after substantial testing
629 template <>
630 struct hash<VECTOR2I>
631 {
632 size_t operator()( const VECTOR2I& k ) const = delete;
633 };
634
635 // Required to enable use of std::hash with maps.
636 template <>
637 struct less<VECTOR2I>
638 {
639 bool operator()( const VECTOR2I& aA, const VECTOR2I& aB ) const;
640 };
641}
642
643#endif // VECTOR2D_H_
Define a general 2D-vector/point.
Definition: vector2d.h:74
VECTOR2< T > operator-(const T &aScalar) const
Scalar subtraction operator.
Definition: vector2d.h:440
VECTOR2< T > & operator+=(const T &aScalar)
Compound assignment operator.
Definition: vector2d.h:351
VECTOR2(const VECTOR2< CastingType > &aVec)
Initializes a vector from another specialization. Beware of rounding issues.
Definition: vector2d.h:100
VECTOR2< T > & operator*=(const T &aScalar)
Definition: vector2d.h:342
extended_type SquaredEuclideanNorm() const
Compute the squared euclidean norm of the vector, which is defined as (x ** 2 + y ** 2).
Definition: vector2d.h:300
VECTOR2< T > & operator*=(const VECTOR2< T > &aVector)
Compound assignment operator.
Definition: vector2d.h:333
const std::string Format() const
Return the vector formatted as a string.
Definition: vector2d.h:408
VECTOR2()
Construct a 2D-vector with x, y = 0.
Definition: vector2d.h:261
VECTOR2(T x, T y)
Construct a vector with given components x, y.
Definition: vector2d.h:285
bool operator>=(const VECTOR2< T > &aVector) const
Definition: vector2d.h:524
static constexpr extended_type ECOORD_MAX
Definition: vector2d.h:79
VECTOR2< T > & operator+=(const VECTOR2< T > &aVector)
Compound assignment operator.
Definition: vector2d.h:324
VECTOR2(const VECTOR2< T > &aVec)
Copy a vector.
Definition: vector2d.h:107
T EuclideanNorm() const
Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
Definition: vector2d.h:293
VECTOR2_TRAITS< T >::extended_type extended_type
Definition: vector2d.h:76
bool operator==(const VECTOR2< T > &aVector) const
Equality operator.
Definition: vector2d.h:531
VECTOR2< T > Perpendicular() const
Compute the perpendicular vector.
Definition: vector2d.h:307
bool operator<=(const VECTOR2< T > &aVector) const
Definition: vector2d.h:510
VECTOR2< T > & operator=(const VECTOR2< T > &aVector)
Assignment operator.
Definition: vector2d.h:315
VECTOR2< T > & operator-=(const T &aScalar)
Compound assignment operator.
Definition: vector2d.h:369
bool operator!=(const VECTOR2< T > &aVector) const
Not equality operator.
Definition: vector2d.h:538
static constexpr extended_type ECOORD_MIN
Definition: vector2d.h:80
extended_type Cross(const VECTOR2< T > &aVector) const
Compute cross product of self with aVector.
Definition: vector2d.h:487
VECTOR2< CastedType > operator()() const
Cast a vector to another specialized subclass. Beware of rounding issues.
Definition: vector2d.h:115
bool operator>(const VECTOR2< T > &aVector) const
Greater than operator.
Definition: vector2d.h:517
extended_type Dot(const VECTOR2< T > &aVector) const
Compute dot product of self with aVector.
Definition: vector2d.h:495
extended_type operator*(const VECTOR2< T > &aVector) const
Scalar product operator.
Definition: vector2d.h:454
VECTOR2< T > operator+(const VECTOR2< T > &aVector) const
Vector addition operator.
Definition: vector2d.h:419
VECTOR2< T > operator-(const VECTOR2< T > &aVector) const
Vector subtraction operator.
Definition: vector2d.h:433
VECTOR2< T > operator*(const T &aFactor) const
Multiplication with a factor.
Definition: vector2d.h:461
VECTOR2< T > operator+(const T &aScalar) const
Scalar addition operator.
Definition: vector2d.h:426
VECTOR2< T > & operator-=(const VECTOR2< T > &aVector)
Compound assignment operator.
Definition: vector2d.h:360
bool operator<(const VECTOR2< T > &aVector) const
Smaller than operator.
Definition: vector2d.h:503
VECTOR2< T > Resize(T aNewLength) const
Return a vector of the same direction, but length specified in aNewLength.
Definition: vector2d.h:378
VECTOR2< T > operator-()
Negate Vector operator.
Definition: vector2d.h:447
VECTOR2< T > operator/(const T &aFactor) const
Division with a factor.
Definition: vector2d.h:469
T coord_type
Definition: vector2d.h:77
Definition: bitmap.cpp:64
int64_t extended_type
Definition: vector2d.h:56
Traits class for VECTOR2.
Definition: vector2d.h:47
T extended_type
< extended range/precision types used by operations involving multiple multiplications to prevent ove...
Definition: vector2d.h:50
size_t operator()(const VECTOR2I &k) const =delete
int sign(T val)
Definition: util.h:111
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:80
T rescale(T aNumerator, T aValue, T aDenominator)
Scale a number (value) by rational (numerator/denominator).
Definition: util.h:105
VECTOR2< double > VECTOR2D
Definition: vector2d.h:617
const int LexicographicalCompare(const VECTOR2< T > &aA, const VECTOR2< T > &aB)
Definition: vector2d.h:569
std::ostream & operator<<(std::ostream &aStream, const VECTOR2< T > &aVector)
Definition: vector2d.h:610
const VECTOR2< T > LexicographicalMax(const VECTOR2< T > &aA, const VECTOR2< T > &aB)
Definition: vector2d.h:545
std::enable_if<!std::numeric_limits< T >::is_integer, bool >::type equals(VECTOR2< T > const &aFirst, VECTOR2< T > const &aSecond, T aEpsilon=std::numeric_limits< T >::epsilon())
Template to compare two VECTOR2<T> values for equality within a required epsilon.
Definition: vector2d.h:597
VECTOR2< unsigned int > VECTOR2U
Definition: vector2d.h:619
const VECTOR2< T > LexicographicalMin(const VECTOR2< T > &aA, const VECTOR2< T > &aB)
Definition: vector2d.h:557
VECTOR2< int > VECTOR2I
Definition: vector2d.h:618
VECTOR2< T > operator*(const T &aFactor, const VECTOR2< T > &aVector)
Definition: vector2d.h:479