2

I've been trying to replicate the system found here: http://www.myphysicslab.com/collision.html

So far this is my code (for the case of hitting an infinitely massive object, like an immovable wall):

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;
}

The results of my code often result in the velocity not reflecting through the normal, or just an entire lack of conservation of momentum. Even when I have it just have it output the results immediately after execution, the results show that it isn't a matter of registering the collision several times, it occurs on its first run as well.

dotProduct returns the dot product of two vectors.

perpDotProduct returns the perp dot product of two vectors

If you need anything explained, or if you'd like to request the code scope to be widened any, please feel free to ask.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Jonathan Pearl
  • 711
  • 8
  • 21
  • 1
    Probably unrelated to your problem, but: "Clean Code" recommends that a method not have more than 3 parameters and considers more parameters a wasted opportunity for encapsulation. Just image how simple your code would read it you encapsulated coordinate pairs / vectors into their own class, which also provides operations for adding, scaling, and computing the dot product of the vectors involved. – meriton Dec 03 '12 at 20:27
  • If the output of your program is wrong, you should consider using a debugger to try to discover the problem. See http://stackoverflow.com/questions/25385173/what-is-a-debugger-and-how-can-it-help-me-diagnose-problems – Raedwald Aug 22 '14 at 06:51

1 Answers1

1

For this kind of task I would recommend to write a simple test, where you pass input parameters into collide method and expect Orientation with values that are known to be valid.

You can use JUnit framework or simple main method:

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

With this code you can debug your method and check that values are correct at each step of your algorithm. Then you can check algorithm with new set of known input and output values.

Also consider cleaning up your code and move repetitive calculations to local variables (i.e. deltaParameter * edgeNormalX)

hoaz
  • 9,883
  • 4
  • 42
  • 53
  • I've actually thought about doing that, but I can not find any test cases other than assuming that if the x velocity is 0, and is moving downwards with no rotation, that if it hits a horizontal wall it should just rebound vertically. Do you know of, or could provide a system in order to generate a set of cases? Yeah, it's a bit dirty and fragmented. I was going thinking of combine all of the dot products between the velocity and collision vector, but I've been changing it so much lately trying to test different alternatives I figured it best leaving it how it is, but I will when I finish. – Jonathan Pearl Dec 03 '12 at 20:36
  • Well, this is very specific question and I am not physicist. My knowledge in this area is limited to our courses in university and that was quite a long time ago. If you know that there is something wrong with code, then you should have a paper calculations that should be correct. That said, compare your paper calculations with what your code does. – hoaz Dec 03 '12 at 20:41
  • All right, after several test cases, and toiling around -- I have found the problem. It was a special case in my segment-to-segment intercept method that was throwing it off. Apparently it would throw erratic numbers in a certain range due to a misnamed variable. Thanks Hoaz, it has been fixed, and I'll be working towards reducing redundant calculations and classing together the parameters. Cheers! – Jonathan Pearl Dec 04 '12 at 04:04