Collision Physics Question

Started by
17 comments, last by Selenaut 11 years, 2 months ago

Hello again, all.

So I've kind of switched gears since my last game idea; this time, I'm thinking about a 2D platformer. I won't get into details, but I'm making the entire engine from scratch and I'm currently having some trouble writing an algorithm for one of the physics mechanics.

So suppose we have an object moving in a 2D plane that hits a static object (e.g. a wall) that is at an angle. Rather than bouncing, the object hits the wall and begins to slide down (or against, or whatever) the slope via deflection. If we know the velocity vector of the object before and the angle of the slope that it collides with, what is the resulting vector?

I have an idea that I can explain in words, but I can't seem to figure out how to program. What I've done on paper is put the object's incident vector's tip at the collision point on the slope. I then extend this vector past (underneath) the slope to find the hypotenuse of a right triangle. The legs are parallel and perpendicular to the face of the slope. the leg of the triangle that's parallel to the slope is obviously the resultant vector of the object, and it moves in that direction to slide down the slope.

The problem is: What is the formula for that?

I've already done bouncing off slopes, but this in comparison is much more complex of a problem. I want to use this to create fluid motion when the PC is sliding up and down slopes.

If you want to see my vector classes, I can post them, but at the moment, I'm just asking for help on the equation.

(Side note: Due to the way I'm planning to implement these slopes, I don't have to worry about ray casting or anything, as the game will be tile-based and each of the slope tiles will have angle variables that can be accessed when colliding with them.)

Thanks,

Selenaut

Advertisement
That you say you have done bouncing, but cannot figure out this, plus that you talk about the 'angle' of the slope tells me you are using trigonometry to do the bouncing... *sigh* :)

The solution is incredibly simple, using simple vector operations.

You have the slope normal vector (As opposed to its angle)
You have the incident velocity.

The outgoing velocity is then: newVelocity = velocity - normal*(1+e)*dot(velocity, normal)
where e is the coefficient of restitution. For a perfectly elastic bounce e = 1, for a perfectly inelastic bounce (your 'slide') e = 0.

If you're struggling to compute the normal vector. Assuming you have two positions for the slope 'a' and 'b' that you're using to compute your angle like atan2(b.y-a.y, b.x-a.x), then the normal for this slope is instead: unit(a.y-b.y, b.x-a.x). The normal is a unit-length vector that points 'out' (or 'in' for these purposes, makes no difference to the result) of the surface, so the left side of a box will have normal (-1, 0) etc.
Thanks for the reply.

My difficulty wasn't in finding the normal of the slope, I can do that in my sleep - my problem was apparently failing to know what a dot product was. Heh... biggrin.png

Thanks for the equation - maybe it'll also fix the bug I'm having with my bounce equation (a ball with a restitution of 0.95 fails to decrease bouncing height enough to where I can safely stop it without having to wait for-freaking-ever).

EDIT: I got the equation working, but my bounce bug still remains, but it now applies to sliding as well (Hurray, moths in the machine). Basically what's happening is that no matter what restitution value (between 0 & 1, obviously) I give the object, it simply keeps bouncing. For ever. And never stops. So should I apply a friction force as well? (I think what's happening is that, since the amount the object bounces is (restitution)^(num of bounces), it simply begins to level out and become more difficult to bounce noticeably less.)

So I have tried to figure out how to handle my collision precision problem, and I can't figure it out. I'm thinking that I can check how far in a direction I can move and then only moving as far as the bounds allow but I can't figure out how to program it. Anybody got any ideas?

EDIT: If there is a simpler algorithm for detecting for collisions, I'm all ears. However at this point, I'll accept anything that works semi-quickly. XD

Thanks,

Selenaut

If you implemented the formula above correctly, a restitution of zero would make the object stop dead in the direction of the normal, and thus not bounce at all. It sounds as though something is still wrong. Is the normal normalised? It should be easy to check whether the equation is working. Find the dot product of the normal and outgoing velocity, and it should be zero.

No, it's nothing with the actual bouncing; it's a problem with collision detection. I can't figure out how to bounce precisely when the object hits a wall.

Also, I could show you my code, but it may get a little confusing as I've already got a lot of stuff set up in separate classes. Really, all I need is a good collision detection algorithm that's precise.

Thanks again,

Selenaut

You're talking about continuous collision detection. You only need that if the objects are moving fast enough that they could pass through a wall in one frame.

Otherwise you can wait until an intersection occurs before correcting it. Move the object out in the direction in which the intersection is a minimum. After that, correct the velocity using the same normal, with or without bounce.

Yes, I realize this; what I've been trying to say is that I can't figure out how to correct the collision so that it is precisely set back to where the object is just barely touching the wall.

When I tried to correct it by simply placing it back into the bounds, it created the effect of an infinitely bouncing ball when its bounce height got small-ish. It never - literally, never - stopped bouncing.

So yes; How do I correctly, err... correct the collision?

Thanks,

Selenaut

Could be the update order. This should work:

Apply gravity and other forces.
Update position.
Find intersections.
Apply position corrections.
Apply collision impulses.

If the contact velocity is below some small threshold, use a restitution of zero, to avoid tiny bounces.

Check the collision calculations. What primitives are you using? How do you find intersection distances?

Okay, let me clarify this:

I'm using an effective AABB for my object. I'm currently attempting to bounce it off the walls of the window (drawing using BufferedImage - it's in Java).

Using my own motion system class, I have the program set up so that every tick (about 1/60 of a second, not the same as a frame) the object moves in relation to its current acceleration and velocity to its new position. Both velocity and acceleration are vectors (a custom class), and x and y are held as doubles for precision.

I then check for whether the AABB is outside of the bounds of the window.

The problem is somewhere in the collision position correction section, which I'm still telling you is the problem. My first go was something like "If the x-val of the AABB is out of bounds, move it so that the x-val is back in bounds; repeat for y."

Then I used the bounce function.

This obviously causes, as I've stated, the infinite bouncing problem (it also doesn't play nice with a "bounce" with restitution of 0). The problem is how I correct the position, and I have an idea of how to fix it: I can check for whether the next movewill put me out of bounds, if so how far; then using this, back up a specific amount so that the intersection amount becomes 0. I'm having troubles coding specifically this.

Sorry if that sounded impatient, it's just that it's very difficult to explain it when I don't have the code to put up atm.

Selenaut

This topic is closed to new replies.

Advertisement