fix mutually canceling orbits
This commit is contained in:
@@ -18,24 +18,32 @@ namespace OrbitMath
|
||||
constexpr float kOrbitLeadAngle_rad = 0.6f;
|
||||
|
||||
// Returns the orbit sense (+1 counter-clockwise, -1 clockwise) that matches
|
||||
// the ship's current movement around `center`, so steering reinforces the
|
||||
// motion the ship already has. When the velocity is nearly radial or near
|
||||
// zero (e.g. a head-on approach or a freshly spawned ship) the sense is
|
||||
// the ship's movement around `center`, so steering reinforces the motion the
|
||||
// ship already has. The sense is taken from the ship's velocity *relative to
|
||||
// the center* (`centerVelocity`): for a moving target this both removes the
|
||||
// target's own motion from the decision and dissolves the degenerate case
|
||||
// where two ships orbiting each other translate in a straight line — there
|
||||
// their shared velocity cancels, leaving ~zero relative velocity. When the
|
||||
// relative velocity is nearly radial or near zero (a head-on approach, a
|
||||
// freshly spawned ship, or that mutual-translation case) the sense is
|
||||
// ill-defined; this is an unstable point the ship leaves within a tick or
|
||||
// two, so a deterministic fallback of +1 is returned.
|
||||
inline float resolveOrbitSign(const QVector2D& shipPos, const QVector2D& center,
|
||||
const QVector2D& velocity)
|
||||
const QVector2D& velocity,
|
||||
const QVector2D& centerVelocity = QVector2D())
|
||||
{
|
||||
const QVector2D radial = shipPos - center;
|
||||
const QVector2D relativeVelocity = velocity - centerVelocity;
|
||||
const float radialLength = radial.length();
|
||||
const float velocityLength = velocity.length();
|
||||
const float velocityLength = relativeVelocity.length();
|
||||
if (radialLength < 1.0e-4f || velocityLength < 1.0e-4f)
|
||||
{
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
// z-component of radial x velocity, normalised to sin(angle) between them.
|
||||
const float cross = radial.x() * velocity.y() - radial.y() * velocity.x();
|
||||
// z-component of radial x relativeVelocity, normalised to sin(angle).
|
||||
const float cross = radial.x() * relativeVelocity.y()
|
||||
- radial.y() * relativeVelocity.x();
|
||||
const float sinAngle = cross / (radialLength * velocityLength);
|
||||
|
||||
constexpr float kRadialEpsilon = 1.0e-3f;
|
||||
|
||||
Reference in New Issue
Block a user