加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
光学.py 17.23 KB
一键复制 编辑 原始数据 按行查看 历史
Yuncheng-Xie 提交于 2023-10-12 16:33 . edited
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701
import tkinter as tk
import numpy as np
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
import matplotlib as mpl
import matplotlib.pyplot as plt
from pl3d import *
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
import sys
maxlev=0.00001
logmod=0
imod=0
Ax=0
A2=1
plt.rcParams['font.family'] = 'SimHei'
plt.rcParams['axes.unicode_minus'] = False
wd=tk.Tk()
d=1000
x0=0.4
y0=0.3
rg=3000
wd.title("点波源干涉")
wd.geometry("1200x800")
f1= Figure(figsize=(6,5), dpi=75)
f2= Figure(figsize=(11,4), dpi=90)
a21=f2.add_subplot(121)
a22=f2.add_subplot(122)
a1=f1.add_subplot(111)
phi=0
lad=500
max=10
custom_font = tk.font.Font(size=16)
custom_font1 = tk.font.Font(size=14)
def getI(m):
Il=[]
A1=1
global A2
global d
global Ax
global lad
global phi
o1=[-d,0,0]
o2=[d,0,0]
k=2*np.pi/lad
for i in range(m.shape[0]):
r1=norm(m[i]-o1)
r2=norm(m[i]-o2)
I=(A1/r1*sin(k*r1)+A2/r2*sin(k*r2+phi))**2+(A1/r1*cos(k*r1)+A2/r2*cos(k*r2+phi))**2+Ax**2/r2**2
Il.append(I)
return Il
def getx0(value):
global x0
x0=np.float64(value)
drawp()
def gety0(value):
global y0
y0=np.float64(value)
drawp()
def getd(value):
global d
d=np.float64(value)
drawp()
def drawp():
a1.clear()
a1.scatter([-d,d],[0,0],c="r")
a1.grid("on")
a1.set_title("波源及光屏位置",size=15)
a1.set_xlabel("X/nm",size=15)
a1.set_ylabel("Y/nm",size=15)
a1.set_xlim([-rg,rg])
a1.set_ylim([-rg,rg])
a1.plot(np.linspace(-rg,rg,10),(np.ones(10))*y0,c="g")
a1.annotate("屏1",[200,y0],size=15)
a1.plot((np.ones(10))*x0,np.linspace(-rg,rg,10),c="orange")
a1.annotate("屏2",[x0,-800],size=15)
a1.annotate("S1",[d,0],size=15)
a1.annotate("S2",[-d,0],size=15)
canvas.draw()
def surf(v,r,X,Y):
v1=v[0]
v2=v[1]
v3=v[2]
r1=r[0]
r2=r[1]
r3=r[2]
Z=r3-((X-r1)*v1+(Y-r2)*v2)/v3
return Z
def hyperbola(x, a, b,y0):
return np.sqrt(b**2*((x/a)**2 - 1)-y0**2)
def gethy(a_value,b_value,m,l=1000):
a21.set_xlabel("X/nm")
a21.set_ylabel("Z/nm")
a21.set_title("光屏1上极强位置")
global y0
xnan=a_value*np.sqrt(y0**2/b_value**2+1)
x_values = np.linspace(xnan,m, l)
# 计算双曲线的 y 值
y_values_positive = hyperbola(x_values, a_value, b_value,y0)
y_values_negative = -y_values_positive
x=np.hstack([x_values[::-1],x_values])
y=np.hstack([y_values_negative[::-1],y_values_positive])
a21.plot(x,y,c='#1f77b4')
a21.plot([a_value,a_value],[np.max(y_values_negative),np.min(y_values_positive)])
a21.plot([xnan,xnan],[np.nanmax(y_values_negative),np.nanmin(y_values_positive)],c='#1f77b4')
xnan=a_value*np.sqrt(y0**2/b_value**2+1)
x_values = np.linspace(-m,-xnan, l)
y_values_positive = hyperbola(x_values, a_value, b_value,y0)
y_values_negative = -y_values_positive
x=np.hstack([x_values[::-1],x_values])
y=np.hstack([y_values_negative[::-1],y_values_positive])
a21.plot(x,y,c='#1f77b4')
a21.plot([a_value,a_value],[np.max(y_values_negative),np.min(y_values_positive)])
a21.plot([-xnan,-xnan],[np.nanmax(y_values_negative),np.nanmin(y_values_positive)],c='#1f77b4')
a21.legend(["极强位置"],loc='upper right')
def draw1():
global lad
global phi
global d
a21.clear()
if imod==0:
m=-5
count=0
while count<=20 and m<70:
a=1/2*(m*lad+phi*lad/(2*np.pi))
m=m+1
if d**2-a**2>0 and a>0:
b=np.sqrt(d**2-a**2)
gethy(a,b,rg)
count=count+1
elif a==0:
a21.plot([0,0],[-rg,rg],c='#1f77b4')
else:
pass
a21.set_xlim(-rg,rg)
a21.set_ylim(-rg,rg)
a21.spines['left'].set_color('g')
a21.spines['bottom'].set_color('g')
a21.spines['right'].set_color('g')
a21.spines['top'].set_color('g')
else:
v=[0,1,0]
r=[0,y0,0]
if v[0]==0:
v[0]=0.0000001
n=100
m=mesh(-rg,rg,n)
pp=trans(m,np.array(v),r)
I=getI(pp)
p=m[:,:2]
intf=LinearNDInterpolator(p,I)
x=np.linspace(-rg,rg,100)
y=np.linspace(-rg,rg,100)
X,Y=np.meshgrid(x,y)
lev=50
maxlev=0.000005
out=intf(X,Y)
lev=np.int16((n/4))
# cour=a3.contourf(X,Y,out,levels=lev,alpha=1)
if logmod==0:
cour=a21.contourf(Y,X,out,levels=np.linspace(0,maxlev,lev),alpha=1)
else:
a21.contourf(X,Y,np.log(out),levels=np.linspace(-20,-20+maxlev,lev),alpha=1)
a21.set_xlabel("X/nm")
a21.set_ylabel("Z/nm")
a21.set_title("光屏1相对光强分布")
canvas2.draw()
def draw2():
global lad
global phi
global d
global x0
a22.clear()
m=-10
count=0
if imod==0:
while m<=np.floor(phi/(2*np.pi))+70:
m=m+1
a=1/2*(m*lad+phi*lad/(2*np.pi))
if d**2-a**2>=0 and (x0**2/a**2-1)>=0 and a>=0:
b=np.sqrt(d**2-a**2)
r=np.sqrt((x0**2/a**2-1))*b
circle = plt.Circle((0, 0), r, edgecolor='#1f77b4', facecolor='none')
a22.add_patch(circle)
a22.set_xlim(-rg*2,rg*2)
a22.set_ylim(-rg*2,rg*2)
a22.set_xlabel("X/nm")
a22.set_ylabel("Z/nm")
a22.set_title("光屏2上极强位置")
a22.legend(["极强位置"],loc='upper right')
a22.spines['left'].set_color('orange')
a22.spines['bottom'].set_color('orange')
a22.spines['right'].set_color('orange')
a22.spines['top'].set_color('orange')
count=count+1
else:
v=[1,0,0]
r=[x0,0,0]
if v[0]==0:
v[0]=0.0000001
n=100
m=mesh(-rg,rg,n)
pp=trans(m,np.array(v),r)
I=getI(pp)
p=m[:,:2]
intf=LinearNDInterpolator(p,I)
x=np.linspace(-rg,rg,100)
y=np.linspace(-rg,rg,100)
X,Y=np.meshgrid(x,y)
lev=50
maxlev=0.000005
out=intf(X,Y)
lev=np.int16((n/4))
# cour=a3.contourf(X,Y,out,levels=lev,alpha=1)
if logmod==0:
a22.contourf(X,Y,out,levels=np.linspace(0,maxlev,lev),alpha=1)
else:
a22.contourf(X,Y,np.log(out),levels=np.linspace(-20,-20+maxlev,lev),alpha=1)
a22.set_xlabel("X/nm")
a22.set_ylabel("Z/nm")
a22.set_title("光屏2相对光强分布")
canvas2.draw()
def newfunc(value=0):
global lad
global phi
global y0
global x0
global d
global imod
if chk_state.get():
imod=1
else:
imod=0
x0=np.float64(sx0.get())
lad=np.float64(sl.get())
phi=np.float64(sp.get())*np.pi
y0=np.float64(sy0.get())
d=np.float64(sd.get())
drawp()
draw1()
draw2()
canvas = FigureCanvasTkAgg(f1, master=wd)
canvas_widget=canvas.get_tk_widget()
canvas_widget.grid(row=0,column=0,rowspan=2,padx=20, pady=0, sticky="n")
drawp()
canvas2 = FigureCanvasTkAgg(f2, master=wd)
canvas2.draw()
canvas_widget2=canvas2.get_tk_widget()
canvas_widget2.grid(row=1,column=0, columnspan=2,padx=0, pady=400, sticky="n")
sx0 = tk.Scale(wd, from_=-rg, length=300,to=rg,resolution=10, orient=tk.HORIZONTAL, command=newfunc,label="屏2位置/nm")
sx0.grid(row=0,column=1,padx=10, pady=70, sticky="n",rowspan=2)
sx0.set(600)
sy0 = tk.Scale(wd, from_=-rg, to=rg,resolution=10, orient=tk.HORIZONTAL,command=newfunc,label="屏1位置/nm",length=300)
sy0.grid(row=0,column=1,padx=10, pady=0, sticky="n",rowspan=2)
sy0.set(800)
sd = tk.Scale(wd, from_=200, to=rg,resolution=10, orient=tk.HORIZONTAL, command=newfunc,label="波源位置/nm",length=300)
sd.grid(row=0,column=1,padx=10, pady=140, sticky="n",rowspan=2)
sd.set(1000)
sl = tk.Scale(wd, from_=200, to=1000,resolution=10, orient=tk.HORIZONTAL, command=newfunc,label=r"波长/nm",length=300)
sl.grid(row=0,column=1,padx=10, pady=210, sticky="n",rowspan=2)
sp = tk.Scale(wd, from_=0, to=5,resolution=0.1, orient=tk.HORIZONTAL, command=newfunc,label=r"初相/π",length=300)
sp.grid(row=0,column=1,padx=10, pady=280, sticky="n",rowspan=2)
f4=Figure(figsize=[6,5],dpi=75)
f3=Figure(figsize=[5,5],dpi=75)
a3=f3.add_subplot()
a4=f4.add_subplot(111,projection="3d")
# def on_resize(event):
# # 获取新的窗口大小
# new_width = event.width
# new_height = event.height
# # 计算新的DPI,可以根据需要调整比例
# new_dpi = min(new_width / 4, new_height / 4)
# # 设置新的DPI
# f1.set_dpi(new_dpi)
# # 调整Figure大小
# f1.set_size_inches(new_width/100, new_height/100) # 调整比例根据需要修改
# wd.bind("<Configure>", on_resize)
def open_wd1():
# 创建新窗口
wd1 = tk.Toplevel(wd)
# 设置新窗口的属性
wd1.title("3维自定义光屏位置")
wd1.geometry("1050x800")
canvas3 = FigureCanvasTkAgg(f3, master=wd1)
canvas_widget3=canvas3.get_tk_widget()
canvas_widget3.grid(row=0,column=1,padx=0)
canvas4 = FigureCanvasTkAgg(f4, master=wd1)
canvas_widget4=canvas4.get_tk_widget()
canvas_widget4.grid(row=0,column=0,padx=60)
entry1=tk.Entry(wd1)
entry1.grid(row=1,column=0,padx=30, pady=25, sticky="ne")
entry2=tk.Entry(wd1)
entry1.config(font=custom_font)
entry2.config(font=custom_font)
entry2.grid(row=1,column=0,padx=30, pady=100, sticky="ne")
entry1.insert(0,"1 2 3")
entry2.insert(0,"800 800 500")
def draw4(vv,r,n=200):
global maxlev
global logmod
global imod
m=mesh(-rg,rg,n)
v=vv
# if vv[2]==0:
# v[2]=0.0000001
# if vv[1]==0:
# v[1]=0.0000001
if vv[0]==0:
v[0]=0.0000001
a3.clear()
pp=trans(m,np.array(v),r)
I=getI(pp)
p=m[:,:2]
intf=LinearNDInterpolator(p,I)
x=np.linspace(-rg,rg,100)
y=np.linspace(-rg,rg,100)
X,Y=np.meshgrid(x,y)
out=intf(X,Y)
lev=np.int16((n/4))
# cour=a3.contourf(X,Y,out,levels=lev,alpha=1)
if logmod==0:
cour=a3.contourf(X,Y,out,levels=np.linspace(0,maxlev,lev),alpha=1)
else:
a3.contourf(X,Y,np.log(out),levels=np.linspace(-20,-20+maxlev,lev),alpha=1)
a3.set_xlabel("X/nm")
a3.set_ylabel("Y/nm")
a3.set_title("相对光强分布")
canvas3.draw()
def draw5(v,r):
global d
a4.clear()
a4.scatter([-d,d],[0,0],[0,0],c="r",s=20)
a4.xaxis.pane.fill = False
a4.yaxis.pane.fill = False
a4.zaxis.pane.fill = False
a4.set_xlim(-1.5*rg,1.5*rg)
a4.set_ylim(-1.5*rg,1.5*rg)
a4.set_zlim(-1.5*rg,1.5*rg)
v1=v[0]
v2=v[1]
v3=v[2]
r1=r[0]
r2=r[1]
r3=r[2]
if v3!=0:
x=[-rg+r1,r1,r1+rg]
y=[-rg+r2,r2,r2+rg]
X,Y=np.meshgrid(x,y)
Z=surf(v,r,X,Y)
a4.plot_surface(X,Y,Z,alpha=0.2)
a4.scatter([r1],[r2],[r3],s=5)
elif v2!=0:
x=np.linspace(-rg+r1,rg+r1,10)
z=np.linspace(-rg+r3,rg+r3,10)
X,Z=np.meshgrid(x,z)
Y=r2-v1/v2*(X-r1)
a4.plot_surface(X, Y, Z, alpha=0.2)
a4.scatter([r1],[r2],[r3],s=5)
else:
y=np.linspace(-rg+r2,rg+r2,10)
z=np.linspace(-rg+r3,rg+r3,10)
Y,Z=np.meshgrid(y,z)
X=r1-v2/v1*(Y-r1)
a4.plot_surface(X, Y, Z, alpha=0.2)
a4.scatter([r1],[r2],[r3],s=5)
vv=v
if v[0]==0:
vv[0]=0.000000001
xx=np.array([1,0,0])
xxtr=rotate_points_to_normal(xx,vv)
a4.quiver(r1, r2, r3, xxtr[0]*5000,xxtr[1]*5000,xxtr[2]*5000,color='k',linewidth=1,arrow_length_ratio=0.1,alpha=0.8)
a4.text(r1+xxtr[0]*5000,r2+xxtr[1]*5000,r3+xxtr[2]*5000,"X",color="k")
xx=np.array([0,1,0])
xxtr=rotate_points_to_normal(xx,vv)
a4.quiver(r1, r2, r3, xxtr[0]*5000,xxtr[1]*5000,xxtr[2]*5000,color='k',linewidth=1,arrow_length_ratio=0.1,alpha=0.8)
a4.text(r1+xxtr[0]*5000,r2+xxtr[1]*5000,r3+xxtr[2]*5000,"Y",color="k")
a4.legend(["波源"])
a4.set_title("波源及光屏位置")
a4.set_xlabel("X/nm")
a4.set_ylabel("Y/nm")
a4.set_zlabel("Z/nm")
canvas4.draw()
def newfunc2():
inputr=entry2.get()
inputv=entry1.get()
mod=egg(inputv)
if mod==0:
return
global lad
global phi
global d
global maxlev
global Ax
global A2
if logmod==0:
maxlev=10**(-np.float64(scl.get()))
else:
maxlev=np.float64(scl.get())*2.5
xx=np.sqrt(np.float64(sx.get())/100)
A2=xx
Ax=np.sqrt((1-xx**2))
lad=np.float64(sl1.get())
phi=np.float64(sp1.get())*np.pi
d=np.float64(sd1.get())
lev=np.int64(slev.get())
try:
v = np.array([float(value) for value in inputv.split(' ')])
r = np.array([float(value) for value in inputr.split(' ')])
except:
tk.messagebox.showerror("错误","非法输入")
if v.shape[0]==3 and r.shape[0]==3 and (np.any(v != 0)):
pass
else:
tk.messagebox.showerror("错误","非法输入")
draw4(v,r,lev)
draw5(v,r)
def newfunc3(value):
inputr=entry2.get()
inputv=entry1.get()
mod=egg(inputv)
if mod==0:
return
global lad
global phi
global d
lad=np.float64(sl1.get())
phi=np.float64(sp1.get())*np.pi
d=np.float64(sd1.get())
try:
v = np.array([float(value) for value in inputv.split(' ')])
r = np.array([float(value) for value in inputr.split(' ')])
except:
tk.messagebox.showerror("错误","非法输入")
if v.shape[0]==3 and r.shape[0]==3 and (np.any(v != 0)):
pass
else:
tk.messagebox.showerror("错误,""非法输入")
draw5(v,r)
l1=tk.Label(wd1,text="光屏法向量",font=custom_font1)
l4=tk.Label(wd1,text="(以空格分割,如1 2 3)",font=custom_font1)
l4.grid(row=1,column=0,padx=40,pady=40,sticky="nw")
l1.grid(row=1,column=0,padx=80,pady=20,sticky="nw")
l2=tk.Label(wd1,text="光屏中心坐标(nm)",font=custom_font1)
l2.grid(row=1,column=0,padx=80,pady=90,sticky="nw")
l3=tk.Label(wd1,text="(以空格分割,如1000 800 500)",font=custom_font1)
l3.grid(row=1,column=0,padx=10,pady=110,sticky="nw")
button2 = tk.Button(wd1, text="计算", command=newfunc2,width=10,height=2,font=custom_font)
button2.grid(row=1,column=1,padx=0, pady=250,sticky="n")
slev = tk.Scale(wd1, from_=0, to=300,resolution=10, orient=tk.HORIZONTAL, command=newfunc,label=r"精细度",length=300)
slev.grid(row=1,column=1,padx=10, pady=10, sticky="n")
slev.set(100)
sl1 = tk.Scale(wd1, from_=200, to=1000,resolution=10, orient=tk.HORIZONTAL, label=r"波长/nm",length=300)
sl1.grid(row=1,column=0,padx=10, pady=150, sticky="n")
sp1 = tk.Scale(wd1, from_=0, to=5,resolution=0.1, orient=tk.HORIZONTAL,label=r"初相/π",length=300)
sp1.grid(row=1,column=0,padx=10, pady=210, sticky="n")
sd1 = tk.Scale(wd1, from_=200, to=rg,resolution=10, orient=tk.HORIZONTAL, command=newfunc3,label="波源位置/nm",length=300)
sd1.grid(row=1,column=0,padx=10, pady=270, sticky="n")
sd1.set(1000)
scl=tk.Scale(wd1, from_=3, to=7,resolution=0.01, orient=tk.HORIZONTAL,label=r"Scale",length=300)
scl.grid(row=1,column=1,padx=10, pady=90 ,sticky="n")
scl.set(5.5)
sx=tk.Scale(wd1, from_=0, to=100,resolution=1, orient=tk.HORIZONTAL,label=r"S2中相干成分比例(%)",length=300)
sx.set(100)
sx.grid(row=1,column=1,padx=10, pady=160 ,sticky="n")
ln2=tk.Label(wd1,text="by 谢昀城 复旦大学 物理系22级")
ln2.grid(row=1,column=1,sticky="ne")
newfunc2()
wd1.mainloop()
wd1.protocol(sys.exit(0))
# 创建按钮
button = tk.Button(wd, text="自定义光屏3维位置", command=open_wd1,font=custom_font)
button.grid(row=1,column=1,padx=200, pady=350, sticky="n")
ln1=tk.Label(wd,text="by 谢昀城 复旦大学 物理系22级")
ln1.grid(row=0,column=1,sticky="SE")
chk_state = tk.IntVar()
checkbox = tk.Checkbutton(wd, text="显示光强",variable=chk_state,command=newfunc)
checkbox.grid(row=0,column=1,sticky="n",padx=100)
wd.mainloop()
wd.protocol(sys.exit(0))
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化