from visual import * ### EFieldBuilder.py ### Interactive E-Field Builder (requires VPython) ### Rob Salgado ### salgado@physics.syr.edu http://physics.syr.edu/~salgado/ ### v0.9972 2002-01-10 tested on Windows 2000 ### with Python-2.2.exe and VPython-2001-12-31.exe ### * used .click instead of .button ### * modified the drag flag #### ### ### v0.997 2001-11-07 tested on Windows 2000 ### with Python-2.1.1.exe and VPython-2001-10-31.exe ### * uses specified shaftwidth for the arrows ### * removes the dependence on fpformat ### v0.996 2001-11-03 tested on Windows 2000 ### with Python-2.1.1.exe and VPython-2001-10-31.exe ### v0.99 2001-10-23 tested on Windows 2000 ### with Python-2.1.1.exe and VPython-2001-10-08.exe print""" Interactive E-Field Builder (v0.9972) Rob Salgado (salgado@physics.syr.edu) This VPython program allows you to position point charges in space. The Electric Field due to those charges is computed dynamically. Use the control panel to change the sign and magnitude of the next charge to be placed. In 'Create' mode:" Left-Clicking once on an empty location will place a new charge there. Left-Clicking-and-Dragging on an existing charge will reposition it. In 'Edit' mode: Left-Clicking once on an existing charge will change its properties. In 'Copy' mode: Left-Clicking once on an existing charge will copy its settings. To delete an existing charge: First, select the 'Edit' mode and set the charge to 0.0. Then, select the charge to be deleted. Wheel-Click-and-Drag or Left-and-Right-Click-and-Drag to zoom in and out. Right-Click-and-Drag to rotate about the origin. """ scene2 = display(title='set Q', x=0,y=0,width=100, height=100, center=(0,0,0), background=(0.25,0.25,0.25)) setQ = sphere(pos=(1,0,0), radius=1, color=color.blue,Q=1.0 ) incQ=cylinder(pos=(-1.5,0.5,0), axis=(0,1,0), radius=0.2,color=color.blue) decQ=cylinder(pos=(-1.5,-0.5,0), axis=(0,-1,0), radius=0.2,color=color.red) #labQ=label(pos=(1,0,0), text=fpformat.fix(setQ.Q, 1),opacity=0.,box=0) labQ=label(pos=(1,0,0), text="%.1f" % setQ.Q,opacity=0.,box=0) modestate=['create','edit','copy'] modeboxQ=box(pos=(-1.5,0,0),color=color.black) modeQ=label(pos=(-1.5,0,0), text='create',box=0,mode=0) scene2.visible=1 scene2.userspin=0 scene2.userzoom=0 scene2.autoscale=0 scene = display(title="E-Field Builder (Rob Salgado)", x=100,y=100) scene.select() scene.newzoom=1 scale=0.2 step=1. S=3. drag=0 charges=[] Efield=[] for x in arange(-S,S,step): for y in arange(-S,S,step): for z in arange(-S,S,step): vec=arrow(pos=(x,y,z),axis=(0,0,0),shaftwidth=scale/4.) Efield.append(vec) scene.autoscale=0 scene.range=(5,5,5) def EFieldAt(p): E = vector(0,0,0) for c in charges: delta=p-c.pos if mag(delta)<2e-13: print "small" print mag(delta) else: E = E + (delta) * c.Q / mag(delta)**3 return scale*E def updateEField(): for v in Efield: v.axis=EFieldAt(v.pos) def update2(): modeQ.text=modestate[modeQ.mode] if modeQ.mode==0: scene2.background=(0.25,0.25,0.25) else: scene2.background=(1,1,1) if setQ.Q>0.0: setQ.color=color.blue elif setQ.Q<0.0: setQ.color=color.red else: setQ.color=color.green labQ.text="%.1f" % setQ.Q n=None while 1: if scene2.mouse.clicked: m = scene2.mouse.getclick() newPick2=scene2.mouse.pick if newPick2==incQ: setQ.Q=setQ.Q+0.5 elif newPick2==decQ: setQ.Q=setQ.Q-0.5 elif newPick2==modeboxQ: modeQ.mode=(modeQ.mode+1)%3 update2() if scene.mouse.clicked: m = scene.mouse.getclick() newPick=scene.mouse.pick if m.click == "none": drag=0 if n!=None: if n.Q>0.0: n.color=color.blue elif n.Q<0.0: n.color=color.red else: n.color=color.green #print "Release" elif m.click == "left": if newPick==None:#if vacant, make new charge newChg=sphere(pos=m.pos, radius=abs(setQ.Q)/5.0, color=setQ.color, Q=setQ.Q) if setQ.Q==0:#give neutral charge a nonzero radius newChg.radius=1.0/5.0 charges.append(newChg) updateEField() n=newChg n.green=(1-n.green) drag=0 #### else: n=newPick if modeQ.mode==0:#toggle drag state n.green=(1-n.green) drag=(drag+1)%2 #### elif modeQ.mode==1:#update charge if setQ.Q !=0.0: n.radius=abs(setQ.Q)/5.0 n.color=setQ.color n.Q=setQ.Q else: n.visible=0 charges.remove(n) modeQ.mode=0 update2() updateEField() elif modeQ.mode==2:#clone existing charge setQ.Q=n.Q setQ.color=n.color labQ.text= "%.1f" % setQ.Q modeQ.mode=0 update2() elif m.click == "right": print "Right" if drag==1: #print "Drag ", #print scene.mouse.button if n!=None: n.pos=scene.mouse.pos updateEField()