![]() | ![]() | ![]() |
Una pallina bianca al centro della scena

from vpython import *
sphere()
Una pallina azzurra e una parete verde a destra

from vpython import *
ball = sphere(color = color.cyan ,
pos = vector(-5, 0, 0),
radius = 0.5 )
wallR = box(color = color.green ,
pos = vector(6, 0, 0) ,
size = vector(0.2, 12, 12))
La posizione della palla dipende dal tempo:
ball.pos = ball.pos + ball.velocità * dt
from vpython import *
ball = sphere(color = color.cyan, pos = vector(-5, 0, 0), radius = 0.5)
wallR = box(color = color.green, pos = vector(6, 0, 0), size = vector(0.2, 12, 12))
ball.velocità = vector(25, 0, 0)
dt = 0.005
t = 0
ball.pos += ball.velocità * dt
Il tempo scorre per alcuni secondi
t = t + dt
from vpython import *
ball = sphere(color = color.cyan, pos = vector(-5, 0, 0), radius = 0.5)
wallR = box(color = color.green, pos = vector(6, 0, 0), size = vector(0.2, 12, 12))
ball.velocità = vector(25, 0, 0)
dt = 0.005
t = 0
while(t < 3):
rate(100)
ball.pos += ball.velocità * dt
t += dt
Se la posizione della palla supera quella del muro a destra allora si inverte il segno della velocità
from vpython import *
ball = sphere(color = color.cyan, pos = vector(-5, 0, 0), radius = 0.5)
wallR = box(color = color.green, pos = vector(6, 0, 0), size = vector(0.2, 12, 12))
ball.velocità = vector(25, 0, 0)
dt = 0.005
t = 0
while(t < 3):
rate(100)
if(ball.pos.x > wallR.pos.x):
ball.velocità.x = -ball.velocità.x
ball.pos += ball.velocità * dt
t += dt
La palla rimbalza sul lato destro ma si perde sul lato sinistro…
Un’altra parete e un’altra condizione per rimbalzare

from vpython import *
ball = sphere(color = color.cyan, pos = vector(-5, 0, 0), radius = 0.5)
wallR = box(color = color.green, pos = vector(6, 0, 0), size = vector(0.2, 12, 12))
ball.velocità = vector(25, 0, 0)
dt = 0.005
t = 0
while(t < 3):
rate(100)
if(ball.pos.x > wallR.pos.x): ball.velocità.x = -ball.velocità.x
if(ball.pos.x < wallL.pos.x): ball.velocità.x = -ball.velocità.x
ball.pos += ball.velocità * dt
t += dt
La palla annega parzialmente nelle pareti, è necessario migliorare il controllo
from vpython import *
ball = sphere(color=color.cyan, pos = vector(-5, 0, 0), radius = 0.5)
wallR = box(color = color.green, pos = vector(+6, 0, 0), size = vector(0.2, 12, 12))
wallL = box(color = color.green, pos = vector(-6, 0, 0), size = vector(0.2, 12, 12))
ball.velocità = vector(25, 0, 0)
dt = 0.005
t = 0
while(t < 3):
rate(100)
if(ball.pos.x + ball.radius > wallR.pos.x): ball.velocità.x = -ball.velocità.x
if(ball.pos.x - ball.radius < wallL.pos.x): ball.velocità.x = -ball.velocità.x
ball.pos += ball.velocità * dt
t += dt
Un vettore di colore giallo segue la palla e indica direzione e verso del movimento

from vpython import *
ball = sphere(color = color.cyan, pos = vector(-5, 0, 0), radius = 0.5)
wallR = box(color = color.green, pos = vector(+6, 0, 0), size = vector(0.2, 12, 12))
wallL = box(color = color.green, pos = vector(-6, 0, 0), size = vector(0.2, 12, 12))
ball.velocità = vector(25, 0, 0)
varr = attach_arrow(ball,
"velocità",
color=color.yellow,
scale=0.1,
shaftwidth=0.2)
dt = 0.005
t = 0
while(t < 3):
rate(100)
if(ball.pos.x + ball.radius > wallR.pos.x): ball.velocità.x = -ball.velocità.x
if(ball.pos.x - ball.radius < wallL.pos.x): ball.velocità.x = -ball.velocità.x
ball.pos += ball.velocità * dt
t += dt
Per seguire la traiettoria della palla aggiungi automaticamente una traccia grafica: make_trail=True

...
ball = sphere(color = color.cyan, make_trail = True, pos = vector(-5, 0, 0), radius = 0.5)
...
La traiettoria completamente orizzontale è prevedibile, aggiungi
- il movimento in verticale
- le pareti in alto e in basso
- i controlli corrispondenti

from vpython import *
ball = sphere(color = color.cyan, make_trail = True, pos = vector(-5, 0, 0), radius = 0.5)
wallR = box(color = color.green, pos = vector(+6, 0, 0), size = vector(.2, 12, 12))
wallL = box(color = color.green, pos = vector(-6, 0, 0), size = vector(.2, 12, 12))
wallU = box(color = color.green, pos = vector(0, +6, 0), size = vector(12, .2, 12))
wallD = box(color = color.green, pos = vector(0, -6, 0), size = vector(12, .2, 12))
ball.velocità = vector(25,7,0)
varr = attach_arrow(ball, "velocità", color=color.yellow, scale=0.1, shaftwidth=0.2)
dt = 0.005
t = 0
while(t < 3):
rate(100)
if(ball.pos.x + ball.radius > wallR.pos.x): ball.velocità.x = -ball.velocità.x
if(ball.pos.x - ball.radius < wallL.pos.x): ball.velocità.x = -ball.velocità.x
if(ball.pos.y + ball.radius > wallU.pos.y): ball.velocità.y = -ball.velocità.y
if(ball.pos.y - ball.radius < wallD.pos.y): ball.velocità.y = -ball.velocità.y
ball.pos += ball.velocità * dt
t += dt
La palla si muove su un piano xy piuttosto che nello spazio 3d, aggiungi
- il movimento in profondità
- una parete di fondo
- la parete frontale è solo immaginata…
- i controlli corrispondenti

L’animazione può continuare all’infinito modificando la condizione del ciclo
...
while(True):
...
Si può aggiungere una seconda palla con colore e vettore velocità diversi

from vpython import *
ball1 = sphere(color = color.cyan , make_trail = True, pos = vector(-5, 0, 0), radius = 0.5)
ball2 = sphere(color = color.magenta, make_trail = True, pos = vector(-5, 0, 0), radius = 0.5)
wallR = box(color = color.green, pos = vector(+6, 0, 0), size = vector(.2, 12, 12))
wallL = box(color = color.green, pos = vector(-6, 0, 0), size = vector(.2, 12, 12))
wallU = box(color = color.green, pos = vector( 0,+6, 0), size = vector(12, .2, 12))
wallD = box(color = color.green, pos = vector( 0,-6, 0), size = vector(12, .2, 12))
wallB = box(color = color.green, pos = vector( 0, 0,-6), size = vector(12, 12, .2))
ball1.velocità = vector(25, 7, 13)
ball2.velocità = vector(23, 5, 7)
varr1 = attach_arrow(ball1, "velocità", scale=0.1, shaftwidth=0.2)
varr2 = attach_arrow(ball2, "velocità", scale=0.1, shaftwidth=0.2)
dt = 0.005
t = 0
while(True):
rate(100)
if(ball1.pos.x + ball1.radius > wallR.pos.x): ball1.velocità.x = -ball1.velocità.x
if(ball1.pos.x - ball1.radius < wallL.pos.x): ball1.velocità.x = -ball1.velocità.x
if(ball1.pos.y + ball1.radius > wallU.pos.y): ball1.velocità.y = -ball1.velocità.y
if(ball1.pos.y - ball1.radius < wallD.pos.y): ball1.velocità.y = -ball1.velocità.y
if(ball1.pos.z + ball1.radius > +6 ): ball1.velocità.z = -ball1.velocità.z
if(ball1.pos.z - ball1.radius < wallB.pos.z): ball1.velocità.z = -ball1.velocità.z
ball1.pos += ball1.velocità*dt
if(ball2.pos.x + ball2.radius > wallR.pos.x): ball2.velocità.x = -ball2.velocità.x
if(ball2.pos.x - ball2.radius < wallL.pos.x): ball2.velocità.x = -ball2.velocità.x
if(ball2.pos.y + ball2.radius > wallU.pos.y): ball2.velocità.y = -ball2.velocità.y
if(ball2.pos.y - ball2.radius < wallD.pos.y): ball2.velocità.y = -ball2.velocità.y
if(ball2.pos.z + ball2.radius > +6 ): ball2.velocità.z = -ball2.velocità.z
if(ball2.pos.z - ball2.radius < wallB.pos.z): ball2.velocità.z = -ball2.velocità.z
ball2.pos += ball2.velocità*dt
t += dt
Ancora…
- Più palline
- Posizione iniziale, velocità, colore a piacere
- Colori delle palline, o delle pareti, che cambiano quando c’è un rimbalzo
- Pareti mobili…
- …
Per evitare che la finestra si adatti a ogni intervento dell’utente escludi autoscale prima del ciclo while
...
scene.autoscale = False
...
Tutorial ufficiale
- https://www.glowscript.org/docs/VPythonDocs/VPython_Intro.pdf
- https://www.vpython.org/contents/docs/VPython_Intro.pdf
- https://www.xn--fz-jlich-95a.de/SharedDocs/Downloads/JULAB/DE/Material_Simulationsrechnen_ball%20in%20a%20box.pdf;jsessionid=76D36C4A9EBEBE17782266CABBE25DBE?__blob=publicationFile
- https://www.glowscript.org/#/user/GlowScriptDemos/folder/Examples/program/Bounce-VPython
- …