Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Sign In with Facebook Sign In with Google Sign In with OpenID

Categories

We have migrated to a new platform! Please note that you will need to reset your password to log in (your credentials are still in-tact though). Please contact lee@programmersheaven.com if you have questions.
Welcome to the new platform of Programmer's Heaven! We apologize for the inconvenience caused, if you visited us from a broken link of the previous version. The main reason to move to a new platform is to provide more effective and collaborative experience to you all. Please feel free to experience the new platform and use its exciting features. Contact us for any issue that you need to get clarified. We are more than happy to help you.

a bouncing ball... stuck with direction changing

netgertnetgert Posts: 331Member
hi
i am making a bouncing ball game (using awt) where the whole stage contains walls that are defined with startpoint and endpoint. the ball has center point and radius. i have managed to detect collisions and disallow crossing the walls (by putting the ball at the position of collision). now i am stuck with getting the new speed on x and y axis (where the ball would go on next step). the wall might be at any angle and the ball might reach the wall (or miss it) on any angle (or go parallel with it). as i said, the collision detection is perfect, but i cant get the new direction the ball should go. this must be expressed as speed on x and y axis. all variables are of type double

thanks in advance
[hr][red][italic][b]N[/b][/red][blue]et[/blue][red][b]G[/b][/red][blue]ert[/italic][/blue][hr]

Comments

  • kreitlerkreitler Posts: 218Member
    Hey NetGert,
    You'll need some vector math to solve your problem. Since I don't know how much math you have (and how much help you want), I'll describe one solution in "high level" terms. If you need more explanation or want more than just "general approach" kind of help, please post again and let me know.
    To solve your problem, you need to know:

    1) the equation of the lines that describe your walls
    2) which wall the ball hit (assuming you know this, since you've already solved collision detection)
    3) the velocity of your ball as a 2D vector (I'm assuming this is a 2D problem...though the solution works equally well in 3D).

    Here's the outline of the solution:

    1) Get the equation for the wall the ball just hit.
    2) Use that equation to generate a normal vector for the wall (i.e., a vector of length 1 unit that is perpendicular to the wall).
    3) Use the normal to break down the ball's velocity into a component perpendicular to the wall (dot product) and parallel to the wall (subtract perpendicular component from the original velocity).
    4) Compute the "post-bounce" velocity by negating the perpendicular component (i.e., ball "reflects" off of wall) and adding in the parallel component.

    That sounds like a lot, but it's really only a few lines of math.
    Good luck. Let me know if this isn't helpful.

    Kreitler



    : hi
    : i am making a bouncing ball game (using awt) where the whole stage contains walls that are defined with startpoint and endpoint. the ball has center point and radius. i have managed to detect collisions and disallow crossing the walls (by putting the ball at the position of collision). now i am stuck with getting the new speed on x and y axis (where the ball would go on next step). the wall might be at any angle and the ball might reach the wall (or miss it) on any angle (or go parallel with it). as i said, the collision detection is perfect, but i cant get the new direction the ball should go. this must be expressed as speed on x and y axis. all variables are of type double
    :
    : thanks in advance
    : [hr][red][italic][b]N[/b][/red][blue]et[/blue][red][b]G[/b][/red][blue]ert[/italic][/blue][hr]
    :

  • netgertnetgert Posts: 331Member
    Thanks for your help, but I need some more. I have had a course about lines and circles and vector multiplying. Subtraction, addition (and I think there was a division) are a gray area to me. Also I have trobles understanding vector tutorials as English is not my mother language and these terms (the ones I have highlighted in red) are unknown to me. I hope you can explain them in basic English, as I haven't found matches for them in dictionary. The actions I cant understand are in blue. I assume the "dot product" is the point where two vectors intersect, but I'm not sure

    : Hey NetGert,
    : You'll need some vector math to solve your problem. Since I don't know how much math you have (and how much help you want), I'll describe one solution in "high level" terms. If you need more explanation or want more than just "general approach" kind of help, please post again and let me know.
    : To solve your problem, you need to know:
    :
    : 1) the equation of the lines that describe your walls
    : 2) which wall the ball hit (assuming you know this, since you've already solved collision detection)
    : 3) the velocity of your ball as a 2D vector (I'm assuming this is a 2D problem...though the solution works equally well in 3D).
    :
    : Here's the outline of the solution:
    :
    : 1) Get the equation for the wall the ball just hit.
    : 2) Use that equation to generate a [red]normal vector[/red] for the wall (i.e., a vector of length 1 unit that is [red]perpendicular[/red] to the wall).
    : 3) Use the normal to break down the ball's velocity into a [red]component perpendicular[/red] to the wall ([red]dot product[/red]) and parallel to the wall ([blue]subtract perpendicular component from the original velocity[/blue]).
    : 4) Compute the "post-bounce" velocity by [blue]negating the perpendicular component[/blue] (i.e., ball "reflects" off of wall) and adding in the parallel component.
    :
    : That sounds like a lot, but it's really only a few lines of math.
    : Good luck. Let me know if this isn't helpful.
    :
    : Kreitler

    [hr][red][italic][b]N[/b][/red][blue]et[/blue][red][b]G[/b][/red][blue]ert[/italic][/blue][hr]

  • kreitlerkreitler Posts: 218Member
    Hi NetGert,
    Your English is better than most native speakers'! I never would have guessed that it wasn't your mother language.
    Fortunately, we should be able to get around the problem using the "universal language" of mathematics. I hope. :p
    First, let's define some terms (some you already know, but I'm going to list them anyway so you know exactly what I mean):

    (I assume we're working in 2D space)

    [b]NEGATE:[/b] in math, this means "reverse", or "multiply by negative one".
    [green]
    example:
    If I "negate" 4, I get -4.
    [/green]

    [b]SCALAR:[/b] a regular number. Scalars have a value, but no direction.
    [green]
    example:
    35 degrees Celsius
    3.14159265359 radians
    [/green]

    [b]VECTOR:[/b] a value with a length and a direction.
    [green]
    example:
    90 km/hr southeast
    15.2 centimeters straight up
    [/green]

    In 2D, we use 2 numbers to represent a vector -- a value in the 'x' direction and a value in the 'y' direction. We'll use vectors to represent the velocity of the ball in your problem.

    [green]
    example: here is a vector that represents a distance of 3 meters in the x direction:

    <3 meters, 0 meters> (first number is the 'x' value, second is the 'y' value.

    example: here is a vector representing a ball traveling in the positive 'x' direction at 1 meter/second and the negative 'y' direction at 5 meters per second:

    <1 m/s, -5 m/s>.
    [/green]

    From now on, I'll describe a general 2D vector like this: [red][/red].

    [blue]
    [b]NOTE:[/b] any vector with a length of 1 unit can be called a "unit vector".
    [/blue]

    [b]VECTOR COMPONENTS:[/b] these are the x and y pieces of the vector. If my vector is <2, -1>, the x-component is '2', and the y-component is '-1'.

    [b]VECTOR ADDITION:[/b] when you add two vectors, you get a new vector. To get the new vector's components, just add the components of the first two vectors.

    [green]
    example:
    vector1 = <1, 3>
    vector2 = <-1, 4>

    vector3 = vector1 + vector2 = <1, 3> + <-1, 4> = <0, 7>
    [/green]

    [b]VECTOR SUBTRACTION:[/b] I don't use vector subtraction. I just negate the second vector and add them.
    [green]
    vector1 = <1, 3>
    vector2 = <-1, 4>

    vector3 = vector1 - vector2 = <1, 3> - <-1, 4> [red]yuck![/red]
    = <1, 3> + (-1 * <-1, 4>) [red]now adding negated <-1, 4>[/red]
    = <1, 3> + <1, -4>
    = <2, -1>
    [/green]

    [b]SCALAR MULTIPLICATION:[/b] this is a way to multiply a scalar by a vector. This gives you a vector. To get the new vector, just multiply the scalar by each of the vector's components.
    [green]
    example:
    vector1 = <7, 2>
    scalar = 3

    vector2 = scalar * vector1 = 3 * <7, 2> = <21, 6>
    [/green]

    [b]DOT PRODUCT:[/b] this is a way to multiply two vectors together. When you take the "dot product" of two vectors, you get a regular number out instead of a vector. I'll talk more about that in a minute. First, here is how you calculate the DOT PRODUCT:

    [green]
    if:
    vector1 =
    vector2 =

    then:
    dot product of vector1 and vector2 = (x1 * x2) + (y1 * y2)
    [/green]

    [red]
    [b]IMPORTANT:[/b] you can use the dot product to figure out how much of vector 1 points in the 'vector2' direction.

    For example, if:
    vector1 =
    vector2 = <1, 0>

    then:
    vector1 dot vector2 = x1 * 1 + y1 * 0 = x1
    [/red]

    See how the dot product selected only the 'x part' of vector1? That works for any direction of vector2. For example, if vector2 pointed up 45 degrees from the x-axis, the above dot product would have given us the amount of vector1 along that 45 degree line.

    [red]
    [b]IMPORTANT:[/b] in order get this direction information from the dot product, vector2 [b]must[/b] have a length of 1 unit.
    [/red]

    We will use this property later on to break up the ball's velocity into one vector that goes "into" the wall and a second vector that goes "along" the wall (parallel).

    From now on, I will use the period (.) to denote a dot product between two vectors:

    v1 dotted with v2 looks like:
    v1 . v2

    [b]PARALLEL:[/b] this means "goes in the same direction as". In other words, if I describe two lines as parallel, they point in the same direction and never cross each other. The two metal rails on a railroad track are "parallel". Another example: the lines forming an equals sign (=) are parallel.

    [b]PERPENDICULAR:[/b] this means "meets at an angle of 90 degrees". The metal rails of a railroad track are perpendicular to the wooden cross-pieces (called 'ties'). Another example: the lines forming a plus sign (+) are perpendicular.

    [b]NORMAL VECTOR:[/b] this is a vector that is "normal" to a line. In other words, the normal vector is perpendicular to the line and has a length of 1 unit. Imagine a small arrow, 1 unit long, sticking out at 90 degrees from your wall. This is the "normal vector" to your wall.

    [red]For a straight wall, the normal vector points in the same direction at every point on the wall.[/red]

    For example, suppose your wall follows the y-axis. In this case, the normal vector would point parallel to the x-axis no matter where your ball hits the wall:

    [blue] |
    |
    |[red]-->[/red] [black](this is a normal vector) [/black]
    |
    |
    |
    [/blue]

    Now that we have those words, we can get started. Let's talk about those actions you highlighted in blue:

    [b]1)HOW DO I CALCULATE THE NORMAL VECTOR TO MY WALL?[/b]
    This is easy to do, but requires many small steps.
    a) Get the equation for the line that describes our wall.
    b) Use the equation to find a vector parallel to the wall.
    c) Use the parallel vector to get the perpendicular vector.
    d) Make the perpendicular vector to get the normal vector (length of 1 unit).

    First, get the equation of the line that describes your wall. The equation for a line looks like this:

    [blue]
    y = mx + b,
    [/blue]

    where 'm' is the [b]slope[/b] (we don't care about 'b'). It is good to know the 'slope' of the line. This tells us how much up the y-axis you will go if you move over on the x-axis (I'm sure you remember this from your line and circle classes).

    We will use the slope to find the parallel vector to our wall. To see how this works, imagine that you are standing next to the line. It has

    slope m = 3 / 4 = (change in y direction / change in x direction)

    Now imagine that you walk 4 meters in the 'x' direction and 3 meters in the 'y' direciton. When you stop, you will again be next to the wall. As long as you move 4 units in x for every 3 units in y, you will move parallel to the wall.

    Here is a vector showing how you walked in this example:

    <4, 3>

    This vector is always parallel to the wall. It is also the same as the slope:

    [green]
    parallel vector =
    [/green]

    Now that we have a parallel vector, getting a perpendicular vector is easy:

    [red]
    perpendicular vector = <-change in y-direction, change in x-direction>
    [/red]

    In this case,

    <-3, 4>

    (also note that <3, -4> would work, too).

    You might remember that -1 / slope gives you the slope of a line that is perpendicular to the original line. We're doing the same thing--we're just using vectors, instead.

    Now that we have the perpendicular vector, we can easily get the normal vector. We just have to make the vector have a length of 1 unit. To do this, we first calculate the length of the vector:

    [code]
    [green]
    length of vector1 = length of
    = square root of (x1 * x1 + y1 * y1)
    [/green]
    [/code]

    Finally, to get a vector whose length is 1 unit, you take the original vector and divide by the length of the vector:

    [green]
    vector of length '1' = original vector / length of original vector
    [/green]

    Going back to our example:
    length of <3, -4> = square root of [3 * 3 + (-4) * (-4)] = 5
    <3, -4> --> transformed to length of 1 --> <3/5, -4/5>

    [code]
    [red]
    Example review:
    The line describing your wall is:
    y = m * x + b
    where m = slope = (dy) / (dx)
    (and dx = change in x, dy = change in y)

    Your 'normal' vector is:
    <-dy, dx> / square root of (dx * dx + dy * dy)

    We have also found the 'parallel unit vector':
    / square root of (dx * dx + dy * dy)
    [/red]
    [/code]

    [b]IMPORTANT:[/b] the 'normal' vector points "away from" the wall. The 'parallel unit vector' points "along" the wall. We will use this to help us figure out how the ball bounces off of the wall.

    [b]2) HOW DO I USE THE PARALLEL AND PERPENDICULAR VECTORS TO FIND THE BALL'S VELOCITY AFTER IMPACT?[/b]
    Remember when we defined the DOT PRODUCT? I said that you can use it to figure out how much of a vector points in the direction of a second vector. I also said this only worked when the second vector had a length of 1 unit.

    Since our parallel and perpendicular vectors have a length of 1 unit, we can use them in this way. This helps us because your ball obeys this rule:

    [b]
    When colliding with a wall, the part of the velocity perpendicular to the wall reverses direction (gets negated). The part that is parallel to the wall does not change.
    [/b]

    So:
    [code]
    [green]
    Let:
    vBall = the velocity of the ball (a vector)
    vWallParallel = the parallel unit vector we found above.
    vWallPerpendicular = the perpendicular unit vector we found above.

    Then, to get the part of the ball's velocity parallel to the wall:
    vBallParallel = vBall . vWallParallel

    And to get the part of the ball's velocity perpendicular to the wall:
    vBallPerpendicular = vBall . vPerpendicular
    [/green]
    [/code]

    Now we know how the ball is moving right before impact. After the ball hits the wall, it will move like this:

    [code]
    [green]
    vBallParallelAfterImpact = vBallParallel
    vBallPerpendicularAfterImpact = -vBallPerpendicular
    [/green]
    [/code]

    We're almost done, but there is a problem. Since we used a dot product, vBallParallel and vBallPerpendicular are numbers, not vectors. To get our final velocity vector, we need to combine them back into a vector. For example, if vBallParallelAfterImpact has a value of 3 m/s, we still need to know the direction in which the ball is moving at 3 m/s.

    We combine the final velocity numbers in the same way we broke up the velocity at the start of the problem: one piece goes in the "parallel" direction, the other in the "perpendicular" direction.

    [code]
    [green]
    Let:
    VbParFinal = final velocity of ball parallel to the wall
    VbPerpFinal = final velocity of ball perpendicular to the wall

    Then:
    Final velocity of ball = VbParFinal * parallel vector +
    VbPerpFinal * perpendicular vector

    [/green]
    [/code]


    Finally, let's plug these numbers into our ongoing example. Let's assume the ball is traveling back along the x-axis (velocity is <-3, 0>) and it hits our wall with slope 3/4.

    [code]
    [green]
    vBall = <-3, 0>
    vParallel = <4/5, 3/5>
    vPerpendicular = <-3/5, 4/5>

    Before collision:
    vBallParallel = <-3, 0> . <4/5, 3/5> = -12 / 5
    vBallPerpendicular = <-3, 0> . <-3/5, 4/5> = 9 / 5

    After collision:
    vBallParallel = (unchanged) = -12 / 5
    vBallPerpendicular = (negated) = -9 / 5

    vBallFinal = (-12 / 5) * <4/5, 3/5> + (-9 / 5) * <-3/5, 4/5>
    = <-48/25, -36/25> + <27/25, -36/25>
    = <-21/25, -72/25>



    [/green]
    [/code]

    That's it--you're done!

    That might seem complicated, but it isn't much math, once you write out the equations. The hard part is explaining it and understanding it. I'm sure that I wasn't clear in some places. If you have more questions, please ask!

    Good luck,

    Kreitler







    : Thanks for your help, but I need some more. I have had a course about lines and circles and vector multiplying. Subtraction, addition (and I think there was a division) are a gray area to me. Also I have trobles understanding vector tutorials as English is not my mother language and these terms (the ones I have highlighted in red) are unknown to me. I hope you can explain them in basic English, as I haven't found matches for them in dictionary. The actions I cant understand are in blue. I assume the "dot product" is the point where two vectors intersect, but I'm not sure
    :
    : : Hey NetGert,
    : : You'll need some vector math to solve your problem. Since I don't know how much math you have (and how much help you want), I'll describe one solution in "high level" terms. If you need more explanation or want more than just "general approach" kind of help, please post again and let me know.
    : : To solve your problem, you need to know:
    : :
    : : 1) the equation of the lines that describe your walls
    : : 2) which wall the ball hit (assuming you know this, since you've already solved collision detection)
    : : 3) the velocity of your ball as a 2D vector (I'm assuming this is a 2D problem...though the solution works equally well in 3D).
    : :
    : : Here's the outline of the solution:
    : :
    : : 1) Get the equation for the wall the ball just hit.
    : : 2) Use that equation to generate a [red]normal vector[/red] for the wall (i.e., a vector of length 1 unit that is [red]perpendicular[/red] to the wall).
    : : 3) Use the normal to break down the ball's velocity into a [red]component perpendicular[/red] to the wall ([red]dot product[/red]) and parallel to the wall ([blue]subtract perpendicular component from the original velocity[/blue]).
    : : 4) Compute the "post-bounce" velocity by [blue]negating the perpendicular component[/blue] (i.e., ball "reflects" off of wall) and adding in the parallel component.
    : :
    : : That sounds like a lot, but it's really only a few lines of math.
    : : Good luck. Let me know if this isn't helpful.
    : :
    : : Kreitler
    :
    : [hr][red][italic][b]N[/b][/red][blue]et[/blue][red][b]G[/b][/red][blue]ert[/italic][/blue][hr]
    :
    :

  • netgertnetgert Posts: 331Member
    Thank You so much, You've been so helpful. I undestand it all better now. I hope I can do it ;-)
    [hr][red][italic][b]N[/b][/red][blue]et[/blue][red][b]G[/b][/red][blue]ert[/italic][/blue][hr]

  • dtdono0dtdono0 Posts: 22Member
    That kreitler guy sounds like a math/physics professor who probably doesn't have a clue about how to do any real coding lol

    : Thank You so much, You've been so helpful. I undestand it all better now. I hope I can do it ;-)
    : [hr][red][italic][b]N[/b][/red][blue]et[/blue][red][b]G[/b][/red][blue]ert[/italic][/blue][hr]
    :
    :

  • kreitlerkreitler Posts: 218Member
    Hee hee--could be that the joke's on you, dt. I *do* have degrees in math and physics, but I write games for a living. I work at Edge of Reality in Texas. Last thing I did was Pitfall: the Lost Expedition. I've written that "bouncing ball" code quite a few times.

    There are a bunch of ways to write code like that, but trust me, using the vector math is one of the faster, easier ways...

    Cheers,
    K.

    : That kreitler guy sounds like a math/physics professor who probably doesn't have a clue about how to do any real coding lol
    :
    : : Thank You so much, You've been so helpful. I undestand it all better now. I hope I can do it ;-)
    : : [hr][red][italic][b]N[/b][/red][blue]et[/blue][red][b]G[/b][/red][blue]ert[/italic][/blue][hr]
    : :
    : :
    :
    :

  • OceanJeffOceanJeff Posts: 15Member
    I have a similar problem with a breakout game that I am developing.

    It's in the rudimentary stages at the moment, but my question is this:

    The ball's velocity is between 3 and 10 in x and y directions.

    How can you tell which side of the blocks on the screen the ball collides with?

    I've thought of taking the last position and current position (once I discover the ball is within a block) and that is the first parametric line, then using the blocks walls as the other parametric lines, and computing which lines intersect with the balls path in the last frame.

    I've been working on this for the past week, and I feel that I need a push to get beyond this point. I am hopeful that I will figure it out soon!

    I'm also reading Andre LaMothe's books on Tricks of the Windows Game Programming Gurus, and his second book on Tricks of the 3D Game Programming Gurus, which are both awesome books, btw!!!

    Anyways, let me know if you think anything about this dilemma of mine...

    Jeff Cummings
  • netgertnetgert Posts: 331Member
    Hi

    I've solved my problem. used mathworld.wolfram.com
    What u need is to rotate the ball's initial coordinates around one of the wall's endpoint coordinates by the angle of wall, counterclockwise (by negative angle)
    have a look at this:
    [code]
    public static double[] rotate(
    double x1, double y1,
    double x, double y, double a) {

    double d;
    a += Math.atan2(y1 - y, x1 - x);
    d = dist(x, y, x1, y1);

    x += d * Math.cos(a);
    y += d * Math.sin(a);

    return new double[] {x, y};
    }
    [/code]
    (rot[0] will be x, rot[1] will be y)
    this will rotate the point (x1, y1) around (x, y) by a radians
    example:
    [code]
    double rot[];
    rot = rotate(ball.x, ball.y, wall.x1, wall.y1, -Math.atan2(wall.y2 - wall.y1, wall.x2 - wall.y2));
    [/code]
    this rotates the point so that the wall is imagined as horizontal. the use basic comparison if rot[0] is below wall.x1 then its on one side of the wall, on the other side if otherwise

    : I have a similar problem with a breakout game that I am developing.
    :
    : It's in the rudimentary stages at the moment, but my question is this:
    :
    : The ball's velocity is between 3 and 10 in x and y directions.
    :
    : How can you tell which side of the blocks on the screen the ball collides with?
    :
    : I've thought of taking the last position and current position (once I discover the ball is within a block) and that is the first parametric line, then using the blocks walls as the other parametric lines, and computing which lines intersect with the balls path in the last frame.
    :
    : I've been working on this for the past week, and I feel that I need a push to get beyond this point. I am hopeful that I will figure it out soon!
    :
    : I'm also reading Andre LaMothe's books on Tricks of the Windows Game Programming Gurus, and his second book on Tricks of the 3D Game Programming Gurus, which are both awesome books, btw!!!
    :
    : Anyways, let me know if you think anything about this dilemma of mine...
    :
    : Jeff Cummings
    :

    [hr][red][italic][b]N[/b][/red][blue]et[/blue][red][b]G[/b][/red][blue]ert[/italic][/blue][hr]

Sign In or Register to comment.