使用Turtle库绘制望远镜和显微镜成像系统原理图

(一)望远镜成像系统(两片凸透镜实现)

1.作用:利用望远镜能够看清远处的物体;
2.组成:由两组凸透镜组成。靠进物体的叫物镜,焦距较长;靠近眼睛的目镜,焦距较短,物镜的第二焦点与目镜的第一焦点重合;
3.原理:物镜的作用是使远处的物体在焦点附近成实像,目镜的作用相当于一个放大镜,用来把像放大

由于不同的透镜材质不同,折射率不同(如果要考虑这些的话,会有很多参数要设置),所以下面的透镜是随便画的,所以,下面透镜圆心角也是随便设的,合理即可。实现得效果大致如下
在这里插入图片描述
下面是为了方便自定义绘图,写了一些自定义函数

下面这个函数用来计算两向量之间的夹角,这个函数有两个参数,v1,v2它们是列表,分别存放在两个向量的四个坐标的位置信息位置。例如:v1=[x1,y1,x2,y2](第一个向量的两个坐标),v3=[x3,y3,x4,y4](第二个向量的两个坐标)。经函数计算后,返回的结果是两个向量的夹角。

这个函数在这个任务里的作用是,计算圆心角。

PS:这里是向量,因为向量有方向,有固定的夹角,而两条直线的夹角由两个。所以,这里是向量

def yuan_xin_jiao(v1, v2):#计算两向量夹角的函数
  dx1 = v1[2] - v1[0]
  dy1 = v1[3] - v1[1]
  dx2 = v2[2] - v2[0]
  dy2 = v2[3] - v2[1]
  angle1 = math.atan2(dy1, dx1)
  angle1 = int(angle1 * 180/math.pi)

  angle2 = math.atan2(dy2, dx2)
  angle2 = int(angle2 * 180/math.pi)

  if angle1*angle2 >= 0:
    included_angle = abs(angle1-angle2)
  else:
    included_angle = abs(angle1) + abs(angle2)
    if included_angle > 180:
      included_angle = 360 - included_angle
  return included_angle

下面这个是,标注图像上字母的函数,a,b是坐标位置,c是要标注的内容

def words(a,b,c):#标注字母的函数
    penup()
    goto(a,b)
    pendown()
    write(c,font=('Arial',7,'normal'))

这个函数,与上面的函数没啥区别,主要是字体大小不同

def character(a,b,c):#写汉字的函数
    penup()
    goto(a,b)
    pendown()
    write(c,font=('Arial',15,'normal'))

下面这个是计算两点之间距离的函数,x1,y1,x2,y2,分别是两点的横纵坐标

def distence(x1,y1,x2,y2):#计算两点之间距离的函数
    p1 = np.array([x1,y1])
    p2 = np.array([x2,y2])
    p3 = p2 - p1
    p4 = math.hypot(p3[0], p3[1])
    return p4

下面是画线前准备的函数,a,b跳转到指定位置

def draw(a,b):#画线前的准备函数
    penup()
    goto(a,b)
    pendown()

下面这个是计算两直线之间角度的函数line1,line2也是列表,分别存放两条直线的四个坐标位置,如:line1=[x1,y1,x2,y2](格式),返回在是焦点的坐标

def point(line1, line2):  # 计算直线交点函数
    x1 = line1[0]  # 取四点坐标
    y1 = line1[1]
    x2 = line1[2]
    y2 = line1[3]

    x3 = line2[0]
    y3 = line2[1]
    x4 = line2[2]
    y4 = line2[3]

    k1 = (y2 - y1) * 1.0 / (x2 - x1)  # 计算k1,由于点均为整数,需要进行浮点数转化
    b1 = y1 * 1.0 - x1 * k1 * 1.0  # 整型转浮点型是关键
    if (x4 - x3) == 0:  # L2直线斜率不存在操作
        k2 = None
        b2 = 0
    else:
        k2 = (y4 - y3) * 1.0 / (x4 - x3)  # 斜率存在操作
        b2 = y3 * 1.0 - x3 * k2 * 1.0
    if k2 == None:
        x = x3
    else:
        x = (b2 - b1) * 1.0 / (k1 - k2)
    y = k1 * x * 1.0 + b1 * 1.0
    return x, y

代码如下:




from turtle import *
import math
import numpy as np



def yuan_xin_jiao(v1, v2):#计算两向量夹角的函数
  dx1 = v1[2] - v1[0]
  dy1 = v1[3] - v1[1]
  dx2 = v2[2] - v2[0]
  dy2 = v2[3] - v2[1]
  angle1 = math.atan2(dy1, dx1)
  angle1 = int(angle1 * 180/math.pi)

  angle2 = math.atan2(dy2, dx2)
  angle2 = int(angle2 * 180/math.pi)

  if angle1*angle2 >= 0:
    included_angle = abs(angle1-angle2)
  else:
    included_angle = abs(angle1) + abs(angle2)
    if included_angle > 180:
      included_angle = 360 - included_angle
  return included_angle

def words(a,b,c):#标注字母的函数
    penup()
    goto(a,b)
    pendown()
    write(c,font=('Arial',7,'normal'))

def character(a,b,c):#写汉字的函数
    penup()
    goto(a,b)
    pendown()
    write(c,font=('Arial',15,'normal'))


def distence(x1,y1,x2,y2):#计算两点之间距离的函数
    p1 = np.array([x1,y1])
    p2 = np.array([x2,y2])
    p3 = p2 - p1
    p4 = math.hypot(p3[0], p3[1])
    return p4

def draw(a,b):#画线前的准备函数
    penup()
    goto(a,b)
    pendown()

def point(line1, line2):  # 计算直线交点函数
    x1 = line1[0]  # 取四点坐标
    y1 = line1[1]
    x2 = line1[2]
    y2 = line1[3]

    x3 = line2[0]
    y3 = line2[1]
    x4 = line2[2]
    y4 = line2[3]

    k1 = (y2 - y1) * 1.0 / (x2 - x1)  # 计算k1,由于点均为整数,需要进行浮点数转化
    b1 = y1 * 1.0 - x1 * k1 * 1.0  # 整型转浮点型是关键
    if (x4 - x3) == 0:  # L2直线斜率不存在操作
        k2 = None
        b2 = 0
    else:
        k2 = (y4 - y3) * 1.0 / (x4 - x3)  # 斜率存在操作
        b2 = y3 * 1.0 - x3 * k2 * 1.0
    if k2 == None:
        x = x3
    else:
        x = (b2 - b1) * 1.0 / (k1 - k2)
    y = k1 * x * 1.0 + b1 * 1.0
    return x, y

f1= eval(input("物镜的焦距f1:"))#这里设置为90
f2= eval(input("目镜的焦距f2:"))#这里设置为30
O1= eval(input("物镜的主点位置O1:"))#这里设置为(-800O2= eval(input("目镜的主点位置O2:"))#这里设置为(400H1= eval(input("物镜的高度H1:"))#这里设置为50
H2= eval(input("目镜的高度H2:"))#这里设置为30
Y1= eval(input("物镜的圆心位置Y1:"))#这里设置为(00Y2= eval(input("目镜的圆心位置Y2:"))#这里设置为(00Y=  eval(input("平行光入射高度Y:"))#这里设置为40
X=  eval(input("绘制平行光的起始位置X:"))#这里设置为-180


character(-50,251,"望远镜成像系统")

r1=distence(Y1,0,O1,H1)#物镜半径
Y1A=[Y1,0,O1,H1]#F2A两点的横纵坐标
Y1B=[Y1,0,O1,-H1]
yuan_xin_jiao1=yuan_xin_jiao(Y1A,Y1B)#计算圆心角



r2=distence(Y2,0,O2,H2)#目镜半径
Y2C=[Y2,0,O2,H2]#Y2C两点的横纵坐标
Y2D=[Y2,0,O2,-H2]
yuan_xin_jiao2=yuan_xin_jiao(Y2C,Y2D)#计算圆心角

draw(0,0)#画光轴,自行合理设置
fd(220)
fd(-440)

draw(O1,H1)#画物镜
seth(-90-yuan_xin_jiao1/2)
circle(r1,yuan_xin_jiao1)
seth(90-yuan_xin_jiao1/2)
circle(r1,yuan_xin_jiao1)

draw(O1,0)#画物镜的主平面
seth(-90)
fd(H1)
fd(-H1*2)

draw(O2,H2)#画目镜
seth(-90-yuan_xin_jiao2/2)
circle(r2,yuan_xin_jiao2)
seth(90-yuan_xin_jiao2/2)
circle(r2,yuan_xin_jiao2)

draw(O2,0)#画目镜的主平面
seth(-90)
fd(H2)
fd(-H2*2)


pencolor('blue')#设定光线的颜色,和字体的颜色

draw(X,Y)
seth(0)
fd(O1-X)

JF1=[O1,Y,O1+f1,0]#EF1两点的横纵坐标
CD=[O2,H2,O2,-H2]
x1,y1=point(JF1, CD)#计算两直线的交点,Q
goto(x1,y1)
fd(100)#自行合理设置

draw(X,-Y)
fd(O1-X)

KF1=[O1,-Y,O1+f1,0]#EF1两点的横纵坐标
CD=[O2,H2,O2,-H2]
x2,y2=point(KF1, CD)#计算两直线的交点,P
goto(x2,y2)
fd(100)#自行合理设置

words(O1,0,'O1')

words(O2,0,'O2')

words(O1,H1,'A')

words(O1,-H1-15,'B')#相对于真实的位置,这里向下偏移15个单位,主要是为了美观,下面的代码中也有类似的操作,就不一一注释了

words(O2,H2,'C')

words(O2,-H2-15,'D')

words(O1,Y-15,'J')

words(O1,-Y,'K')

words(x2,y2,'P')

words(x1,y1,'Q')

words(O1-f1,0,'-F1')

words(O1+f1,0+15,'F1')

words(O2-f2,0-15,'-F2')

words(O2+f2,0,'F2')


character(O1,H1+30,"物镜")

character(O2,H2+30,"目镜")

hideturtle()
done()


效果如下

在这里插入图片描述

(二)显微镜成像系统(两片凸透镜实现)

1.作用:用来观察细微物体或物体细微部。
2。原理:根据凸透镜的成像原理 ,要经过凸透镜的两次成像,先用一个接近物体的凸透镜使物体成-放大的实像,然后再用另一个接近眼睛的凸透镜把这个实像再次放大,就能看清很微小的物体。
3.组成:由一个透镜或者几个透镜的组合构成,离物体近的透镜叫物镜,其焦距较短;离眼睛近的透镜叫目镜,其焦距比物镜稍大,两镜间的距离可以调节。

实现大致效果如下:
在这里插入图片描述
下面这个函数是用来计算函数的倾斜角度的,用上面的计算向量夹角的函数当然也可以,但这里配合turtle.seth函数使用更方便

def angle(x1,y1,x2,y2):#计算直线的倾斜角度角度
    oue_put = math.atan((y1 - y2) / (x1-x2))
    oue_put = math.degrees(oue_put)
    return oue_put

看看代码吧:



from turtle import *
import math
import numpy as np

def angle(x1,y1,x2,y2):#计算直线的倾斜角度角度
    oue_put = math.atan((y1 - y2) / (x1-x2))
    oue_put = math.degrees(oue_put)
    return oue_put


def yuan_xin_jiao(v1, v2):#计算两向量夹角的函数
  dx1 = v1[2] - v1[0]
  dy1 = v1[3] - v1[1]
  dx2 = v2[2] - v2[0]
  dy2 = v2[3] - v2[1]
  angle1 = math.atan2(dy1, dx1)
  angle1 = int(angle1 * 180/math.pi)

  angle2 = math.atan2(dy2, dx2)
  angle2 = int(angle2 * 180/math.pi)

  if angle1*angle2 >= 0:
    included_angle = abs(angle1-angle2)
  else:
    included_angle = abs(angle1) + abs(angle2)
    if included_angle > 180:
      included_angle = 360 - included_angle
  return included_angle

def words(a,b,c):#标注字母的函数
    penup()
    goto(a,b)
    pendown()
    write(c,font=('Arial',7,'normal'))

def character(a,b,c):#写汉字的函数
    penup()
    goto(a,b)
    pendown()
    write(c,font=('Arial',15,'normal'))


def distence(x1,y1,x2,y2):#计算两点之间距离的函数
    p1 = np.array([x1,y1])
    p2 = np.array([x2,y2])
    p3 = p2 - p1
    p4 = math.hypot(p3[0], p3[1])
    return p4

def draw(a,b):#画线前的准备函数
    penup()
    goto(a,b)
    pendown()

def point(line1, line2):  # 计算直线交点函数
    x1 = line1[0]  # 取四点坐标
    y1 = line1[1]
    x2 = line1[2]
    y2 = line1[3]

    x3 = line2[0]
    y3 = line2[1]
    x4 = line2[2]
    y4 = line2[3]

    k1 = (y2 - y1) * 1.0 / (x2 - x1)  # 计算k1,由于点均为整数,需要进行浮点数转化
    b1 = y1 * 1.0 - x1 * k1 * 1.0  # 整型转浮点型是关键
    if (x4 - x3) == 0:  # L2直线斜率不存在操作
        k2 = None
        b2 = 0
    else:
        k2 = (y4 - y3) * 1.0 / (x4 - x3)  # 斜率存在操作
        b2 = y3 * 1.0 - x3 * k2 * 1.0
    if k2 == None:
        x = x3
    else:
        x = (b2 - b1) * 1.0 / (k1 - k2)
    y = k1 * x * 1.0 + b1 * 1.0
    return x, y
L=  eval(input("主光轴的长度L:"))#这里设置为300
f1= eval(input("物镜的焦距f1:"))#这里设置为40
f2= eval(input("目镜的焦距f2:"))#这里设置为100
O1= eval(input("物镜的主点位置O1:"))#这里设置为(-800O2= eval(input("目镜的主点位置O2:"))#这里设置为(1000H1= eval(input("物镜的高度H1:"))#这里设置为50
H2= eval(input("目镜的高距H2:"))#这里设置为100
Y1= eval(input("物镜的圆心位置Y1:"))#这里设置为(00Y2= eval(input("目镜的圆心位置Y2:"))#这里设置为(-200X=  eval(input("物体的位置X:"))#这里设置为(-1400Y=  eval(input("物体的高度Y:"))#这里设置为40

character(-50,251,"显微镜成像系统")

r1=distence(Y1,0,O1,H1)#物镜半径
F1A=[Y1,0,O1,H1]#-F1A两点的横纵坐标
F1B=[Y1,0,O1,-H1]#-F1B两点的横纵坐标
yuan_xin_jiao1=yuan_xin_jiao(F1A,F1B)#计算圆心角



r2=distence(Y2,0,O2,H2)#目镜半径
F2C=[Y2,0,O2,H2]#-F2C两点的横纵坐标
F2D=[Y2,0,O2,-H2]##-F2D两点的横纵坐标
yuan_xin_jiao2=yuan_xin_jiao(F2C,F2D)#计算圆心角

draw(0,0)#画光轴
fd(L)
fd(-2*L)


draw(O1,H1)#画物镜
seth(-90-yuan_xin_jiao1/2)
circle(r1,yuan_xin_jiao1)
seth(90-yuan_xin_jiao1/2)
circle(r1,yuan_xin_jiao1)


draw(O1,0)#画物镜的主平面
seth(-90)
fd(H1)
fd(-H1*2)


draw(O2,H2)#画目镜
seth(-90-yuan_xin_jiao2/2)
circle(r2,yuan_xin_jiao2)
seth(90-yuan_xin_jiao2/2)
circle(r2,yuan_xin_jiao2)



draw(O2,0)#画目镜的主平面
seth(-90)
fd(H2)
fd(-H2*2)

draw(X,0)#画物的位置
seth(90)
fd(Y)


pencolor('blue')#设定光线的颜色,和字体的颜色
draw(X,Y)#跳转到Y点,画直线YA
seth(0)
fd(O1-X)

YO1=[X,Y,O1,0]#YO1两点的横纵坐标
EF1=[O1,Y,O1+f1,0]
x1,y1=point(YO1, EF1)#计算两直线的交点
print(x1,y1)

goto(x1,y1)#跳转到G点,画直线GJ
distence3=distence(x1,y1,O2,y1)#计算GJ的距离
fd(distence3)

draw(X,Y)#跳转到Y点,画直线YG
goto(x1,y1)

GO2=[x1,y1,O2,0]#GO2两点的横纵坐标
JF2=[O2,y1,O2+f2,0]
x2,y2=point(GO2, JF2)#计算两直线的交点


draw(x2,y2)#跳转到P点
angle1=angle(O2,0,x1,y1)#计算O2G的倾斜角度
seth(angle1)
distence1=distence(x1,y1,x2,y2)#计算GP的距离
for i in range (10):#这里是为了画倾斜的虚线
    fd(distence1/20)
    penup()
    fd(distence1/20)
    pendown()
fd(200)#自行合理设置

draw(x2,y2)#跳转到P点
angle2=angle(O2,y1,x2,y2)##计算JP的倾斜角度
seth(angle2)
distence2=distence(O2,y1,x2,y2)#计算JP的距离
for i in range (10):#这里是为了画倾斜的虚线
    fd(distence2/20)
    penup()
    fd(distence2/20)
    pendown()
fd(300)#自行合理设置

draw(x2,y2)#跳转到Pfor i in range (10):#这里是为了P点到主光轴的的虚线
    seth(-90)
    fd(y2/20)
    penup()
    fd(y2/20)
    pendown()

#下面X点,B点,D,G点,P点,J点的坐标皆偏离主光轴-15个单位,为了美观
words(X,-15,'X')

words(X,Y,'Y')

words(O1-f1,0,'F1')#F1左焦点

words(O1,0,'O1')

words(O1+f1,0,'-F1')#F1右焦点

words(O2-f2,0,'F2')#F2左焦点

words(O2,0,'O2')

words(O2+f2,0,'-F2')#F2左焦点

words(O1,H1,'A')

words(O1,-H1-15,'B')

words(O2,H2,'C')

words(O2,-H2-15,'D')

words(O1,Y-15,"E")

words(x1,y1-15,"G")

words(x2,y2-15,"P")

words(O2,y1-15,"J")


character(x2-30,y2/2,"虚像")

character(O1,H1+30,"物镜")

character(O2,H2+30,"目镜")

hideturtle()
done()






效果如下:
在这里插入图片描述
数据输入示例:
主光轴的长度L:300
物镜的焦距f1:40
目镜的焦距f2:100
物镜的主点位置O1:-80
目镜的主点位置O2:100
物镜的高度H1:50
目镜的高距H2:100
物镜的圆心位置Y1:0
目镜的圆心位置Y2:-20
物体的位置X:-140
物体的高度Y:40

(三)结语

如果有什么错误的地方,还请大家批评指正,最后,希望小伙伴们都能有所收获。码字不易,喜欢的话,关注一波在走吧

在这里插入图片描述

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值