Недостаток здесь в классе Android VelocityTracker
: если ваша скорость в направлении X превышает максимальную частоту, она изменяется равной maxVelocity и то же самое для Y. Но это означает, что если мы идем под углом 20 ° и со скоростью 200, а наша максимальная частота равна 20. Наша скорость изменяется на 20 * sqrt (2) под углом 45 °. Правильный ответ заключается в масштабировании mXVelocity и mYVeloicity соотношением фактической скорости и maxVelocity.Выше maxVelocity меняет направление на диагональ, обходное решение
Мой вопрос: мне нужно прибегнуть к двум квадратным корням, чтобы исправить эту ошибку?
Скорость - это направление и скорость объекта. Изменение направления из-за достижения максимальной скорости должно считаться дефектом. Это также явно вызывает недостаток в том, что диагональная скорость быстрее ортогональной.
Проблематика бит кода сродни:
mXVelocity = accumX < 0.0f ? Math.max(accumX, -maxVelocity) : Math.min(accumX, maxVelocity);
mYVelocity = accumY < 0.0f ? Math.max(accumY, -maxVelocity) : Math.min(accumY, maxVelocity);
Чтобы обойти эту проблему я использую:
tracker.computeCurrentVelocity(units); //maxVelocity
double velocityX = tracker.getXVelocity();
double velocityY = tracker.getYVelocity();
double actualVelocitySq = velocityX * velocityX + velocityY * velocityY;
double maxVelocitySq = maxVelocity * maxVelocity;
if (actualVelocitySq > maxVelocitySq) {
//double excessFactor = Math.sqrt(maxVelocitySq)/Math.sqrt(actualVelocitySq);
double excessFactor = Math.sqrt(maxVelocitySq/actualVelocitySq); //leewz's optimization
velocityX *= excessFactor;
velocityY *= excessFactor;
}
Есть ли какой-нибудь способ сделать избежать двойного квадратного корня? Или какая-то другая вещь, которая в противном случае исправляет эту жуткую ошибку?
Update:
Ответ, как представляется, масштаб обоих компонентов в соответствии с одним компонентом, который превышает максимальную скорость на наиболее. Это не строго масштабирование в соответствии с фактической скоростью, но оно фиксирует основную часть проблемы с помощью простой математики.
double scale;
double vectorX = Math.abs(velocityX);
double vectorY = Math.abs(velocityY);
if (vectorX > maxVelocity) {
scale = maxVelocity/vectorX;
if (vectorY > maxVelocity) {
scale = Math.min(scale, maxVelocity/vectorY);
}
velocityX *= scale;
velocityY *= scale;
} else {
if (vectorY > maxVelocity) {
scale = maxVelocity/vectorY;
velocityX *= scale;
velocityY *= scale;
}
}
Примечание для читателей: Код с дефектом в вопросе находится в 'VelocityTracker.computeCurrentVelocity (единиц, maxVelocity) Android,', а не кода Аскера. – leewz