当其中一个顶点与它发生碰撞时,我试图弹出一个多边形,该多边形具有一个(不可移动的)墙上的速度和角速度.我可以检测到碰撞,并且我已经研究了如何计算输入并知道我需要什么输出,但是无法找到或计算出响应的实现.任何帮助将不胜感激.
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;
}
Run Code Online (Sandbox Code Playgroud)
虽然不是完全无关紧要,但计算可以减少到高中水平的数学.我走的最多 - 但不是全部 - 一路走来:最后的二次方程我留给你写下来解决.SO上没有LateX,所以请耐心等待.
答案取决于几个附加参数:(1)物体M的质量,(2)物体的惯性矩,表示为I,(3)碰撞的弹性系数,比如α - 意思,多少碰撞中保留动能:0表示完全失去能量(塑性碰撞),1表示完全保持动能(完全弹性碰撞).
根据牛顿力学规则,墙壁沿着rv(在你的符号中)对物体运行一些未知的脉冲 J(基本上是F dt),导致直线和角动量的变化:
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
现在我们要求最终的动能是初始动能的α倍(这是碰撞弹性的定义).如果你将这两个表达式等同,你将得到J中的二次方程式 - 记下解决方案,并按要求得到Vf和Af.
关于交叉积的注意事项:在2D中,J x cp可以将乘积缩减为标量J*cp*sin(theta),其中θ是cp和rv之间的角度.
Theta已签署,必须小心谨慎!简而言之,如果你的a(角动量)对于逆时针旋转是正的 - 那么theta,J和cp之间的角度应该是从J到cp的逆时针角度.例如+45,当cp从J逆时针旋转45度时(当然是弧度)
这是我在SO的降价中所做的最好的事情.随意询问是否需要进一步澄清.
[编辑:](1)我修复了-cp回到cp.这个乘法顺序(Jxcp)已经翻转了符号,无需额外翻转.
(2)这是一个LateX-less图形尝试:

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