Проблемы с Inertina при добавлении силы в 2d Physic

Я пытаюсь сделать очень простые 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, добавляя и импульс моему жесткому телу для всего запаса силы на всех содержащихся в нем частицах.

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

    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, чтобы увидеть, где инерция хранится, и похоже, что это переменная жесткого тела (как масса). Я нашел в Интернете, что Инерция = масса * (r * r)
проблема => что такое r ...

-if - расстояние до моего центра тяжести (поэтому положение моего жесткого тела), очевидно, всегда равно 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 ‹numberOfParticle) I + = (massOfParticle (i) * (RelativePosOfParticle (i) * RelativePosOfParticle (i)) В этом случае лучше, потому что если я возведу в квадрат расстояние до каждой частицы ( вместо того, чтобы сначала искать в центре), my I будет больше 0. Но я не уверен, что это правильная формула ...

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

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

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

Мариус.


person user1482649    schedule 21.01.2013    source источник


Ответы (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 - это его центр тяжести, тогда работа будет легкой.

Момент инерции равен mr 2, суммированный по частицам. То есть каждая частица вносит свой вклад 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. Таким образом, у одиночной сферы есть положительный момент инерции (и она не будет вращаться), а все другие объекты по-прежнему имеют реалистичную физику.

person Beta    schedule 21.01.2013
comment
Спасибо, очень полезно, я попробую это сейчас, но сейчас у вас есть объяснение формулы в box2d. this.m_I = massData.I - this.m_mass * (massData.center.x * massData.center.x + massData.center.y * massData.center.y); Если они сначала вычисляют центр, в моем случае результат равен 0, а затем умножают на массу, все равно 0? это ошибка? - person user1482649; 22.01.2013
comment
У меня нет объяснения этому. Я не знаком с box2d и не знаю, что такое this и massData. - person Beta; 22.01.2013
comment
@ user1482649, это всего лишь базовая физика - теорема Гюйгенса-Штейнера. В нем говорится, что момент инерции вокруг оси, параллельной оси (или оси в 2D случае), которая проходит через центр масс (CoM) твердого тела, является моментом инерции относительно оси CoM плюс общая масса тела, умноженная на квадрат расстояния между двумя осями. Здесь он применяется для вычисления момента инерции относительно CoM с учетом момента инерции относительно любой фиксированной оси вращения (обратите внимание, что в 2D любые две оси вращения всегда параллельны, в отличие от 3D-случая). - person Hristo Iliev; 22.01.2013
comment
@Beta теперь работает лучше, но у меня возникает проблема, когда у меня есть только одна частица в моем твердом теле в позиции (0,0), поэтому вычисление инерции дает мне 0, и я не могу делить на 0. Какую инерцию я должен установить на мой объект в этом случае? - person user1482649; 22.01.2013
comment
@ user1482649, если это точечная масса и ось вращения проходит через нее, то момент инерции равен 0, но также любая сила, приложенная к точке, дает нулевой крутящий момент и, следовательно, никакого вращения (кроме того, точечные объекты вращаются только в специальной теории относительности и квантовая механика, но не в классической механике). Вы должны обрабатывать это как особую ситуацию в вашем решателе. - person Hristo Iliev; 23.01.2013
comment
@HristoIliev Хорошо, спасибо, даже если у меня возникнут проблемы с пониманием, чтобы я мог физический движок правильно вычислить инерцию, потому что если мы возьмем мяч в реальном мире, инерция - это часть миллиарда частиц, не находящихся в центре (это атомы ), но в физическом движке мы аппроксимируем его сеткой идеального шара в позиции (0,0), и поэтому инерция становится равной 0. Я не понимаю, как традиционный физический движок (2d или 3d) может решить эту проблему. ситуация. - person user1482649; 23.01.2013