【问题标题】:Problems with Inertina when add force in 2d physic在 2d 物理中添加力时惯性的问题
【发布时间】:2013-01-21 22:23:33
【问题描述】:

我尝试制作一个非常简单的 2d 物理函数来解决以球体粒子作为对撞机的刚体,

我有这么一个刚体和粒子类:

    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(用脉冲将力存储在粒子中并定位我的粒子的世界位置):

    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 工作得很好,因为它接缝的角速度在最轻微的碰撞时会变得非常大, 目前,我没有使用任何阻尼(线性或角度),并且我的 angularVelocity 没有惯性,

我猜惯性缺失是我的问题,但是当我在互联网上查看如何计算它时,我有点困惑,

我在 box2d 中查看是否存储了惯性,并且它似乎是刚体的变量(作为质量)。 我在互联网上发现惯性 = 质量 * (r*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的计算是正确的,看代码的时候漏掉了什么?

非常感谢^^,

马吕斯。

【问题讨论】:

    标签: 2d box2d physics momentum angular-momentum


    【解决方案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。所以孤球具有正惯性矩(并且不会旋转),而所有其他物体仍然具有真实的物理特性。

    【讨论】:

    • 谢谢,很有用,我现在试试,不过到现在,有没有对box2d中公式的解释。 this.m_I = massData.I - this.m_mass * (massData.center.x * massData.center.x + massData.center.y * massData.center.y);如果他们先计算中心,在我的情况下结果是 0,然后乘以质量,仍然是 0 吗?是错误吗?
    • 我对此没有任何解释。 box2d不熟悉,不知道thismassData是什么。
    • @user1482649,这只是基础物理学——惠更斯-施泰纳定理。它指出,关于一个轴的惯性矩,平行于通过刚体质心 (CoM) 的轴(或 2D 情况下的轴),是关于 CoM 轴的惯性矩加上总体质量乘以两个轴之间的平方距离。在这里,它被应用于计算关于 CoM 的惯性矩,给定关于任何固定旋转轴的惯性矩(请注意,在 2D 中,与 3D 情况不同,任何两个旋转轴始终平行)。
    • @Beta 它现在工作得更好了,但是当我的刚体中只有粒子在位置 (0,0) 时出现问题,所以惯性的计算给了我 0,我不能除以 0。在这种情况下,我应该为我的对象设置什么惯性?
    • @user1482649,如果它是一个点质量并且旋转轴穿过它,那么转动惯量为 0,但任何施加在该点上的力都会产生零扭矩,因此不会旋转 (除了点物体只在狭义相对论和量子力学中旋转,而不在经典力学中旋转)。您应该将其作为求解器中的特殊情况来处理。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-20
    • 1970-01-01
    • 1970-01-01
    • 2021-06-30
    相关资源
    最近更新 更多