#!/bin/sh """:" exec python $0 ${1+"$@"} """ # ---------------------- HelloWaves.py ---------------------- # # This program demonstrates how to make an animation of the # wave equation. The user can specify the initial # conditions by dragging the graph. # # For an extended version and explanation of the # wave equation, see HelloWavesExt.py # from Tkinter import * # The Tk package import Pmw # The Python MegaWidget package import math # import the sin-function master = Tk() # build Tk-environment npoints = 15 # use 10 points on each curve def mouseDrag(event): global idx u[idx] = g.yaxis_invtransform(event.y) g.element_configure("string", ydata=tuple(u)) def mouseDown(event): global idx g.element_bind("string", "<Motion>", mouseDrag) el = g.element_closest(event.x, event.y) idx = el["index"] def mouseUp(event): g.element_unbind("string", "<Motion>") def run(): global u, up, um, C g.element_configure("string", symbol="") init() ntimesteps = 200 # the length of the animation for t in range(ntimesteps): for i in range(1, len(u)-1): up[i] = 2*u[i] -um[i] + C*C*(u[i+1] - 2*u[i] + u[i-1]) um = u[:] u = up[:] g.element_configure("string", ydata=tuple(u)) master.after(10) # wait 0.01 second master.update_idletasks() # update screen g.element_configure("string", symbol="circle") def init(): global u, up, um, C C = 0.8 # make special value for um (incorporating du/dt=0 at t=0): um = u[:] # ensure that um is an array of correct length... for i in range(1, len(um)-1): um[i] = u[i] + 0.5*C*C*(u[i+1] - 2*u[i] + u[i-1]) up = u[:] if not Pmw.Blt.haveblt(master): # Is Blt installed? print("BLT is not installed!") else: vector_x = [] # x values (grid points used in the numerical scheme) u = [] # u values (as computed by the wave equation) # make a default graph for x in range(npoints+1): vector_x.append(x*0.1) if(x < 2.0*npoints/3): u.append(x/(2.0*npoints/3)) else: u.append(float(npoints-x)/(npoints/3)) g = Pmw.Blt.Graph(master) # make a new graph area g.pack(expand=1, fill='both') curvename = 'string' g.line_create(curvename, xdata=tuple(vector_x), ydata=tuple(u), pixels=7, smooth='natural') # use spline smoothing g.element_bind("string", "<ButtonPress>", mouseDown) g.element_bind("string", "<ButtonRelease>", mouseUp ) g.yaxis_configure(min=-1, max=1) g.configure(title='Hello world of waves', bufferelements=0) buttons = Pmw.ButtonBox(master, labelpos='n', label_text='Options') buttons.pack(fill='none', expand=0, padx=10, pady=10) buttons.add('Simulate', command=run) buttons.add('Quit', command=master.quit) master.mainloop()