Jump to content

  • Log In with Google      Sign In   
  • Create Account


Collision Physics Question


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
18 replies to this topic

#1 Selenaut   Members   -  Reputation: 102

Like
0Likes
Like

Posted 27 January 2013 - 11:17 AM

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



Sponsor:

#2 luca-deltodesco   Members   -  Reputation: 637

Like
3Likes
Like

Posted 27 January 2013 - 02:17 PM

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, 27 January 2013 - 02:19 PM.


#3 Selenaut   Members   -  Reputation: 102

Like
-1Likes
Like

Posted 27 January 2013 - 04:17 PM

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.)

Edited by Selenaut, 27 January 2013 - 04:51 PM.


#4 Selenaut   Members   -  Reputation: 102

Like
0Likes
Like

Posted 28 January 2013 - 02:39 PM

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



#5 EWClay   Members   -  Reputation: 659

Like
1Likes
Like

Posted 28 January 2013 - 03:43 PM

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.

#6 Selenaut   Members   -  Reputation: 102

Like
-1Likes
Like

Posted 28 January 2013 - 07:12 PM

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



#7 EWClay   Members   -  Reputation: 659

Like
0Likes
Like

Posted 29 January 2013 - 05:08 AM

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.

#8 Selenaut   Members   -  Reputation: 102

Like
-1Likes
Like

Posted 29 January 2013 - 09:12 AM

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



#9 EWClay   Members   -  Reputation: 659

Like
0Likes
Like

Posted 29 January 2013 - 11:07 AM

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?

#10 Selenaut   Members   -  Reputation: 102

Like
-1Likes
Like

Posted 29 January 2013 - 11:31 AM

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



#11 EWClay   Members   -  Reputation: 659

Like
1Likes
Like

Posted 29 January 2013 - 03:21 PM

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.

#12 Selenaut   Members   -  Reputation: 102

Like
0Likes
Like

Posted 30 January 2013 - 10:24 AM

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(θvw)|/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



#13 EWClay   Members   -  Reputation: 659

Like
1Likes
Like

Posted 30 January 2013 - 11:06 AM

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.

#14 Selenaut   Members   -  Reputation: 102

Like
-1Likes
Like

Posted 30 January 2013 - 11:26 AM

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, 30 January 2013 - 11:38 AM.


#15 luca-deltodesco   Members   -  Reputation: 637

Like
0Likes
Like

Posted 30 January 2013 - 02:00 PM

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.



#16 Selenaut   Members   -  Reputation: 102

Like
-1Likes
Like

Posted 30 January 2013 - 02:04 PM

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, 30 January 2013 - 03:18 PM.


#17 luca-deltodesco   Members   -  Reputation: 637

Like
1Likes
Like

Posted 30 January 2013 - 04:21 PM

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* smile.png

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.



#18 Selenaut   Members   -  Reputation: 102

Like
-1Likes
Like

Posted 30 January 2013 - 05:57 PM

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, 31 January 2013 - 12:01 PM.


#19 Selenaut   Members   -  Reputation: 102

Like
-1Likes
Like

Posted 31 January 2013 - 12:00 PM

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?






Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS