Как создать (математическую) функцию для положения бильярдного шара при учете трения

поэтому я создаю симуляцию бильярдного шара. Текущая версия вычисляет новое положение мяча для каждого шага, но я хотел бы создать математическую функцию (f(x)) для положения мячей. Это не слишком сложно, но что меня действительно сбивает с толку, так это заставить его работать с трением.

Для мяча у меня есть следующая соответствующая информация: скорость/скорость, положение/начальное положение и коэффициент трения. Я могу рассчитать расстояние, которое мяч проходит за один шаг, возведя коэффициент трения в степень x. Проблема в том, что я могу заставить его работать, только вычисляя новую позицию шаг за шагом. Я проиллюстрировал это в Ti-Nspire:

Как создать (математическую) функцию для положения бильярдного шара при учете трения

Как создать (математическую) функцию для положения бильярдного шара при учете трения

Как создать (математическую) функцию для положения бильярдного шара при учете трения

Если это, в конце концов, сложнее и менее эффективно, чем простое обновление каждую секунду, дайте мне знать. Если у вас есть решение, как я могу получить его как функцию или лучшее решение, сообщите мне об этом. Спасибо за любую помощь заранее:)

Предоставьте достаточно кода, чтобы другие могли лучше понять или воспроизвести проблему.

Community 08.10.2022 14:58
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
1
80
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Уменьшение скорости пропорционально ее текущей величине в непрерывном времени (по сравнению с дискретными временными шагами) в значительной степени является определением экспоненциального затухания. Это означает, что функция непрерывного времени, соответствующая вашему дискретно-ступенчатому масштабированию, будет

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

Другие вопросы по теме