Russian Qt Forum
Ноябрь 25, 2024, 09:00 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 [2]   Вниз
  Печать  
Автор Тема: Движок физики. Силы, Ньютон  (Прочитано 15735 раз)
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #15 : Март 13, 2020, 17:26 »

Предположим для своевольного объекта задан маршрут движения. Тогда будет известно направление его движения в следующий момент времени. С учетом внешнего воздействия и текущих параметров внутренней модели (количество снаряжения, уровень ловкости, уровень сил, мотивация и др.) можно определить величину необходимых усилий, скорости перемещения, следующую точку на маршруте.
Надеюсь я Вас понял. Придать char'у некоторое специфическое/индивидуальное поведение - это конечно интересно. Но сейчас речь идет о самой базовой, "рудиментарной" работе с движком. Есть текущий вектор силы - и в данной теме совершенно не волнует как его посчитали, неважно что там привлекалось для его расчета. Главное он посчитан и известен. Кроме него известна текущая (реальная) скорость объекта и крутящий момент. Теперь надо скормить эту силу движку так чтобы юзер получил удобное, предсказуемое поведение (а не ту фигню что придумал Ньютон). Разумеется юзера интересует скорость, поэтому давать какие-то установки скорости в UI не запрещено. Но менять скорость для движка напрямую низзя, как уже говорилось, потеряем физику.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #16 : Март 14, 2020, 12:30 »

Вот траектории движения с поворотом (аттач). Юзер совсем не возражает против левой и средней картинок, наоборот, ясно что какая-то (регулируемая) плавность/радиус нужны. Но "чисто по Ньютону" получается правая картинка - старая/имеющаяся скорость никак не гасится. Люди так не ездиют! Приложить силу в обратном направлении.. ну что это трудно сделать из UI уже говорилось, но это и по смыслу неверно - необязательно велосипедист тормозит на повороте, но всегда поворачивает руль (меняет вектор силы)

Так как бум гасить?

Записан
ssoft
Программист
*****
Offline Offline

Сообщений: 584


Просмотр профиля
« Ответ #17 : Март 16, 2020, 07:57 »

Так как бум гасить?

Если всё происходит в невесомости в открытом космосе, то именно правый вариант является правильным.)

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

Если нужна реальная физика, привлеките к работе физика-механика, который распишет физические модели поведения объектов и явлений в упрощении, достаточном для решении Ваших задач.
Ну или придется осваивать физику самостоятельно).

Если известна целевая траектория движения, то всегда можно рассчитать скорость и ускорение в любой момент времени.
Если же требуется управление какими-то характеристиками объекта со стороны пользователя во время игры, то без модели управления здесь не обойтись.
Записан
ssoft
Программист
*****
Offline Offline

Сообщений: 584


Просмотр профиля
« Ответ #18 : Март 16, 2020, 08:21 »

Но "чисто по Ньютону" получается правая картинка - старая/имеющаяся скорость никак не гасится. Люди так не ездиют! Приложить силу в обратном направлении.. ну что это трудно сделать из UI уже говорилось, но это и по смыслу неверно - необязательно велосипедист тормозит на повороте, но всегда поворачивает руль (меняет вектор силы)

Интересно Вы мыслите), но неверно.
Если велосипедист не затормозит на повороте - улетит в кювет), что и бывает с автомобилями в реальной жизни при гололёде.
Поворотом руля, нажатием на тормоз велосипедист как раз управляет силой сопротивления за счет трения, которая зависит кроме всего прочего от ширины соприкосновения поверхностей вдоль направления движения. Точно также конькобежец управляет скоростью и направлением движения только за счет поворота лезвия конька.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #19 : Март 16, 2020, 11:47 »

Интересно Вы мыслите), но неверно.
Утверждение "неверно" подразумевает что верный ответ/решение известно. Но я в упор его не вижу в Ваших постах Улыбающийся Где Вы просто перечисляете все что Вам известно даже не пытаясь делать никаких выводов. Да, все что Вы сказали разумно, но .. из этого ровным счетом ничего не следует, и как решать - хз.  Немудрено что сваливаемся в обычное "лапки кверху", мол, да пусть этим физики занимаются (а мы продолжим лакать std::move и.т.п.)

Попробуем подойти более конкретно, разберемся почему в жизни велик едет как на средней картинке. Вот аттач, вертикальный (черный) вектор - начальная скорость, и вот теперь повернули руль по направлению зеленого вектора. Разложим черный вектор на 2 компоненты. На зеленую действует лишь небольшая сила трения (качения). А вот синий попадает под раздачу, на него действует мощная сила трения скольжения

F = m * g * k

где

m * g = (масса на гравитацию) сила прижимающая велик к земле
k = коэффициент трения

Эта сила значительна и обычно гасит синий вектор мгновенно. Увидеть "занос на повороте" можно только если скорость уж слишком велика и/или k мал (едем по льду).

Если нужна реальная физика, привлеките к работе физика-механика,
Рискну предположить что Вы никогда его не привлекали Улыбающийся Поверьте, рез-т будет плачевный. Да и какую "физику" мы хотим? Все что нужно "с точки зрения физики" изложено выше. Да, в реальной жизни инерция успешно гасится. И, естественно, юзер хочет иметь такое поведение. И, конечно, его не волнуют никакие тонкости. Нажал/ввел - и вот объект имеет поведение велосипеда, машины, самолета, птицы и.т.д. А сам объект может быть просто кубик, не будет никто создавать колеса, закрылки, оперение и.т.п, это затратно и ненадежно. Ну и разумеется "какие опции дать юзеру" никакой физик Вам не скажет, это чисто работа программиста. Настоящая (а не так, темплейтики рисовать).

Ну ладно, попробуем с чего-то начать. Предлагаю дать параметр "brake" или "Inertia brake" (в тех же единицах что и ускорение) который прилагается к "синему вектору" - тому что не совпадает с текущим напр-ем силы. С клампом до нуля (т.е. тормозит но не двигает назад).

Понимаю что это предложение "наивно" - первое что приходит в голову. Критикуем, улучшаем... (в глубине души еще теплится надежда, правда совсем слабо Улыбающийся)  
« Последнее редактирование: Март 16, 2020, 11:50 от Igors » Записан
ssoft
Программист
*****
Offline Offline

Сообщений: 584


Просмотр профиля
« Ответ #20 : Март 16, 2020, 15:56 »

Попробуем подойти более конкретно, разберемся почему в жизни велик едет как на средней картинке. Вот аттач, вертикальный (черный) вектор - начальная скорость, и вот теперь повернули руль по направлению зеленого вектора. Разложим черный вектор на 2 компоненты. На зеленую действует лишь небольшая сила трения (качения). А вот синий попадает под раздачу, на него действует мощная сила трения скольжения.

Трение качения может быть существенно сильнее трения скольжения. Система ABS в автомобилях, как раз не позволяет автомобилю скользить.
Для велика ещё одной силой может быть сила тяжести из-за его наклона (смещения центра тяжести) в момент поворота. Что хорошо видно в соревнованиях мотогонщиков, например.

Если нужна реальная физика, привлеките к работе физика-механика,
Рискну предположить что Вы никогда его не привлекали Улыбающийся Поверьте, рез-т будет плачевный. Да и какую "физику" мы хотим?

Привлекал и математиков и физиков. Результат разнонаправленный).

Все-таки требуется конкретнее сформулировать цель - чтобы было просто похоже или чтобы прям математическая модель поведения колеса, велика или чего-то ещё имитировалась?

Если нужно просто похоже, то для "физического" поведения кубика достаточно в первом приближении добавить силу, действующую на объект по нормали к целевому вектору движения, величина которой зависит от модуля угла между фактическим и целевым направлением F * sin(alpha). Поиграйте значением F, думаю, что подберете оптимальное.
За счет чего реально формируется такая сила можно не объяснять пользователю).

Иначе потребуется привлечение достаточно серьезных моделей, в которых, действительно, нет времени разбираться.
Но в поиске по ключевым словам "математическая модель движения велосипеда/машины" и т.п. выводится достаточно большое количество научных работ.
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #21 : Март 17, 2020, 05:23 »

Ну и разумеется "какие опции дать юзеру" никакой физик Вам не скажет, это чисто работа программиста. Настоящая (а не так, темплейтики рисовать).  
Докатились. Взять готовый физический движок и решить какие опции дать юзеру стало настоящей работой программиста. Даже не финдреплейсы писать... Улыбающийся
Какие уж там темплейтики. Улыбающийся
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #22 : Март 17, 2020, 12:14 »

Все-таки требуется конкретнее сформулировать цель - чтобы было просто похоже или чтобы прям математическая модель поведения колеса, велика или чего-то ещё имитировалась?
Ну какая же "матмодель колеса" если, как говорилось, юзер даже не собирается создавать никаких колес? Однако "просто похоже" звучит неуместно и пренебрежительно. Можно спокойно считать это "простой моделью".

Если нужно просто похоже, то для "физического" поведения кубика достаточно в первом приближении добавить силу, действующую на объект по нормали к целевому вектору движения, величина которой зависит от модуля угла между фактическим и целевым направлением F * sin(alpha). Поиграйте значением F, думаю, что подберете оптимальное.
За счет чего реально формируется такая сила можно не объяснять пользователю).
Как-то мутно. Да и вызов sin не украшает (народная примета). Почему не так (псевдокод)
Код
C++ (Qt)
float brakeInertia = ...  // величина "гашения" задаваемая юзером
vec3 force = ...  // текущий вектор силы задаваемый юзером
vec3 cur_speed = body->getLinearSpeed();  // текущая скорость объекта
 
// вектор силы инерции (синий = черный - зеленый)
vec3 interia = cur_speed - force * dot(cur_speed, force) / force.lengthSquare();
 
// применяем brakeInteria
if (brakeInertia > inertia.length())  // полное подавление
 interia = -interia;
else
inertia = -interia.normalized() * brakeInteria; // частичное подавление
 
Масса - константа, на нее домножим когда уже полезем в движок добавлять interia
Это то что Вы имели ввиду? (если нет - поправьте)

Теперь хотелось бы чтобы Вы покритиковали этот (очевидно примитивный) подход/способ.
Напр бросается в глаза что мы давим инерцию "без разницы откуда она взялась" и это легко может оказаться неверным. Напр сила гравитации подавляться не должна.

Еще мысль которая кажется мне интересной. А не связать ли это с движением "лицом вперед"? (которое тоже надо делать). Т.е. мы не "поворачиваем руль" а заклинили его и привязали к нему веревочку за которую тянем, в конце-концов сам велик повернется по направлению силы. Конечно это "другая задача"
Записан
ssoft
Программист
*****
Offline Offline

Сообщений: 584


Просмотр профиля
« Ответ #23 : Март 18, 2020, 08:40 »

Может и так). Отсутствие четкого понимания, что чем является и в чём измеряется мешает восприятию.

Код
C++ (Qt)
float brakeInertia = ...  // величина "гашения" задаваемая юзером
   // сила
   // мощность (работа в единицу времени)
   // процент от величины ...
   // ???
 
vec3 force = ...  // текущий вектор силы задаваемый юзером
   // здесь должен быть суммарный вектор всех сил, действующих на объект
   // с учетом сил тяжести и т.п.
 
vec3 cur_speed = body->getLinearSpeed();  // текущая скорость объекта
   // m*v^2/2 - кинематическая энергия
 
// вектор силы инерции (синий = черный - зеленый)
vec3 interia = cur_speed - force * dot(cur_speed, force) / force.lengthSquare();
   // это всё-таки составляющая вектора скорости, никак не сила
 
// применяем brakeInteria
if (brakeInertia > inertia.length())  // полное подавление
 interia = -interia;
else
inertia = -interia.normalized() * brakeInteria; // частичное подавление
   // что здесь происходит - совсем не ясно
   // здесь считается дополнительная сила?
   // что значит полное подавление?
 
// наверное, должно быть как-то так:
   // если brakeInteria дополнительная сила
   vec3 demp_force = -interia.normalized() * brakeInteria;
   // если brakeInteria процент от действующей силы (0..100)
   vec3 demp_force = -interia.normalized() * brakeInteria * force.lenght() / 100;
 
// общая сила, действующая на объект
   vec3 total_force = force + demp_force;
   // далее считаем кинематические характеристики на следующем шаге
 
   // если brakeInteria мощность, то компонента скорости перпендикулярная действию силы
   // на следующем шаге по времени, исходя из закона сохранения энергии, будет равна
   float under_root = interia.lengthSquare() - 2 / M * brakeInteria * dt
       // M - масса объекта, dt - шаг по времени
   vec3 orthogonal_velocity = under_root >= 0
       : interia.normalized() * sqrt( under_root );
       : -interia.normalized() * sqrt( -under_root );
 

Как без массы обходиться, даже если она константа мне не понятно, так как она является составной частью законов сохранения энергии, импульса и массы).
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #24 : Март 18, 2020, 10:51 »

Ваш последний ответ меня порадовал. Вот есть же люди которые хотят по-настоящему вникнуть в суть, а не так, "функции найти".

Комментировать весь код - размажется, попробую "ключевые моменты"

1)
Код
C++ (Qt)
float brakeInertia = ...  // величина "гашения" задаваемая юзером
 
Дальнейший расчет будет в скоростях, поэтому если, как я предлагал, "гашение" юзеру дается в тех же единицах что и ускорение (1/(sec * sec), то
Код
C++ (Qt)
brakeInertia = user_value * dt;
Где dt - время шага симуляции. Это (максимальный) модуль скорости которую можно отнять от скорости инерции

2)
   // это всё-таки составляющая вектора скорости, никак не сила
Совершенно верно, это то что отнимается от скорости за время dt. Стало быть, это соответствует ускорению (в 1 / sec^2)
Код
C++ (Qt)
vec3 a = inertia / dt;
и движку скармливается сила
Код
C++ (Qt)
vec3 F = body->getMass() * a;

3)
   // что здесь происходит - совсем не ясно
    // здесь считается дополнительная сила?
    // что значит полное подавление?
Это просто кламп как для трения. Гашение может затормозить до нуля (т.е. полностью), но не двигает в противоположном напр-и

3)
// общая сила, действующая на объект
rigidBody имеет линейную скорость и крутящий момент (члены класса). Если ничего более не происходит, то объект продолжает двигаться/вращаться с этими скоростями (по Ньютону). Силы (линейная и круговая) обнуляются перед каждым шагом и пере-создаются/накапливаются на каждом шаге. Получить суммарные силы действующие на объект  можно, но из чего они получились - хз. И "после нас" кто-то (может и сам движок) может добавить еще силу(ы).

Силы действуют по Ньютону. Если "ничего более нет" то сила тупо добавит скорость
Код
C++ (Qt)
body->m_linearSpeed += body->m_force / body->getMass() * dt;
Однако обычно "еще много чего есть" (коллизии, constraint'ы - там страшнЭ и.т.п.), поэтому "рассчитать следующую точку пути" не имеет смысла, этим занимается движок, для этого он собсно и нужен. И юзать m*v*v тоже ни к чему - движок это сделает сам.
« Последнее редактирование: Март 18, 2020, 10:57 от Igors » Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #25 : Март 18, 2020, 12:55 »

Вот есть же люди которые хотят по-настоящему вникнуть в суть, а не так, "функции найти".
Ну вы "функции уже нашли" в готовом то движке, теперь форум должен бросить все свои дела, вникнуть в суть и рассказать вам как эти функции использовать... Ну а чо, дел же больше нет. Улыбающийся
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #26 : Март 23, 2020, 12:40 »

Ну вот, единственный собеседник - и тот юркнул в родное std::болото Плачущий
Ладно, добавил параметр "тормоз инерции", для поворотов работает. В аттаче траектории, для всех Acceleration=100 и MaxSpeed = 60, отличаются величиной тормоза (слева направо 3, 10, 100)

Однако 2 другие проблемы (стартового поста) это еще не решает.

"Останов объекта" - нужно как-то натравить тормоз на черный вектор (текущая скорость), но пока не соображу как (ну или "при каких условиях").

"Быстрый старт" - сама по себе проблема не великая, но маячит более общая задача: объект имеет опцию MinSpeed, т.е. не может двигаться со скоростью меньше заданной. Ну вот не ходют (нормальные) люди со скоростью 30 см/сек, а физика этого не понимает. Надо что-то придумать, но пока нет идей.

Да, ну и конечно, (в известной мере) беспокоит: а насколько "солидно" решение с "тормозом"? Где же Рунги, Куты, словом, чудесные "дифуры" которые решают все-все? Разве так можно, разложить вектор и пятью строчками (меньше) все решить? Конечно нет, это не "настоящее" решение, а так, "чтобы было похоже" и.т.п. Ну, правду сказать, я пока не вижу чем плохо простое решение (да и сообщать о его простоте юзеру необязательно). Тем более что мотив "ничего не делать т.к. это слишком сложно"  очевиден. Ну может я неправ, покритикуйте, расскажите что дает "истинное" решение (не надеюсь)
Записан
Страниц: 1 [2]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.176 секунд. Запросов: 22.