1.1
Una pallina al centro e una parete fissa a destra

from vpython import *
wall_1 = box(color = color.red, pos = vector(16, 0, 0), size = vector(0.25, 24, 24))
ball = sphere(color = color.yellow)
1.2
La posizione della palla dipende dal tempo:
ball.speed = vector(8, 0, 0), la palla ha una nuova caratteristicads = ball.speed*dt, la variazione della posizione nell’intervallo di tempoball.pos += ds, la posizione viene aggiornata
from vpython import *
wall_1 = box(color = color.red, pos = vector(16, 0, 0), size = vector(0.25, 24, 24))
ball = sphere(color = color.yellow, speed = vector(8, 0, 0))
dt = 0.02
time = 0
ds = ball.speed*dt
ball.pos += ds
1.3
Il tempo scorre per alcuni secondi: time = time+dt

from vpython import *
wall_1 = box(color = color.red, pos = vector(16, 0, 0), size = vector(0.25, 24, 24))
ball = sphere(color = color.yellow, speed = vector(8, 0, 0))
dt = 0.02
time = 0
while(time < 8):
rate(50)
ds = ball.speed*dt
ball.pos += ds
time += dt
La palla ha attraversato il muro!
1.4
Se la palla rischia di superare il muro a destra allora si rende necessario invertire il segno della sua velocità
from vpython import *
wall_1 = box(color = color.red, pos = vector(16, 0, 0), size = vector(0.25, 24, 24))
ball = sphere(color = color.yellow, speed = vector(8, 0, 0))
dt = 0.02
time = 0
while(time < 8):
rate(50)
if(ball.pos.x > wall_1.pos.x):
ball.speed.x *= -1
ds = ball.speed*dt
ball.pos += ds
time += dt
1.5
La palla rimbalza sul lato destro ma si perde sul lato sinistro.
Aggiungi un’altra parete e un’altra condizione per rimbalzare.

from vpython import *
wall_1 = box(color = color.red, pos = vector(+16, 0, 0), size = vector(0.25, 24, 24))
wall_2 = box(color = color.red, pos = vector(-16, 0, 0), size = vector(0.25, 24, 24))
ball = sphere(color = color.yellow, speed = vector(8, 0, 0))
dt = 0.02
time = 0
while(time < 8):
rate(50)
if(ball.pos.x > wall_1.pos.x):
ball.speed.x *= -1
if(ball.pos.x < wall_2.pos.x):
ball.speed.x *= -1
ds = ball.speed*dt
ball.pos += ds
time += dt
Miglioramenti
- La palla annega nelle pareti…
- Evidenziare gli urti con le pareti
- Rendere visibile la direzione della palla
- Rendere visibile la traiettoria della palla
2.1
La palla annega parzialmente nelle pareti, è necessario aggiungere una distanza di sicurezza
from vpython import *
wall_1 = box(color = color.red, pos = vector(+16, 0, 0), size = vector(0.25, 24, 24))
wall_2 = box(color = color.red, pos = vector(-16, 0, 0), size = vector(0.25, 24, 24))
ball = sphere(color = color.yellow, speed = vector(8, 0, 0))
DIST = ball.radius+wall_1.size.x
dt = 0.02
time = 0
while(time < 8):
rate(50)
if(ball.pos.x+DIST > wall_1.pos.x):
ball.speed.x *= -1
if(ball.pos.x-DIST < wall_2.pos.x):
ball.speed.x *= -1
ds = ball.speed*dt
ball.pos += ds
time += dt
2.2
La palla e la parete colpita cambiano il proprio attributo emissive

from vpython import *
wall_1 = box(color = color.red, pos = vector(+16, 0, 0), size = vector(0.25, 24, 24))
wall_2 = box(color = color.red, pos = vector(-16, 0, 0), size = vector(0.25, 24, 24))
ball = sphere(color = color.yellow, speed = vector(8, 0, 0))
DIST = ball.radius+wall_1.size.x
dt = 0.02
time = 0
while(time < 8):
rate(50)
if(ball.pos.x+DIST > wall_1.pos.x):
ball.speed.x *= -1
ball.emissive = not ball.emissive
wall_1.emissive = not wall_1.emissive
if(ball.pos.x-DIST < wall_2.pos.x):
ball.speed.x *= -1
ball.emissive = not ball.emissive
wall_2.emissive = not wall_2.emissive
ds = ball.speed*dt
ball.pos += ds
time += dt
2.3
Un vettore segue la palla e indica la direzione e il verso del movimento

from vpython import *
wall_1 = box(color = color.red, pos = vector(+16, 0, 0), size = vector(0.25, 24, 24))
wall_2 = box(color = color.red, pos = vector(-16, 0, 0), size = vector(0.25, 24, 24))
ball = sphere(color = color.yellow, speed = vector(8, 0, 0))
dir_b = attach_arrow(ball, "speed", scale = 0.5, shaftwidth = 0.25)
DIST = ball.radius+wall_1.size.x
dt = 0.02
time = 0
while(time < 8):
rate(50)
if(ball.pos.x+DIST > wall_1.pos.x):
ball.speed.x *= -1
ball.emissive = not ball.emissive
wall_1.emissive = not wall_1.emissive
if(ball.pos.x-DIST < wall_2.pos.x):
ball.speed.x *= -1
ball.emissive = not ball.emissive
wall_2.emissive = not wall_2.emissive
ds = ball.speed*dt
ball.pos += ds
time += dt
2.4
Per seguire la traiettoria della palla aggiungi automaticamente una traccia grafica
ball.make_trail = Trueball.retain = 50, il numero di passi visibili

from vpython import *
wall_1 = box(color = color.red, pos = vector(+16, 0, 0), size = vector(0.25, 24, 24))
wall_2 = box(color = color.red, pos = vector(-16, 0, 0), size = vector(0.25, 24, 24))
ball = sphere(color = color.yellow,
speed = vector(8, 0, 0),
make_trail = True, retain = 50)
dir_b = attach_arrow(ball, "speed", scale = 0.5, shaftwidth = 0.25)
DIST = ball.radius+wall_1.size.x
dt = 0.02
time = 0
while(time < 8):
rate(50)
if(ball.pos.x+DIST > wall_1.pos.x):
ball.speed.x *= -1
ball.emissive = not ball.emissive
wall_1.emissive = not wall_1.emissive
if(ball.pos.x-DIST < wall_2.pos.x):
ball.speed.x *= -1
ball.emissive = not ball.emissive
wall_2.emissive = not wall_2.emissive
ds = ball.speed*dt
ball.pos += ds
time += dt
Ulteriori miglioramenti
3.1
- Il tempo scorre per sempre:
while(True): - Aggiungi le pareti in verticale e in profondità (con delle costanti semplificative)
- La parete verso l’utente NON è visibile:
wall_5.visible = False
- La parete verso l’utente NON è visibile:
- Modifica il vettore velocità:
ball.speed = vector(9, 8, 7)

from vpython import *
d12 = 16; dd12 = 2*d12; SPES = 0.25
d34 = 12; dd34 = 2*d34
d56 = 12; dd56 = 2*d56
wall_1 = box(color=color.red , pos=vector(+d12, 0, 0), size=vector(SPES, dd34, dd56))
wall_2 = box(color=color.red , pos=vector(-d12, 0, 0), size=vector(SPES, dd34, dd56))
wall_3 = box(color=color.green, pos=vector( 0,+d34, 0), size=vector(dd12, SPES, dd56))
wall_4 = box(color=color.green, pos=vector( 0,-d34, 0), size=vector(dd12, SPES, dd56))
wall_5 = box(color=color.blue , pos=vector( 0, 0,+d56), size=vector(dd12, dd34, SPES),
visible = False)
wall_6 = box(color=color.blue , pos=vector( 0, 0,-d56), size=vector(dd12, dd34, SPES))
ball = sphere(color = color.yellow,
speed = vector(9, 8, 7),
make_trail = True, retain = 100)
dir_b = attach_arrow(ball, "speed", scale = 0.5, shaftwidth = 0.25)
dt = 0.02
time = 0
DIST = ball.radius+SPES
while(True):
rate(50)
if(ball.pos.x+DIST > wall_1.pos.x):
ball.speed.x *= -1
ball.emissive = not ball.emissive
wall_1.emissive = not wall_1.emissive
if(ball.pos.x-DIST < wall_2.pos.x):
ball.speed.x *= -1
ball.emissive = not ball.emissive
wall_2.emissive = not wall_2.emissive
if(ball.pos.y+DIST > wall_3.pos.y):
ball.speed.y *= -1
ball.emissive = not ball.emissive
wall_3.emissive = not wall_3.emissive
if(ball.pos.y-DIST < wall_4.pos.y):
ball.speed.y *= -1
ball.emissive = not ball.emissive
wall_4.emissive = not wall_4.emissive
if(ball.pos.z+DIST > wall_5.pos.z):
ball.speed.z *= -1
ball.emissive = not ball.emissive
if(ball.pos.z-DIST < wall_6.pos.z):
ball.speed.z *= -1
ball.emissive = not ball.emissive
wall_6.emissive = not wall_6.emissive
ds = ball.speed*dt
ball.pos += ds
time += dt
3.2
Aggiunge etichette con informazioni numeriche su
time, lo scorrere del tempoball.pos, la posizione istantanea della pallina

from vpython import *
d12 = 16; dd12 = 2*d12; SPES = 0.25
d34 = 12; dd34 = 2*d34
d56 = 12; dd56 = 2*d56
wall_1 = box(color=color.red , pos=vector(+d12, 0, 0), size=vector(SPES, dd34, dd56))
wall_2 = box(color=color.red , pos=vector(-d12, 0, 0), size=vector(SPES, dd34, dd56))
wall_3 = box(color=color.green, pos=vector( 0,+d34, 0), size=vector(dd12, SPES, dd56))
wall_4 = box(color=color.green, pos=vector( 0,-d34, 0), size=vector(dd12, SPES, dd56))
wall_5 = box(color=color.blue , pos=vector( 0, 0,+d56), size=vector(dd12, dd34, SPES),
visible = False)
wall_6 = box(color=color.blue , pos=vector( 0, 0,-d56), size=vector(dd12, dd34, SPES))
ball = sphere(color = color.yellow,
speed = vector(9, 8, 7),
make_trail = True, retain = 100)
dir_b = attach_arrow(ball, "speed", scale = 0.5, shaftwidth = 0.25)
lbl_t = label(box = False, pos = vector(0, +d34+2, d56))
lbl_b = label(box = False, pos = vector(0, -d34-2, d56), color = ball.color)
dt = 0.02
time = 0
DIST = ball.radius+SPES
while(time < 10):
rate(50)
if(ball.pos.x+DIST > wall_1.pos.x):
ball.speed.x *= -1
ball.emissive = not ball.emissive
wall_1.emissive = not wall_1.emissive
if(ball.pos.x-DIST < wall_2.pos.x):
ball.speed.x *= -1
ball.emissive = not ball.emissive
wall_2.emissive = not wall_2.emissive
if(ball.pos.y+DIST > wall_3.pos.y):
ball.speed.y *= -1
ball.emissive = not ball.emissive
wall_3.emissive = not wall_3.emissive
if(ball.pos.y-DIST < wall_4.pos.y):
ball.speed.y *= -1
ball.emissive = not ball.emissive
wall_4.emissive = not wall_4.emissive
if(ball.pos.z+DIST > wall_5.pos.z):
ball.speed.z *= -1
ball.emissive = not ball.emissive
if(ball.pos.z-DIST < wall_6.pos.z):
ball.speed.z *= -1
ball.emissive = not ball.emissive
wall_6.emissive = not wall_6.emissive
ds = ball.speed*dt
ball.pos += ds
lbl_t.text = "time = {:.2f}".format(time)
lbl_b.text = "({:.2f}, {:.2f}, {:.2f})".format(ball.pos.x, ball.pos.y, ball.pos.z)
time += dt
3.3
Una seconda pallina con le stesse caratteristiche / comportamenti eccetto l’evidenza degli urti con le pareti.
Rinomina ball in ball_1 e poi copia e incolla tutto…

from vpython import *
d12 = 16; dd12 = 2*d12; SPES = 0.25
d34 = 12; dd34 = 2*d34
d56 = 12; dd56 = 2*d56
wall_1 = box(color=color.red , pos=vector(+d12, 0, 0), size=vector(SPES, dd34, dd56))
wall_2 = box(color=color.red , pos=vector(-d12, 0, 0), size=vector(SPES, dd34, dd56))
wall_3 = box(color=color.green, pos=vector( 0,+d34, 0), size=vector(dd12, SPES, dd56))
wall_4 = box(color=color.green, pos=vector( 0,-d34, 0), size=vector(dd12, SPES, dd56))
wall_5 = box(color=color.blue , pos=vector( 0, 0,+d56), size=vector(dd12, dd34, SPES),
visible = False)
wall_6 = box(color=color.blue , pos=vector( 0, 0,-d56), size=vector(dd12, dd34, SPES))
ball_1 = sphere(color = color.yellow, speed = vector(9, 8, 7), make_trail = True, retain = 100)
ball_2 = sphere(color = color.cyan , speed = vector(7, 8, 9), make_trail = True, retain = 100)
dir_b1 = attach_arrow(ball_1, "speed", scale = 0.5, shaftwidth = 0.25)
dir_b2 = attach_arrow(ball_2, "speed", scale = 0.5, shaftwidth = 0.25)
lbl_t = label(box = False, pos = vector(0, +d34+2, d56))
lbl_b1 = label(box = False, pos = vector(-d12, -d34-2, d56), color = ball_1.color)
lbl_b2 = label(box = False, pos = vector(+d12, -d34-2, d56), color = ball_2.color)
dt = 0.02
time = 0
DIST = ball_1.radius+SPES
while(time < 10):
rate(50)
lbl_t.text = "time = {:.2f}".format(time)
if(ball_1.pos.x+DIST > wall_1.pos.x):
ball_1.speed.x *= -1
ball_1.emissive = not ball_1.emissive
wall_1.emissive = not wall_1.emissive
if(ball_1.pos.x-DIST < wall_2.pos.x):
ball_1.speed.x *= -1
ball_1.emissive = not ball_1.emissive
wall_2.emissive = not wall_2.emissive
if(ball_1.pos.y+DIST > wall_3.pos.y):
ball_1.speed.y *= -1
ball_1.emissive = not ball_1.emissive
wall_3.emissive = not wall_3.emissive
if(ball_1.pos.y-DIST < wall_4.pos.y):
ball_1.speed.y *= -1
ball_1.emissive = not ball_1.emissive
wall_4.emissive = not wall_4.emissive
if(ball_1.pos.z+DIST > wall_5.pos.z):
ball_1.speed.z *= -1
ball_1.emissive = not ball_1.emissive
if(ball_1.pos.z-DIST < wall_6.pos.z):
ball_1.speed.z *= -1
ball_1.emissive = not ball_1.emissive
wall_6.emissive = not wall_6.emissive
ds = ball_1.speed*dt
ball_1.pos += ds
lbl_b1.text = "({:.2f}, {:.2f}, {:.2f})".format(ball_1.pos.x, ball_1.pos.y, ball_1.pos.z)
if(ball_2.pos.x+DIST > wall_1.pos.x):
ball_2.speed.x *= -1
if(ball_2.pos.x-DIST < wall_2.pos.x):
ball_2.speed.x *= -1
if(ball_2.pos.y+DIST > wall_3.pos.y):
ball_2.speed.y *= -1
if(ball_2.pos.y-DIST < wall_4.pos.y):
ball_2.speed.y *= -1
if(ball_2.pos.z+DIST > wall_5.pos.z):
ball_2.speed.z *= -1
if(ball_2.pos.z-DIST < wall_6.pos.z):
ball_2.speed.z *= -1
ds = ball_2.speed*dt
ball_2.pos += ds
lbl_b2.text = "({:.2f}, {:.2f}, {:.2f})".format(ball_2.pos.x, ball_2.pos.y, ball_2.pos.z)
time += dt
Glowscript
Web VPython 3.2
d12 = 16; dd12 = 2*d12; SPES = 0.25
d34 = 12; dd34 = 2*d34
d56 = 12; dd56 = 2*d56
wall_1 = box(color=color.red , pos=vector(+d12, 0, 0), size=vector(SPES, dd34, dd56))
wall_2 = box(color=color.red , pos=vector(-d12, 0, 0), size=vector(SPES, dd34, dd56))
wall_3 = box(color=color.green, pos=vector( 0,+d34, 0), size=vector(dd12, SPES, dd56))
wall_4 = box(color=color.green, pos=vector( 0,-d34, 0), size=vector(dd12, SPES, dd56))
wall_5 = box(color=color.blue , pos=vector( 0, 0,+d56), size=vector(dd12, dd34, SPES),
visible = False)
wall_6 = box(color=color.blue , pos=vector( 0, 0,-d56), size=vector(dd12, dd34, SPES))
ball_1 = sphere(color = color.yellow, speed = vector(9 , 8 , 7 ), make_trail = True, retain = 100)
ball_2 = sphere(color = color.cyan , speed = vector(9.1, 8.1, 7.1), make_trail = True, retain = 100)
dir_b1 = attach_arrow(ball_1, "speed", scale = 0.5, shaftwidth = 0.25)
dir_b2 = attach_arrow(ball_2, "speed", scale = 0.5, shaftwidth = 0.25)
lbl_t = label(box = False, pos = vector(0, +d34+2, d56))
lbl_b1 = label(box = False, pos = vector(-d12, -d34-2, d56), color = ball_1.color)
lbl_b2 = label(box = False, pos = vector(+d12, -d34-2, d56), color = ball_2.color)
dt = 0.02
time = 0
DIST = ball_1.radius+SPES
while(True):
rate(50)
lbl_t.text = "time = {:.2f}".format(time)
if(ball_1.pos.x+DIST > wall_1.pos.x):
ball_1.speed.x *= -1
ball_1.emissive = not ball_1.emissive
wall_1.emissive = not wall_1.emissive
if(ball_1.pos.x-DIST < wall_2.pos.x):
ball_1.speed.x *= -1
ball_1.emissive = not ball_1.emissive
wall_2.emissive = not wall_2.emissive
if(ball_1.pos.y+DIST > wall_3.pos.y):
ball_1.speed.y *= -1
ball_1.emissive = not ball_1.emissive
wall_3.emissive = not wall_3.emissive
if(ball_1.pos.y-DIST < wall_4.pos.y):
ball_1.speed.y *= -1
ball_1.emissive = not ball_1.emissive
wall_4.emissive = not wall_4.emissive
if(ball_1.pos.z+DIST > wall_5.pos.z):
ball_1.speed.z *= -1
ball_1.emissive = not ball_1.emissive
if(ball_1.pos.z-DIST < wall_6.pos.z):
ball_1.speed.z *= -1
ball_1.emissive = not ball_1.emissive
wall_6.emissive = not wall_6.emissive
ds = ball_1.speed*dt
ball_1.pos += ds
lbl_b1.text = "({:.2f}, {:.2f}, {:.2f})".format(ball_1.pos.x, ball_1.pos.y, ball_1.pos.z)
if(ball_2.pos.x+DIST > wall_1.pos.x):
ball_2.speed.x *= -1
if(ball_2.pos.x-DIST < wall_2.pos.x):
ball_2.speed.x *= -1
if(ball_2.pos.y+DIST > wall_3.pos.y):
ball_2.speed.y *= -1
if(ball_2.pos.y-DIST < wall_4.pos.y):
ball_2.speed.y *= -1
if(ball_2.pos.z+DIST > wall_5.pos.z):
ball_2.speed.z *= -1
if(ball_2.pos.z-DIST < wall_6.pos.z):
ball_2.speed.z *= -1
ds = ball_2.speed*dt
ball_2.pos += ds
lbl_b2.text = "({:.2f}, {:.2f}, {:.2f})".format(ball_2.pos.x, ball_2.pos.y, ball_2.pos.z)
time += dt
Ancora miglioramenti?
- Più palline
- Velocità variabile (?)
- Gestione degli urti tra palline (?)
- Pareti mobili (?)
- Interattività (start/stop, accelera/decelera, …)
- Breakout, Pinball (???)