import turtle as t
import math
def Init_Parameters(): #初始化参数
global B, U, m, q, Rmax, π, n, x, y, θ, α, Revolve_direction, v, v1, r, Ek, k, K
B=eval(input("B /T = ")) #磁感应强度,B>0指向屏幕内,B<0指向屏幕外
U=eval(input("U /V = ")) #加速电压,只能取正值
m=eval(input("m /kg = ")) #质量,只能取正值
q=eval(input("q /C = ")) #电荷量,取正值或负值
Rmax=eval(input("Rmax /m = ")) #D形盒半径,确定粒子运动范围
π=math.pi
n=1 #粒子被加速的次数
x=float() #粒子实际位置横坐标
y=float() #粒子实际位置纵坐标
θ=int() #轨迹圆心角
α=int() #表示粒子碰触边界瞬间的圆心角
Ek=float() #粒子动能
Revolve_direction=int() #旋转方向
v=v1=(2*abs(q)*U/m)**(1/2) #v:粒子速度 v1:第一次加速后的速度
r=abs(m*v/(q*B)) #轨迹半径
k=((n+1)/n)**0.5 #加速前后轨迹半径比
K=400/Rmax #修正系数,按比例调整示意图大小,确保整个示意图显示在屏幕范围内
def Set_Screen():
screen=t.Screen()
screen.title("Cyclotron")
screen.bgcolor("white")
def Set_Turtle():
global crevice, boundary, annotate_Rmax, magnetic_lines, annotate_v1, annotate_v, particle
t.setup(1000,1000,None,0)
crevice=t.Turtle() #画狭缝
boundary=t.Turtle() #画D形盒边界
annotate_Rmax=t.Turtle() #标注D形盒半径
magnetic_lines=t.Turtle() #画磁感线
annotate_v1=t.Turtle() #标注v1
annotate_v=t.Turtle() #标注v
particle=t.Turtle() #画粒子轨迹
crevice.speed(0)
boundary.speed(0)
annotate_Rmax.speed(0)
magnetic_lines.speed(0)
annotate_v1.speed(0)
annotate_v.speed(0)
particle.speed(0)
boundary.color("blue")
annotate_Rmax.color("grey")
annotate_v1.color("red")
annotate_v.color("orange")
annotate_Rmax.width(5)
annotate_v1.width(5)
annotate_v.width(5)
particle.width(1)
crevice.ht()
boundary.ht()
annotate_Rmax.ht()
magnetic_lines.ht()
annotate_v1.ht()
annotate_v.ht()
def Crevice(): #画狭缝
crevice.pu()
crevice.goto(-K*Rmax,1)
crevice.pd()
crevice.fd(2*K*Rmax)
crevice.pu()
crevice.goto(-K*Rmax,-1)
crevice.pd()
crevice.fd(2*K*Rmax)
def Boundary(): #画D形盒边界
boundary.pu()
boundary.goto(0,-K*Rmax)
boundary.pd()
boundary.circle(K*Rmax)
def Annotate_Rmax(): #标注D形盒半径
annotate_Rmax.seth(45)
annotate_Rmax.goto(math.cos(π/4)*K*Rmax, math.sin(π/4)*K*Rmax)
annotate_Rmax.write("Rₘ={}m".format(Rmax), font=("Arial",30,"normal"))
annotate_Rmax.rt(150)
annotate_Rmax.fd(20)
annotate_Rmax.bk(20)
annotate_Rmax.rt(60)
annotate_Rmax.fd(20)
def Magnetic_Lines(): #画磁感线
magnetic_lines.pu()
magnetic_lines.goto(-350, 300)
magnetic_lines.write("B={}T".format(B), font=("Arial",50,"normal"))
magnetic_field=''
if B>0:
magnetic_field="✕"
elif B<0:
magnetic_field="●"
for i in range(-500,501,200):
for j in range(-500,501,200):
magnetic_lines.goto(i,j)
magnetic_lines.pd()
magnetic_lines.write(magnetic_field,font=("Arial",20,"normal"))
magnetic_lines.pu()
def Annotate_v1(): #标注v1
annotate_v1.seth(90)
annotate_v1.pd()
annotate_v1.speed(0)
annotate_v1.fd(30)
annotate_v1.write("v₁={:.2f}m/s".format(v),font=("Arial",20,"normal"))
annotate_v1.rt(150)
annotate_v1.begin_fill()
for i in range(3):
annotate_v1.fd(10)
annotate_v1.rt(120)
annotate_v1.end_fill()
def Track_Parameters(): #计算轨迹参数
global center_x, center_y, orient_center, Revolve_direction
center_x=float()
center_y=1
orient_center=int()
if q*B>0:
Revolve_direction=1
center_x=-r
orient_center=1
elif q*B<0:
Revolve_direction=-1
center_x=r
orient_center=-1
def Revolve(center_x, center_y, θ, Revolve_direction): #计算粒子位置,使粒子转动
global x , y , r
x=Revolve_direction*r*(math.cos(θ*π/180))+center_x
y=r*(math.sin(θ*π/180))+center_y #x, y为粒子实际位置,单位m
X=K*x #X, Y为particle对象在屏幕上的位置,无单位
Y=K*y
particle.goto(X, Y)
def Particle(): #画粒子轨迹
global x, y, r, α, n, k, v, Ek, center_x, center_y, orient_center
particle.shapesize(0.2)
particle.shape("circle")
particle.seth(90)
particle.pd()
Break=bool()
while True:
for θ in range(0,361):
if x**2+y**2>=Rmax**2: #检测粒子是否到达边界
α=θ
Ek=0.5*m*v**2
Break=True
break
if θ==180 or θ==360:
if θ==180:
center_y-=2
else:
center_y+=2
orient_center*=-1
center_x=center_x+orient_center*r-orient_center*r*k #计算圆心横坐标
r*=k
v*=k
n+=1
k=((n+1)/n)**0.5
particle.fd(2)
continue
Revolve(center_x, center_y, θ, Revolve_direction)
if Break:
break
def Annotate_v(): #标注v
annotate_v.pu()
annotate_v.goto(K*x, K*y)
annotate_v.pd()
if Revolve_direction==-1:
annotate_v.seth(π-α+90)
else:
annotate_v.seth(α+90)
annotate_v.fd(30*v/v1)
annotate_v.rt(150)
annotate_v.begin_fill()
for i in range(3):
annotate_v.fd(10)
annotate_v.rt(120)
annotate_v.end_fill()
annotate_v.lt(150)
annotate_v.pu()
annotate_v.fd(70)
annotate_v.pd()
annotate_v.write("v={:.2f}m/s".format(v),font=("Arial",20,"normal"))
print("v={:.2e}m/s".format(v))
print("Eₖ={:.2e}J".format(Ek))
def main():
Init_Parameters()
Set_Screen()
Set_Turtle()
Crevice()
Boundary()
Annotate_Rmax()
Magnetic_Lines()
Annotate_v1()
Track_Parameters()
Particle()
Annotate_v()
t.done()
if __name__=="__main__":
main()