69template <
class T =
int>
88 template <
typename CastingType>
91 if( std::is_floating_point<T>() )
93 x =
static_cast<T
>( aVec.
x );
94 y =
static_cast<T
>( aVec.
y );
96 else if( std::is_floating_point<CastingType>() )
98 CastingType minI =
static_cast<CastingType
>( std::numeric_limits<T>::min() );
99 CastingType maxI =
static_cast<CastingType
>( std::numeric_limits<T>::max() );
101 x =
static_cast<T
>( std::clamp( aVec.
x, minI, maxI ) );
102 y =
static_cast<T
>( std::clamp( aVec.
y, minI, maxI ) );
104 else if( std::is_integral<T>() && std::is_integral<CastingType>() )
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() );
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 ) );
114 x =
static_cast<T
>( aVec.
x );
115 y =
static_cast<T
>( aVec.
y );
127 template <
typename U>
130 if( std::is_floating_point<U>::value )
132 return VECTOR2<U>(
static_cast<U
>(
x ),
static_cast<U
>(
y ) );
134 else if( std::is_floating_point<T>() )
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 ) ) );
141 else if( std::is_integral<T>() && std::is_integral<U>() )
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 );
149 static_cast<U
>( std::clamp( x64, minI, maxI ) ),
150 static_cast<U
>( std::clamp( y64, minI, maxI ) ) );
154 return VECTOR2<U>(
static_cast<U
>(
x ),
static_cast<U
>(
y ) );
288 if( std::is_integral<T>::value )
289 return KiROUND<double, T>(
std::abs( x ) * M_SQRT2 );
291 return static_cast<T
>(
std::abs( x ) * M_SQRT2 );
295 return static_cast<T
>(
std::abs( y ) );
297 return static_cast<T
>(
std::abs( x ) );
299 if( std::is_integral<T>::value )
300 return KiROUND<double, T>( std::hypot( x, y ) );
302 return static_cast<T
>( std::hypot( x, y ) );
317 return perpendicular;
387 if( x == 0 && y == 0 )
395 newX = newY =
std::abs( aNewLength ) * M_SQRT1_2;
403 newX = std::sqrt(
rescale( newLength_sq, x_sq, l_sq ) );
404 newY = std::sqrt(
rescale( newLength_sq, y_sq, l_sq ) );
407 if( std::is_integral<T>::value )
411 *
sign( aNewLength );
415 return VECTOR2<T>(
static_cast<T
>( x < 0 ? -newX : newX ),
416 static_cast<T
>( y < 0 ? -newY : newY ) )
417 *
sign( aNewLength );
425 std::stringstream ss;
427 ss <<
"( xy " << x <<
" " << y <<
" )";
440template <
class T,
class U>
448template <FloatingPo
int T,
class U>
451 return VECTOR2<T>( aLHS.
x + aScalar, aLHS.
y + aScalar );
455template <Integral T, Integral U>
458 return VECTOR2<T>( aLHS.
x + aScalar, aLHS.
y + aScalar );
462template <Integral T, FloatingPo
int U>
469template <
class T,
class U>
477template <FloatingPo
int T,
class U>
480 return VECTOR2<T>( aLHS.
x - aScalar, aLHS.
y - aScalar );
484template <Integral T, Integral U>
487 return VECTOR2<T>( aLHS.
x - aScalar, aLHS.
y - aScalar );
491template <Integral T, FloatingPo
int U>
505template <
class T,
class U>
513 return (extended_type)aLHS.
x * aRHS.
x + (extended_type)aLHS.
y * aRHS.
y;
517template <
class T,
class U>
524template <
class T,
class U>
534 if( std::is_integral<T>::value )
537 return VECTOR2<T>(
static_cast<T
>( x / aFactor ),
static_cast<T
>( y / aFactor ) );
559 VECTOR2<double> diff(
static_cast<double>( aVector.
x - x ),
static_cast<double>( aVector.
y - y ) );
569 return dx * dx + dy * dy;
576 return ( *
this * *
this ) < ( aVector * aVector );
583 return ( *
this * *
this ) <= ( aVector * aVector );
590 return ( *
this * *
this ) > ( aVector * aVector );
597 return ( *
this * *
this ) >= ( aVector * aVector );
604 return ( aVector.
x == x ) && ( aVector.
y == y );
611 return ( aVector.
x != x ) || ( aVector.
y != y );
620 else if( aA.
x == aB.
x && aA.
y > aB.
y )
632 else if( aA.
x == aB.
x && aA.
y < aB.
y )
644 else if( aA.
x > aB.
x )
650 else if( aA.
y > aB.
y )
669typename std::enable_if<!std::numeric_limits<T>::is_integer,
bool>::type
671 T aEpsilon = std::numeric_limits<T>::epsilon() )
673 if( !
equals( aFirst.
x, aSecond.
x, aEpsilon ) )
678 return equals( aFirst.
y, aSecond.
y, aEpsilon );
685 aStream <<
"[ " << aVector.
x <<
" | " << aVector.
y <<
" ]";
Define a general 2D-vector/point.
constexpr bool operator==(const VECTOR2< T > &aVector) const
Equality operator.
constexpr bool operator>=(const VECTOR2< T > &aVector) const
constexpr VECTOR2< U > operator()() const
Cast a vector to another specialized subclass. Beware of rounding issues.
constexpr VECTOR2< T > & operator=(const VECTOR2< T > &aVector)
Assignment operator.
constexpr extended_type Cross(const VECTOR2< T > &aVector) const
Compute cross product of self with aVector.
double Distance(const VECTOR2< extended_type > &aVector) const
Compute the distance between two vectors.
constexpr extended_type SquaredEuclideanNorm() const
Compute the squared euclidean norm of the vector, which is defined as (x ** 2 + y ** 2).
constexpr extended_type SquaredDistance(const VECTOR2< T > &aVector) const
Compute the squared distance between two vectors.
const std::string Format() const
Return the vector formatted as a string.
constexpr VECTOR2< T > & operator*=(const VECTOR2< T > &aVector)
Compound assignment operator.
static constexpr extended_type ECOORD_MAX
constexpr VECTOR2< T > & operator-=(const T &aScalar)
Compound assignment operator.
constexpr VECTOR2< T > & operator+=(const T &aScalar)
Compound assignment operator.
constexpr bool operator!=(const VECTOR2< T > &aVector) const
Not equality operator.
constexpr VECTOR2< T > & operator-=(const VECTOR2< T > &aVector)
Compound assignment operator.
constexpr bool operator<(const VECTOR2< T > &aVector) const
Smaller than operator.
constexpr VECTOR2< T > operator-()
Negate Vector operator.
T EuclideanNorm() const
Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
VECTOR2_TRAITS< T >::extended_type extended_type
constexpr VECTOR2< T > operator/(double aFactor) const
Division with a factor.
constexpr VECTOR2(const VECTOR2< CastingType > &aVec)
Initializes a vector from another specialization. Beware of rounding issues.
constexpr VECTOR2< T > Perpendicular() const
Compute the perpendicular vector.
static constexpr extended_type ECOORD_MIN
constexpr VECTOR2(const VECTOR2< T > &aVec)
Copy a vector.
constexpr extended_type Dot(const VECTOR2< T > &aVector) const
Compute dot product of self with aVector.
constexpr VECTOR2(T x, T y)
Construct a vector with given components x, y.
constexpr VECTOR2< T > & operator*=(const T &aScalar)
constexpr bool operator<=(const VECTOR2< T > &aVector) const
constexpr VECTOR2()
Construct a 2D-vector with x, y = 0.
VECTOR2< T > Resize(T aNewLength) const
Return a vector of the same direction, but length specified in aNewLength.
constexpr VECTOR2< T > & operator+=(const VECTOR2< T > &aVector)
Compound assignment operator.
constexpr bool operator>(const VECTOR2< T > &aVector) const
Greater than operator.
std::ostream & operator<<(std::ostream &aStream, const EDA_TEXT &aText)
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Traits class for VECTOR2.
T extended_type
extended range/precision types used by operations involving multiple multiplications to prevent overf...
size_t operator()(const VECTOR2I &k) const =delete
constexpr int sign(T val)
T rescale(T aNumerator, T aValue, T aDenominator)
Scale a number (value) by rational (numerator/denominator).
VECTOR2< int32_t > VECTOR2I
VECTOR2< double > VECTOR2D
constexpr const VECTOR2< T > & LexicographicalMax(const VECTOR2< T > &aA, const VECTOR2< T > &aB)
constexpr VECTOR2I KiROUND(const VECTOR2D &vec)
constexpr VECTOR2< std::common_type_t< T, U > > operator+(const VECTOR2< T > &aLHS, const VECTOR2< U > &aRHS)
constexpr VECTOR2< std::common_type_t< T, U > > operator-(const VECTOR2< T > &aLHS, const VECTOR2< U > &aRHS)
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.
constexpr const VECTOR2< T > & LexicographicalMin(const VECTOR2< T > &aA, const VECTOR2< T > &aB)
VECTOR2< int64_t > VECTOR2L
constexpr auto operator*(const VECTOR2< T > &aLHS, const VECTOR2< U > &aRHS)
constexpr int LexicographicalCompare(const VECTOR2< T > &aA, const VECTOR2< T > &aB)