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;

}