1 任务描述
请用Python编写程序画出如图1所示的花篮图形。
图1 花篮图形
2 数学知识点
(1)正多边形
正多边形为二维平面内各边相等,各角也相等的多边形。
正n边形的内角和为:(n-2)×180°;正n边形的一个内角是(n-2)×180°÷n。
正n边形外角和等于360°,正n边形的一个外角为360°÷n。
正多边形各边所对的外接圆的圆心角都相等,这个圆心角叫做正多边形的中心角。正多边形中心角为360°÷n。
以如图2所示的正六边形为例,它的内角和为720°,其中一个内角为120°;它的外角和为360°,那么它的一个外角和一个中心角均为60°。
图2 正六边形
(2)叠边形
我们知道,等边三角形的一个外角是120°,正方形的一个外角是90°。多边形的外角和是360°。
如果存在一种多边形,边长相同;但边数不是整数,比如说,在3和4之间,有3.5条边,它的外角和也同样是360°,那么一个外角是360°/3.5≈102.85°。两个这样的图形是7条边,外角和是720°,相当于两圈画了7个边。这是个什么样的图形呢?我们画一下外角为102.85°,边长相同的多边形,形成如图3所示的图形。这样的图形,可以称之为叠边形。
如果360°正好被边的数目整除,那么画笔旋转一周图形就闭合了。但叠边形的特点是,画笔以一定的边长画正多边形,外角旋转360°时不能形成闭合图形,需要旋转720°或者更多圈才能完成图形闭合。
图3 外角为102.85°的叠边形
同样,我们可以作出外角为360°/4.5≈80°的叠边形,两圈画9个边,如图4所示。再作出外角为360°/6.5≈55.4°的叠边形,两圈画13个边,如图5所示。
图4 外角为80°的叠边形
图5 外角为55.4°的叠边形
如果画10条边3圈画完,那么平均每360°画3.3条边,外角为360°/3.3≈108°的叠边形如图6所示。
图6 外角为108°的叠边形
(3)三角形的正弦定理
在任意一个平面三角形中,各边和它对角的正弦值的比相等。即:
a/sinA =b/sinB =c/sinC
三角形的边角关系如图7所示,根据三角形的正弦定理可得:
b=a(sinB/sinA)
c=a(sinC/sinA)
图7 三角形的边角关系
(4)弧度值和角度值
一个角有角度值和弧度值。90°的角相当于π/2,180°的角相当于π。在几何图形的边角计算过程中,经常需要弧度值和角度值之间相互转换。
二者的转换关系为:
弧度值=π×角度值/180°
3 编程知识点
(1)画布大小和位置的设置
在turtle库中setup()函数可以设置画布的宽、高,以及画布在电脑屏幕中的位置。比如:
其中,width是画布的宽,height是画布的高,在这里,输入的宽和高为整数,表示画布是800像素宽,600像素高;(startx,starty)表示画布窗口左上角顶点的位置,这里表示画布左上角顶点的坐标为(100,100)。
再比如:
在这里,width和height是小数,表示占据电脑屏幕的比例,即turtle画布的宽是屏幕宽度的60%,高是屏幕高度的60%;(startx,starty)为空时,即没有设置,则表示画布窗口位于屏幕中心。
(2)正多边形的画法
正多边形具有相同的边长和外角,在画正多边形的时候,只需要在循环体里完成画笔前移一个相同的长度,然后逆时针旋转或顺时针旋转一个相同的角度即可。
类似前面画正方形的方法,图8所示的程序是画10个正多边形,边长都是50个像素,填充颜色依次从颜色列表colors中选取。为了避免大的正多边形覆盖小的正多边形,先画正12边形,再画正11边形……依此类推直到画完等边三角形。正多边形的外角是360°/n,每次循环中画笔逆时针旋转360°/n即可。运行整个程序的结果如图9所示。
图8 画10个正多边形的程序代码
图9 程序运行结果:画多个正多边形
(3)旋转多边形的画法
在画多边形的时候,如果每次画笔旋转的角度是某一正多边形的外角,但边长逐渐有规律的增加,会是什么样的图形呢?
正9边形,其外角是40°,初始角度为0°,初始边长为1像素。在每次循环中让画笔逆时针旋转40°,边长增加1像素,旋转多边形的程序代码如图10所示,运行结果如图11所示。
图10 旋转多边形的程序代码
图11 程序运行结果:画旋转多边形
如果在图10所示的程序中,把画笔左旋的角度改为39°或者41°会是什么样子呢?
画笔左旋的角度改为39°的运行结果如图12所示。画笔左旋的角度改为41°的运行结果如图13所示。从这两个图形可以看出,多边形有了螺旋状的效果。
图12 程序运行结果:画旋转多边形(左旋角度改为39°)
图13 程序运行结果:画旋转多边形(左旋角度为41°)
(4)叠边形程序设计
画叠边形的程序设计并不难,和画正多边形的方法类似。难点是旋转角度的控制。
比如11边形,如果画笔旋转一圈图形闭合,就是正11边形,外角是360°/11;如果画笔旋转两圈或两圈以上图形闭合,就是叠边形。旋转两圈图形闭合,外角是360°×2/11,旋转三圈图形闭合,外角是360°×3/11,旋转4圈图形闭合,外角是360°×4/11。11边闭合叠边形的程序设计如图14所示。
当旋转圈数i等于2,3,4,5时,多边形外角的计算结果小于180°,程序运行结果如图15所示。
图14 11边闭合叠边形的程序代码
图15 程序运行结果:11边闭合叠边形
(5)math库的radians()和degrees()
在math库中,提供了弧度值和角度值之间的转换函数。函数radians()把角度值转换为弧度值;函数degrees()把弧度值转换为角度值,如图16所示。
图16 弧度值和角度值之间的转换
(6)math库的sin(x)和cos(x)
math库提供了求一个数的三角函数值的方法。函数sin(x)用于求取一个以弧度为单位的数的正弦值;函数cos(x)用于求取一个以弧度为单位的数的余弦值。求正弦值和余弦值的代码如图17所示。
图17 求正弦值和余弦值的代码
4 任务分析
图18所示的花篮由多个叠边形组成,从内层到外层叠边形的外接圆半径由小变大。叠边形由20个边组成,是通过画笔旋转3圈完成的。
由此可以得出,叠边形的外角为360°×3/20约等于54°,每条边对应的中心角为54°,即∠DOE=54°,那么∠OED=∠ODE=(180°-54°)/2=63°。
每个叠边形一共20个顶点,顶点和圆心的连线为外接圆的半径,相邻顶点和圆心连线的夹角为18°,即∠DOC=18°。于是∠ODC=∠OCD=81°。
这个叠边形花篮由多个不同外接圆半径的叠边形组成,内层的叠边形外接圆半径和外层叠边形外接圆半径之间存在函数关系。根据三角形正弦定理,在△ODB中,OD/sin∠OBD=OB/sin∠ODB;在△ODE中,DE/sin∠DOE=OD/sin∠OED。
即,如果叠边形的外接圆半径为r,那么,叠边形的边长是l=r×sin54°/sin63°;
更大一层的叠边形的外接圆半径为r′=r×sin(180°-18°-63°)/sin63°。
图18 叠边形花篮边角关系分析
该程序应该由两层循环组成,外层循环控制各个不同半径的叠边形数目,内层循环控制每一个叠边形各个边的绘制。
程序的逻辑结构如下:
5 程序设计
新建一个Python程序文件tpolygoncolorful.py,叠边形花篮的程序代码如图19所示。
程序中除了导入turtle,还需要导入math库,以便可以使用radians()函数和sin()函数。
设置画布宽和高分别为电脑屏幕的50%,如setup(width=0.5,height=0.5)。画布的背景颜色bgcolor设为black。使用颜色列表colors,设置画笔粗细和画笔移动速度。
多个叠边形从内层到外层、从小往大逐层绘制。叠边形的初始半径为1像素,边长由l=r×sin54°/sin63°得到,下一层更大的叠边形半径由r=r×sin99°/sin63°得到。按照这个规律不断迭代,可得到一系列逐渐增大的叠边形半径。每一个叠边形的画笔起笔位置在(0,-r)处,画笔朝向为90°-63°。
图19 叠边形花篮的程序代码
6 运行结果
运行程序tpolygoncolorful.py,结果如图20所示。
图20 程序运行结果:叠边形花篮
7 发散思考
(a)如果将画布的大小重新设置,对图形的效果有何影响?
将图19所示程序中的setup()函数改为setup(width=0.2,height=0.2,startx=300,starty=200),程序运行的结果如图21所示。
图21 程序运行结果:画布大小调整后图形的显示效果
(b)如果将颜色列表取消,使用单一颜色,图形效果如何?
在图19所示程序中把colors列表设置和pencolor()设置注释掉,在循环开始前设置pencolor(”gold”),程序运行结果如图22所示。
图22 程序运行结果:金黄色的叠边形花篮
8 挑战自我
请用Python作图,以9个边旋转两周可闭合的叠边形图形为基础,以该叠边形的外接圆变成下一个叠边形的内切圆为规律,扩展画图。共画20个从外接圆半径为1像素逐渐增大的叠边形。
参考程序
参考答案文件:tpolygontest.py,9个边旋转两周的叠边形组合图形的程序代码如图23所示。
图23 9个边旋转两周的叠边形组合图形程序代码
程序运行结果如图24所示。
图24 程序运行结果:9个边旋转两周的叠边形组合图形
本章小结
·数学知识:正多边形和叠边形;
三角形的正弦定理;
弧度值和角度值的关系。
·编程知识:画布大小和位置的设置;
正多边形的画法;
螺旋多边形的画法;
叠边形程序设计思路;
math库的函数radians()和degrees();
math库的函数sin(x)和cos(x)。