Jump to content
  • Advertisement
Sign in to follow this  
cptrnet

Collision problem

This topic is 4934 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

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.

Share this post


Link to post
Share on other sites
Advertisement
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

Share this post


Link to post
Share on other sites
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 spheres
Function 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]

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
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));

}

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!