2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки


Правила форума


Посмотреть правила форума



Начать новую тему Ответить на тему
 
 Расчёт скорости на заданом расстоянии (нетривиально)
Сообщение01.07.2017, 17:25 


01/07/17
6
Здравствуйте все!

Занимаюсь разработкой компьютерных игр. Встала необходимость сделать алгоритм расчёта энергии пули в шутере. Формально задача звучит так: Начальная скорость объекта (пули) задана ($V_0$). Известно расстояние, на котором произошла коллизия (попадание в монстра) ($S$). На пулю во время её полёта воздействует сила лобового сопротивления $F_d=C_x\frac{\rho V^2}{2} S$; ($C_x$, плотность воздуха и площадь лобового сечения заданы). Масса пули $m$ задана. Необходимо найти скорость $V$ в точке встречи.

Если решать в лоб, то задача тривиальная:
код: [ скачать ] [ спрятать ]
Используется синтаксис C#
        float s=0;
        float V=V0;
        float t=0;
        float dt = 0.0001F;
        while(s<S)
        {
            float Fd=Cx*(rho*Mathf.Pow(V,2)*0.5F)*S;
            float a=Fd/m;
            float dV=a*dt;

            V-=dV;
            s+=V*dt;
            t+=dt;
        }
 


Т.е., как вы видите, решается простым последовательным суммированием, после прохода цикла мы имеем $V$ в точке встречи. Всё бы ничего, но проблема в том что такой расчёт занимает очень много времени (по меркам компьютера, разумеется). Как можно это сделать короче, желательно не создавая цикла?

(Я попробовал находить скорость, составив и решив интегральное уравнение, но не получается его составить (да, в институте вышку проходил мимо, кто ж знал что так в жизни пригодится!) Не могу даже толком объяснить, что не получается. :-( Тут несколько неизвестных, и уравнение, вроде как, должно быть не одно, а система уравнений. Причём, непонятно как корректно подставить в эти уравнения формулу расчёта лобового сопротивления)

 Профиль  
                  
 
 Re: Расчёт скорости на заданом расстоянии (нетривиально)
Сообщение01.07.2017, 17:52 
Заслуженный участник
Аватара пользователя


22/06/12
2129
/dev/zero
В общем двумерном случае у вас есть плоскость выстрела, которая содержит линию, вдоль которой направлена начальная скорость, и эта плоскость перпендикулярна земле. Имеем плоскую задачу про сопротивление воздуха.

Для её решения можно использовать второй закон Ньютона в форме $m \mathbf{\dot v} = - k v \mathbf v + m \mathbf g$, потом к этому дифференциальному уравнению добавить начальные условия (радиус-вектор пули в момент выстрела и её вектор начальной скорости). Решив это дифференциальное уравнение, можно найти траекторию пули и прочие необходимые характеристики. Давайте определимся: либо мы решаем задачу численно, тогда вас стоит отослать, например, к книге Калиткина "Численные методы", либо мы пробуем решить задачу аналитически. Интегрированию, вроде, уравнение должно поддаваться, но я не пробовал.

-- 01.07.2017, 17:55 --

Говорят, что вызов библиотечной функции pow очень медленный, поэтому в таких процедурах, которые должны быстро работать, советуют обходиться более простыми аналогами, здесь, скажем, достаточно умножить число само на себя. Читаемость кода это даже улучшит, на мой взгляд.

-- 01.07.2017, 18:09 --

Можно предложить и другой подход: на каждом отрезке времени $dt$ пересчиьывать кинетическую энергию по формуле
$$
m v\ \mathrm dv = m g\  \mathrm dh - k v (\mathbf v \cdot \mathrm d \mathbf s),
$$
где $\mathrm d \mathbf s$ -- элемент траектории пули. Это вектор, который состоит из компонент $(\mathrm d x, \mathrm dy)$, а каждая компонента вычисляется по формуле $\mathrm dx=v_x \ \mathrm dt$, аналогично для вертикальной компоненты. Здесь, однако, $\mathrm dy = \mathrm dh$ - изменение вертикальной координаты. Этим способом мы получим величину скорости в некоторый момент времени, но про траекторию сказать уже ничего не сможем. Впрочем, если оно не надо, то второй способ мне представляется более простым.

 Профиль  
                  
 
 Re: Расчёт скорости на заданом расстоянии (нетривиально)
Сообщение01.07.2017, 18:30 


01/07/17
6
2 StaticZero
Поясню некоторые детали. Нам не требуется определять положение траектории в рассматриваемой нами двумерной плоскости (движок игры уже сделал это за нас). Соответственно, начальное положение пули в глобальной системе координат в момент выстрела нам не важно. Действие силы тяжести также не учитывается (дистанции стрельбы в шутере невелики - десятки метров, и отклонение пули вниз, по моему предположению, будет невелико. Поэтому ради экономии вычислительных ресурсов мы имитируем полёт пули с помощью raycast. Эта функция строит "луч" из заданной точки в заданном направлении, и возвращает объект и точку, в которой "луч" пересёк первый на его пути объект). Поэтому, вероятно, добавлять ускорение $mg$ от силы тяготения тоже не нужно.

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

Что касается метода pow - да, спасибо, вы правы. Хотя поставщики библиотек бьют себя пяткой в разные места говоря что нынче всё уже оптимизированно.

 Профиль  
                  
 
 Re: Расчёт скорости на заданом расстоянии (нетривиально)
Сообщение01.07.2017, 18:32 
Заслуженный участник
Аватара пользователя


23/07/08
10652
Crna Gora
Я ценю стремление к точности, но неужели геймер сможет заметить неправдоподобность модели, в которой скорость пули постоянна?

 Профиль  
                  
 
 Re: Расчёт скорости на заданом расстоянии (нетривиально)
Сообщение01.07.2017, 18:39 


01/07/17
6
StaticZero в сообщении #1230940 писал(а):
-- 01.07.2017, 18:09 --

Можно предложить и другой подход: на каждом отрезке времени $dt$ пересчиьывать кинетическую энергию по формуле
$$
m v\ \mathrm dv = m g\  \mathrm dh - k v (\mathbf v \cdot \mathrm d \mathbf s),
$$
где $\mathrm d \mathbf s$ -- элемент траектории пули. Это вектор, который состоит из компонент $(\mathrm d x, \mathrm dy)$, а каждая компонента вычисляется по формуле $\mathrm dx=v_x \ \mathrm dt$, аналогично для вертикальной компоненты. Здесь, однако, $\mathrm dy = \mathrm dh$ - изменение вертикальной координаты. Этим способом мы получим величину скорости в некоторый момент времени, но про траекторию сказать уже ничего не сможем. Впрочем, если оно не надо, то второй способ мне представляется более простым.

Этот вариант прокатил бы, если бы $dt$ было достаточно мало. Но он не работает нормально - скорость полёта пули велика (честные 500-700 м/с), а скорость обновления движка - фиксированные 60 тактов в секунду, т.е., $dt$ у нас 1/60-я секунды, большое время для реалистичной физики. В результате изменение энергии получается очень неплавным. (А ещё без дополнительных ухищрений мы получаем ситуацию когда пуля просто пролетит через противника, не задев его - на следующем кадре она оказывается уже далеко за ним :lol: )

 Профиль  
                  
 
 Re: Расчёт скорости на заданом расстоянии (нетривиально)
Сообщение01.07.2017, 18:43 
Заслуженный участник


05/08/14
1564
Daniil85 в сообщении #1230938 писал(а):
На пулю во время её полёта воздействует сила лобового сопротивления Fd=Cx*$\frac{\rho V^2}{2}$*S;

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

 Профиль  
                  
 
 Re: Расчёт скорости на заданом расстоянии (нетривиально)
Сообщение01.07.2017, 18:44 


01/07/17
6
svv в сообщении #1230946 писал(а):
Я ценю стремление к точности, но неужели геймер сможет заметить неправдоподобность модели, в которой скорость пули постоянна?

От скорости пули зависит её кинетическая энергия, от энергии зависит количество сбитых с геймера/монстра хитпоинтов. На длинных дистанциях (выше 50 м) для слабого оружия это будет заметно.
Конечно, можно было бы написать какой-то отпотолочный алгоритм, симулирующий падение энергии пули на расстоянии. Но это было бы не клёво. Гораздо интереснее научиться решать задачи подобного рода. :-)

 Профиль  
                  
 
 Re: Расчёт скорости на заданом расстоянии (нетривиально)
Сообщение01.07.2017, 18:47 
Заслуженный участник
Аватара пользователя


23/07/08
10652
Crna Gora
Спасибо, понял.

 Профиль  
                  
 
 Re: Расчёт скорости на заданом расстоянии (нетривиально)
Сообщение01.07.2017, 18:55 


01/07/17
6
dsge в сообщении #1230952 писал(а):
Daniil85 в сообщении #1230938 писал(а):
На пулю во время её полёта воздействует сила лобового сопротивления Fd=Cx*$\frac{\rho V^2}{2}$*S;

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

Погуглил, интересный вариант. Спасибо, попробую поэкспериментировать.

 Профиль  
                  
 
 Re: Расчёт скорости на заданом расстоянии (нетривиально)
Сообщение01.07.2017, 19:39 
Заслуженный участник
Аватара пользователя


22/06/12
2129
/dev/zero
Daniil85 в сообщении #1230945 писал(а):
фактически, упрощение.

Вы знаете, вообще говоря, нет. Скажем, если интеграл уравнения имеет какой-нибудь такой вид, где функция выражается неявным образом, например
$$
\ln(x^2 + y^2) + \arctg xy = C,
$$
то, чтобы получать значения $y=y(x)$, нужно решить нелинейное уравнение численным методом. Чем это проще, чем решать исходное уравнение, которое привело к такому интегралу, сразу численно?

Daniil85 в сообщении #1230945 писал(а):
численных методов решения такой задачи от аналитических

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

Daniil85 в сообщении #1230945 писал(а):
Поэтому, вероятно, добавлять ускорение $mg$ от силы тяготения тоже не нужно.

Если так, то исходная задача становится и вовсе одномерной. Для того, чтобы её решить, введём замену переменных, убирая время из уравнения:$v(t) = u(s)$, где $s$ - координата вдоль линии выстрела. Соответственно, $\dot v=uu'$, и получаем закон изменения кинетической энергии в виде
$$ m u\ \mathrm du = - k u^2 \ \mathrm ds, $$
которое уже точно интегрируется в явном виде:
$$
\dfrac{\mathrm du}{u} = - \dfrac{k}{m}\ \mathrm ds,
$$
далее все шаблонно делается для ДУ с разделяющимися переменными. Результат - экспоненциальный спад скорости (и кинетической энергии) с расстоянием, пройденным в среде. На небольшом расстоянии от точки выстрела экспонента будет похожа на линейную функцию, что ещё больше упрощает ситуацию, при необходимости (скажем, если из геометрии ситуации ясно, что пуля попадёт в объект, находящийся на близком расстоянии). Небольшие расстояния здесь небольшие в том смысле, что они малы по сравнению с некоторым характерным расстоянием, на котором скорость спадает в $e$ раз.

Daniil85 в сообщении #1230948 писал(а):
Этот вариант прокатил бы, если бы $dt$ было достаточно мало. Но он не работает нормально - скорость полёта пули велика (честные 500-700 м/с), а скорость обновления движка - фиксированные 60 тактов в секунду, т.е., $dt$ у нас 1/60-я секунды, большое время для реалистичной физики.

Если коэффициент сопротивления среды велик, то да, будет существенная неприятность. Но не в этом случае, по крайней мере (см. выше).

 Профиль  
                  
 
 Re: Расчёт скорости на заданом расстоянии (нетривиально)
Сообщение01.07.2017, 21:40 


01/07/17
6
StaticZero в сообщении #1230963 писал(а):
получаем закон изменения кинетической энергии в виде
$$ m u\ \mathrm du = - k u^2 \ \mathrm ds, $$


Слушайте, это великолепно! Если б вы не напомнили мне, я бы не вспомнил что второй закон Ньютона пишется в таком виде! :-) А ведь эта запись это считай половина ответа. Ну и да, после замены переменной чтобы убрать время, всё становится решаемо как по учебнику.

В результате получается что
$u(s)=v_0\cdot e^{\frac{-k}{m}s}$


Соответственно, всё считается как надо! :D

Спасибо вам огромное!

 Профиль  
                  
 
 Re: Расчёт скорости на заданом расстоянии (нетривиально)
Сообщение01.07.2017, 21:42 
Заслуженный участник
Аватара пользователя


04/09/14
5011
ФТИ им. Иоффе СПб
StaticZero в сообщении #1230940 писал(а):
Для её решения можно использовать второй закон Ньютона в форме $m \mathbf{\dot v} = - k v \mathbf v + m \mathbf g$
Поскольку при горизонтальном выстреле вертикальная скорость мала, можно из нее выкинуть сопротивление воздуха, и получится
$$
\begin{align}
\dot{v}_x&=- k v_x^2\\
\dot{v}_y&=-mg,
\end{align}
$$
откуда мгновенно получим $v_x=\frac{v_{x0}}{v_{x0}kt+1},\; v_y=v_{y0}-gt$, что, по-моему, вполне сойдет, если мы стреляем более-менее горизонтально. При выстреле под углом имеет смысл оставить сопротивление вдоль линии выстрела и учесть член вида $\frac{mg}{v^2}$ как возмущение.

 Профиль  
                  
 
 Re: Расчёт скорости на заданом расстоянии (нетривиально)
Сообщение01.07.2017, 23:16 
Аватара пользователя


31/12/13
148
Daniil85
А как же зависимость $c_x(M)$? Придирчивые геймеры оценят! :D
Она, правда, заставит вернуться к численным методам, если её брать реальную, без упрощений.
А так, решение для постоянного к-та лобового сопротивления есть, например, в книжке "Средства поражения и боеприпасы". Совпадает с приведенным здесь: $V(x)=V_0e^{-Ax}$

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 13 ] 

Модераторы: Модераторы Математики, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group