计算游戏中车辆的2D合力

时间:2012-03-06 00:25:06

标签: physics trigonometry collision

我正在尝试计算在发生碰撞时会对圆形物体起作用的力。不幸的是,我的机制略有生锈,所以我遇到了一些麻烦。

我有一个包含成员的代理类

vector position // (x,y)
vector velocity // (x,y)
vector forward // (x,y)  
float radius   // radius of the agent (all circles)
float mass     

因此,如果我们有A,B:Agent,并且在下一个时间步,速度将改变位置。如果要发生碰撞,我想计算出会对物体起作用的力。

我知道需要Line1 =(B.position-A.position)来计算合力的角度但是当我必须考虑车辆的当前速度时,如何计算它是令人困惑的。碰撞角度。

arctan(L1.y,L1.x)是力的角度(方向可以确定) sin / cos是组件的高度/宽度

我也知道要计算我需要使用的旋转轴 x = cos(T)* vel.x + sin(T)* vel.y y = cos(T)* vel.y + sin(T)* vel.x

这是我的大脑无法应付的地方..任何帮助都会受到赞赏。

正如我所说,目的是计算出应用于物体的矢量力,因为我已经考虑过基本物理学。

添加了一个小的psudocode来显示我开始使用它的位置..

A,B:Agent 

Agent {
    vector position, velocity, front;
    float radius,mass;
}

vector dist = B.position - A.position;
float distMag = dist.magnitude();

if (distMag < A.radius + B.radius) { // collision 
    float theta = arctan(dist.y,dist.x);
    flost sine = sin(theta);
    float cosine = cos(theta);

    vector newAxis = new vector; 
      newAxis.x  = cosine * dist .x + sine * dist .y;
      newAxis.y  = cosine * dist .y - sine * dist .x;

    // Converted velocities
    vector[] vTemp = { 
         new vector(), new vector()         };
    vTemp[0].x  = cosine * agent.velocity.x + sine * agent.velocity.y;
    vTemp[0].y  = cosine * agent.velocity.y - sine * agent.velocity.x;
    vTemp[1].x  = cosine * current.velocity.x + sine * current.velocity.y;
    vTemp[1].y  = cosine * current.velocity.y - sine * current.velocity.x;        

这是希望堆栈上有一个好奇的数学怪才。

1 个答案:

答案 0 :(得分:0)

让我们假设在不失一般性的情况下,我们在碰撞之前处于第二个对象的参考系中。

保持势头:

m1*vx1 = m1*vx1' + m2*vx2'
m1*vy1 = m1*vy1' + m2*vy2'

解决vx1',vy1':

vx1' = vx1 - (m2/m1)*vx2'
vy1' = vy1 - (m2/m1)*vy2'

暗地里,我会记住vx1'*vx1' + vy1'*vy1' = v1'*v1'

这一事实

能量守恒(弹性碰撞给我们的一个问题是入射角是反射角):

m1*v1*v1 = m1*v1'*v1' + m2*v2'+v2'

解决v1'平方:

v1'*v1' = v1*v1 - (m2/m1)v2'*v2'

结合消除v1':

(1-m2/m1)*v2'*v2' = 2*(vx2'*vx1+vy2'*vy1)

现在,如果你曾经看过一个静止的池球击中,你知道它会在接触法线的方向飞行(这与你的θ相同)。

v2x' = v2'cos(theta)
v2y' = v2'sin(theta)

因此:

v2' = 2/(1-m2/m1)*(vx1*sin(theta)+vy1*cos(theta))

现在你可以解决v1'(使用v1'=sqrt(v1*v1-(m2/m1)*v2'*v2')或者根据输入变量解决整个问题)。

我们打电话给phi = arctan(vy1/vx1)。相对于交点处圆的切线的入射角为90-phi-thetapi/2-phi-theta,如果您愿意的话)。再次添加该反射,然后转换回相对于水平的角度。我们称之为入射角psi = 180-phi-2*thetapi-phi-2*theta)。或者,

psi = (180 or pi) - (arctan(vy1/vx1))-2*(arctan(dy/dx))

所以:

vx1' = v1'sin(psi)
vy1' = v1'cos(psi)

考虑一下:如果这些圆圈应该是实心的3D球体,那么每个球体使用与半径立方成比例的质量(注意比例常数抵消)。如果它们应该是盘状的,则使用与半径平方成比例的质量。如果它们是环,只需使用半径。

下一步要考虑:由于计算机在离散时间事件中更新,实际上您有重叠的对象。在计算每个对象的新位置之前,应该退出对象以使它们不重叠。要获得额外的功劳,请计算出他们应该相交的时间,然后在新的方向上移动它们一段时间。请注意,此时间只是重叠/旧速度。这很重要的原因是你可能想象一个计算的碰撞导致对象仍然重叠(导致它们再次碰撞)。

下一点要考虑:将原始问题转化为此问题,只需从对象1中减去对象2的速度(按组件划分)。计算完毕后,请记得将其添加回来。

要考虑的最后一点:我可能在某个地方出现了代数错误。你应该认真考虑检查我的工作。