Thursday, December 22, 2016

Flaw in VelocityTracker changes to a diagonal.

Velocity is the direction and speed of an object. Changing the direction because of the maximum velocity was reached must be considered a defect. This also clearly causes a flaw in that a diagonal velocity is faster than the orthogonal one.

The problematic bit of code akin to:
mXVelocity = accumX < 0.0f ? Math.max(accumX, -maxVelocity) : Math.min(accumX, maxVelocity);
mYVelocity = accumY < 0.0f ? Math.max(accumY, -maxVelocity) : Math.min(accumY, maxVelocity);

The flaw here is that if your velocity in the X direction exceeds the maxVelocity it is changed equal maxVelocity and the same for the Y. But, that means that if we are going at 20° angle and at a speed of 200, and our maxVelocity is 20. Our velocity is changed to be 20*sqrt(2) at a 45° angle. The correct answer is to scale the mXVelocity and mYVeloicity by the ratio of the actual velocity and maxVelocity.

mXVelocity = accumX;
mYVelocity = accumY;
double actualVelocitySq = mXVelocity * mXVelocity + mYVelocity * mYVelocity;
double maxSpeedSq = maxVelocity * maxVelocity;
if (actualVelocitySq > maxSpeedSq) {
    double excessFactor = Math.sqrt(maxSpeedSq)/Math.sqrt(actualVelocitySq);
    mXVelocity *= excessFactor;
    mYVelocity *= excessFactor;
}