JAVA动圆与非动圆弹性碰撞

标签 java math physics collision geometry

我正在尝试编写一个java移动应用程序(J2ME),但我遇到了一个问题:在我的项目中,有称为镜头的移动圆圈,以及称为球体的非移动圆圈。当射击击中球体时,根据经典物理定律,它应该反弹。但是我找不到任何此类算法。

镜头的移动由 x 轴和 y 轴上的速度(像素/更新)来描述。有关圆圈的所有信息都是已知的:它们的位置、半径和射击速度(在 x 轴和 y 轴上)。

注意:碰撞后球体不会开始移动,它会停留在原位。碰撞是两者之间的弹性碰撞,而球体保持静止

这里是Shot类中的碰撞解决方法:

public void collision(Orb o)
{
    //the orb's center point
    Point oc=new Point(o.getTopLeft().x+o.getWidth()/2,o.getTopLeft().y+o.getWidth()/2);
    //the shot's center point
    Point sc=new Point(topLeft.x+width/2,topLeft.y+width/2);

    //variables vx and vy are the shot's velocity on axis x and y
    if(oc.x==sc.x)
    {
        vy=-vy;
        return ;
    }

    if(oc.y==sc.y)
    {
        vx=-vx;
        return ;
    }

    // o.getWidth() returns the orb's width, width is the shot's width

    double angle=0;  //here should be some sort of calculation of the shot's angle
    setAngle(angle);
}

public void setAngle(double angle)
{
    double v=Math.sqrt(vx*vx+vy*vy);
    vx=Math.cos(Math.toRadians(angle))*v;
    vy=-Math.sin(Math.toRadians(angle))*v;
}

提前感谢所有帮助者

最佳答案

在碰撞点,动量、角动量和能量都被保留。设 m1、m2 为圆盘的质量,p1=(p1x,p1y)、p2=(p2x,p2y) 为碰撞时圆盘中心的位置,u1、u2 为碰撞前的速度,v1,v2 为碰撞后的速度。那么守恒定律要求

0 = m1*(u1-v1)+m2*(u2-v2)
0 = m1*cross(p1,u1-v1)+m2*cross(p2,u2-v2)
0 = m1*dot(u1-v1,u1+v1)+m2*dot(u2-v2,u2+v2)

使用第一个方程消除 u2-v2

0 = m1*cross(p1-p2,u1-v1)
0 = m1*dot(u1-v1,u1+v1-u2-v2)

第一个告诉我们,(u1-v1) 因此 (u2-v2) 是 (p1-p2) 的倍数,脉冲交换是在法向或径向方向上,没有切向相互作用。脉冲和能量守恒现在导致相互作用常数a,因此

u1-v1 = m2*a*(p1-p2)
u2-v2 = m1*a*(p2-p1)
0 = dot(m2*a*(p1-p2), 2*u1-m2*a*(p1-p2)-2*u2+m1*a*(p2-p1))

产生非零交互作用项a的条件

2 * dot(p1-p2, u1-u2) = (m1+m2) * dot(p1-p2,p1-p2) * a

现在可以使用分数来解决

b = dot(p1-p2, u1-u2) / dot(p1-p2, p1-p2)

作为

a = 2/(m1+m2) * b

v1 = u1 - 2 * m2/(m1+m2) * b * (p1-p2)
v2 = u2 - 2 * m1/(m1+m2) * b * (p2-p1)

要使第二个圆盘静止,请将 u2=0 并将其质量 m2 设置为非常大或无穷大,然后第二个公式为 v2=u2=0,第一个公式为 v2=u2=0

<小时/>

v1 = u1 - 2 * dot(p1-p2, u1) / dot(p1-p2, p1-p2) * (p1-p2)

<小时/>

也就是说,v1 是 u1 在以 (p1-p2) 作为法线的平面上的反射。请注意,碰撞点的特征为 norm(p1-p2)=r1+r2

dot(p1-p2, p1-p2) = (r1+r2)^2

这样分母就可以从碰撞检测中得知。

<小时/>

根据您的代码,oc{x,y} 包含固定圆盘或球体的中心,sc{x,y} 包含中心,{vx,vy} 包含移动圆盘的速度。

  1. 计算 dc={sc.x-oc.x, sc.y-oc.y}dist2=dc.x*dc.x+dc.y*dc.y

    1.a 检查 sqrt(dist2) 是否足够接近 sc.radius+oc.radius。人们普遍认为,比较平方更有效。如果dist2太小,请微调交点的位置。

  2. 计算 dot = dc.x*vx+dcy*vydot = dot/dist2

  3. 更新vx = vx - 2*dot*dc.xvy = vy - 2*dot*dc.y

特殊情况包含在这些公式中,例如,对于 dc.y==0,即 oc.y==sc.y 得到 dot=vx/dc.x,从而得到 vx=-vxvy=vy 结果。

关于JAVA动圆与非动圆弹性碰撞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23180453/

相关文章:

java - 创建一个类似 "Notification Bar"的菜单

python - 由重叠圆圈组成的图形的面积和周长

python - DataFrame 的派生

algorithm - 在圆形碰撞和旋转方面需要帮助吗? - 游戏物理

c++ - 如何包装对象,使它们成为无法交互的独立类型?

java - 如何确定异常是否为 ClientAbortException

java - 使用 SSL 的 Metro Web 服务 - 这是一个安全的对话吗

java - 从Java代码检查CFS中是否存在某个文件

c# - 使用数学运算符评估字符串

ios - 使用 3 个 CGPoints 寻找角度