Maths for bouncing a ball around a window..
-
Hi all I'm playing around with threading at the moment (self-directed learning) and what I would like to do is bounce balls around in a windows each with a thread of their own. I know this might not be the BEST way to do this, I want to do it purely for the learning. My idea is that I'll have a ball object that will be updated by a timer Event. At regular intervals, on a separate thread, I'll get the positions off all my balls and Draw them to the window. I will probably attempt to get some collision detection between balls going eventually but for now, they'll just bounce if they hit the sides/top of the window. Anyway, what I really would like to do is have the balls move around with fairly good physics. ie. gravity. But, my maths although good is inappropriate (I did maths & statistics at A level for my current career in biology). So, what equations can I use to give me x and y coordinates when I plug in an increasing value for time(t)? I realise I'll need to check if for x+radius>=rightWallX and x-radius<=leftWallX etc. it's just the movement in the presence of gravity I need. Can anyone help me out with the maths? I did try google but I think I'm failing to provide the 'right' search terms to find what I want.
-
Hi all I'm playing around with threading at the moment (self-directed learning) and what I would like to do is bounce balls around in a windows each with a thread of their own. I know this might not be the BEST way to do this, I want to do it purely for the learning. My idea is that I'll have a ball object that will be updated by a timer Event. At regular intervals, on a separate thread, I'll get the positions off all my balls and Draw them to the window. I will probably attempt to get some collision detection between balls going eventually but for now, they'll just bounce if they hit the sides/top of the window. Anyway, what I really would like to do is have the balls move around with fairly good physics. ie. gravity. But, my maths although good is inappropriate (I did maths & statistics at A level for my current career in biology). So, what equations can I use to give me x and y coordinates when I plug in an increasing value for time(t)? I realise I'll need to check if for x+radius>=rightWallX and x-radius<=leftWallX etc. it's just the movement in the presence of gravity I need. Can anyone help me out with the maths? I did try google but I think I'm failing to provide the 'right' search terms to find what I want.
I would use two integer properties for the ball object, called DeltaX and DeltaY. These would represent the number of pixels for the ball to move along the X and Y axis. A good starting point would probably be 3 as a value for both of these variables. When DeltaX is positive, the ball is moving to the right; and when negative, the ball is moving to the left. When DeltaY is positive, the ball is moving down; and when negative, the ball is moving up. When you encounter the edge of the form, simply multiply the appropriate variable by -1 to change its direction. Something like this:
private bool BallHitBoundary(Ball ball)
{
/* Check if the game ball hit a form boundary. If so, change the direction of the ball accordingly and
* return true. Otherwise return false. */
if (ball.Top <= ClientRectangle.Top || ball.Bottom >= ClientRectangle.Bottom)
{
// Game ball hit the top or bottom. Change the Y direction the other way.
ball.ReverseDeltaY();
return true;
}if (ball.Left <= ClientRectangle.Left || ball.Right >= ClientRectangle.Right) { // Game ball hit the left or right side. Change the X direction the other way. ball.ReverseDeltaX(); return true; } else { return false; }
}
and the ReverseDeltaY() and ReverseDeltaX() are methods for the ball object that simply multiply DeltaY/DeltaX by -1:
/// <summary>
/// Reverses DeltaX by multiplying by -1.
/// </summary>
internal void ReverseDeltaX()
{
DeltaX *= -1;
}/// <summary>
/// Reverses DeltaY by multiplying by -1.
/// </summary>
internal void ReverseDeltaY()
{
DeltaY *= -1;
}The above is actual code from a project I built to make a Breakout game just for the fun of it. The ball object inherits from a Panel object with a solid circle drawn inside of it. It works good for me.
-NP Never underestimate the creativity of the end-user.
-
I would use two integer properties for the ball object, called DeltaX and DeltaY. These would represent the number of pixels for the ball to move along the X and Y axis. A good starting point would probably be 3 as a value for both of these variables. When DeltaX is positive, the ball is moving to the right; and when negative, the ball is moving to the left. When DeltaY is positive, the ball is moving down; and when negative, the ball is moving up. When you encounter the edge of the form, simply multiply the appropriate variable by -1 to change its direction. Something like this:
private bool BallHitBoundary(Ball ball)
{
/* Check if the game ball hit a form boundary. If so, change the direction of the ball accordingly and
* return true. Otherwise return false. */
if (ball.Top <= ClientRectangle.Top || ball.Bottom >= ClientRectangle.Bottom)
{
// Game ball hit the top or bottom. Change the Y direction the other way.
ball.ReverseDeltaY();
return true;
}if (ball.Left <= ClientRectangle.Left || ball.Right >= ClientRectangle.Right) { // Game ball hit the left or right side. Change the X direction the other way. ball.ReverseDeltaX(); return true; } else { return false; }
}
and the ReverseDeltaY() and ReverseDeltaX() are methods for the ball object that simply multiply DeltaY/DeltaX by -1:
/// <summary>
/// Reverses DeltaX by multiplying by -1.
/// </summary>
internal void ReverseDeltaX()
{
DeltaX *= -1;
}/// <summary>
/// Reverses DeltaY by multiplying by -1.
/// </summary>
internal void ReverseDeltaY()
{
DeltaY *= -1;
}The above is actual code from a project I built to make a Breakout game just for the fun of it. The ball object inherits from a Panel object with a solid circle drawn inside of it. It works good for me.
-NP Never underestimate the creativity of the end-user.
So you didn't attempt to model gravity in the motion of your ball? Effectively your ball was in outer space? :-)
-
So you didn't attempt to model gravity in the motion of your ball? Effectively your ball was in outer space? :-)
I suppose that's one way to look at it. Or in this case, gravity is pulling along the Z-axis keeping the balls on the playing field, like a pool table. :-D If you want gravity to pull down on the Y-axis (towards the bottom of the form), I'm sure that could be incorporated by changing the value of the DeltaY property, but the math is beyond me too. Sorry.
-NP Never underestimate the creativity of the end-user.
-
I suppose that's one way to look at it. Or in this case, gravity is pulling along the Z-axis keeping the balls on the playing field, like a pool table. :-D If you want gravity to pull down on the Y-axis (towards the bottom of the form), I'm sure that could be incorporated by changing the value of the DeltaY property, but the math is beyond me too. Sorry.
-NP Never underestimate the creativity of the end-user.
I think I might have found my own answers here actually. I'll have a play around and see what I come up with. But you were on the right track with what you said. Modify the DeltaY by adding a constant gravity component each iteration. I guess I could also add a 'friction' component acting in the -Y and -X directions each iteration to have the ball slow due to air resistance too. Hmmm! This could be a fun experiment...
-
Hi all I'm playing around with threading at the moment (self-directed learning) and what I would like to do is bounce balls around in a windows each with a thread of their own. I know this might not be the BEST way to do this, I want to do it purely for the learning. My idea is that I'll have a ball object that will be updated by a timer Event. At regular intervals, on a separate thread, I'll get the positions off all my balls and Draw them to the window. I will probably attempt to get some collision detection between balls going eventually but for now, they'll just bounce if they hit the sides/top of the window. Anyway, what I really would like to do is have the balls move around with fairly good physics. ie. gravity. But, my maths although good is inappropriate (I did maths & statistics at A level for my current career in biology). So, what equations can I use to give me x and y coordinates when I plug in an increasing value for time(t)? I realise I'll need to check if for x+radius>=rightWallX and x-radius<=leftWallX etc. it's just the movement in the presence of gravity I need. Can anyone help me out with the maths? I did try google but I think I'm failing to provide the 'right' search terms to find what I want.
It seems at a first glance that it can only bounce once in one timestep, but it can in fact bounce multiple times in succession in one timestep. If you take any shortcuts there, balls can "escape", usually through the corners, and it will be uncommon enough that it could go undetected essentially forever (you can use that to decide that it's really OK, or that it's a very nasty bug, but it's good to be aware of it). If the speeds of the balls are reasonably low and the timestep is reasonably short, balls can still bounce twice, in the corners. Also, the simple implementation of bouncing actually bounces off of a virtual surface some distance outside the box depending on how far the ball traveled outside in a step. A more correct way to implement it is calculating the intersection of the box with the half-line in the direction that the ball is traveling, then bouncing "some time in the past when it was at that position" (flipping a speed and, crucially, updating the balls position by mirroring it around the line it bounced into*), then looping until the ball is inside the box. Like the other problem, this effect gets worse and worse for higher speeds and longer time steps. So yes, it's actually pretty complicated. * that is why you calculate the intersection point - to get the line it first bounced into. There would otherwise be an ambiguity when the ball is in the "outside quadrant" of a corner.
-
Hi all I'm playing around with threading at the moment (self-directed learning) and what I would like to do is bounce balls around in a windows each with a thread of their own. I know this might not be the BEST way to do this, I want to do it purely for the learning. My idea is that I'll have a ball object that will be updated by a timer Event. At regular intervals, on a separate thread, I'll get the positions off all my balls and Draw them to the window. I will probably attempt to get some collision detection between balls going eventually but for now, they'll just bounce if they hit the sides/top of the window. Anyway, what I really would like to do is have the balls move around with fairly good physics. ie. gravity. But, my maths although good is inappropriate (I did maths & statistics at A level for my current career in biology). So, what equations can I use to give me x and y coordinates when I plug in an increasing value for time(t)? I realise I'll need to check if for x+radius>=rightWallX and x-radius<=leftWallX etc. it's just the movement in the presence of gravity I need. Can anyone help me out with the maths? I did try google but I think I'm failing to provide the 'right' search terms to find what I want.
As Harold mentioned you have to make a computation strategy for collisions e.g. ball vs ball and ball vs frame. Here are some terms that you can google. You can go the variable time step way - good for getting the simulation right. You can go fixed time step - good for having the simulation go fast. One computation strategy could be as follows until no more collisions occur in a time step: - within a time step calculate the next collision - calculate the physics for involved objects Collision checking is a discipline in itself - a moving ball within a time step can be looked at as a sweeping volume being a capsule. Collision checking results in a collision time within a time step and a set of contact points. The physics can be as complicated as you want to. You can keep it very simple by sticking with kinematics (position, velocity) added some impulse calculation or go very exotic by adding lots of dynamics (gravity, friction, spin, energy loss, etc.). About gravity: If gravity is g (9.82[m/s^2]) downwards and you have a time step of deltaTime [s], all balls need to have their velocity changed by velocity change due to gravity: deltaVg = deltaTime * g In any case, have fun :) Kind Regards, Keld Ølykke