Collision problem

Started by
15 comments, last by cptrnet 18 years, 10 months ago
Hi I have two circles when they collide I trade their velocities just for right now, but it seems sometimes they stick together, thats probably because I trade the velocities and i keeps trading it because its colliding, the way I want to deal with this is pull them apart so there not colliding anymore and then trade their velocities. Would I need to find out the angle they collide at? I dont know how to do any of this, If there is a better way please let me know, or if you know a way to do it the way im thinking, thanks.
If you insist on saying "DUH", try to make a post that makes a little more sense
Advertisement
For my E-Motion remake, which is all about colliding spheres, I used the info on this subject from this page:

Collision detection in AniSprite

Very clearly written, with illustrations and everything.
I don't understand a single word on there, I am really lost.
If you insist on saying "DUH", try to make a post that makes a little more sense
it's using te reflection angle. I prefer the vector maths version. Much easier. Incidently, this is also tied with Newton's principle of the conservation of momentum for elastic collisions.

If you don't understand, you should really read about

1) Newton's laws of physics
2) vector maths, trigonometry, linear algebra. And possibly matrices if you wanna go one step further.

That's all there is. You can't do game phyiscs without those well covered. Most of it is A-level phyiscs and maths.

If you do understand those principles, maybe this will help.

http://www.gamedev.net/community/forums/topic.asp?topic_id=318145

Everything is better with Metal.

If it helps, here is the (simplified) function that handles the sphere collisions in my game E-Motion Deluxe. I left out the big-small-sphere collision and the new-sphere-spawn part, because that is irrelevant here. It is written in BlitzBasic, a BASIC language, and i'll explain a few things that are particular to this specific basic "dialect" so you'll understand.

For example the code Spheres(4)\ySpeed# means, look in the array called Spheres, take the 4th record and look at the ySpeed# variable (or "property") of that record. In BlitzBasic a # (pound sign) means it is a floating point variable or constant. All variables without a # are integers. And the ; (semi-colon) is the comment indicator.

So here goes. [grin]

Const THRESHOLD_FORCE# = 0.1; Nr1, Nr2 are Spheres array indexes; X1#, Y1# and X2#, Y2# are the centre position of the 2 spheresFunction HandleSphereCollision(Nr1, Nr2, X1#, Y1#, X2#, Y2#)  ; collision angle, angle of line through centre of the spheres  CollisionAngle = ATan2((Y2 - Y1), (X2 - X1))  ; align sphere speed vectors to the collision angle  AngleBall1 = ATan2(Spheres(Nr1)\ySpeed#, Spheres(Nr1)\xSpeed#) - CollisionAngle  AngleBall2 = ATan2(Spheres(Nr2)\ySpeed#, Spheres(Nr2)\xSpeed#) - CollisionAngle  ;preserve kinetic energy, E(k), the speed vector  Ek1# = Sqr((Spheres(Nr1)\ySpeed#^2) + (Spheres(Nr1)\xSpeed#^2)) ; ^2 means to the 2nd power  Ek2# = Sqr((Spheres(Nr2)\ySpeed#^2) + (Spheres(Nr2)\xSpeed#^2))  ;speed vectors aligned, so now the x-axis IS the collision angle, swap the x-vectors  CollisionXspeed1# = Ek1# * Cos(AngleBall1)  CollisionYspeed1# = Ek1# * Sin(AngleBall1)  CollisionXspeed2# = Ek2# * Cos(AngleBall2)  CollisionYspeed2# = Ek2# * Sin(AngleBall2)  ; if spheres are already moving away from each other, then they cannot collide  ; this situation can occur when spheres is spawned, and overlaps another sphere  If ((CollisionXspeed2# - CollisionXspeed1#) < 0) Then    ;spheres not already moving away, so swap the x-vectors    tmpX# = CollisionXspeed1#    CollisionXspeed1# = CollisionXspeed2#    CollisionXspeed2# = tmpX#  End If  ; when colliding, spheres MUST move away from each other, must have at least some speed  If (CollisionXspeed1# > -1*THRESHOLD_FORCE#) Then CollisionXspeed1# = -1 * THRESHOLD_FORCE#  If (CollisionXspeed2# < THRESHOLD_FORCE#) Then CollisionXspeed2# = THRESHOLD_FORCE#  ;preserve new calculated kinetic energy  Ek1# = Sqr(CollisionYspeed1#^2 + CollisionXspeed1#^2) ; ^2 means to the 2nd power  Ek2# = Sqr(CollisionYspeed2#^2 + CollisionXspeed2#^2)  ;reverse aligning speed vectors  AngleBall1 = ATan2(CollisionYspeed1, CollisionXspeed1) + CollisionAngle  AngleBall2 = ATan2(CollisionYspeed2, CollisionXspeed2) + CollisionAngle  ;store new xSpeed and ySpeed values  Spheres(Nr1)\xSpeed# = Ek1# * Cos(AngleBall1)  Spheres(Nr1)\ySpeed# = Ek1# * Sin(AngleBall1)  Spheres(Nr2)\xSpeed# = Ek2# * Cos(AngleBall2)  Spheres(Nr2)\ySpeed# = Ek2# * Sin(AngleBall2)End Function


[Edited by - BdR on June 1, 2005 1:14:59 PM]
thanks for all the help guys.
BdR I tried to implement your code but when the two circles touch they disappear, I put a break point to see what where there new velocities and they seem fine.
If you insist on saying "DUH", try to make a post that makes a little more sense
I put about 50 circles moving around and somtimes it works, but mostly when the two circles touch the disappear or go up in the top left corner.
If you insist on saying "DUH", try to make a post that makes a little more sense
he is using divisions. Check for divide by zeroes, and generally values of vectors. If it works most of the time, likely to be a math bug. can't help you with that.

Everything is better with Metal.

No, i'm not using division in my example, there is no dividing at all. Remember that in code Spheres(Nr1)\xSpeed#, the \ (backslash) is a property indicator, not a division operator. Division is done with a / (slash) it's a bit confusing, i know..

In Visual Basic code it would look something like this Spheres(Nr1).xSpeed so which programming language do you use anyway?
I am using C# .net
here is my code

public void TradeVelocity(xVolume volume)		{			double THRESHOLD_FORCE = 0.1f;			double x1, y1, x2, y2;			x1 = XPos + Radius;			y1 = YPos + Radius;			x2 = volume.XPos + volume.Radius;			y2 = volume.YPos + volume.Radius;			double CollisionAngle = Math.Atan2((y2 - y1), (x2 - x1));			double AngleBall1 = Math.Atan2(velocity.Y, velocity.X) - CollisionAngle;			double AngleBall2 = Math.Atan2(volume.velocity.Y, volume.velocity.X) - CollisionAngle;			double ek1 = (velocity.Y * velocity.Y) + (velocity.X * velocity.X);			ek1 = ek1 * ek1;			double ek2 = (volume.velocity.Y * volume.velocity.Y) + (volume.velocity.X * volume.velocity.X);			ek2 = ek2 * ek2;			Vector3 CollisionSpeed1;			CollisionSpeed1.X = (float)(ek1 * Math.Cos(AngleBall1));			CollisionSpeed1.Y = (float)(ek1 * Math.Sin(AngleBall1));			Vector3 CollisionSpeed2;			CollisionSpeed2.X = (float)(ek2 * Math.Cos(AngleBall2));			CollisionSpeed2.Y = (float)(ek2 * Math.Sin(AngleBall2));			if((CollisionSpeed2.X - CollisionSpeed1.X) < 0)			{				float tempX = CollisionSpeed1.X;				CollisionSpeed1.X = CollisionSpeed2.X;				CollisionSpeed2.X = tempX;			}			if(CollisionSpeed1.X > -1 * THRESHOLD_FORCE)			{				CollisionSpeed1.X = -1 * (float)(THRESHOLD_FORCE);			}			if(CollisionSpeed2.X < THRESHOLD_FORCE)			{				CollisionSpeed2.X = (float)(THRESHOLD_FORCE);			}			ek1 = (CollisionSpeed1.Y * CollisionSpeed1.Y) + (CollisionSpeed1.X * CollisionSpeed1.X);			ek1 = ek1 * ek1;			ek2 = (CollisionSpeed2.Y * CollisionSpeed2.Y) + (CollisionSpeed2.X * CollisionSpeed2.X);			ek2 = ek2 * ek2;			AngleBall1 = Math.Atan2(CollisionSpeed1.Y, CollisionSpeed1.X) + CollisionAngle;			AngleBall2 = Math.Atan2(CollisionSpeed2.Y, CollisionSpeed2.X) + CollisionAngle;			velocity.X = (float)(ek1 * Math.Cos(AngleBall1));			velocity.Y = (float)(ek1 * Math.Sin(AngleBall1));			volume.velocity.X = (float)(ek2 * Math.Cos(AngleBall2));			volume.velocity.Y = (float)(ek2 * Math.Sin(AngleBall2));		}
If you insist on saying "DUH", try to make a post that makes a little more sense

This topic is closed to new replies.

Advertisement