我的Rigid Body Collision代码如何不一致?

时间:2012-12-03 20:11:36

标签: java physics collision rigid-bodies

我一直在尝试复制此处找到的系统:http://www.myphysicslab.com/collision.html

到目前为止,这是我的代码(用于击中无限大型物体的情况,如不可移动的墙壁):

public static Orientation collide( float bodyMass_1, float bodyVelocityX_1, float bodyVelocityY_1, float bodyAngleMomentum_1 , float pointXFromCenterX_1, 
float pointYFromCenterY_1, float momentOfInertia_1,
float edgeNormalX, float edgeNormalY, float elasticity )
{
    Orientation returning;

    float outAngleMomentum_1;

    float outVelocityX_1, outVelocityY_1;

    float relativeNormal;
    float deltaParameter;

    float pointVelocityX_1, pointVelocityY_1;

    pointVelocityX_1 = bodyVelocityX_1 - bodyAngleMomentum_1 * pointYFromCenterY_1;
    pointVelocityY_1 = bodyVelocityY_1 + bodyAngleMomentum_1 * pointXFromCenterX_1;


    System.out.println( edgeNormalX );
    System.out.println( edgeNormalY );

    relativeNormal = (float) Funct3D.dotProduct( pointVelocityX_1, pointVelocityY_1,edgeNormalX, edgeNormalY );


    if ( relativeNormal < 0 )
    {

        deltaParameter = (-(1 + elasticity) *( (float) Funct3D.dotProduct( pointVelocityX_1, pointVelocityY_1, edgeNormalX, edgeNormalY ) ))/ 
        ( 1/bodyMass_1 + Funct3D.sqr( (float) Funct3D.perpDotProduct(pointXFromCenterX_1,pointYFromCenterY_1,edgeNormalX,edgeNormalY)) / momentOfInertia_1 );

        outVelocityX_1 = bodyVelocityX_1 + deltaParameter * edgeNormalX / bodyMass_1;
        outVelocityY_1 = bodyVelocityY_1 + deltaParameter * edgeNormalY / bodyMass_1;

        outAngleMomentum_1 = bodyAngleMomentum_1 + (float)     Funct3D.perpDotProduct(pointXFromCenterX_1, pointYFromCenterY_1,     deltaParameter*edgeNormalX, deltaParameter*edgeNormalY ) / momentOfInertia_1;

        returning = new Orientation( outVelocityX_1, outVelocityY_1, outAngleMomentum_1 );
    }
    else
    {
        System.out.println( "NO COLLISION" );
        returning = new Orientation( bodyVelocityX_1, bodyVelocityY_1, bodyAngleMomentum_1 );
    }
    return returning;
}

我的代码的结果通常导致速度不能通过正常反映,或者只是完全缺乏动量守恒。即使我拥有它只是让它在执行后立即输出结果,结果表明它不是多次注册碰撞的问题,它也是在第一次运行时发生的。

dotProduct返回两个向量的点积。

perpDotProduct返回两个向量的perp点积

如果您需要解释任何内容,或者您​​想要扩大代码范围,请随时提出。

1 个答案:

答案 0 :(得分:1)

对于这类任务,我建议您编写一个简单的测试,将输入参数传递给collide方法,并期望Orientation具有已知有效的值。

您可以使用JUnit框架或简单的main方法:

Orientation orientation = collide(a, b, c, d, ...);
assertEquals(KNOWN_X, orientation.getX());
assertEquals(KNOWN_Y, orientation.getX());
assertEquals(KNOWN_MOMENTUM, orientation.getMomentum());

使用此代码,您可以调试方法并检查算法的每个步骤的值是否正确。然后,您可以使用新的已知输入和输出值集检查算法。

还要考虑清理代码并将重复计算移到局部变量(即deltaParameter * edgeNormalX