Results 1 to 18 of 18

Thread: reflecting off of a jimmy... jonno

  1. #1
    TaylorGordon
    Guest

    Question reflecting off of a jimmy... jonno

    I am programming a minigolf game on vb, and i am stuck with a problem of the determining how the ball bounces off of walls.

    The movement of the ball is decided on two variables:
    ballxmove and ballymove


    The total of abs(ballxmove) + abs(ballymove) is 1, so if ballxmove is -1, then ballymove = 0, and so the ball moves straight left 1 pixel. if ballxmove=1 then the ball moves straight forward. However, is can also be decimals, so like, ballxmove=.5, ballymove=.5 (this will result in the ball moving on a 45 degree angle down and to the right)

    Here's my problem.

    I have walls that if the ball hits the ballxmove and ballymove have to change so that it apears the ball has bounced off the wall.

    I know the coordinates the 2 ends of the wall, and so i could get the slope of the wall, because the ball would bounce off the wall differently depending on the slope of the wall, and then also on the slope of the ball(ballymove/ballxmove).

    blah!

    I've drawn a diagram that might help explain what i need to find out better.


    http://www.geocities.com/jabroni270/diagram.gif


    Thank you!

  2. #2
    Frenzied Member
    Join Date
    Jul 1999
    Posts
    1,800
    on a horizontal wall multiply the yspeed by -1
    on a vertical wall multiply the xspeed by -1
    on a slanted (slope of 1 or -1) wall multiply both speeds by -1


  3. #3
    TaylorGordon
    Guest
    Yes. I know that, However the slanted walls aren't always 45 degrees, they could be any angle, So I need a formula to calculate the new x- and y-movements

  4. #4
    Frenzied Member
    Join Date
    Jul 1999
    Posts
    1,800
    you can get the slopes of the ball path, and the wall. figure out the angle, and from that you can find an angle of reflection


  5. #5
    Junior Member
    Join Date
    Jun 2002
    Location
    Urbana, IL
    Posts
    24
    The general formula you are looking for is:
    V' = V-2*N*dotp(N,V)

    Where V is your velovity vector, N is the unit normal to the surface, and V' is the resulting vector after bouncing of the surface.

    dotp is the dot product defined as x1*x2+y1*y2

    If you have more questions about what stuff means, or how this equation was derived feel free to ask, or consult a beginning calculus book.

  6. #6
    TaylorGordon
    Guest

    Question

    Thank you, i appreciate it.


    But i haven't taken calculus yet so i don't understand. I kinda get it, but i dont the how to get what V is, b/c i dont know what vector velocity is, and i dont know what N would is-even though you explained in, and since there is no built-in dotp function in vb, i need to make my own, so i dont really understand the x1*x2+y1*y2. I dont understand anything really.


    And also the wall the ball moves is decided on the x it moves and y it moves. So how can i take the V' and change it two the xmove and ymove. BTW the speed is constant.

  7. #7
    Junior Member
    Join Date
    Jun 2002
    Location
    Urbana, IL
    Posts
    24
    Okay here is a basic vector arithmatic lesson.

    A 2d vector is often written as <x,y> where x is the change along the x axis and y is the change along the y axis. So if in a ball is moving along a line with a slope of 4 that could be written as the vector <1, 4>. So as you see a vector can be as simple as writing the slope a different way.

    The magnitude of a vector is determined by square the compnents and adding them so in our case 1^2 + 4^2 = 17 so the magnitude of <1,4> is 17. Normal when doing vector physics the magnitude is the same as the speed of the object. so in our case the ball is moving at 17 units per time unit.

    For many formulas a unit vector is required, which simply mean the magnitude is 1. Any vector can be made into a unit vector by divding the components by the magnitude. So <1,4> / 17 = <1/17, 4/17> this new vector has the same slope, but different length.

    A normal to a line or vector is simply the vector perpendicular to it. So if your vector is <0,1>, <1,0> would be normal to it. In our case <4,1> would be normal to <1,-4>.

    Dot Product is a function that takes 2 vectors and returns a single number. If the 2 vectors are <2,3> and <4,5> the dot product would be 2*4 + 3*5 = 23. Simply mutliply the first values then add that to the second values multiplied. This can easily be written as a VB function in 1 line.


    To determine N in your problem you need to simply translate the slope of your wall to a vector and then find the unit normal to it. Make sure the unit normal is on the correct side of the wall though.

    To find V simply take the slope of the line the ball is traveling along so in your case <ballxmove, ballymove>. In your case you don't need to normalize these vectors. But if you were using real vectors factoring in speed and all the magnitude of V' would be the same as V.

    Now that you have V and N you can plug them into the equation:
    V' = V-2*N*dotp(N,V)

    Now that you know V' you have the bouncexmove and bounceymove.

    Oh when multiplying a constant by a vector multiple the constant by each component of the vector. 2*<1,4> = <2,8>.

    As a bonus bit of information if you were curious how you multiply vectors that is what dotp is. Dot Product is one way to multiply vectors, cross product is another way. So really you don't exactly multiple vectors.

    Hope this helps clear things up.

  8. #8
    sql_lall
    Guest

    Wink Using trig.

    Seeing as you haven't used vectors, i'll try explaining using trig.

    Using trigonometry you can work out these things from x-steps and y-steps:

    1) You know the current path of the ball (I.e. the direction on a compass it's travelling in, 0-359T - T = true north)

    2) You know the angle of the wall (also the compass direction)

    A bit of Physics:
    Angle of incident = Angle of reflection

    i.e.
    3) You know the angle between the ball's new path out from the wall and the wall itself.

    Now you can calculate the new vectors.

    I.e. Wall pointing 80oT
    Ball coming in at 30oT
    =>angle between wall and ball path = 50oT
    (a 100o-30o-50o triangle formed)

    => angle coming out from wall = 130oT

    using trig you should now be able to find out ballxmove and ballymove such that the ball is now moving at 130oT

    In short:
    Angle of wall = WoT
    Angle of ball path in = BoT
    => Angle of ball path out =
    (2W - B)oT

    Now all you have to do, using trig, is find the correct ballxmove and ballymove to have the ball moving in the right direction.

    Can i just suggest than instead of having:
    abs(ballxmove) + abs(ballymove) = 1
    Have:
    ballxmove = cos(x) 'in degrees
    ballymove = sin(x) 'in degrees
    This way all your movements will be the same length.

  9. #9
    Junior Member
    Join Date
    Jun 2002
    Location
    Urbana, IL
    Posts
    24
    I would strongly recommend that you take the hour now to learn how vector math works as it will save you tons of time in the long wrong. Also anyone looking at your code or talking to you about collisions won't think your an idiot.

    The method I gave you is actually very simple. What sql_lall proposed initially sounds simple, but there are many things he didn't tell you how to do because they aren't simple.

    >using trig you should now be able to find out ballxmove and
    ballymove such that the ball is now moving at 130oT

    To do this first you have to consider that it is 130 degrees of a 80 degree wall. So that is net 30 degrees to your axis. Which is different then the 30 degree angle of the balls path because that was in relation to the wall. In relation to the axis the ball came in at 290 degrees. So now we know the ball is moving at 30 degrees off the y axis. We could find a decimal reprentation of the slope using tangent, but ideally you would want a fractional number.

    I am getting confused just describing how complicated it would be to do it this way. The method i described uses absolutly no trigonometric functions, just basic math really. Vectors aren't complicated. Also save yourself other headaches and start measuring all your angles in radians not degrees. In the math world degrees is a measure of the temperature in your lecture hall.

  10. #10
    TaylorGordon
    Guest

    Question god damn you half japanese girls...

    Oh man. I am confused.

    Ok, lets say I do it with vectors, how would i take the equation and make it
    ballxmove= ... and another one that is ballymove=...

    because in vb you can't, or i dont know how to, have a vector equal something like, (ballxmove, ballymove) =...

    ballxmove and ballymove are supposed to equal the new x and y movements the ball has after its hit the wall

    so

    if ballhitswall then
    ballxmove=?
    ballymove=?
    end if

    the wall is a line object called Wall, and it has an x1, x2, y1, and a y2.

    How do i write this two equations?

    I tried rewriting you vector eqation and failed horribly...

  11. #11
    Junior Member
    Join Date
    Jun 2002
    Location
    Urbana, IL
    Posts
    24
    I don't really see how this is complicated, but i will try to clarify again.

    The best way to solve this problem in code is to just make a vector class that has 2 attributes x and y, and maybe a method of dotp.

    The eally ugly, but most straight forward way is just with a bunch of variables.

    are formula is: V' = V-2*N*dotp(N,V)

    lets say ballx and bally represent the incoming "velocity" of the ball, and bouncex and bouncey is the "velocity" of the ball after striking the wall.

    Recall:
    V = <ballx, bally>
    MagnitudeN = sqrt( (wall.x2-wall.x1)^2 + (wall.y2-wall.y1)^2) )
    N = <(wall.y2-wall.y1) / MagnitudeN, -(wall.x2-wall.x1) / MagnitudeN>

    So:
    dotp = (ballx * abs(wall.y2-wall.y1) / MagnitudeN) - (bally * abs(wall.x2-wall.x1) / MagnitudeN)
    bouncex = ballx - 2 * dotp * (wall.y2-wall.y1) / MagnitudeN
    bouncey = bally - 2 * dotp * (wall.x2-wall.x1) / MagnitudeN

    Bam you are done

  12. #12
    sql_lall
    Guest

    Talking Once again...

    For realism, you probably should think of using:
    ballxmove = cos(x) 'in degrees
    ballymove = sin(x) 'in degrees

    (or maybe:
    ballxmove = sin(x) 'in degrees
    ballymove = cos(x) 'in degrees
    one of the two is right)

    This way, each time your ball moves it will move 1 unit in each direction.

    At the moment, with abs(ballxmove) + abs(ballymove) = 1
    if ballxmove = 1
    ballymove = 0
    total shift = *1* unit

    if ballxmove = 0.5
    ballymove = 0.5
    total shift = Sqrt(0.25 + 0.25) = *sqrt(2) / 2* units.

    sqrt(2)/2 < 1
    => if your ball travels diagonally, the total distance it travels is shorter than if it goes directly N,E,S,or W. i.e. if you hit at an angle other that 0,90,180 or 270, the ball will seem to travel more slowly.

    THat's why i have suggested you use angles. If you want the ball to travel K units at NoT, just have:
    ballxmove = K * cos(N) 'in degrees
    ballymove = K * sin(N) 'in degrees

    This way, to slow the ball down due to friction, just decrease K. When the ball hits a wall, just work out the new N. Simple!

  13. #13
    Junior Member
    Join Date
    Jun 2002
    Location
    Urbana, IL
    Posts
    24
    sql_lall is correct you do want the vector to be a unit vector (magnitude of 1). You can see this is true with the trigonemetric relation of sin^2 + cos^2 = 1. But if you use vectors like I suggest you really never get an angle to use so instead you should just keep your vectors, unit vectors. This is very simple. Initially you make sure your vectors are normal by dividing by the magnitude, and then the formula i gave you will keep that same magnitude in the bounce vector as the input vector, thus keeping it a unit vector.

  14. #14
    Junior Member
    Join Date
    Jun 2002
    Location
    Urbana, IL
    Posts
    24
    sql_lall is correct you do want the vector to be a unit vector (magnitude of 1). You can see this is true with the trigonemetric relation of sin^2 + cos^2 = 1. But if you use vectors like I suggest you really never get an angle to use so instead you should just keep your vectors, unit vectors. This is very simple. Initially you make sure your vectors are normal by dividing by the magnitude, and then the formula i gave you will keep that same magnitude in the bounce vector as the input vector, thus keeping it a unit vector.

  15. #15
    Junior Member
    Join Date
    Jun 2002
    Location
    Urbana, IL
    Posts
    24
    sql_lall is correct you do want the vector to be a unit vector (magnitude of 1). You can see this is true with the trigonemetric relation of sin^2 + cos^2 = 1. But if you use vectors like I suggest you really never get an angle to use so instead you should just keep your vectors, unit vectors. This is very simple. Initially you make sure your vectors are normal by dividing by the magnitude, and then the formula i gave you will keep that same magnitude in the bounce vector as the input vector, thus keeping it a unit vector.

  16. #16
    Junior Member
    Join Date
    Jun 2002
    Location
    Urbana, IL
    Posts
    24
    sql_lall is correct you do want the vector to be a unit vector (magnitude of 1). You can see this is true with the trigonemetric relation of sin^2 + cos^2 = 1. But if you use vectors like I suggest you really never get an angle to use so instead you should just keep your vectors, unit vectors. This is very simple. Initially you make sure your vectors are normal by dividing by the magnitude, and then the formula i gave you will keep that same magnitude in the bounce vector as the input vector, thus keeping it a unit vector.

  17. #17
    TaylorGordon
    Guest

    Angry Still Doesn't Work!

    Code:
     
                   If Ball Hits An Angled Wall Then
                        
                        
                        Dim DotP As Double
                        Dim MagnitudeN As Double
                        Dim TotalMove As Double
                        Dim NewTotal As Double
                        
                        'Calculates the Total Movement of the ball
                        TotalMove = Abs(BallXMove) + Abs(BallYMove)
                        
                        MagnitudeN = ((wall(x).X2 - wall(x).X1) ^ 2 + (wall(x).Y2 - wall(x).Y1) ^ 2) ^ 0.5
        
                        DotP = (BallXMove * Abs(wall(x).Y2 - wall(x).Y1) / MagnitudeN) - (BallYMove * Abs(wall(x).X2 - wall(x).X1) / MagnitudeN)
                            
                        BallXMove = BallXMove - 2 * DotP * (wall(x).Y2 - wall(x).Y1) / MagnitudeN
                        BallYMove = BallYMove - 2 * DotP * (wall(x).X2 - wall(x).X1) / MagnitudeN
                        
                        'Calculates the New Total Movement of the Ball
                        NewTotal = Abs(BallXMove) + Abs(BallYMove)
                        
                        'Changes the movements so the ball moves at the same speed as before
                        BallXMove = BallXMove * (TotalMove / NewTotal)
                        BallYMove = BallYMove * (TotalMove / NewTotal)
                        
                        'Changes Position of Ball
                        BallX = BallX + (BallXMove * 2 * (Power / 100))
                        BallY = BallY + (BallYMove * 2 * (Power / 100))
                        
                        ball.Left = BallX
                        ball.Top = BallY
                        CTT = x
                        Exit Sub
                    End If

    This is the code I have for when the ball hits an angled wall, and it doesn't work. The ball does not bounce off on the angle it should. Can you see any mistakes???

  18. #18
    Junior Member
    Join Date
    Jun 2002
    Location
    Urbana, IL
    Posts
    24
    Below is code for a bounce function that I have tried and works. Keep in mind that the bounce of the ball might look a little off depending on how you calculate the point of impact and the center of mass. Also note that I jot rid of some of your velocity code as it is uneccesary as far as I can tell. After the bounce the ball will maintain the same velocity.

    Private Sub Bounce()
    Dim DotP As Double
    Dim MagnitudeN As Double
    Dim NewTotal As Double
    Dim BallXUnit As Double
    Dim BallYUnit As Double
    Dim NormX As Double
    Dim NormY As Double

    MagnitudeN = ((wall.X2 - wall.X1) ^ 2 + (wall.Y2 - wall.Y1) ^ 2) ^ 0.5

    NormX = -(wall.Y2 - wall.Y1) / MagnitudeN
    NormY = (wall.X2 - wall.X1) / MagnitudeN

    DotP = (BallXMove * NormX) + (BallYMove * NormY)

    BallXMove = BallXMove - 2 * DotP * NormX
    BallYMove = BallYMove - 2 * DotP * NormY

    'path = path + 1
    'linPath(path).X1 = BallX
    'linPath(path).Y1 = BallY

    'Changes Position of Ball
    BallX = BallX + BallXMove
    BallY = BallY + BallYMove

    ball.Left = BallX
    ball.Top = BallY

    End Sub

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width