回到首页 返回首页
回到顶部 回到顶部
返回上一页 返回上一页
best-icon

【Mind+Python】凸透镜成像动态规律 简单

头像 许培享 2021.08.23 2953 0

背景:

人教版初中八年级《物理》上册书的重难点章节是第五章《透镜及其应用》。本章特点之一是概念多,如:透镜、凸透镜、凹透镜;光心、主光轴(主轴)、焦点、焦距(1、2倍焦距);光的会聚与发散,实像与虚像等等。教学与学习难点有光学作图,凸透镜成像的动态规律等,大多数学生难以解决实际问题。

其中的核心内容(重难点)是第三节《凸透镜成像的规律》。抓住了规律,特别是动态规律(作光路图),就容易突破这个难点,就能容易理解照相机、投影仪(幻灯机)、放大镜,以及后面的近视眼镜、显微镜、天文望远镜、潜望镜等。

我们先来看几张PPT:

project-image
project-image
project-image
project-image
project-image
project-image

动态规律:

project-image
project-image

从以上PPT我们看出,只有掌握了凸透镜成像的规律,才能理解透镜成像的虚、实;正、倒;大、小;教师可以通过演示实验,在讲台上或者PPT上动画展示,学生们记忆规律口诀等。但是课后同学们仍然难以形成内化的知识规律,也不可能在实验室里反复折腾。特别是对于物体与透镜的距离改变时发生的动态规律更难把握。因此,在2020年12月份,python版程序——“凸透镜的动态规律”首次试验基本实现动态规律。课后,同学们可以在电子白板上自由操作了。

这里的代码在V1.7.1RC1.0 Mind+中增添了一些效果功能,于8/24/2021完成。

程序功能:

1、固定元素:在屏幕大窗口中展示凸透镜示意图(含主光轴、光心、焦点、2倍焦点等);

2、绘制动态元素:鼠标或触摸设备随机点击凸透镜左边任意位置(点击次数暂设置为20),立即在此位置画出代表物体的箭头形状、发出两条特殊光线(平行于主光轴和穿过光心)、相应的两条折射光线及物体所成的实像(或虚像-带反射延长线),右上出现相应提示标签等。为了前后对比,不会擦除已画动态元素。

编制过程:

步骤1 布局窗口大小坐标系、画出固定元素

如:利用graphics.py 库文件功能,绘制凸透镜示意图(含主光轴、光心、焦点、2倍焦点、提示标签)

project-image
project-image

步骤2 动态元素

动态元素--物体、实像、虚像、光线都同时随鼠标的点击而增添画出。

物体:(不改变大小)只在主光轴左侧上方水平位置;位置由鼠标点击时的X轴位置决定。

实像:只在主光轴右侧下方位置变化(改变大小);关键顶点位置由过光心直线与过右焦点直线的两直线方程相交之解得到。

虚像:只在主光轴左侧上方位置变化(改变大小);同上。

光线:仅穿过光心的变化。确定光线由物体箭头顶点与坐标原点决定。

以下81、82是核心代码。

project-image

步骤3 程序结构

主程序main()

主要完成固定元素绘制及最后调用下面两个子程序。

子程序1:myobj_ray()

绘制动态对象。

子程序2: display_noteText()

绘制动态对象变化时的提示标签及显示效果。(这两天的附加功能)

以下代码附加详细注释

代码
# 动态规律
# 12/2020 ini
# 08/23-24/2021 ok

from graphics import *  # 导入库文件
from random import * 
global noteText_loc
noteText_loc = 0
win = GraphWin("凸透镜成像动态规律",1280,600) # 设置窗口及标题
win.setCoords(-700,-563,1100,281) # 设置相对坐标系
noteText = Text(Point(600,100),'成像规律提示') # 提示标签
noteText.setTextColor('green')
noteText.setStyle("bold")
noteText.setSize(22)
noteText.draw(win)
################ 定义主函数
def main(): 
    mainAxis = Rectangle(Point(-690,3),Point(1090,-3))
    mainAxis.setWidth(1)
    mainAxis.setFill("blue")
    mainAxis.draw(win)
    Text(Point(1000,20),'主光轴').draw(win) # 凸透镜主光轴标签
    
    #画凸透镜示意图
    triangleUp = Polygon(Point(-20,220),Point(20,220),Point(0,250))
    triangleUp.setFill("cyan")
    triangleUp.draw(win)
    triangleDown = Polygon(Point(-20,-220),Point(20,-220),Point(0,-250))
    triangleDown.setFill("cyan")    
    triangleDown.draw(win)
        
    lens = Rectangle(Point(-5,-222),Point(5,220))
    lens.setWidth(0)
    lens.setFill("CYAN")
    lens.draw(win)
    Text(Point(0,-270),'凸透镜').draw(win) # 凸透镜标签
    
    fdotC = Circle(Point(0,0),8) # 画光心
    fdotC.setWidth(1)
    fdotC.setFill("yellow")
    fdotC.draw(win)
    Text(Point(0,-30),'光心').draw(win) # 光心标签
    
    fdotL = Circle(Point(-150,0),10) # 画左焦点
    fdotL.setFill("yellow")
    Text(Point(-150,-30),'F').draw(win) # 一倍焦距左标签
    fdotL.draw(win)

    fdotR = Circle(Point(150,0),10) # 画右焦点
    fdotR.setFill("yellow")
    Text(Point(150,30),'F').draw(win) # 一倍焦距右标签
    fdotR.draw(win)

    fdotL2 = Circle(Point(-300,0),10) # 画左两倍焦距点
    fdotL2.setFill("yellow")
    Text(Point(-300,-30),'2F').draw(win) # 二倍焦距左标签
    fdotL2.draw(win)

    fdotR2 = Circle(Point(300,0),10) # 画右两倍焦距点
    fdotR2.setFill("yellow")
    Text(Point(300,30),'2F').draw(win) # 二倍焦距右标签
    fdotR2.draw(win)

    for i in range(20): # 设置成像画图次数
        myobj_ray() #调用成像子函数
        display_noteText() #调用提示标签子函数
################### 定义绘制光线子函数
# 注:待成像的实物必须位于凸透镜的左边,所以鼠标点击右边无效
def myobj_ray(): 
    global noteText_loc
    objX = win.getMouse().getX()
    while objX > 0: # 只捕捉鼠标点击凸透镜左边
        objX = win.getMouse().getX()
        
        
    if -310 < objX < -290: # 鼠标点击在 2F 附近则直接“吸附”为 2F 点
        objX = -300
    if -160 < objX < -140: # 鼠标点击在 F 附近则直接“吸附”为 F 点
        objX = -149
    
    px = 135/(135/objX+0.9) # (px,py)是两个直线方程的交点
    py = px*135/objX        # y = 135  - 0.9x;y = kx(k = 135/objX)
            
    obj = Polygon(Point(objX-7,0),Point(objX+7,0),Point(objX+7,110),
                  Point(objX+15,110),Point(objX,135),
                  Point(objX-15,110),Point(objX-7,110)) # 画实物(固定大小的棕色箭头)
    obj.setFill("brown")

    scaleV = py/135
    phoVR = Polygon(Point(px-7*scaleV,0),Point(px+7*scaleV,0),
                   Point(px+7*scaleV,110*scaleV),Point(px+15*scaleV,110*scaleV),
                   Point(px,py),Point(px-15*scaleV,110*scaleV),
                   Point(px-7*scaleV,110*scaleV)) # 画像
    if  -150 < objX < 0:
        phoVR.setFill("yellow")
        phoVR.setOutline("yellow") # 如果是放大镜原理成的虚像用黄色
    else:
        phoVR.setFill("orange") # 否则成实像用橙色
    
    rayh = Line(Point(objX,135),Point(0,135))
    rayh.setWidth(3)
    rayh.setArrow("last")
    rayh.setFill("red") # 画来自实物平行主光轴的带方向的光线
    
    rayf = Line(Point(0,135),Point(150,0))
    rayf.setWidth(3)
    rayf.setArrow("last")
    rayf.setFill("red") # 画Y轴到X轴的固定光线

    rayp = Line(Point(150,0),Point(750,-540))
    rayp.setWidth(3)
    rayp.setArrow("last")
    rayp.setFill("red") # 接上固定光线画X轴到无线远的固定光线

    rayc = Line(Point(objX,135),Point(0,0))
    rayc.setWidth(3)
    rayc.setArrow("last")
    rayc.setFill("red") # 画来自实物且穿过光心的带方向的光线

    if -150 < objX < 0: # 虚像(放大镜原理)
        raycc = Line(Point(objX,135),Point(px,py))# 过光心光线反向延长线
        raycc.setWidth(3)
        raycc.setArrow("none")
        raycc.setFill("yellow") # 成虚像的反向延长线用黄色
        raycc.draw(win)
        
        raycc = Line(Point(0,0),Point(-px,-py)) # 过光心后的折射光线
        raycc.setWidth(3)
        raycc.setArrow("last")
        raycc.setFill("red")
        raycc.draw(win)
        
        raycp = Line(Point(0,135),Point(px,py)) # 平行光折射的反向延长线
        raycp.setWidth(3)
        raycp.setArrow("none")
        raycp.setFill("yellow") # 成虚像的反向延长线用黄色
        raycp.draw(win)
        
    else: # 成实像时过光心后的折射光线
        raycc = Line(Point(0,0),Point(px,py))
        raycc.setWidth(3)
        raycc.setArrow("last")
        raycc.setFill("red")
        raycc.draw(win)
        
    if objX < -10:
        obj.draw(win)   
        phoVR.draw(win)
        rayh.draw(win)
        rayf.draw(win)
        rayp.draw(win)
        rayc.draw(win)

    noteText_loc = objX
        
################## 定义更新成像规律提示标签子程序
def display_noteText():   
    global noteText_loc    
    noteText.undraw() # 擦除原提示标签
    noteStr  = ''
    if  -140 < noteText_loc < 0:
        noteStr  = '放大镜原理,物体在一倍焦距内成放大的虚像'
      
    elif  noteText_loc == -149:
        noteStr  = '物体刚好在焦点不成像'
        
    elif -300 < noteText_loc < -150:
        noteStr  = '投影仪原理,物体在一倍两倍焦距间成放大实像'

    elif noteText_loc == -300:        
        noteStr  = '物体刚好在两倍焦距上成等大实像'

    elif noteText_loc < -300:
        noteStr  = '照相机原理,物体在两倍焦距外成缩小实像'

    noteText.setText(noteStr)
    noteText.setSize(randint(16,26))# 随机改变字体大小、颜色及位置
    noteText.setTextColor(color_rgb(randint(0,255),randint(0,255),randint(0,255)))
    noteText.move(0,randrange(-10,30,10))
    noteText.draw(win) # 重画新提示标签
    
################# 主程序
main()

Python代码模式运行

代码中库文件 graphics.py 见附件

此文件放在如下位置:
C:\Users\admin\Documents\mindplus-py\environment\Python3.6.5-64\Lib\

评论

user-avatar