Saturday 5 March 2011

VPython - Bouncing Ball

This week I will show you how to make a bouncing ball. Firstly we will give it a 1 dimensional bounce (just up and down), and then add on extras in other weeks, such as going into 2 dimensions and putting in wind or resistances, or walls.

If you haven't got VPython yet look to the bottom post to download it.

Firstly, we will need python to use the VPython module, so we need to "call it". To do this, at the very top of the page, type "from visual import *". This will give you access to all the 3D objects that VPython gives you ( without doing this you would get an error message whenever you wanted to make an object).

Next, we need to create a ball. VPython classifies this shape as a sphere, so to add a ball to the screen we need to just type "sphere( )" below what we have written already. If you run the program now, you will see a white ball in the middle of the screen (you can zoom out by pressing down both right and left mouse buttons and then moving the mouse down, or you can rotate by just pressing the right mouse button down and moving the mouse).

Next we want something that the ball can bounce on (you can program so that it bounces on nothing, but it looks better if you have a floor to bounce on).The floor can be based on a box, which is created by typing "box( )". If we run the program now, you will see that the box and the ball overlap each other, as we have not defined where we are going to put them. Go back to the code and type in the brackets next to the ball:
"pos = (0,50,0)". This makes the ball start at the position 0 meters across, 50 meters up, and 0 meters inwards. If we run the program again, the objects should be in the correct places (the ball 50 meters above the box), but the ball and the box look tiny. Now lets change the size of the box and the ball to make it look a bit better. To do this, add "size = (20,2,20)" inside the brackets next to box, and add ",radius=2" after the position in the ball bracket, remembering to put the comma after the position for the ball.

Now we need to define a few constants that we are going to use later on. For starters, lets define gravity. To do this, simply type "g = 9.8". We will define a few more later when we need them, but now lets get on to the movement of the ball.

There is only one force that we want to act on our ball at the moment - the force of gravity. This force is constant, so we can use the SUVAT equations (if you don't know about them, you can go here - http://en.wikipedia.org/wiki/Equations_of_motion). We also need Newton's Second Law - that the force on an object equals its mass times its acceleration (F=ma). Now we have what we need to set up the motion of the ball.

First, we need to set up a loop so that the motion is constant and the equations aren't used only once. To do this, first type "finished = False", making sure the false is capitalised, then type below "while not finished:", making sure that there is a colon at the end. If you press enter now, the cursor should be indented to the right. Now type "rate(100). This limits the speed at which the animation runs, so it doesn't run too fast to see, or slow down your computer.

Now we need to use our equations. The first equation we need is F=ma. We know the acceleration (which is gravity which we defined earlier), but we don't know the mass. Underneath the other constants type "mass=1". Now the ball has a mass, we can work out the do the equation. Type underneath the rate "force = vector(0,-mass * g,0)", and underneath that write "acceleration = force/mass" (we could have just used g for the acceleration here, but this way makes it easier when we are adding other forces).

Now to work out the velocity. For this we need a SUVAT equation. We know acceleration and position, and we are finding final velocity, but nothing else. We need to define some more variables. Underneath the constants type "velocity = (0,0,0)" and "dt = 0.01" (ball starting at rest, with the time difference between each frame is 0.01 seconds).

Now we have all we need to form a SUVAT equation. we now know initial velocity, acceleration, and time step, and we are finding final velocity (after the time step), so we use "v = v0+at". To use this you just have to type "velocity += acceleration*dt" (the plus in front of the equals sign adds on the acceleration*dt to whatever the velocity was, which is what we want). Finally, we need another SUVAT equation to work out the position of the ball. We now have basically everything, and we need to find displacement (s), so the equation to use is
"s = s0 + vt - 0.5at^2".

Now we come across a problem. We have made a sphere and placed it where we want it, but now we want to come back to it to change its position. To correct this we need to name our ball (lets call it ball to be easy). To do this we need to go back to where the sphere is in the text and before it we need to type "ball =", so the line now reads "ball = sphere(pos=(0,50,0),radius=2)". Now we have named our ball, we can move the ball to wherever we like.

After the velocity equation in the loop, type "ball.pos += velocity*dt - 0.5*acceleration*dt**2". This will make it so that the position of the ball will constantly update every time the loop is run. Now run the program and you will see the ball falling like it would in real life (with no air resistance), but after a time, our ball goes straight through the box.

To fix this, you will need the program to check whether the ball has touched the box, and if it has, to rebound off it. To do this you will need to name the box. Like how we named the ball, type "floor = " before box. Then put in the loop "if ball.pos.y < ball.radius + 0.5*floor.height:" (the right hand side is the distance from the middle of the ball to the middle of the box when they are touching each other) then press enter and type "velocity.y = -velocity.y". This will make the ball bounce. Run the program and you will see the ball bouncing.

Before I go, I will say about colouring the objects. If I wanted to make the ball red, all I will have to do is to type "color=color.red" into the brackets after ball. You can do this with any object. There is basically all the colours you can think of, as you don't need to stick with predefined colours - you can type "color = (1,0,0)" instead of "color.red". You can mix up all the colours by using any decimals of red-green-blue from (0,0,0) to (1,1,1). Try experimenting with the colours. You can also try experimenting with the values in the simulation, such as the starting height (change the pos values in the ball bracket) or any of the things you defined, such as velocity or gravity or mass.

-------------------------------------------------------------------------------------------------------------
The whole program that we created today is here:


from visual import *

floor = box(size = (20,2,20),color=(0.6,0.3,0.9))
ball = sphere(pos=(0,50,0),radius=2,color=(0.3,0.9,0.6))

g = 9.8
finished = False
mass=1
velocity = vector(0,0,0)
dt = 0.01

while not finished:
    rate(100)
    force=vector(0,-mass*g,0)
    acceleration=force/mass
    velocity +=acceleration*dt
    ball.pos += velocity*dt - 0.5*acceleration*dt**2
    if ball.pos.y < ball.radius+0.5*floor.height:
        velocity.y = -velocity.y
-------------------------------------------------------------------------------------------------------------

Next time, I will add to the program we made here by adding effects such as 2 dimensional movement, wind, resistances, and walls. I will also be looking into changing what the display screen shows, such as where the camera starts, and how much of the scene it shows.

No comments:

Post a Comment