Расчет силы вращения 2D спрайта

35

Мне интересно, есть ли у кого-нибудь элегантный способ вычисления следующего сценария.

У меня есть объект (n) количество квадратов, случайных форм, но мы будем притворяться, что они все прямоугольники.

Мы имеем дело с отсутствием гравитации, поэтому рассмотрим объект в космосе сверху вниз. Я прикладываю силу к объекту на определенном квадрате (как показано ниже).

Применяя силу

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

jgallant
источник
Что вы хотите, чтобы произошло с силой во времени, когда объект вращается? Всегда ли это относится к одному и тому же квадрату в одном и том же направлении? Он "сметает" по краю объекта? Имея информацию, которую вы предоставляете, вы можете получить только соответствующую вращающую силу (точнее крутящий момент), но если вы хотите из этого вывести скорость вращения, вам нужно будет либо дать импульс (а не силу), либо объяснить, как сила должна применяться со временем.
Сам Хочевар
Честно говоря, это, вероятно, будет лучшим вопросом для phys.stackexchange.com, так как это полностью вопрос базовой механики.
BlueRaja - Дэнни Пфлюгофт

Ответы:

44

Вы пытаетесь рассчитать крутящий момент. Крутящий момент зависит от приложенной силы F, точки приложения и центра масс объекта.

1) Центр масс . Определите центр масс объекта.

2) Точка приложения : определите точку, в которой действует сила.

3) Момент рука : расстояние между двумя точками, определенными выше.

Point centerofMass
Point applicationPoint
Vector momentArm = applicationPoint - centerofMass

4) Угловая сила : разделите вашу силу F на два ортогональных вектора: один параллельный линии в 3) и один перпендикулярный. Параллельная составляющая не влияет на момент импульса. Перпендикулярный делает. Вы можете рассчитать параллельную составляющую по векторной проекции.Вы можете вычесть это из оригинала, чтобы получить перпендикулярный компонент. В псевдокоде ( dotозначает точечное произведение)

Vector myForce
Vector momentArm

parallelComponent = momentArm * (dot(myForce, momentArm) / dot(momentArm, momentArm))
angularForce = myForce - parallelComponent

5) Крутящий момент : перпендикулярная составляющая силы, умноженная на длину плеча момента.

Vector angularForce
Vector torque = angularForce * momentArm.Length

Чтобы получить от крутящего момента до угловой скорости:

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

2) Угловое ускорение :

Vector angularAcceleration = torque / momentOfInertia

3) Угловая скорость : угловая скорость будет увеличиваться, пока крутящий момент применяется. Таким образом, формула будет примерно иметь вид: «Угловая скорость в момент времени T является совокупной суммой углового ускорения вплоть до T ». Это выражается в псевдокоде как

void Update(float elapsedSeconds):
    orientation += 0.5 * angularVelocity * elapsedSeconds;
    angularVelocity += angularAcceleration * elapsedSeconds;
    orientation += 0.5 * angularVelocity * elapsedSeconds;
Джимми
источник
Большая информация, однако, часть, с которой я больше всего неясен, состоит в том, как определить, какой должна быть сила крутящего момента. У меня есть все компоненты на месте, как вы описали.
августа
@Jon: у вас есть компоненты, то есть у вас есть шаги 1 - 3, и вы не можете понять, как рассчитать шаг 4? Это в первую очередь сложный шаг. Я добавлю немного больше деталей там.
Джимми
3
Ориентация, являющаяся совокупной суммой угловой скорости, orientation += angularVelocity * elapsedSecondsявляется неправильной, поскольку она переоценивает скорость в течение временного шага, а это означает, что разные частоты кадров будут давать разные ориентации. Правильная формула будет: float oldVelocity = angularVelocity; angularVelocity += angularAcceleration * elapsedSeconds; orientation += 0.5f * (angularVelocity + oldVelocity) * elapsedSeconds;. Кроме того, поскольку гравитации нет, я предлагаю вместо этого использовать «центр масс». +1 за очень хорошее объяснение, хотя.
Сам Хочевар
1
Часть перпендикулярной силы будет действовать для ускорения центра масс, и когда сила прикладывается ближе к центру масс, этот коэффициент увеличивается. Ответ хороший и очень четкий, но в этом отношении он кажется неполным.
Сэм Уоткинс
Чтобы ответить на мой собственный комментарий, я читаю статьи Криса Хеккера по физике: chrishecker.com/Rigid_body_dynamics . Оказывается, что сила или импульс в любой точке оказывает хорошо известное влияние на центр масс согласно F = ma или a2 = a1 + p, как если бы тело не могло вращаться. Это следует из закона сохранения линейного импульса. Компонента силы, перпендикулярная радиусу, также вызывает вращающий момент и изменение углового момента, как описано в ответе Джимми.
Сэм Уоткинс
7

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

весна и точки

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

Ali1S232
источник