Fix rounding issues
Rescaling and rotating has been leaving 1nm errors due to integer truncation in VECTOR2I. This rounds integers using KiROUND before returning
This commit is contained in:
parent
4f6134b60d
commit
b2cfd7f479
|
@ -31,6 +31,7 @@
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
#include <math/util.h>
|
#include <math/util.h>
|
||||||
|
|
||||||
|
@ -376,15 +377,33 @@ VECTOR2<T>& VECTOR2<T>::operator-=( const T& aScalar )
|
||||||
template <class T>
|
template <class T>
|
||||||
VECTOR2<T> VECTOR2<T>::Rotate( double aAngle ) const
|
VECTOR2<T> VECTOR2<T>::Rotate( double aAngle ) const
|
||||||
{
|
{
|
||||||
// Avoid 0 radian rotation, case very frequently found
|
// Avoid common radian rotations that may allow for angular error
|
||||||
if( aAngle == 0.0 )
|
if( aAngle == 0.0 || aAngle == 2 * M_PI )
|
||||||
return VECTOR2<T> ( T( x ), T( y ) );
|
return VECTOR2<T> ( T( x ), T( y ) );
|
||||||
|
|
||||||
|
if( aAngle == M_PI_2 )
|
||||||
|
return VECTOR2<T>( -T( y ), T( x ) );
|
||||||
|
|
||||||
|
if( aAngle == M_PI )
|
||||||
|
return VECTOR2<T>( -T(x), -T( y ) );
|
||||||
|
|
||||||
|
if( aAngle == 3 * M_PI_2 )
|
||||||
|
return VECTOR2<T>( T( y ), -T( x ) );
|
||||||
|
|
||||||
double sa = sin( aAngle );
|
double sa = sin( aAngle );
|
||||||
double ca = cos( aAngle );
|
double ca = cos( aAngle );
|
||||||
|
|
||||||
return VECTOR2<T> ( T( (double) x * ca - (double) y * sa ),
|
if( std::is_integral<T>::value )
|
||||||
T( (double) x * sa + (double) y * ca ) );
|
{
|
||||||
|
return VECTOR2<T> ( KiROUND( (double) x * ca - (double) y * sa ),
|
||||||
|
KiROUND( (double) x * sa + (double) y * ca ) );
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return VECTOR2<T> ( T( (double) x * ca - (double) y * sa ),
|
||||||
|
T( (double) x * sa + (double) y * ca ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -397,9 +416,24 @@ VECTOR2<T> VECTOR2<T>::Resize( T aNewLength ) const
|
||||||
extended_type l_sq_current = (extended_type) x * x + (extended_type) y * y;
|
extended_type l_sq_current = (extended_type) x * x + (extended_type) y * y;
|
||||||
extended_type l_sq_new = (extended_type) aNewLength * aNewLength;
|
extended_type l_sq_new = (extended_type) aNewLength * aNewLength;
|
||||||
|
|
||||||
return VECTOR2<T> (
|
if( std::is_integral<T>::value )
|
||||||
( x < 0 ? -1 : 1 ) * sqrt( rescale( l_sq_new, (extended_type) x * x, l_sq_current ) ),
|
{
|
||||||
( y < 0 ? -1 : 1 ) * sqrt( rescale( l_sq_new, (extended_type) y * y, l_sq_current ) ) ) * sign( aNewLength );
|
return VECTOR2<T> (
|
||||||
|
( x < 0 ? -1 : 1 ) *
|
||||||
|
KiROUND( std::sqrt( rescale( l_sq_new, (extended_type) x * x, l_sq_current ) ) ),
|
||||||
|
( y < 0 ? -1 : 1 ) *
|
||||||
|
KiROUND( std::sqrt( rescale( l_sq_new, (extended_type) y * y, l_sq_current ) ) )
|
||||||
|
* sign( aNewLength ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return VECTOR2<T> (
|
||||||
|
( x < 0 ? -1 : 1 ) *
|
||||||
|
std::sqrt( rescale( l_sq_new, (extended_type) x * x, l_sq_current ) ),
|
||||||
|
( y < 0 ? -1 : 1 ) *
|
||||||
|
std::sqrt( rescale( l_sq_new, (extended_type) y * y, l_sq_current ) ) )
|
||||||
|
* sign( aNewLength );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -467,7 +501,7 @@ VECTOR2<T> VECTOR2<T>::operator*( const T& aFactor ) const
|
||||||
template <class T>
|
template <class T>
|
||||||
VECTOR2<T> VECTOR2<T>::operator/( const T& aFactor ) const
|
VECTOR2<T> VECTOR2<T>::operator/( const T& aFactor ) const
|
||||||
{
|
{
|
||||||
VECTOR2<T> vector( x / aFactor, y / aFactor );
|
VECTOR2<T> vector( KiROUND( x / aFactor ), KiROUND( y / aFactor ) );
|
||||||
return vector;
|
return vector;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue