• Advertisement

# Collision Physics Question

This topic is 1815 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

## Recommended Posts

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

#### Share this post

##### Share on other sites
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. Edited by luca-deltodesco

#### Share this post

##### Share on other sites
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...

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.) Edited by Selenaut

#### Share this post

##### Share on other sites

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

#### Share this post

##### Share on other sites
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.

#### Share this post

##### Share on other sites

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

#### Share this post

##### Share on other sites
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.

#### Share this post

##### Share on other sites

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

#### Share this post

##### Share on other sites
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?

#### Share this post

##### Share on other sites

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

#### Share this post

##### Share on other sites
Moving the AABB back into the bounds of the window is exactly what you should do, with the velocity change applied after that.

I can't help much beyond that, sorry. Everything needed to solve the problem is in this thread; it should work, short of bugs.

#### Share this post

##### Share on other sites

Okay, so I came up with this formula for finding the precise moment of impact.
t = the amount of time one discreet timestep takes (currently set at 1/60 of a second)
mv = magnitude of the velocity vector (x & y change each stimestep by t*velocity, with respect to each axis)
p = the amount the moving object penetrated past the collision point as measured by the wall's normal (0 if it didn't collide)
?v = angle of the velocity vector
?w = the angle of the wall

The amount of time the object should move is equal to t - (|p/sin(?v-?w)|/mv). Then it bounces, and runs the rest of the timestep. I'm almost certain this is correct, right?

Well, I'm getting a bug where when it corrects, the object bounces, but flies off the screen when the bounce height gets near 0. Within a second, its coordinates are in the billions (bouncing off the walls of a 640*480-ish window - obviously a problem.) So, err..... Yeah. Any ideas?

Selenaut

#### Share this post

##### Share on other sites
Probably caused by division by zero or a small number. Also I don't think you need angles in the formula.

If the speed in the direction of the wall is v and p is the penetration distance at the end of the move then the time to collision is (t - p / v).

But if p <= 0 then time = t, and if p > vt then time to collision = 0. Check those first to avoid numerical errors in the division.

#### Share this post

##### Share on other sites

I'm using angles because I'm using vectors and not keeping track of individual x- and y- axis motion, but rather speed in a direction. The use of angles also gives me the possibility of using angles other than right angles, e.g. 45- and 22.5-degree ramps. (I'm hoping to get to ramps in the future, but at the moment I'm only worrying about 90-degree angles; I'm just trying to write it so that it's easy to port later.)

EDIT: I forgot to mention the whole division thing: That's exactly what it is, and I can't believe I didn't realize that. I'll let you know if correcting that fixes the problem.

Thanks,

Selenaut

PS: I hate the quick edit feature. XD

Edited by Selenaut

#### Share this post

##### Share on other sites

What reason do you have to say that using x/y vectors would not permit you to have anything but right-angle ramps? Using angle/magnitude for vectors is almost NEVER the good way of doing things, it quite simply makes everything more complicated.

#### Share this post

##### Share on other sites

Using angle/magnitude for vectors is almost NEVER the good way of doing things, it quite simply makes everything more complicated.

Unless you're planning on using non-right-angles for anything other than ramps... which I am. Also, nice oxymoron. ;)

EDIT: I see what you mean, definitely less trig involved, even for my above statement. I'll convert all my classes, and tell you how it turns out.
EDIT 2: Okay, how the heck to I program bouncing now? XD

Selenaut Edited by Selenaut

#### Share this post

##### Share on other sites

It is not that there is less trig involved when using x-y vectors, but that there is NO trig involved.

I already showed you earlier how to do bouncing.

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.

#### Share this post

##### Share on other sites

Are you saying that I can just use the x- and y-components to do the same thing? I figured it out but had to use a bit of trig... and the original method. XD

EDIT: ...Why the heck do I have like 7 -1's on this thread alone? (Not to mention they're my only -1's.) How am I supposed to report this?

Edited by Selenaut

#### Share this post

##### Share on other sites

Alright, shy of some bugs that I can fix relatively quickly (hopefully), I got it working. Thanks guys.

Selenaut

P.S.: Can anybody tell me why I have so many -1's?

#### Share this post

##### Share on other sites

• Advertisement