Проблемы с инертиной, когда прибавляют силы в 2д физике

Я пытаюсь сделать очень простые 2-ые физические функции для решения твердого тела с сферическими частицами в качестве коллайдеров,

У меня так жесткая телосложение и класс частиц:

    function _rigidBody () {
        this._position = cc.p(0.0, 0.0);
    this._angle = 0;
    this._linearVelocity = cc.p(0.0, 0.0);
    this._angularVelocity = 0.0;
    this._force = cc.p(0.0, 0.0);
    this._angularMoment = 0;
    this._mass = 1.0;

    this._particles = [];
    }
    function _particle () {
    this._initialPosition = cc.p(0.0, 0.0);
    this._relativePosition = cc.p(0.0, 0.0);
    this._worldPosition = cc.p(0.0, 0.0);
    this._linearVelocity = cc.p(0.0, 0.0);
    this._force = cc.p(0.0, 0.0);
    this._radius = 10.0;
    }

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

И я вычисляю LinearVelocity и AngularVelocity, добавляя и добавляя импульс к моему HardBody для всего накопления силы на всех частицах, которые он содержит.

моя функция addImpulse (с импульсом хранит силу в частице и позиционирует мировую позицию моей частицы):

    this.AddImpulse = function(bodyIdx,impulse,position){
    var b = g_Bodies[ bodyIdx ];
    if(position == null){position = b._position;}

    b._linearVelocity.x += (impulse.x/ b._mass);
        b._linearVelocity.y += (impulse.y/ b._mass);
        b._angularVelocity +=  ((position.x - b._position.x) * impulse.y -                
                                (position.y - b._position.y) * impulse.x);
};

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

Я предполагаю, что пропустить инерцию - моя проблема, но я немного запутался, когда смотрю в интернете, как это вычислить,

Я заглядываю в box2d, чтобы увидеть, где хранится инерция, и кажется, что она является переменной значения bodBody (как массы). Я нахожу в Интернете, что инерция = масса * (r*r)
проблема => что такое...

-Если это расстояние до моего центра тяжести (так что положение моего жесткого тела), очевидно, всегда равно 0 (body.position - body.position == 0)

  • в box2d я нашел: this.m_I = massData.I - this.m_mass * (massData.center.x * massData.center.x + massData.center.y * massData.center.y); И шов massData.center должен быть центром фигуры от твердого тела, проблема в моем случае, моя фигура - это 2 сферы, одна в (0,10) и одна в (0,-10), поэтому центр этого равен (0,0) ....

  • на другом веб-сайте я обнаружил, что: for(i

Если кто-то может объяснить мне по-простому, как вычислить инерцию? Могу ли я вычислить инерцию для моего жесткого тела напрямую (а не по частям)? могу ли я сохранить инерцию или если она углубится, где применяется импульс (я читал это также на другом сайте...)? и / или почему я могу ошибаться в своей функции импульса, чтобы получить такую ​​большую угловую скорость (возможно, это нормально, и демпфирование решает эту проблему - это физический двигатель других).

А также, если кто-то может ответить (просто из любопытства), использует ли box2d простую версию инерции, потому что она быстрее вычисляется и результат достаточно хорош? Или расчет Box2d правильный, и я что-то упускаю, когда читаю код?

Большое спасибо ^^,

Marius.

1 ответ

Решение

Первое: вы правы, проблема в том, что вы не учитываете момент инерции (который является вращательным аналогом массы). Посмотрите на код:

b._linearVelocity.x += (impulse.x/ b._mass);
b._linearVelocity.y += (impulse.y/ b._mass);
b._angularVelocity +=  ((position.x - b._position.x) * impulse.y -
                            (position.y - b._position.y) * impulse.x);

Когда вы вычисляете линейную скорость, вы делитесь на массу; Вы должны сделать что-то подобное для углового движения.

Если положение rigidBody это его центр тяжести, тогда работа будет легкой.

Момент инерции mr2 суммируется по частицам. То есть каждая частица способствует m*r*r, где m масса частицы, а r это расстояние от частицы до центра тяжести.

Например, если ваша фигура состоит из 2 сфер, одна в (0,10) и одна в (0,-10), обе массы 5, тогда центр тяжести находится в

C = (5*(0,10)+5*(0,-10))/(5+5) = (0,0)

и момент инерции

I = 5*10*10 + 5*(-10)*(-10) = 1000

Изменение угловой скорости будет

b._angularVelocity += (((position.x - b._position.x) * impulse.y -
                        (position.y - b._position.y) * impulse.x))/I;

Если ваша фигура состоит из 2 сфер, одна в (0,10) с массой 5 ​​и одна в (0, -10) с массой 10, то центр тяжести находится в

C = (5*(0,10)+10*(0,-10))/(5+10) = (0,-10/3)

и момент инерции

I = 5*(40/3)*(40/3) + 5*(-20/3)*(-20/3) = 10000/9

РЕДАКТИРОВАТЬ:

Проблема возникает в частном случае одной сферы (или расположенных рядом сфер). Эти сферы рассматриваются как точечные массы, поэтому момент инерции (I) будет ноль. И все импульсы направлены через центр сферы, поэтому крутящий момент (угловая "сила") будет равен нулю. Так что не должно быть угловой скорости, но по методу выше это будет 0/0, Одно из решений: каждая сфера вносит небольшой постоянный вклад в момент инерции (это означает, что сфера не является точечной массой - она ​​имеет небольшую протяженность, поэтому она может вращаться). Теперь вклад каждой сферы m*r*r + d, где d например, 0.0001, Таким образом, одинокая сфера имеет положительный момент инерции (и не будет вращаться), и все другие объекты все еще имеют реалистичную физику.

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