import math, turtle
def Init_Parameters(): #初始化参数
global U, d, L, m, q, v0, v_y, v, E, F, a, t1, t, x, y, α, θ, t_d, t_L, t_x, t_y, k, X0, t_pos
U=eval(input("U /V = ")) #偏转电压(U>0场强E向下,U<0场强E向上)
d=eval(input("d /m = ")) #偏转板间距
L=eval(input("L /m = ")) #偏转板长度
m=eval(input("m /kg = ")) #粒子质量
q=eval(input("q /C = ")) #粒子电荷
v0=eval(input("v₀ /(m•s⁻1) = ")) #粒子初速度,只能取正值
#矢量:规定水平向右为x轴正方向,竖直向下为y轴正方向
E=U/d #电场强度
F=q*E #电场力
a=F/m #加速度
t1=L/v0 #粒子水平方向上最长运动时间
if a==0:
t2=math.inf #竖直方向无加速度,不偏移,t2无穷大
else:
t2=(d/abs(a))**0.5 #粒子竖直方向上最长运动时间
t=min(t1, t2) #t为粒子实际运动时间
x=v0*t #粒子水平方向上的位移
y=0.5*a*(t**2) #粒子竖直方向上的位移
v_y=a*t #粒子竖直方向上的末速度
v=(v0**2+v_y**2)**0.5 #粒子末速度
α=math.atan(v_y/v0) #速度偏角
θ=math.atan(y/x) #位移偏角
# t_L,t_d,t_x,t_y各参数在屏幕上显示的尺寸
if d<=L: #调整示意图大小,使偏转板尺寸不超过600像素,确保整个示意图显示在屏幕范围内
t_L=600
t_d=t_L*(d/L)
else:
t_d=600
t_L=t_d*(L/d)
K=t_L/L #参数换算比例
t_x=K*x
t_y=-K*y
k=t_y/(t_x**2) #粒子轨迹方程的参数k
X0=-t_L/2 #粒子轨迹方程的参数X0
t_pos=(t_x+X0, t_y) #粒子最终位置
def Set_Screen():
turtle.ht()
screen=turtle.Screen()
screen.title("Oscilloscope")
screen.bgcolor("white")
screen.setup(1000,1000,None,0)
def Set_Turtle():
global coordinate, capacitor, annotate_L, annotate_d, electric_line, \
annotate_v0, annotate_vy, annotate_v, particle, auxiliary_line, annotate_angle
coordinate=turtle.Turtle() #画坐标系
capacitor=turtle.Turtle() #画偏转板
annotate_L=turtle.Turtle() #标注L
annotate_d=turtle.Turtle() #标注d
electric_line=turtle.Turtle() #画电场线
annotate_v0=turtle.Turtle() #标注v0
annotate_vy=turtle.Turtle() #标注vy
annotate_v=turtle.Turtle() #标注v
particle=turtle.Turtle() #画粒子轨迹
auxiliary_line=turtle.Turtle() #画辅助线
annotate_angle=turtle.Turtle() #标注偏转角
coordinate.speed(0)
capacitor.speed(0)
annotate_L.speed(0)
annotate_d.speed(0)
electric_line.speed(0)
annotate_v0.speed(0)
annotate_vy.speed(0)
annotate_v.speed(0)
particle.speed(0)
auxiliary_line.speed(0)
annotate_angle.speed(0)
coordinate.color("grey")
capacitor.color("black")
annotate_L.color("grey")
annotate_d.color("grey")
electric_line.color("blue")
annotate_v0.color("red")
annotate_vy.color("green")
annotate_v.color("orange")
particle.color("black")
auxiliary_line.color("grey")
capacitor.width(5)
electric_line.width(2)
annotate_v0.width(3)
annotate_vy.width(3)
annotate_v.width(3)
particle.width(1)
annotate_angle.width(3)
coordinate.ht()
capacitor.ht()
annotate_L.ht()
annotate_d.ht()
electric_line.ht()
annotate_v0.ht()
annotate_vy.ht()
annotate_v.ht()
particle.ht()
auxiliary_line.ht()
annotate_angle.ht()
coordinate.pu()
capacitor.pu()
annotate_L.pu()
annotate_d.pu()
electric_line.pu()
annotate_v0.pu()
particle.pu()
annotate_v0.pu()
annotate_vy.pu()
annotate_v.pu()
auxiliary_line.pu()
annotate_angle.pu()
def Coordinate(): #画坐标系
coordinate.goto(-t_L/2,0)
coordinate.pd()
coordinate.write("O", font=("Arial",20,"normal"))
coordinate.goto(t_L/2,0)
coordinate.write("x", font=("Arial",20,"normal"))
coordinate.seth(150)
coordinate.fd(10)
coordinate.bk(10)
coordinate.lt(60)
coordinate.fd(10)
coordinate.bk(10)
coordinate.goto(-t_L/2,0)
coordinate.seth(270)
coordinate.fd(t_d/2)
coordinate.write("y", font=("Arial",20,"normal"))
coordinate.seth(120)
coordinate.fd(10)
coordinate.bk(10)
coordinate.rt(60)
coordinate.fd(10)
coordinate.bk(10)
def Capacitor(): #画偏转板
capacitor.seth(0)
capacitor.goto(-t_L/2,t_d/2)
capacitor.pd()
capacitor.fd(t_L)
capacitor.pu()
capacitor.goto(-t_L/2,-t_d/2)
capacitor.pd()
capacitor.fd(t_L)
capacitor.pu()
capacitor.seth(45)
capacitor.width(3)
for i in range(-24,25,1):
capacitor.goto(t_L*i/48,t_d/2)
capacitor.pd()
capacitor.fd(15)
capacitor.pu()
for i in range(-24,25,1):
capacitor.goto(t_L*i/48,-t_d/2)
capacitor.pd()
capacitor.bk(15)
capacitor.pu()
def Annotate_L(): #标注L
if a>0:
annotate_L.goto(-t_L/2, t_d/2)
else:
annotate_L.goto(-t_L/2, -t_d*5/8)
annotate_L.pd()
annotate_L.seth(90)
annotate_L.fd(t_d/8)
annotate_L.bk(t_d/16)
annotate_L.seth(30)
annotate_L.fd(t_L/32)
annotate_L.bk(t_L/32)
annotate_L.rt(60)
annotate_L.fd(t_L/32)
annotate_L.bk(t_L/32)
annotate_L.seth(0)
annotate_L.fd(t_L)
annotate_L.seth(150)
annotate_L.fd(t_L/32)
annotate_L.bk(t_L/32)
annotate_L.lt(60)
annotate_L.fd(t_L/32)
annotate_L.bk(t_L/32)
annotate_L.seth(90)
annotate_L.fd(t_d/16)
annotate_L.bk(t_d/8)
annotate_L.pu()
if a>0:
annotate_L.goto(-t_L/8, t_d*5/8)
else:
annotate_L.goto(-t_L/8, -t_d*3/4)
annotate_L.write("L={}m".format(L),font=("Arial",40,"normal"))
def Annotate_d(): #标注d
annotate_d.goto(-t_L/2, t_d/2)
annotate_d.pd()
annotate_d.seth(180)
annotate_d.fd(t_d/8)
annotate_d.bk(t_d/16)
annotate_d.seth(240)
annotate_d.fd(t_L/32)
annotate_d.bk(t_L/32)
annotate_d.lt(60)
annotate_d.fd(t_L/32)
annotate_d.bk(t_L/32)
annotate_d.seth(270)
annotate_d.fd(t_d)
annotate_d.seth(120)
annotate_d.fd(t_L/32)
annotate_d.bk(t_L/32)
annotate_d.rt(60)
annotate_d.fd(t_L/32)
annotate_d.bk(t_L/32)
annotate_d.seth(0)
annotate_d.fd(t_d/16)
annotate_d.bk(t_d/8)
annotate_d.pu()
annotate_d.goto(-t_L*13/16, 0)
annotate_d.write("d={}m".format(d),font=("Arial",40,"normal"))
def Electric_line(): #画电场线
if U>0:
electric_line.seth(270)
for i in range(-5,6,2):
electric_line.goto(t_L*i/12,t_d/2)
electric_line.pd()
electric_line.fd(t_d)
electric_line.pu()
electric_line.lt(150)
for i in range(-5,6,2):
electric_line.goto(t_L*i/12,-t_d/2)
electric_line.begin_fill()
for j in range(3):
electric_line.fd(15)
electric_line.lt(120)
electric_line.end_fill()
electric_line.write("E={}V/m".format(E),font=("Arial",40,"normal"))
elif U<0:
electric_line.seth(90)
for i in range(-5,6,2):
electric_line.goto(t_L*i/12,-t_d/2)
electric_line.pd()
electric_line.fd(t_d)
electric_line.pu()
electric_line.rt(150)
for i in range(-5,6,2):
electric_line.goto(t_L*i/12,t_d/2)
electric_line.begin_fill()
for j in range(3):
electric_line.fd(15)
electric_line.rt(120)
electric_line.end_fill()
electric_line.write("E={}V/m".format(E),font=("Arial",40,"normal"))
def Annotate_velocity(turtle_v, name, value, criterion, t_pos, heading): #标注速度
turtle_v.goto(t_pos)
turtle_v.pd()
turtle_v.seth(heading)
turtle_v.fd(50*value/criterion)
turtle_v.rt(150)
turtle_v.begin_fill()
for i in range(3):
turtle_v.fd(10)
turtle_v.rt(120)
turtle_v.end_fill()
turtle_v.lt(150)
turtle_v.pu()
turtle_v.fd(30)
turtle_v.write("{}={:.2f}m/s".format(name, value), font=("Arial",20,"normal"))
def Particle(): #画粒子轨迹
particle.goto(-t_L/2,0)
particle.pd()
particle.shape("circle")
particle.shapesize(0.2)
particle.st()
for X in range(round(-t_L/2),round(t_x-(t_L/2))):
Y=k*((X-X0)**2)
particle.goto(X,Y)
particle.ht()
def v_Decomposition(): #速度v正交分解
Annotate_velocity(annotate_v, "v", v, v0, t_pos, -math.degrees(α))
if a!=0:
Annotate_velocity(annotate_v0, "v₀", v0, v0, t_pos, 0)
Annotate_velocity(annotate_vy, "vy", abs(v_y), v0, t_pos, 180+90*a/abs(a))
def dotted_line(t, Len, dot_len): #画虚线
line_len=0
n=0
while True:
if n%2==0:
t.pd()
else:
t.pu()
n+=1
line_len+=dot_len
if line_len>=Len:
last=Len-line_len+dot_len
t.fd(last)
break
else:
t.fd(dot_len)
t.pu()
def Auxiliary_line(): #画辅助线
if a!=0:
v_pos=[]
v_pos.append(t_pos[0]+50)
v_pos.append(t_pos[1]+50*math.tan(-α))
auxiliary_line.goto(v_pos[0], v_pos[1])
auxiliary_line.seth(180-90*a/abs(a))
dotted_line(auxiliary_line, 50*math.tan(abs(α)), 5)
auxiliary_line.goto(v_pos[0], v_pos[1])
auxiliary_line.seth(180)
dotted_line(auxiliary_line, 50, 5)
auxiliary_line.goto(t_pos)
auxiliary_line.pd()
auxiliary_line.seth(180-90*a/abs(a))
dotted_line(auxiliary_line, abs(t_y), 5)
auxiliary_line.goto(t_pos)
auxiliary_line.pd()
auxiliary_line.seth(180-math.degrees(α))
dotted_line(auxiliary_line, ((t_x/2)**2+t_y**2)**0.5, 5)
auxiliary_line.goto(t_pos)
auxiliary_line.pd()
auxiliary_line.seth(180-math.degrees(θ))
dotted_line(auxiliary_line, (t_x**2+t_y**2)**0.5, 5)
def Annotate_angle(): #标注偏转角
if a!=0:
r=t_x/10
annotate_angle.goto(t_x/2+X0+r, 0)
annotate_angle.seth(180+90*a/abs(a))
annotate_angle.color("cyan")
annotate_angle.pd()
annotate_angle.circle(-a/abs(a)*r, a/abs(a)*math.degrees(α))
annotate_angle.pu()
annotate_angle.goto(t_x/2+X0+r, -30*a/abs(a))
annotate_angle.write("α={:.2f}°".format(abs(math.degrees(α))), font=("Arial",20,"normal"))
annotate_angle.goto(X0+r, 0)
annotate_angle.seth(180+90*a/abs(a))
annotate_angle.color("purple")
annotate_angle.pd()
annotate_angle.circle(-a/abs(a)*r, a/abs(a)*math.degrees(θ))
annotate_angle.pu()
annotate_angle.goto(X0+r, -30*a/abs(a))
annotate_angle.write("θ={:.2f}°".format(abs(math.degrees(θ))), font=("Arial",20,"normal"))
def Output(): #输出结果
print("E={:.2f}V/m".format(E))
print("F={:.2f}N".format(F))
print("a={:.2f}m/s2".format(a))
print("t={:.2f}s".format(t))
print("x={:.2f}m".format(x))
print("y={:.2f}m".format(y))
print("v={:.2f}m/s".format(v))
print("vy={:.2f}m/s".format(v_y))
print("α={:.2f}°".format(abs(math.degrees(α))))
print("θ={:.2f}°".format(abs(math.degrees(θ))))
def main():
Init_Parameters()
Set_Screen()
Set_Turtle()
Coordinate()
Capacitor()
Annotate_L()
Annotate_d()
Electric_line()
Annotate_velocity(annotate_v0, "v₀", v0, v0, (X0, 0), 0)
Particle()
v_Decomposition()
Auxiliary_line()
Annotate_angle()
Output()
turtle.done()
if __name__=="__main__":
main()