Всем привет!
Думаю, уже много раз решалась проблема с написанием баллистики в виде вычисления угла наклона орудия до выстрела. Собственно, нашел пару интересных решений и вот в чем проблема: реализовал формулу θ = arctan((V^2 ± sqrt(V^4 - g(gx^2 + 2yV^2))) / (gx)) вот таким образом:
const float g = 980.664978f * GravityScale;
const float expression = FMath::Pow(Speed, 4) - g * (FMath::Pow(HorizontalDistance, 2) + 2 * VerticalDistance * FMath::Pow(Speed, 2));
const float sqrtExpression = FMath::Sqrt(expression);
const float angle1Radians = FMath::Atan((FMath::Pow(Speed, 2) + sqrtExpression) / (g * HorizontalDistance));
const float angle2Radians = FMath::Atan((FMath::Pow(Speed, 2) - sqrtExpression) / (g * HorizontalDistance));
const float angle1 = FMath::RadiansToDegrees(angle1Radians);
const float angle2 = FMath::RadiansToDegrees(angle2Radians);
const float originalAngle = FMath::Atan(VerticalDistance / HorizontalDistance);
const float originalAngleDegrees = FMath::RadiansToDegrees(originalAngle);
const float diff1 = FMath::Abs(originalAngleDegrees - angle1);
const float diff2 = FMath::Abs(originalAngleDegrees - angle2);
const float angle = (diff1 < diff2) ? angle1 : angle2;
if (VerticalDistance < 0.0f)
{
return -angle;
}
else
{
return angle;
}
Как определяю переменные:
Speed - постоянная, равная скорости полёта снаряда
HorizontalDistance - через функцию Get Horizontal Distance To, где target == self (класс с орудием) и Other Actor == actor, на которого идёт прицеливание (определяется в другой функции)
VerticalDistance - это "координата Actor по Z - координата сокета ствола орудия по Z"
В целом функция работает неплохо, но со странной погрешностью - если на дистанции +/- 200м погрешность составляет ~.6°, то на дистанции +/- 400м погрешность составляет уже ~2°. Есть какие-нибудь идеи, что я делаю не так? Не закидывайте тапками, опыта не так уж и много.
Прикладываю еще скриншот блюпринта, в котором реализовано использование функции.