4
\$\begingroup\$

I'm trying to bounce a polygon that has both velocity and angular velocity off a (immovable) wall when one of the vertices collides with it. I can detect the collision, and I've worked out how to calculate the inputs and know what outputs I need, but haven't been able to find or work out an implementation for the response. Any help would be greatly appreciated.

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;
}
\$\endgroup\$
3
  • \$\begingroup\$ Chris Hecker has written nice article about rigid body dynamics. This article describes exactly what you are asking for. Link to the home of article: chrishecker.com/Rigid_Body_Dynamics Part 3 of this article talks about collision response: chrishecker.com/images/e/e7/Gdmphys3.pdf \$\endgroup\$ Commented Jun 15, 2015 at 9:59
  • 2
    \$\begingroup\$ Have you ever thought about using an already built physics engine or you really want to make this yourself? \$\endgroup\$ Commented Jun 18, 2015 at 14:44
  • \$\begingroup\$ I have, and would but this is really the only function I need that I can't figure out myself. Plus I'd like it to be as lightweight as possible so I can run it on mobile browsers with Javascript. I also have the rest of the physics working already, and I think my collision tests are better optimized for my use case rather than using a general purpose solution. \$\endgroup\$
    – pixelmike
    Commented Jun 18, 2015 at 15:55

1 Answer 1

3
+50
\$\begingroup\$

You've got the moving part right but the rotating adds a significant amount of complexity to the problem. Luckily, you can hack in rotational velocity with a formula mentioned here. It approximates rotational velocity based on the distance from the center of mass to the point of contact, and the positional velocity.

Here's an implementation:

a = (cp.x * v.y - cp.y * v.x) / (cp.x * cp.x + cp.y * cp.y);

Or:

a = Vector.Cross (cp, v) / cp.sqrMagnitude;

Most of the time, you can stop here and not consider the transfer of energy between rotational and positional velocity because then you would have to get into surface friction and other scary things. For something like a boulder rolling off a mountain or a stick thrown against a wall, this would work perfectly. For a more physicsy game though, you might have to pick up a physics textbook and learn the subject inside-out - or just port an existing physics engine to your liking.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .