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 <iostream>
|
||||
#include <sstream>
|
||||
#include <type_traits>
|
||||
|
||||
#include <math/util.h>
|
||||
|
||||
|
@ -376,15 +377,33 @@ VECTOR2<T>& VECTOR2<T>::operator-=( const T& aScalar )
|
|||
template <class T>
|
||||
VECTOR2<T> VECTOR2<T>::Rotate( double aAngle ) const
|
||||
{
|
||||
// Avoid 0 radian rotation, case very frequently found
|
||||
if( aAngle == 0.0 )
|
||||
// Avoid common radian rotations that may allow for angular error
|
||||
if( aAngle == 0.0 || aAngle == 2 * M_PI )
|
||||
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 ca = cos( aAngle );
|
||||
|
||||
return VECTOR2<T> ( T( (double) x * ca - (double) y * sa ),
|
||||
T( (double) x * sa + (double) y * ca ) );
|
||||
if( std::is_integral<T>::value )
|
||||
{
|
||||
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_new = (extended_type) aNewLength * aNewLength;
|
||||
|
||||
return VECTOR2<T> (
|
||||
( 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 );
|
||||
if( std::is_integral<T>::value )
|
||||
{
|
||||
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>
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue