KiCad PCB EDA Suite
Loading...
Searching...
No Matches
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 The 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 <algorithm>
32#include <limits>
33#include <iostream>
34#include <sstream>
35#include <type_traits>
36
37#include <math/util.h>
38
42template <class T>
44{
47 typedef T extended_type;
48};
49
50template <>
51struct VECTOR2_TRAITS<int>
52{
53 typedef int64_t extended_type;
54};
55
56// Forward declarations for template friends
57template <class T>
58class VECTOR2;
59template <class T>
60std::ostream& operator<<( std::ostream& aStream, const VECTOR2<T>& aVector );
61
69template <class T = int>
71{
72public:
74 typedef T coord_type;
75
76 static constexpr extended_type ECOORD_MAX = std::numeric_limits<extended_type>::max();
77 static constexpr extended_type ECOORD_MIN = std::numeric_limits<extended_type>::min();
78
79 T x, y;
80
82 constexpr VECTOR2();
83
85 constexpr VECTOR2( T x, T y );
86
88 template <typename CastingType>
89 constexpr VECTOR2( const VECTOR2<CastingType>& aVec )
90 {
91 if( std::is_floating_point<T>() )
92 {
93 x = static_cast<T>( aVec.x );
94 y = static_cast<T>( aVec.y );
95 }
96 else if( std::is_floating_point<CastingType>() )
97 {
98 CastingType minI = static_cast<CastingType>( std::numeric_limits<T>::min() );
99 CastingType maxI = static_cast<CastingType>( std::numeric_limits<T>::max() );
100
101 x = static_cast<T>( std::clamp( aVec.x, minI, maxI ) );
102 y = static_cast<T>( std::clamp( aVec.y, minI, maxI ) );
103 }
104 else if( std::is_integral<T>() && std::is_integral<CastingType>() )
105 {
106 int64_t minI = static_cast<int64_t>( std::numeric_limits<T>::min() );
107 int64_t maxI = static_cast<int64_t>( std::numeric_limits<T>::max() );
108
109 x = static_cast<T>( std::clamp( static_cast<int64_t>( aVec.x ), minI, maxI ) );
110 y = static_cast<T>( std::clamp( static_cast<int64_t>( aVec.y ), minI, maxI ) );
111 }
112 else
113 {
114 x = static_cast<T>( aVec.x );
115 y = static_cast<T>( aVec.y );
116 }
117 }
118
120 constexpr VECTOR2( const VECTOR2<T>& aVec )
121 {
122 x = aVec.x;
123 y = aVec.y;
124 }
125
127 template <typename U>
128 constexpr VECTOR2<U> operator()() const
129 {
130 if( std::is_floating_point<U>::value )
131 {
132 return VECTOR2<U>( static_cast<U>( x ), static_cast<U>( y ) );
133 }
134 else if( std::is_floating_point<T>() )
135 {
136 T minI = static_cast<T>( std::numeric_limits<U>::min() );
137 T maxI = static_cast<T>( std::numeric_limits<U>::max() );
138 return VECTOR2<U>( static_cast<U>( std::clamp( x, minI, maxI ) ),
139 static_cast<U>( std::clamp( y, minI, maxI ) ) );
140 }
141 else if( std::is_integral<T>() && std::is_integral<U>() )
142 {
143 int64_t minI = static_cast<int64_t>( std::numeric_limits<U>::min() );
144 int64_t maxI = static_cast<int64_t>( std::numeric_limits<U>::max() );
145 int64_t x64 = static_cast<int64_t>( x );
146 int64_t y64 = static_cast<int64_t>( y );
147
148 return VECTOR2<U>(
149 static_cast<U>( std::clamp( x64, minI, maxI ) ),
150 static_cast<U>( std::clamp( y64, minI, maxI ) ) );
151 }
152 else
153 {
154 return VECTOR2<U>( static_cast<U>( x ), static_cast<U>( y ) );
155 }
156 }
157
165 T EuclideanNorm() const;
166
175
176
182 constexpr VECTOR2<T> Perpendicular() const;
183
190 VECTOR2<T> Resize( T aNewLength ) const;
191
197 const std::string Format() const;
198
202 constexpr extended_type Cross( const VECTOR2<T>& aVector ) const;
203
207 constexpr extended_type Dot( const VECTOR2<T>& aVector ) const;
208
213 double Distance( const VECTOR2<extended_type>& aVector ) const;
214
218 constexpr extended_type SquaredDistance( const VECTOR2<T>& aVector ) const;
219
220 // Operators
221
223 constexpr VECTOR2<T>& operator=( const VECTOR2<T>& aVector );
224
226 constexpr VECTOR2<T>& operator+=( const VECTOR2<T>& aVector );
227
229 constexpr VECTOR2<T>& operator*=( const VECTOR2<T>& aVector );
230
231 constexpr VECTOR2<T>& operator*=( const T& aScalar );
232
234 constexpr VECTOR2<T>& operator+=( const T& aScalar );
235
237 constexpr VECTOR2<T>& operator-=( const VECTOR2<T>& aVector );
238
240 constexpr VECTOR2<T>& operator-=( const T& aScalar );
241
244
246 constexpr VECTOR2<T> operator/( double aFactor ) const;
247
249 constexpr bool operator==( const VECTOR2<T>& aVector ) const;
250
252 constexpr bool operator!=( const VECTOR2<T>& aVector ) const;
253
255 constexpr bool operator<( const VECTOR2<T>& aVector ) const;
256 constexpr bool operator<=( const VECTOR2<T>& aVector ) const;
257
259 constexpr bool operator>( const VECTOR2<T>& aVector ) const;
260 constexpr bool operator>=( const VECTOR2<T>& aVector ) const;
261};
262
263
264// ----------------------
265// --- Implementation ---
266// ----------------------
267
268template <class T>
269constexpr VECTOR2<T>::VECTOR2() : x{}, y{}
270{
271}
272
273
274template <class T>
275constexpr VECTOR2<T>::VECTOR2( T aX, T aY )
276{
277 x = aX;
278 y = aY;
279}
280
281
282template <class T>
284{
285 // 45° are common in KiCad, so we can optimize the calculation
286 if( std::abs( x ) == std::abs( y ) )
287 {
288 if( std::is_integral<T>::value )
289 return KiROUND<double, T>( std::abs( x ) * M_SQRT2 );
290
291 return static_cast<T>( std::abs( x ) * M_SQRT2 );
292 }
293
294 if( x == 0 )
295 return static_cast<T>( std::abs( y ) );
296 if( y == 0 )
297 return static_cast<T>( std::abs( x ) );
298
299 if( std::is_integral<T>::value )
300 return KiROUND<double, T>( std::hypot( x, y ) );
301
302 return static_cast<T>( std::hypot( x, y ) );
303}
304
305
306template <class T>
308{
309 return (extended_type) x * x + (extended_type) y * y;
310}
311
312
313template <class T>
315{
316 VECTOR2<T> perpendicular( -y, x );
317 return perpendicular;
318}
319
320
321template <class T>
322constexpr VECTOR2<T>& VECTOR2<T>::operator=( const VECTOR2<T>& aVector )
323{
324 x = aVector.x;
325 y = aVector.y;
326 return *this;
327}
328
329
330template <class T>
331constexpr VECTOR2<T>& VECTOR2<T>::operator+=( const VECTOR2<T>& aVector )
332{
333 x += aVector.x;
334 y += aVector.y;
335 return *this;
336}
337
338
339template <class T>
340constexpr VECTOR2<T>& VECTOR2<T>::operator*=( const VECTOR2<T>& aVector )
341{
342 x *= aVector.x;
343 y *= aVector.y;
344 return *this;
345}
346
347
348template <class T>
349constexpr VECTOR2<T>& VECTOR2<T>::operator*=( const T& aScalar )
350{
351 x *= aScalar;
352 y *= aScalar;
353 return *this;
354}
355
356
357template <class T>
358constexpr VECTOR2<T>& VECTOR2<T>::operator+=( const T& aScalar )
359{
360 x += aScalar;
361 y += aScalar;
362 return *this;
363}
364
365
366template <class T>
367constexpr VECTOR2<T>& VECTOR2<T>::operator-=( const VECTOR2<T>& aVector )
368{
369 x -= aVector.x;
370 y -= aVector.y;
371 return *this;
372}
373
374
375template <class T>
376constexpr VECTOR2<T>& VECTOR2<T>::operator-=( const T& aScalar )
377{
378 x -= aScalar;
379 y -= aScalar;
380 return *this;
381}
382
383
384template <class T>
385VECTOR2<T> VECTOR2<T>::Resize( T aNewLength ) const
386{
387 if( x == 0 && y == 0 )
388 return VECTOR2<T> ( 0, 0 );
389
390 double newX;
391 double newY;
392
393 if( std::abs( x ) == std::abs( y ) )
394 {
395 newX = newY = std::abs( aNewLength ) * M_SQRT1_2;
396 }
397 else
398 {
399 extended_type x_sq = (extended_type) x * x;
400 extended_type y_sq = (extended_type) y * y;
401 extended_type l_sq = x_sq + y_sq;
402 extended_type newLength_sq = (extended_type) aNewLength * aNewLength;
403 newX = std::sqrt( rescale( newLength_sq, x_sq, l_sq ) );
404 newY = std::sqrt( rescale( newLength_sq, y_sq, l_sq ) );
405 }
406
407 if( std::is_integral<T>::value )
408 {
409 return VECTOR2<T>( static_cast<T>( x < 0 ? -KiROUND( newX ) : KiROUND( newX ) ),
410 static_cast<T>( y < 0 ? -KiROUND( newY ) : KiROUND( newY ) ) )
411 * sign( aNewLength );
412 }
413 else
414 {
415 return VECTOR2<T>( static_cast<T>( x < 0 ? -newX : newX ),
416 static_cast<T>( y < 0 ? -newY : newY ) )
417 * sign( aNewLength );
418 }
419}
420
421
422template <class T>
423const std::string VECTOR2<T>::Format() const
424{
425 std::stringstream ss;
426
427 ss << "( xy " << x << " " << y << " )";
428
429 return ss.str();
430}
431
432
433template <class T>
434concept FloatingPoint = std::is_floating_point<T>::value;
435
436template <class T>
437concept Integral = std::is_integral<T>::value;
438
439
440template <class T, class U>
442 const VECTOR2<U>& aRHS )
443{
444 return VECTOR2<std::common_type_t<T, U>>( aLHS.x + aRHS.x, aLHS.y + aRHS.y );
445}
446
447
448template <FloatingPoint T, class U>
449constexpr VECTOR2<T> operator+( const VECTOR2<T>& aLHS, const U& aScalar )
450{
451 return VECTOR2<T>( aLHS.x + aScalar, aLHS.y + aScalar );
452}
453
454
455#ifndef SWIG
456template <Integral T, Integral U>
457constexpr VECTOR2<T> operator+( const VECTOR2<T>& aLHS, const U& aScalar )
458{
459 return VECTOR2<T>( aLHS.x + aScalar, aLHS.y + aScalar );
460}
461
462
463template <Integral T, FloatingPoint U>
464constexpr VECTOR2<T> operator+( const VECTOR2<T>& aLHS, const U& aScalar )
465{
466 return VECTOR2<T>( KiROUND( aLHS.x + aScalar ), KiROUND( aLHS.y + aScalar ) );
467}
468#endif
469
470
471template <class T, class U>
473 const VECTOR2<U>& aRHS )
474{
475 return VECTOR2<std::common_type_t<T, U>>( aLHS.x - aRHS.x, aLHS.y - aRHS.y );
476}
477
478
479template <FloatingPoint T, class U>
480constexpr VECTOR2<T> operator-( const VECTOR2<T>& aLHS, U aScalar )
481{
482 return VECTOR2<T>( aLHS.x - aScalar, aLHS.y - aScalar );
483}
484
485
486#ifndef SWIG
487template <Integral T, Integral U>
488constexpr VECTOR2<T> operator-( const VECTOR2<T>& aLHS, U aScalar )
489{
490 return VECTOR2<T>( aLHS.x - aScalar, aLHS.y - aScalar );
491}
492
493
494template <Integral T, FloatingPoint U>
495constexpr VECTOR2<T> operator-( const VECTOR2<T>& aLHS, const U& aScalar )
496{
497 return VECTOR2<T>( KiROUND( aLHS.x - aScalar ), KiROUND( aLHS.y - aScalar ) );
498}
499#endif
500
501
502template <class T>
504{
505 return VECTOR2<T> ( -x, -y );
506}
507
508
509template <class T, class U>
510#ifdef SWIG
511constexpr double operator*( const VECTOR2<T>& aLHS, const VECTOR2<U>& aRHS )
512#else
513constexpr auto operator*( const VECTOR2<T>& aLHS, const VECTOR2<U>& aRHS )
514#endif
515{
516 using extended_type = typename VECTOR2<std::common_type_t<T, U>>::extended_type;
517 return (extended_type)aLHS.x * aRHS.x + (extended_type)aLHS.y * aRHS.y;
518}
519
520
521template <class T, class U>
522constexpr VECTOR2<std::common_type_t<T, U>> operator*( const VECTOR2<T>& aLHS, const U& aScalar )
523{
524 return VECTOR2<std::common_type_t<T, U>>( aLHS.x * aScalar, aLHS.y * aScalar );
525}
526
527
528template <class T, class U>
529constexpr VECTOR2<std::common_type_t<T, U>> operator*( const T& aScalar, const VECTOR2<U>& aVector )
530{
531 return VECTOR2<std::common_type_t<T, U>>( aScalar * aVector.x, aScalar * aVector.y );
532}
533
534
535template <class T>
536constexpr VECTOR2<T> VECTOR2<T>::operator/( double aFactor ) const
537{
538 if( std::is_integral<T>::value )
539 return VECTOR2<T>( KiROUND( x / aFactor ), KiROUND( y / aFactor ) );
540 else
541 return VECTOR2<T>( static_cast<T>( x / aFactor ), static_cast<T>( y / aFactor ) );
542}
543
544
545template <class T>
546constexpr typename VECTOR2<T>::extended_type VECTOR2<T>::Cross( const VECTOR2<T>& aVector ) const
547{
548 return (extended_type) x * (extended_type) aVector.y -
549 (extended_type) y * (extended_type) aVector.x;
550}
551
552
553template <class T>
554constexpr typename VECTOR2<T>::extended_type VECTOR2<T>::Dot( const VECTOR2<T>& aVector ) const
555{
556 return (extended_type) x * (extended_type) aVector.x +
557 (extended_type) y * (extended_type) aVector.y;
558}
559
560template <class T>
561double VECTOR2<T>::Distance( const VECTOR2<extended_type>& aVector ) const
562{
563 VECTOR2<double> diff( static_cast<double>( aVector.x - x ), static_cast<double>( aVector.y - y ) );
564 return diff.EuclideanNorm();
565}
566
567template <class T>
568constexpr typename VECTOR2<T>::extended_type
570{
571 const extended_type dx = (extended_type) x - aVector.x;
572 const extended_type dy = (extended_type) y - aVector.y;
573 return dx * dx + dy * dy;
574}
575
576
577template <class T>
578constexpr bool VECTOR2<T>::operator<( const VECTOR2<T>& aVector ) const
579{
580 return ( *this * *this ) < ( aVector * aVector );
581}
582
583
584template <class T>
585constexpr bool VECTOR2<T>::operator<=( const VECTOR2<T>& aVector ) const
586{
587 return ( *this * *this ) <= ( aVector * aVector );
588}
589
590
591template <class T>
592constexpr bool VECTOR2<T>::operator>( const VECTOR2<T>& aVector ) const
593{
594 return ( *this * *this ) > ( aVector * aVector );
595}
596
597
598template <class T>
599constexpr bool VECTOR2<T>::operator>=( const VECTOR2<T>& aVector ) const
600{
601 return ( *this * *this ) >= ( aVector * aVector );
602}
603
604
605template <class T>
606constexpr bool VECTOR2<T>::operator==( VECTOR2<T> const& aVector ) const
607{
608 return ( aVector.x == x ) && ( aVector.y == y );
609}
610
611
612template <class T>
613constexpr bool VECTOR2<T>::operator!=( VECTOR2<T> const& aVector ) const
614{
615 return ( aVector.x != x ) || ( aVector.y != y );
616}
617
618
619template <class T>
620constexpr const VECTOR2<T>& LexicographicalMax( const VECTOR2<T>& aA, const VECTOR2<T>& aB )
621{
622 if( aA.x > aB.x )
623 return aA;
624 else if( aA.x == aB.x && aA.y > aB.y )
625 return aA;
626
627 return aB;
628}
629
630
631template <class T>
632constexpr const VECTOR2<T>& LexicographicalMin( const VECTOR2<T>& aA, const VECTOR2<T>& aB )
633{
634 if( aA.x < aB.x )
635 return aA;
636 else if( aA.x == aB.x && aA.y < aB.y )
637 return aA;
638
639 return aB;
640}
641
642
643template <class T>
644constexpr int LexicographicalCompare( const VECTOR2<T>& aA, const VECTOR2<T>& aB )
645{
646 if( aA.x < aB.x )
647 return -1;
648 else if( aA.x > aB.x )
649 return 1;
650 else // aA.x == aB.x
651 {
652 if( aA.y < aB.y )
653 return -1;
654 else if( aA.y > aB.y )
655 return 1;
656 else
657 return 0;
658 }
659}
660
661
672template <class T>
673typename std::enable_if<!std::numeric_limits<T>::is_integer, bool>::type
674equals( VECTOR2<T> const& aFirst, VECTOR2<T> const& aSecond,
675 T aEpsilon = std::numeric_limits<T>::epsilon() )
676{
677 if( !equals( aFirst.x, aSecond.x, aEpsilon ) )
678 {
679 return false;
680 }
681
682 return equals( aFirst.y, aSecond.y, aEpsilon );
683}
684
685
686template <class T>
687std::ostream& operator<<( std::ostream& aStream, const VECTOR2<T>& aVector )
688{
689 aStream << "[ " << aVector.x << " | " << aVector.y << " ]";
690 return aStream;
691}
692
693/* Default specializations */
697
698/* KiROUND specialization for vectors */
699inline constexpr VECTOR2I KiROUND( const VECTOR2D& vec )
700{
701 return VECTOR2I( KiROUND( vec.x ), KiROUND( vec.y ) );
702}
703
704/* STL specializations */
705namespace std
706{
707 // Required to enable correct use in std::map/unordered_map
708 // DO NOT USE hash tables with VECTOR2 elements. It is inefficient
709 // and degenerates to a linear search. Use the std::map/std::set
710 // trees instead that utilize the less operator below
711 // This function is purposely deleted after substantial testing
712 template <>
713 struct hash<VECTOR2I>
714 {
715 size_t operator()( const VECTOR2I& k ) const = delete;
716 };
717
718 // Required to enable use of std::hash with maps.
719 template <>
720 struct less<VECTOR2I>
721 {
722 bool operator()( const VECTOR2I& aA, const VECTOR2I& aB ) const;
723 };
724}
725
726#endif // VECTOR2D_H_
Define a general 2D-vector/point.
Definition: vector2d.h:71
constexpr bool operator==(const VECTOR2< T > &aVector) const
Equality operator.
Definition: vector2d.h:606
constexpr bool operator>=(const VECTOR2< T > &aVector) const
Definition: vector2d.h:599
constexpr VECTOR2< U > operator()() const
Cast a vector to another specialized subclass. Beware of rounding issues.
Definition: vector2d.h:128
constexpr VECTOR2< T > & operator=(const VECTOR2< T > &aVector)
Assignment operator.
Definition: vector2d.h:322
constexpr extended_type Cross(const VECTOR2< T > &aVector) const
Compute cross product of self with aVector.
Definition: vector2d.h:546
double Distance(const VECTOR2< extended_type > &aVector) const
Compute the distance between two vectors.
Definition: vector2d.h:561
constexpr extended_type SquaredEuclideanNorm() const
Compute the squared euclidean norm of the vector, which is defined as (x ** 2 + y ** 2).
Definition: vector2d.h:307
constexpr extended_type SquaredDistance(const VECTOR2< T > &aVector) const
Compute the squared distance between two vectors.
Definition: vector2d.h:569
const std::string Format() const
Return the vector formatted as a string.
Definition: vector2d.h:423
constexpr VECTOR2< T > & operator*=(const VECTOR2< T > &aVector)
Compound assignment operator.
Definition: vector2d.h:340
static constexpr extended_type ECOORD_MAX
Definition: vector2d.h:76
constexpr VECTOR2< T > & operator-=(const T &aScalar)
Compound assignment operator.
Definition: vector2d.h:376
constexpr VECTOR2< T > & operator+=(const T &aScalar)
Compound assignment operator.
Definition: vector2d.h:358
constexpr bool operator!=(const VECTOR2< T > &aVector) const
Not equality operator.
Definition: vector2d.h:613
constexpr VECTOR2< T > & operator-=(const VECTOR2< T > &aVector)
Compound assignment operator.
Definition: vector2d.h:367
constexpr bool operator<(const VECTOR2< T > &aVector) const
Smaller than operator.
Definition: vector2d.h:578
constexpr VECTOR2< T > operator-()
Negate Vector operator.
Definition: vector2d.h:503
T EuclideanNorm() const
Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
Definition: vector2d.h:283
VECTOR2_TRAITS< T >::extended_type extended_type
Definition: vector2d.h:73
constexpr VECTOR2< T > operator/(double aFactor) const
Division with a factor.
Definition: vector2d.h:536
constexpr VECTOR2(const VECTOR2< CastingType > &aVec)
Initializes a vector from another specialization. Beware of rounding issues.
Definition: vector2d.h:89
constexpr VECTOR2< T > Perpendicular() const
Compute the perpendicular vector.
Definition: vector2d.h:314
static constexpr extended_type ECOORD_MIN
Definition: vector2d.h:77
constexpr VECTOR2(const VECTOR2< T > &aVec)
Copy a vector.
Definition: vector2d.h:120
constexpr extended_type Dot(const VECTOR2< T > &aVector) const
Compute dot product of self with aVector.
Definition: vector2d.h:554
constexpr VECTOR2(T x, T y)
Construct a vector with given components x, y.
Definition: vector2d.h:275
constexpr VECTOR2< T > & operator*=(const T &aScalar)
Definition: vector2d.h:349
constexpr bool operator<=(const VECTOR2< T > &aVector) const
Definition: vector2d.h:585
constexpr VECTOR2()
Construct a 2D-vector with x, y = 0.
Definition: vector2d.h:269
VECTOR2< T > Resize(T aNewLength) const
Return a vector of the same direction, but length specified in aNewLength.
Definition: vector2d.h:385
constexpr VECTOR2< T > & operator+=(const VECTOR2< T > &aVector)
Compound assignment operator.
Definition: vector2d.h:331
T coord_type
Definition: vector2d.h:74
constexpr bool operator>(const VECTOR2< T > &aVector) const
Greater than operator.
Definition: vector2d.h:592
std::ostream & operator<<(std::ostream &aStream, const EDA_TEXT &aText)
Definition: eda_text.cpp:1311
STL namespace.
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition: eda_angle.h:390
int64_t extended_type
Definition: vector2d.h:53
Traits class for VECTOR2.
Definition: vector2d.h:44
T extended_type
extended range/precision types used by operations involving multiple multiplications to prevent overf...
Definition: vector2d.h:47
size_t operator()(const VECTOR2I &k) const =delete
constexpr int sign(T val)
Definition: util.h:159
T rescale(T aNumerator, T aValue, T aDenominator)
Scale a number (value) by rational (numerator/denominator).
Definition: util.h:153
VECTOR2< int32_t > VECTOR2I
Definition: vector2d.h:695
VECTOR2< double > VECTOR2D
Definition: vector2d.h:694
constexpr const VECTOR2< T > & LexicographicalMax(const VECTOR2< T > &aA, const VECTOR2< T > &aB)
Definition: vector2d.h:620
constexpr VECTOR2I KiROUND(const VECTOR2D &vec)
Definition: vector2d.h:699
constexpr VECTOR2< std::common_type_t< T, U > > operator+(const VECTOR2< T > &aLHS, const VECTOR2< U > &aRHS)
Definition: vector2d.h:441
constexpr VECTOR2< std::common_type_t< T, U > > operator-(const VECTOR2< T > &aLHS, const VECTOR2< U > &aRHS)
Definition: vector2d.h:472
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:674
constexpr const VECTOR2< T > & LexicographicalMin(const VECTOR2< T > &aA, const VECTOR2< T > &aB)
Definition: vector2d.h:632
VECTOR2< int64_t > VECTOR2L
Definition: vector2d.h:696
constexpr auto operator*(const VECTOR2< T > &aLHS, const VECTOR2< U > &aRHS)
Definition: vector2d.h:513
constexpr int LexicographicalCompare(const VECTOR2< T > &aA, const VECTOR2< T > &aB)
Definition: vector2d.h:644