поэтому я создаю симуляцию бильярдного шара. Текущая версия вычисляет новое положение мяча для каждого шага, но я хотел бы создать математическую функцию (f(x)) для положения мячей. Это не слишком сложно, но что меня действительно сбивает с толку, так это заставить его работать с трением.
Для мяча у меня есть следующая соответствующая информация: скорость/скорость, положение/начальное положение и коэффициент трения. Я могу рассчитать расстояние, которое мяч проходит за один шаг, возведя коэффициент трения в степень x. Проблема в том, что я могу заставить его работать, только вычисляя новую позицию шаг за шагом. Я проиллюстрировал это в Ti-Nspire:
Если это, в конце концов, сложнее и менее эффективно, чем простое обновление каждую секунду, дайте мне знать. Если у вас есть решение, как я могу получить его как функцию или лучшее решение, сообщите мне об этом. Спасибо за любую помощь заранее:)
Уменьшение скорости пропорционально ее текущей величине в непрерывном времени (по сравнению с дискретными временными шагами) в значительной степени является определением экспоненциального затухания. Это означает, что функция непрерывного времени, соответствующая вашему дискретно-ступенчатому масштабированию, будет
V (t) = V0 e-λt
где V0 — начальная скорость в момент времени 0, а λ — скорость затухания. Нам нужно откалибровать скорость затухания, чтобы она соответствовала вашему фрикоэфу, а это значит, что мы хотим
V(1) = коэффициент трения * V0,
и поэтому
e-λ*1 = фриккоэф
уступающий
λ = -ln(friccoef).
Затем мы можем получить пройденное расстояние как функцию времени t, интегрируя скорость от 0 до t. Результирующая формула для положения в момент времени t, если движение начинается в момент времени t0 со скоростью Vt0 и начальным местоположением Xt0, будет
Хt = Хt0 + Vt0 (1 - e-λ(t - t0)) / λ.
Чтобы показать непрерывную эволюцию функции во времени, я использовал gnuplot с t0 = 0, V0 = 32, X0 = 123 и friccoef = 0,9:
Возвращаясь к релевантности stackoverflow, приведенные выше формулы могут быть напрямую реализованы в Python:
from math import log, exp
def rate(friction_coeff):
return -log(friction_coeff)
def position(elapsed_time, x_0, v_0, friction_coeff):
lmbda = rate(friction_coeff)
return x_0 + v_0 * (1.0 - exp(-lmbda * elapsed_time)) / lmbda
def velocity(elapsed_time, v_0, friction_coeff):
return v_0 * exp(-rate(friction_coeff) * elapsed_time)
def time_to(destination, x_0, v_0, friction_coeff):
lmbda = rate(friction_coeff)
return -log(1.0 - lmbda * (destination - x_0) / v_0) / lmbda
Несколько простых тестов...
# A few test cases
x_0 = 2
destination = 12
v_0 = 5
friction_coeff = 0.9
t = time_to(destination, x_0, v_0, friction_coeff)
print(f"Time to go from {x_0} to {destination} starting at velocity {v_0} is {t}")
print(f"Position at time {t} is calculated to be {position(t, x_0, v_0, friction_coeff)}")
print(f"Velocity at time {t} is {velocity(t, v_0, friction_coeff)}")
произвести следующий вывод:
Time to go from 2 to 12 starting at velocity 5 is 2.24595947233019
Position at time 2.24595947233019 is calculated to be 12.00000
Velocity at time 2.24595947233019 is 3.946394843421737
Предоставьте достаточно кода, чтобы другие могли лучше понять или воспроизвести проблему.