mtDNA 发表于 2022-9-2 19:10

【Python】turtle绘制光路图(高中物理几何光学)

根据高中物理知识编写的简易作图脚本

```
#反射定理 i1′=i1
#折射定理 n1*sin(i1)=n2*sin(i2)

import turtle as t
from math import *

def Get_n(index):   #获取折射率
    subs=["₁", "₂"]
    while True:
      n=eval(input("n{}=".format(subs)))
      if n>0:
            break
      else:
            print("折射率应为正")
            continue
    return n

def Get_i1():       #获取入射角
    while True:
      i1=eval(input("i₁ /deg="))
      if 0<=i1<=90:
            break
      else:
            print("入射角范围为0~90°")
            continue
    return i1

def Set_Parameters():   #设置参数
    global n1, n2, C, i1, i2, i1_    #两种介质折射率n1, n2   临界角C 入射角i1 折射角i2 反射角i1_(i1′)
    n1=Get_n(0)
    n2=Get_n(1)
    i1=Get_i1()
    i1_=i1

    if i1==90:
      i1_=i2=None
    else:
      if n1>n2:
            C=degrees(asin(n2/n1))       #计算临界角判断是否全反射
            print("C={:.2f}°".format(C))
            if i1>=round(C,3):
                i2=None
            else:
                i2=degrees(asin(n1*sin(radians(i1))/n2))
      else:
            i2=degrees(asin(n1*sin(radians(i1))/n2))



def Set_Turtles():#设置海龟
    global incident_wave, reflected_wave, refracted_wave, normal_line, interface, annotation
    incident_wave=t.Turtle()    #画入射光
    reflected_wave=t.Turtle()   #画反射光
    refracted_wave=t.Turtle()   #画折射光
    normal_line=t.Turtle()      #画法线
    interface=t.Turtle()             #画反射界面
    annotation=t.Turtle()         #标注

    incident_wave.ht()            #隐藏海龟
    reflected_wave.ht()
    refracted_wave.ht()
    normal_line.ht()
    interface.ht()
    annotation.ht()

    incident_wave.speed(0)      #设置为速度最快
    reflected_wave.speed(0)
    refracted_wave.speed(0)
    normal_line.speed(0)
    interface.speed(0)
    annotation.speed(0)

    incident_wave.width(5)      #调整粗细
    reflected_wave.width(5)
    refracted_wave.width(5)
    normal_line.width(3)
    interface.width(3)
    annotation.width(3)

    incident_wave.color("red")
    reflected_wave.color("red")
    refracted_wave.color("red")

    incident_wave.up()
    reflected_wave.up()
    refracted_wave.up()
    normal_line.up()
    interface.up()
    annotation.up()



def Draw_interface():   #画反射界面
    interface.goto(-300,0)
    interface.down()
    interface.fd(600)



def Draw_normal_line():   #画法线
    normal_line.goto(0,300)
    normal_line.rt(90)
    for i in range(60):
      normal_line.down()
      normal_line.fd(5)
      normal_line.up()
      normal_line.fd(5)




def Draw_incident_wave():   #画入射光
    incident_wave.goto(300*cos(radians(i1)+pi/2),300*sin(radians(i1)+pi/2))
    incident_wave.down()
    incident_wave.seth(270+i1)
    incident_wave.fd(300)
    incident_wave.goto(150*cos(radians(i1)+pi/2),150*sin(radians(i1)+pi/2))
    incident_wave.rt(150)
    incident_wave.begin_fill()
    for i in range(3):
      incident_wave.fd(10)
      incident_wave.rt(120)
    incident_wave.end_fill()



def Draw_reflected_wave():#画反射光
    reflected_wave.down()
    if i1_==None:
      reflected_wave.seth(0)
      reflected_wave.fd(300)
      reflected_wave.goto(150,0)
    else:
      reflected_wave.seth(90-i1_)
      reflected_wave.fd(300)
      reflected_wave.goto(150*cos(pi/2-radians(i1_)),150*sin(pi/2-radians(i1_)))
    reflected_wave.rt(150)
    reflected_wave.begin_fill()
    for i in range(3):
      reflected_wave.fd(10)
      reflected_wave.rt(120)
    reflected_wave.end_fill()



def Draw_refracted_wave():#画折射光
    if i2==None:
      pass
    else:    #total_internal_reflection=False
      refracted_wave.down()
      refracted_wave.seth(270+i2)
      refracted_wave.fd(300)
      refracted_wave.goto(150*cos(radians(i2)+pi*3/2),150*sin(radians(i2)+pi*3/2))
      refracted_wave.rt(150)
      refracted_wave.begin_fill()
      for i in range(3):
            refracted_wave.fd(10)
            refracted_wave.rt(120)
      refracted_wave.end_fill()



def Write_annotation():   #标注
    annotation.color("green")
    annotation.goto(-300,5)
    annotation.write("n₁={:.2f}".format(n1), font=("Arial",40,"normal"))
    annotation.goto(-300,-60)
    annotation.write("n₂={:.2f}".format(n2), font=("Arial",40,"normal"))
    annotation.color("blue")

    #标注入射角
    if i1==90:
      pass
    else:
      annotation.goto(-30,45)
      annotation.write("i₁", font=("Arial",30,"normal"))
      annotation.goto(0,45)
      annotation.down()
      annotation.seth(180)
      annotation.circle(45,i1)
      annotation.up()

    #标注反射角
    if i1_==None:
      pass
    else:
      annotation.goto(5,50)
      annotation.write("i₁′", font=("Arial",30,"normal"))
      annotation.goto(0,50)
      annotation.down()
      annotation.seth(0)
      annotation.circle(-50,i1_)
      annotation.up()

    #标注折射角
    if i2==None:
      pass
    else:
      annotation.goto(5,-95)
      annotation.write("i₂", font=("Arial",30,"normal"))
      annotation.goto(0,-50)
      annotation.down()
      annotation.seth(0)
      annotation.circle(50,i2)
    annotation.up()


    #标注参数
    annotation.goto(-300,-100)
    if i1==90:
      pass
    else:
      annotation.write("i₁={:.2f}°".format(i1), font=("Arial",30,"normal"))

    annotation.goto(-300,-150)
    if i1_==None:
      pass
    else:
      annotation.write("i₁′={:.2f}°".format(i1_), font=("Arial",30,"normal"))
      
    annotation.goto(-300,-200)
    if i2==None and i1<90:
      annotation.write("全反射", font=("Arial",30,"normal"))
    elif i2!=None:
      annotation.write("i₂={:.2f}°".format(i2), font=("Arial",30,"normal"))



def main():
    Set_Parameters()
    Set_Turtles()
    Draw_interface()
    Draw_normal_line()
    Draw_incident_wave()
    Draw_reflected_wave()
    Draw_refracted_wave()
    Write_annotation()
    t.done()



if __name__=="__main__":
    main()
```




调试:输入参数后回车输入下一个





bdcpc 发表于 2022-9-2 20:22

大神,谢谢分享

留点口德 发表于 2022-9-2 22:31

感谢分享

liu2514 发表于 2022-9-3 04:52

感谢大神,来学习学习思路。

ghoob321 发表于 2022-9-3 07:38

谢谢分享膜拜

ghoob321 发表于 2022-9-3 07:39

谢谢分享感谢大神,来学习学习思路。
页: [1]
查看完整版本: 【Python】turtle绘制光路图(高中物理几何光学)