2D碰撞响应 - 旋转,移动的多边形撞墙。

3

我正在尝试将一个具有速度和角速度的多边形从不可移动的墙壁上弹回,当其中一个顶点与其碰撞时。我可以检测到碰撞,并且已经计算出了输入并知道需要什么输出,但是我还没有找到或者想出响应的实现方法。任何帮助都将不胜感激。

function collisionResponse(
    c, // object center of mass position
    v, // velocity of object
    a, // the angular velocity of the object
    p, // point of contact with line
    n  // normalized normal of line
) {
    //  Make a vector from center mass to contact point
    cp = p - c;

    //  Total velocity at contact point (add angular effect)
    pv.x = v.x - cp.y * a;
    pv.y = v.y + cp.x * a;

    //  Reflect point of contact velocity off the line (wall)
    rv = reflect( pv, n );

    // ..magic happens.. ??

    result.v = ?? // resulting object velocity
    result.a = ?? // resulting object angular velocity
    return result;
}
1个回答

5
虽然并不十分简单,但这个计算可以简化为高中数学水平。我会解释大部分,但不是全部:最终的二次方程需要你自己写下来并解决。由于SO上没有LaTeX,所以请耐心等待。
答案取决于几个附加参数:(1) 物体的质量M,(2) 物体的转动惯量,表示为I,(3) 碰撞的弹性系数,称为alpha - 意思是碰撞中有多少动能得到保留:0表示完全损失能量(塑性碰撞),1表示完全保留动能(完全弹性碰撞)。
墙对物体施加了一些尚未知的冲量J(实质上是F dt),沿着rv(按照您的符号),根据牛顿力学规则导致了直线和角动量的变化。

J x cp = I * diff(a) (这是一个叉积,详情见下文)

J = M * diff(v)

假设初始速度为Vi,最终速度为Vf,同样地,初始角速度为Ai,最终角速度为Af。因此:

Vf = Vi + J/m

Af = Ai + (J x cp) / I

初始和最终动能分别为:

Ei = 0.5 * M * Vi^2 + 0.5 * I * Ai^2 Ef = 0.5 * M * Vf^2 + 0.5 * I * Af^2

将Vf和Af代入:

= 0.5*M*(Vi + J/m)^2 + 0.5*I*(Ai + (J x cp) / I)^2

现在我们要求最终动能是初始动能的alpha倍(这是碰撞弹性的定义)。如果将这两个表达式相等,你将得到一个以J为未知量的二次方程 - 记下解答,你就能得到所需的Vf和Af。

关于叉积的注释:在二维中,J x cp 的积可以简化为一个标量,即 J*cp*sin(theta),其中 theta 是 cp 和 rv 之间的夹角。Theta 是有符号的,必须注意其符号!简而言之,如果你的 a(角动量)对逆时针旋转是正的,则 J 和 cp 之间的角度 theta 应该是从 J 到 cp 的逆时针角度,例如当 cp 逆时针旋转 45 度时为 +45。(当然是弧度制)这大概是我在 SO 的 markdown 中能做到的最好的了。如果需要更多的澄清,请随时问我。

[编辑:] (1) 我将 -cp 更正为 cp。这个乘法顺序(Jxcp)已经翻转了符号,不需要额外翻转。

(2) 这是一次没有使用 LateX 的图形尝试:J cp

(3) 只有在假设质量密度均匀时,质量m和转动惯量I才由一个恒定的乘法系数相关。如果您确实假设可以放弃其中一个输入 - 但它们通常被保留为两个,因为它们形成了一种更直接的描述对象的方式。
(4) 澄清:转动惯量 I不是从方程中推导出的变量,而是问题的参数。就像质量M一样-本质上,它描述了旋转物体的难度-它描述了旋转物体的难度。详细的(不复杂的)积分计算在维基百科链接中,对于简单的物体-球体,圆柱体,立方体-您可以轻松地在线找到预先计算好的结果。

非常感谢你,Ofek。我今晚会尝试着去解决这个问题。 - pixelmike
差异。diff(v) = Vf - Vi - Ofek Shilon
抱歉,我的数学技能非常薄弱。我仍然不理解如何使用需要J的方程式,但我们需要计算出速度和角速度以计算J...而这些正是我想要得到的结果。还有一件事…我们需要物体的质量吗?对于任何质量都是相同的,是吗? - pixelmike
感谢您的所有时间。我想我有点困惑,我确实有J,它是我的向量rv。我不知道的是I的值。所以我的函数将是:result.v = v + rv; result.a = a + cross(rv, cp) / i; 但我仍然没有I的值。 - pixelmike
不适合放在评论中 - 我在答案中加入了一些关于I的细节。 - Ofek Shilon
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接