<jupyter_start><jupyter_text>The Physics of a Bouncing Ball---Prerequisites: *BouncingBall_Introduction* and  *BouncingBall_FirstAnimation* ---We are ready now to do some **Physics**!We will animate a ball so that it can move across the screen. To do this, we will need to define new attributes of the ball. We need a velocity, which we can set using the command below. We note that python knows nothing about units. We will defined positions and velocities as numbers, and for simplicity, we will assume that these are all in the International System of Units.We will start by loading the two necessary packages, and then we will initiate the time, and the time step.<jupyter_code>from vpython import *
from math import *
t=0
dt = 0.1<jupyter_output><empty_output><jupyter_text>We create a separate canvas, on which we will draw the ball and the two walls, as previously, then define the velocity of the ball as a vector in a 3 dimensional coordinate system (x, y, z):$$ \vec v = (1,0,0) m/s $$<jupyter_code>canvas()

ball = sphere(pos=vector(0,0,0),radius=0.5,color=color.magenta)
wallL = box(pos=vector(-10,0,0),size=vector(0.1,10,5),color=color.white)
wallR = box(pos=vector(10,0,0),size=vector(0.1,10,5),color=color.white)
ball.velocity = vector(1,0,0)<jupyter_output><empty_output><jupyter_text>The underlying physical equation that characterizes the motion of the ball is:$$\Delta \vec r = \vec v \Delta t $$ We implement this equation using the logic that after one time step, the new position will be the old position plus the change in position. $$\vec r_{new} = \vec r_{old} + \Delta \vec r $$The previous expression represents three equations, one for each of the x, y and z coordinates! $$x_{new} = x_{old} + \Delta x \\y_{new} = y_{old} + \Delta y \\z_{new} = z_{old} + \Delta z $$We can just let python worry about that detail! We also see that python is managing all the vectors for us. When coding, we implement this the object ball, and the atributes position and velocity: ``ball.pos = ball.pos + ball.velocity * dt``We add this expression to a ``while`` loop. next, we want the ball to bounce off the walls. This is a simple reflection, in which the component of the velocity that is normal to the reflecting surface changes sign. This means that at the wall we need to reverse the x component of the velocity:$$v_x \rightarrow -v_x$$We code this by adding two ``if`` conditional statements inside the ``while`` loop:``if ball.pos.x < wallL.pos.x:         ball.velocity.x = - ball.velocity.x    if ball.pos.x > wallR.pos.x:         ball.velocity.x = - bal.velocity.x``Let's implement this:<jupyter_code>while t < 100:
    rate(100)
    ball.pos = ball.pos + ball.velocity * dt
    t = t + dt
    if ball.pos.x < wallL.pos.x:
         ball.velocity.x = - ball.velocity.x
    if ball.pos.x > wallR.pos.x:
         ball.velocity.x = - ball.velocity.x<jupyter_output><empty_output><jupyter_text>Drawing More Shapes Now that we have the ball bouncing around, we can introduce a couple of additional shapes to help us visualize the motion. Let's try the code again, this time by changing ball's velocity to be in more than one dimension ``ball.velocity = vector(1,0.1,0)``.We will start by drawing the ball again, such that it leaves a trail, with ``make_tail``, that retains 50 points along the path. We will also add an ``arrow`` that we will use to to indicate the direction of the ball. We need to create the arrow after we have defined both the ball and its velocity. The arrow will have to be updated every time the ball moves, so at the end our loop we will add the lineNow let's write the program again, as below, then restart the kernel.<jupyter_code>canvas()

dot = sphere(pos=vector(0,0,0),radius=0.5,color=color.cyan,make_trail=True)
dot.trail_color = color.magenta
dot.interval = 10
dot.retain = 50

boxL = box(pos=vector(-10,0,0),size=vector(0.1,10,5),color=color.yellow)
boxR = box(pos=vector(10,0,0),size=vector(0.1,10,5),color=color.yellow)

dot.velocity = vector(1,0.1,0)
dot.dir = arrow(pos=ball.pos,axis=dot.velocity,color=dot.color)
t = 0
dt = 0.1
while t < 100:
    rate(100)
    dot.pos = dot.pos + dot.velocity*dt
    t = t + dt
    if dot.pos.x < boxL.pos.x:
        dot.velocity.x = -dot.velocity.x
    if dot.pos.x > wallR.pos.x:
        dot.velocity.x = -dot.velocity.x
    dot.dir.pos = dot.pos
    dot.dir.axis = dot.velocity
    dot.dir.length = mag(dot.velocity)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10793150067598017, 'fraction_numerical': 0.01915277151870212, 'mean_word_length': 4.090596330275229, 'pattern_counts': {'":': 0, '<': 22, '<?xml version=': 0, '>': 20, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '4', 'dir': 'jupyter-structured-clean-dedup', 'id': '254530', 'license': 'CC0-1.0', 'n_tokens_mistral': 1452, 'n_tokens_neox': 1375, 'n_words': 557, 'path': 'BouncingBall_Physics.ipynb', 'repo_name': 'mbabiuc/computationalphysicsmu', 'size': '4438'}