diff --git a/source/maths/FixedVector2D.h b/source/maths/FixedVector2D.h index 87c8fd4916..100c42597e 100644 --- a/source/maths/FixedVector2D.h +++ b/source/maths/FixedVector2D.h @@ -204,6 +204,7 @@ public: /** * Compute the dot product of this vector with another. + * Likely to overflow if both vectors are large-ish (around the 200 range). */ fixed Dot(const CFixedVector2D& v) const { @@ -219,6 +220,16 @@ public: return ret; } + /** + * @return -1, 0 or 1 if this and @v face respectively opposite directions, perpendicular, or same directions. + */ + int RelativeOrientation(const CFixedVector2D& v) const + { + i64 x = MUL_I64_I32_I32(X.GetInternalValue(), v.X.GetInternalValue()); + i64 y = MUL_I64_I32_I32(Y.GetInternalValue(), v.Y.GetInternalValue()); + return x > -y ? 1 : x < -y ? -1 : 0; + } + CFixedVector2D Perpendicular() const { return CFixedVector2D(Y, -X); diff --git a/source/simulation2/components/CCmpUnitMotion.cpp b/source/simulation2/components/CCmpUnitMotion.cpp index 92722eead2..b8635700fe 100644 --- a/source/simulation2/components/CCmpUnitMotion.cpp +++ b/source/simulation2/components/CCmpUnitMotion.cpp @@ -1149,7 +1149,7 @@ bool CCmpUnitMotion::ComputeTargetPosition(CFixedVector2D& out, const MoveReques // Check if we anticipate the target to go through us, in which case we shouldn't anticipate // (or e.g. units fleeing might suddenly turn around towards their attacker). - if ((out - cmpPosition->GetPosition2D()).Dot(tempPos - cmpPosition->GetPosition2D()) >= fixed::Zero()) + if ((out - cmpPosition->GetPosition2D()).RelativeOrientation(tempPos - cmpPosition->GetPosition2D()) >= 0) out = tempPos; } } diff --git a/source/simulation2/helpers/Geometry.cpp b/source/simulation2/helpers/Geometry.cpp index f7563969ad..4be531c8ce 100644 --- a/source/simulation2/helpers/Geometry.cpp +++ b/source/simulation2/helpers/Geometry.cpp @@ -342,13 +342,13 @@ static bool SquareSAT(const CFixedVector2D& a, const CFixedVector2D& axis, const fixed hh = halfSize.Y; CFixedVector2D p = axis.Perpendicular(); - if (p.Dot((u.Multiply(hw) + v.Multiply(hh)) - a) <= fixed::Zero()) + if (p.RelativeOrientation(u.Multiply(hw) + v.Multiply(hh) - a) <= 0) return true; - if (p.Dot((u.Multiply(hw) - v.Multiply(hh)) - a) <= fixed::Zero()) + if (p.RelativeOrientation(u.Multiply(hw) - v.Multiply(hh) - a) <= 0) return true; - if (p.Dot((-u.Multiply(hw) - v.Multiply(hh)) - a) <= fixed::Zero()) + if (p.RelativeOrientation(-u.Multiply(hw) - v.Multiply(hh) - a) <= 0) return true; - if (p.Dot((-u.Multiply(hw) + v.Multiply(hh)) - a) <= fixed::Zero()) + if (p.RelativeOrientation(-u.Multiply(hw) + v.Multiply(hh) - a) <= 0) return true; return false;