por Jaime E. Villate. Universidade do Porto, Portugal.
VPython é um módulo adicional para Python, que inclui classes para criar vários tipos de formas geométricas em três dimensões, podendo ser colocadas em movimento facilmente. VPython usa a biblioteca gráfica OpenGL. A versão mais recente, 7, lança as animações dentro dum browser, usando WebGL e Javascript.
VPython é software livre que pode ser descarregado no seu sítio Web e instalado em todos os principais sistemas operativos.
from vpython import * def deslocar(corpo): global dt queda = True p = corpo.traj.point(corpo.traj.npoints-1)['pos'] corpo.pos += dt*corpo.v + dt**2*corpo.a/2. if corpo.v.y < 0 and corpo.pos.y < corpo.radius: if p.y != corpo.pos.y: f = (p.y - corpo.radius)/(p.y - corpo.pos.y) corpo.pos -= (1 - f)*(corpo.pos - p) corpo.v += f*dt*corpo.a corpo.t += f*dt queda = False else: corpo.t += dt corpo.v += dt*corpo.a corpo.traj.append(pos=vec(corpo.pos)) corpo.d += mag(corpo.pos - p) return queda def resultados(corpo): p0 = corpo.traj.point(0)['pos'] alcance = corpo.pos.x - p0.x velocidade = corpo.d / corpo.t scene.caption += '<b>'+corpo.legenda+'</b>\n' scene.caption += 'Tempo de voo = {:.2f} s\n'.format(corpo.t) scene.caption += 'Alcance horizontal = {:.2f} m\n'.format(alcance) scene.caption += 'Distância percorrida = {:.2f} m\n'.format(corpo.d) scene.caption += 'Velocidade média = {:.2f} m/s\n'.format(velocidade) return def projetar(corpo, vel, ang, leg): corpo.v = vel*vec(cos(ang*pi/180.), sin(ang*pi/180.), 0) corpo.t = corpo.d = 0 corpo.legenda = leg corpo.traj = curve(pos=vec(corpo.pos),color=corpo.color) scene = canvas(title = '<h1>Lançamento de projéteis no ar</h1>', forward=vec(-0.5,-0.2,-1)) scene.caption = '' a = 47. dt = 0.01 g = vec(0,-9.8,0) q1 = q2 = q3 = True bola1 = sphere(pos=vec(-7.5,0.2,1), radius=0.4, color=vec(0.93,1,0.16)) bola2 = sphere(pos=vec(-7.5,0.1,0), radius=0.2, color=vec(1,0,0)) bola3 = sphere(pos=vec(-7.5,0.1,-1), radius=0.2, color=vec(1,0.49,0.05)) chao = box(pos=vec(0,-0.1,0), size=vec(16,0.2,10), texture=textures.wood) parede = box(pos=vec(0,2.8,-5.05),size=vec(16,6,0.1), color=vec(0.7,0.7,0.7)) sitio = text(pos=vec(0,2.8,-5), text='def.fe.up.pt', color=color.blue, align='center', depth=0) projetar (bola1, 12, 45., 'Bola de ténis') projetar (bola2, 12, 45., 'Sem resistência do ar') projetar (bola3, 12, 45., 'Bola de ping-pong') bola2.a = g while q1 or q2 or q3: rate(100) bola1.a = g - 0.01606*mag(bola1.v)*bola1.v bola3.a = g - 0.14176*mag(bola3.v)*bola3.v if q1: q1 = deslocar (bola1) if q2: q2 = deslocar (bola2) if q3: q3 = deslocar (bola3) resultados(bola2) resultados(bola1) resultados(bola3)
from vpython import * scene = canvas(title='<h1>Oscilador harmónico simples</h1>', autoscale=0, width=500, height=500, range=7, forward=vec(0,0,-1)) chao = box(pos=vec(0,-6.1,0),size=vec(20,0.1,10),texture=textures.wood) parede = box(pos=vec(0,3.85,-5.05),size=vec(20,20,0.1), color=vec(0.7,0.7,0.7)) sitio = text(pos=vec(0,3.85,-5), text='def.fe.up.pt', color=color.blue, align='center', depth=0) # Mola e cilindro bar0 = curve(radius=0.03) for ang in arange(pi,-pi/2.,-0.1): bar0.append(vec(0, 5.2+0.23*sin(ang), 0.23*cos(ang))) bar0.append(pos=vec(0,4.5,0)) bar0.append(pos=vec(0,4.5,0.3)) mola1 = helix(pos=vec(0,4.5,0), radius=0.3, thickness=0.05, coils=30, axis = vec(0,-5.8,0)) bar1 = curve(radius=0.03, pos=[vec(0,-1.6,0),vec(0,-1.3,0),vec(0,-1.3,0.3)]) c1 = cylinder(pos=vec(0,-2,0),radius=0.5,axis=vec(0,0.4,0), color=vec(0.3,0.3,0.3)) # Barras do suporte s1 = cylinder(pos=vec(3,5.2,0),radius=0.2, axis=vec(-4,0,0)) s2 = cylinder(pos=vec(2.5,5.2,0),radius=0.6, axis=vec(-1,0,0),color=vec(0.5,0.5,0.6)) s3 = cylinder(pos=vec(2,-5,0.4),radius=0.2, axis=vec(0,11,0)) s4 = cylinder(pos=vec(2,-6.05,0.4),radius=0.8, axis=vec(0,1,0),color=vec(0.9,0.9,0.6)) # Função que alonga/comprime a mola y1 unidades def alongar_mola(y1): c1.pos.y = y1 - 2 bar1.origin = vec(0,y1,0) mola1.axis.y = y1 - 5.8 def uf(rf): # velocidade no espaço de fase a = (-k1*rf.y-b1*rf.z)/m1 return vec(0,rf.z, a) rf = vec(0, 0.9, 0) m1 = 0.3; k1 = 16; b1 = 0.02 dt = 0.01 alongar_mola(rf.y) while True: rate(100) uf1 = uf(rf) uf2 = uf(rf + dt*uf1 / 2.) uf3 = uf(rf + dt*uf2 / 2.) uf4 = uf(rf + dt*uf3) ufm = (uf1 + 2*uf2 + 2*uf3 + uf4)/6. rf += dt*ufm alongar_mola(rf.y)
from vpython import * scene = canvas(title='<h1>Pêndulo</h1>', autoscale=0, range=5, center=vec(0,3,0), forward=vec(-0.3,0,-1)) chao = box(pos=vec(0,-0.85,0),size=vec(20,0.1,10),texture=textures.wood) parede = box(pos=vec(0,7.1,-5.05),size=vec(20,16,0.1), color=vec(0.7,0.7,0.7)) sitio = text(pos=vec(0,7.1,-5), text='def.fe.up.pt', color=color.blue, align='center', depth=0) barra = box(pos=vec(0,-1.4,0), size=vec(0.2,3.2,0.2), color=vec(1,1,0)) disco = cylinder(pos=vec(0,-3,-0.2), radius=0.6, axis=vec(0,0,0.4), color=vec(0.5,0.5,0.8)) pendulo = compound([barra, disco]) pendulo.pos=vec(0,1.8,0) eixo = cylinder(pos=vec(0,3.5,0.3), radius=0.09, axis=vec(0,0,-1), color=vec(0.7,0.4,0.1)) b1 = box(pos=vec(0,1.7,-1), size=vec(1,4.2,0.6), color=vec(0.7,0.4,0.1)) b2 = box(pos=vec(0,-0.6,-0.5), size=vec(3,0.4,1.6), color=vec(0.7,0.4,0.1)) pendulo.w = 10 pendulo.angulo = 0 pendulo.l = 3 dt = 0.01 while True: rate(100) pendulo.a = -98*sin(pendulo.angulo)/pendulo.l pendulo.w = pendulo.w + pendulo.a*dt pendulo.angulo = pendulo.angulo + pendulo.w*dt pendulo.rotate(axis=vec(0,0,1), angle=pendulo.w*dt, origin=vec(0,3.5,0))