diff --git a/include/math/vector2d.h b/include/math/vector2d.h index a5eaa604e0..8c09602c60 100644 --- a/include/math/vector2d.h +++ b/include/math/vector2d.h @@ -54,6 +54,8 @@ template <> struct VECTOR2_TRAITS { typedef int64_t extended_type; + static const extended_type ECOORD_MAX = 0x7fffffffffffffffULL; + static const extended_type ECOORD_MIN = 0x8000000000000000ULL; }; // Forward declarations for template friends @@ -123,6 +125,15 @@ public: */ T EuclideanNorm() const; + /** + * Function Squared Euclidean Norm + * computes the squared euclidean norm of the vector, which is defined as (x ** 2 + y ** 2). + * It is used to calculate the length of the vector. + * @return Scalar, the euclidean norm + */ + extended_type SquaredEuclideanNorm() const; + + /** * Function Perpendicular * computes the perpendicular vector @@ -130,40 +141,6 @@ public: */ VECTOR2 Perpendicular() const; - /** - * Function LineProjection - * computes the perpendicular projection point of self on a line - * going through aA and aB points. - * @return Projected point - */ - VECTOR2 LineProjection( const VECTOR2& aA, const VECTOR2& aB ) const; - - /** - * Function LineSide - * determines on which side of directed line passing via points aEnd - * and a start aStart we are. - * @return: < 0: left, 0 : on the line, > 0 : right - */ - int LineSide( const VECTOR2& aStart, const VECTOR2& aEnd ) const; - - /** - * Function LineDistance - * returns the closest Euclidean distance to a line defined by points - * aStart and aEnd. - * @param aDetermineSide: when true, the sign of the returned value indicates - * the side of the line at which we are (negative = left) - * @return the distance - */ - T LineDistance( const VECTOR2& aStart, const VECTOR2& aEnd, - bool aDetermineSide = false ) const; - - /** - * Function ClosestSegmentPoint - * returns the closest point on a line segment defined by aStart and aEnd. - * @return: our point - */ - VECTOR2 ClosestSegmentPoint( const VECTOR2& aStart, const VECTOR2& aEnd ) const; - /** * Function Resize * returns a vector of the same direction, but length specified in aNewLength @@ -308,6 +285,13 @@ T VECTOR2::EuclideanNorm() const return sqrt( (extended_type) x * x + (extended_type) y * y ); } +template +typename VECTOR2::extended_type VECTOR2::SquaredEuclideanNorm() const +{ + return (extended_type)x * x + (extended_type) y * y ; +} + + template double VECTOR2::Angle() const @@ -367,89 +351,6 @@ VECTOR2& VECTOR2::operator-=( const T& aScalar ) y -= aScalar; return *this; } - - -template -int VECTOR2::LineSide( const VECTOR2& aStart, const VECTOR2& aEnd ) const -{ - VECTOR2 d = aEnd - aStart; - VECTOR2 ap = *this - aStart; - - extended_type det = (extended_type) d.x * (extended_type) ap.y - - (extended_type) d.y * (extended_type) ap.x; - - return det < 0 ? -1 : (det > 0 ? 1 : 0); -} - - -template -VECTOR2 VECTOR2::LineProjection( const VECTOR2& aA, const VECTOR2& aB ) const -{ - const VECTOR2 d = aB - aA; - extended_type det = (extended_type) d.x * d.x + d.y * (extended_type) d.y; - extended_type dxdy = (extended_type) d.x * d.y; - extended_type qx = - ( (extended_type) aA.x * d.y * d.y + (extended_type) d.x * d.x * x - dxdy * - (aA.y - y) ) / det; - extended_type qy = - ( (extended_type) aA.y * d.x * d.x + (extended_type) d.y * d.y * y - dxdy * - (aA.x - x) ) / det; - - return VECTOR2 ( (T) qx, (T) qy ); -} - - -template -T VECTOR2::LineDistance( const VECTOR2& aStart, const VECTOR2& aEnd, - bool aDetermineSide ) const -{ - extended_type a = aStart.y - aEnd.y; - extended_type b = aEnd.x - aStart.x; - extended_type c = -a * aStart.x - b * aStart.y; - - T dist = ( a * x + b * y + c ) / sqrt( a * a + b * b ); - return aDetermineSide ? dist : abs( dist ); -} - - -template -VECTOR2 VECTOR2::ClosestSegmentPoint( const VECTOR2& aStart, - const VECTOR2& aEnd ) const -{ - VECTOR2 d = (aEnd - aStart); - extended_type l_squared = (extended_type) d.x * d.x + (extended_type) d.y * d.y; - - - if( l_squared == 0 ) - { - return aStart; - } - - extended_type t = - (extended_type) (x - aStart.x) * (extended_type) d.x + - (extended_type) (y - aStart.y) * (extended_type) d.y; - - if( t < 0 ) - { - return aStart; - } - else if( t > l_squared ) - { - return aEnd; - } - - double xp = (double) t * (double) d.x / (double) l_squared; - double yp = (double) t * (double) d.y / (double) l_squared; - - /*VECTOR2 proj = aStart + VECTOR2 ( ( t * (extended_type) d.x / l_squared ), - ( t * ( extended_type) d.y / l_squared ) );*/ - - VECTOR2 proj = aStart + VECTOR2 ( (T) xp, (T) yp ); - - return proj; -} - - template VECTOR2 VECTOR2::Rotate( double aAngle ) const { @@ -464,14 +365,15 @@ VECTOR2 VECTOR2::Rotate( double aAngle ) const template VECTOR2 VECTOR2::Resize( T aNewLength ) const { - if( x == 0 && y == 0 ) - return VECTOR2 ( 0, 0 ); + if(x == 0 && y == 0) + return VECTOR2 (0, 0); - T l = this->EuclideanNorm(); + extended_type l_sq_current = (extended_type)this->x * this->x + (extended_type)this->y * this->y; + extended_type l_sq_new = (extended_type) aNewLength * aNewLength; - return VECTOR2 ( - rescale( aNewLength, x, l ), - rescale( aNewLength, y, l ) ); + return VECTOR2 ( + (this->x < 0 ? -1 : 1 ) * sqrt(rescale(l_sq_new, (extended_type) x * x, l_sq_current)), + (this->y < 0 ? -1 : 1 ) * sqrt(rescale(l_sq_new, (extended_type) y * y, l_sq_current))); }