2D Collision response - rotating, moving polygon hitting a wall

1k views Asked by At

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

There are 1 answers

11
Ofek Shilon On

While not entirely trivial, the calculation can be reduced to high school level math. I'll walk most - but not all - of the way: the final quadratic equation I leave to you to write down and solve. There is no LateX on SO, so bear with me here.

The answer depends on several additional parameters: (1) The mass of the object M, (2) The moment of inertia of the object, denote as I, (3) An elasticity coefficient for the collision, say alpha - meaning, how much kinetic energy is conserved in the collision: 0 for complete loss of energy (plastic collision), 1 for complete preservation of kinetic energy (perfect elastic collision).

The wall operates some yet unknown impulse J (essentially F dt) on the object, along rv (in your notation), resulting both in change of straight and angular momentum, according to the Newtonian mechanics rules:

J x cp = I * diff(a) (this is a cross product, more below)

J = M * diff(v)

Say the initial velocity is Vi and the final one Vf, and similarly the initial angular velocity Ai and final Af. So:

Vf = Vi + J/m

Af = Ai + (J x cp) / I

The initial and final kinetic energy are:

Ei = 0.5 * M * Vi^2 + 0.5 * I * Ai^2 Ef = 0.5 * M * Vf^2 + 0.5 * I * Af^2

Letting Vf and Af in:

= 0.5*M*(Vi + J/m)^2 + 0.5*I*(Ai + (J x cp) / I)^2

Now we demand that the final kinetic energy be alpha times the initial kinetic energy (this is the definition of elasticity of a collision). If you equate those two expressions you'd get a quadratic equation in J - jot down the solution and you have Vf and Af as requested.

Note about cross product: in 2D the product J x cp can be reduced to a scalar obtained as J*cp*sin(theta), where theta is the angle between cp and rv.

Theta is signed and care must be taken with its sign! In a nutshell, if your a (the angular momentum) is positive for counter-clockwise rotation - then theta, the angle between J and cp, should be the counter-clockwise angle from J to cp. e.g. +45 when cp is 45 deg counter-clockwise from J. (in radians of course)

That's about the best I can do in SO's markdown. Feel free to ask if more clarifications are needed.

[Edits:] (1) I fixed -cp back to cp. This order of multiplication (Jxcp) already flips the sign, no need for an extra flip.

(2) Here's a LateX-less graphic attempt: J cp

(3) Only when assuming uniform mass density, are m and I related by a constant multiplicative coefficient. If you do assume that you can drop one of the inputs - but they are typically kept as two, as they form a more straightforward way of describing the object.

(4) Clarification: the moment of inertia I is not a variable to be deduced from the equation, it is a parameter of the problem. Just like the mass M - essentially, how hard it is to accelerate the object -it describes how hard it is to rotate the object. The detailed (not complicated) integral calculation is at the wikipedia link, and for simple objects - balls, cylinders, cubes - you'd easily find canned results online.