Sign in to follow this  

Simulate collision between two balls of equal mass?

This topic is 4686 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 all, Have been developing an Air Hockey game in C# and have only really gotten round to the idea of angles / collisions etc. Basically, the user controls the paddle (an ellipse) with the mouse. The puck is just an ellipse also. The puck can sense if a collision occurs (the paddle is inside it) so it's just the matter of figuring out how to simulate a realistic collision (i.e - in the opposite direction to which it was hit from and at a suitable speed). Any tips / advice on how to implement this would be great! Thanks in advance. Brian PS - I have it going the right direction using this code but at an unrealistic speed.
public void Player1Collision()
{
    x_vel = puck_x - paddle1_x;
    y_vel = puck_y - paddle1_y;
}

Share this post


Link to post
Share on other sites
Try this:


//
#define MIN(A, B) (((A) < (B)) ? (A) : (B))
int Distance2D(int X, int Y)
{
X = abs(X);
Y = abs(Y);
int Distance = MIN(X, Y);
return (X + Y - (Distance >> 1) - (Distance >> 2) + (Distance >> 4));
}
//
void Player1Collision(float PaddleForce)
{
float NormalX = puck_x - paddle1_x;
float NormalY = puck_y - paddle1_y;

float Distance = Distance2D(NormalX, NormalY);
if(Distance <= 2.0f * puck_Radius)
{
NormalX /= Distance;
NormalY /= Distance;

x_vel = (NormalX - -NormalY) * PaddleForce;
y_vel = (NormalY - NormalX) * PaddleForce;
}
}


Share this post


Link to post
Share on other sites
Cheers for the very useful code, UltimaX.

But your code has made me realise how inexperienced i am in the area of Game Programming and physics as:

(a) i have used no float types.. only ints.
(b) i have no idea what you mean by
#define MIN(A, B) (((A) < (B)) ? (A) : (B))

(c) i have not even calculated a radius with my ellipses (balls)

I think the only one for you and others to understand my plight is for me to post my entire source code. I don't want to do that as it's messy, it's a pain in the ass for people to try and read through and it's unnecessary.

I don't want to pester you people by posting my entire source code and asking you to step through every little fault. It's unfair and like i said, it's un-necessary.

Thank you for the help anyways. It's much appreciated.

PS - Bender.. i would have made that joke if you didn't think of it first! :)

Share this post


Link to post
Share on other sites
Quote:
#define MIN(A, B) (((A) < (B)) ? (A) : (B))

Is just a macro for:

int Min(int A, int B)
{
if( A < B)
return A;
else
return B;
}


Quote:
The puck can sense if a collision occurs (the paddle is inside it) so it's just the matter of figuring out how to simulate a realistic collision (i.e - in the opposite direction to which it was hit from and at a suitable speed).


That is a physics question of which you will need to use vectors for "realisitc" collisions. I am underqualified to explain, but maybe someone else can. The idea is that the puck will have a direction and magnitude it is traveling. When the paddle hits it, it too will have a direction and mass. I am thinking if you add the vectors, you will get a resultant of which tells the magnitude and direction it *should* go in. I'm sorry that I do not kave any examples of it, but maybe you can do some research into it as well.

- Drew

Share this post


Link to post
Share on other sites
Drew..

I think i got an example using vectors on how to simulate a collision between two balls (no jokes, Bender! :D).

But i think it's in C.. can anyone convert this to C# as can't find ways to implement DotProd or Normalise in C#.


void collision (void)
{
// ball movement (Yes?)

x1 += xVect1;
y1 += yVect1;

x2 += xVect2;
y2 += yVect2;

// test for collision

if (distance > radius1 + radius2)
{
return;
}

// if we get here, the balls have collided,
// so we do the collision calculations

xVelocity = xVect2 - xVect1;
yVelocity = yVect2 - yVect1;

// Normalize
Normal (x1 - x2, y1 - y2, normal);

approach = DotProd(normal[0], normal[1], xVelocity, yVelocity);

// calculate velocity change

xNewVect = normal[0] * approach;
yNewVect = normal[1] * approach;

// change velocities

xVect1 += xNewVect;
yVect1 += yNewVect;

xVect2 -= xNewVect;
yVect2 -= yNewVect;
}

Share this post


Link to post
Share on other sites
To your first questions:

#define MIN(A, B) (((A) < (B)) ? (A) : (B))

//--As Drew pointed out:
int Min(int A, int B)
{
if(A < B)
{
return A;
}
else
{
return B;
}

//--Or like the macro
//-- return (A < B ? A : B)
}

//--But the macro will also accept other data types like floats, longs, etc.
//--Example
int Min(float A, float B)
{
if(A < B)
{
return A;
}
else
{
return B;
}

//--Or like the macro
//-- return (A < B ? A : B)
}
//--Etc.




Quote:

i have used no float types.. only ints.

You really should be using floats, you will get more precise results.


Quote:

i have not even calculated a radius with my ellipses (balls)

For 2D, I usually just guess about what the radius qould be. Try 5, if the collision occurs before it hits the paddle, try 4. If the collision is furthur inside the paddle then try 6. Just keep playing until you get it. It shouldn't be too big of a hassle since there is not going to be hundreds of objects.


Quote:

That is a physics question of which you will need to use vectors for "realisitc" collisions. I am underqualified to explain, but maybe someone else can. The idea is that the puck will have a direction and magnitude it is traveling. When the paddle hits it, it too will have a direction and mass. I am thinking if you add the vectors, you will get a resultant of which tells the magnitude and direction it *should* go in. I'm sorry that I do not kave any examples of it, but maybe you can do some research into it as well.


This is what my first example does in a very simple manner. It's not a true reaction, but for a pong game it will give justified results. If you have VB ans want to see another style look at the demo I made 3 years ago:

(Kinetic Collision Responce)
If you only see only the lines being drawn and nothing but black (Device failed to create) then change D3DSWAPEFFECT_DISCARD to D3DSWAPEFFECT_FLIP in the XEngine class and make sure D3DPP.MultiSampleType is D3DMULTISAMPLE_NONE.
http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=36081&lngWId=1



To your last question:
I have never programmed in C#, but here's the Dot Product and Normalize functions (Didn't see them in the source you posted)

DotProduct:

//
//--If you use vectors
float DotProduct(const VECTOR2* Vector1, const VECTOR2* Vector2)
{
return ((Vector1->X * Vector2->X) + (Vector1->Y * Vector2->Y));
}
//
//--If you don't use vectors
float DotProduct(const float Vector1_X, const float Vector1_Y, const float Vector2_X, const float Vector2_Y)
{
return ((Vector1_X * Vector2_X) + (Vector1_Y * Vector2_Y));
}



Magnitude (For Normalize):

//
//--If you use vectors
float Magnitude(VECTOR2* Vector)
{
return sqrtf((Vector->X * Vector->X) + (Vector->Y * Vector->Y));
}
//
//--If you don't use vectors
void Magnitude(float VectorX, float VectorY)
{
return sqrtf((VectorX * VectorX) + (VectorY * VectorY));
}



Normalize:

//
//--If you use vectors
void Normalize(VECTOR2* Vector)
{
float Magnitude = 1 / Magnitude(Vector);
Vector->X *= Magnitude;
Vector->Y *= Magnitude;
}
//
//--If you don't use vectors
void Normalize(float VectorX, float VectorY)
{
float Magnitude = 1 / Magnitude(VectorX, VectorY);
VectorX *= Magnitude;
VectorY *= Magnitude;
}

Share this post


Link to post
Share on other sites
Cheeers for all the help everyone!

Am trying to implement it right now but very busy with lots of other stuff.

Little things are irritating me though..

Such as the variables x1, y1, x2, y2 - the source code above for void collision (void) is the only code that was available so i have no fit of the context for those variables.

Will work and report when i'm finished (or more than likely, when i'm stuck)

PS - Am taking your advice and am trying to make everything floats.

Share this post


Link to post
Share on other sites
Am having some problems implementing it in. I'm using floats.. not too sure how to make / use the vectors. Here's my code so far. Can anyone suggest ways to change it? Remember, i had the angles working. It's just an appropriate speed i require. By the way, it checks for a collision between it goes into Player1Collision() method. All you need to know is:
- puck_x and puck_y are the x and y co-ordinates of my puck.
- paddle1_x and paddle1_y are the x and y co-ordinates of my paddle
- x_vel and y_vel are the velocity of the x and y co-ordinates on the puck.

Any suggestions / tips (no matter how big or small) are much appreciated as i'm really not too sure of this area of Vectors / Normalizing etc.

Thanks in advance.

Brian


private void Player1Collision()
{
puck_x += xVect1;
puck_y += yVect1;

paddle1_x += xVect2;
paddle1_y += yVect2;

x_vel = paddle1_x - puck_x;
y_vel = paddle1_y - puck_y;

// Normalize
Normalize(puck_x - paddle1_x, puck_y - paddle1_y);

float approach = DotProduct(VectorX, VectorY, x_vel, y_vel);

// calculate velocity change
xNewVect = VectorX * approach;
yNewVect = VectorY * approach;

puck_x += xNewVect;
puck_y += yNewVect;

paddle1_x -= xNewVect;
paddle1_y -= yNewVect;
}

void Normalize(float VectorX, float VectorY)
{
douVectX = Convert.ToDouble(VectorX);
douVectY = Convert.ToDouble(VectorY);

//float magnitude = 1 / Mag(VectorX, VectorY);
double magnitude = 1 / Mag(douVectX, douVectY);
double doubleMag = Convert.ToDouble(magnitude);

douVectX *= magnitude;
douVectY *= magnitude;
}

float DotProduct(float Vector1_X, float Vector1_Y, float Vector2_X, float Vector2_Y)
{
return ((Vector1_X * Vector2_X) + (Vector1_Y * Vector2_Y));
}

public double Mag(double VectorX, double VectorY)
{
return Math.Sqrt((douVectX * douVectX) + (douVectY * douVectY));
}


Share this post


Link to post
Share on other sites

This topic is 4686 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this