Python几何图形编程之五彩点图

1 任务描述

用Python作图,在原点处画一个大圆点,从原点出发角度均匀地分布着12串小点,每串上等距离分布着5个颜色不同的小点。整个图形呈顺时针方向旋转。

2 数学知识点

(1)角
角是由两条有公共端点的射线组成的几何图形。这两条射线叫做角的边,它们的公共端点叫做角的顶点,如图1所示。
锐角:大于0°,且小于90°的角叫做锐角。
直角:等于90°的角叫做直角。
钝角:大于90°且小于180°的角叫做钝角。
平角:等于180°的角叫做平角。
自动草稿

图1 角

(2)周角
角的一边绕着顶点旋转一周与另一边重合时所形成的角,叫做周角。周角等于360°。用弧度表示为2π弧度。
img

图2 周角

(3)线段
线段是指两点之间的连线。线段用表示两个端点的大写字母或一个小写字母表示,如记作线段AB或线段a。连接两点间线段的长度叫做这两点间的距离(distance)。线段如图3所示。
img

图3 线段

3 编程知识点

(1)函数setheading()和forward()
我们知道,线段是两个点之间的连线。知道两个点的坐标,自然可以画出这条线段来。从前面的介绍可以得知,如果画笔在起点位置,用函数goto()可以画出这条线段。
假若,现在我们只知道起点的位置、线段的长度,以及与横轴正向的夹角,能否画出这条线段来呢?从相关几何知识可知,这样的线段也是可以画出来的。
在Python的turtle库里,设置画笔朝向的函数是setheading(),括弧里的参数为画笔的角度。角度是以横轴正向为0°,逆时针旋转为正,顺时针旋转为负。前移画笔一定长度的函数是forward(),括弧里参数是画笔前移的像素值。
如图4所示,画AB线段,可以让在A点的画笔通过使用goto(20,20)移动到B点,也可以在A点设置画笔的朝向为45°,然后前移AB线段的长度。根据勾股定理,从点(0,0)到点(20,20)的AB线段长约为28像素。
img

图4 AB线段的画法

turtle画笔的初始位置在原点(0,0),线段的两种画法的程序代码如图25所示,左图是已知线段另外一点的坐标是(20,20)的画法;右图是已知线段与横轴的夹角是45°,长度为28像素的画法。两种方法画出来的线段是一样的。
img

图5 线段的两种画法的程序代码

(2)函数pensize()和pencolor()
在几何知识中,线段是有长度和方向的,且由两个端点的位置决定,没有宽度和颜色的概念。但在turtle画图中,线段还有宽度和颜色的属性。可以用函数pensize()指定画笔的宽度,单位是像素,用函数pencolor()指定画笔的颜色。画不同宽度和不同颜色的4条线段的程序代码如图6所示。程序运行结果如图7所示。
img

图6 画不同宽度和不同颜色的4条线段的程序代码

img

图7 程序运行结果:画四条线段

(3)函数hideturtle()和showturtle()
在前面用turtle画图的例子中,程序运行完成后,总有一个黑色箭头留在画面上,这是画笔最后的位置和朝向的指示。在设计不需要显示画笔的图形时,可以使用函数hideturtle()来隐藏。如果需要显示已经隐藏的画笔,可以使用函数showturtle()完成。
如图8所示的程序代码,开始隐藏画笔,也就是在画前两条线段时是看不到画笔形状的,画完两条线段后,显示画笔;在画最后两条线段的过程中,可以看到画笔的形状;在整个图画完后,再隐藏画笔。程序运行结果如图9所示。
img

图8 隐藏和显示画笔的程序代码

img

图9 程序运行结果:隐藏画笔

(4)颜色列表
列表是Python中一种特殊的数据序列。列表中的每个元素可以是Python的各种数据类型。元素放在方括号内,用逗号分隔。列表中的第一个索引(元素)是0,第二个索引是1,依此类推。
为了生成五颜六色的图形,我们选用6种颜色,组成颜色列表colors,如图10所示。
举例来说,如图11所示,从原点(0,0)出发,画36条各种颜色的线。线的宽度为5像素,线条之间的夹角为360°/36=10°,即第i条线与横轴正向的夹角为(10×i)°,画笔的方向设置为setheading(10×i)。
img
img

图10 颜色列表的程序代码

img

图11 画从原点出发的36条各种颜色线条的程序代码

线的颜色从下面颜色列表中取得。
假设颜色列表中有6种颜色,每画6条线,颜色重复一次。循环画36条线,我们用i%6(循环变量i对6取余)来做颜色索引。
每画完一条线,都要抬笔,用函数goto(0,0)使画笔回到原点,然后落笔,再用函数forward()画下一条线。
程序运行结果如图12所示。
img

图12 程序运行结果:各种颜色的线条

(5)嵌套循环
在一个循环语句中包含另一个循环语句,叫做嵌套循环。嵌套循环是编程语言中常见的逻辑结构。那么嵌套循环在画图的过程中有什么用呢?前面我们用一层for循环画了36条线。如果想在每条线的末端再画三个点,就需要使用嵌套循环来解决了。嵌套循环在画图中完成的是两个不同维度的循环要求。程序代码如图13所示。程序运行结果如图14所示。
img

图13 使用嵌套循环画图的程序代码

(6)条件判断
如果在特定的位置上,在不同的条件下需要用画笔画不同的图形,这需要进行条件判断,不同的条件下运行不同的画图程序代码。在计算机编程语言中,条件判断是一种常用的逻辑结构,是依据给定的逻辑运算结果(True或False),执行相应代码的程序结构。
img
img
img

图14 程序运行结果:线加点图形

两个分支的条件判断结构如下:
三个以上分支的条件判断结构,需要在两个分支的条件判断结构中,使用elif来增加新的条件分支,结构如下:
如图15所示,这段代码显示了条件判断语句的作用。首先,从Python的Shell上获取用户的选择。如果用户选择1,即if(choice==1),画一个100像素的红点;如果用户选择其他,即else,画一个100像素的蓝点。
img
img

图15 条件判断示例程序代码

4 任务分析

原点处有一个较大的棕色的点,从原点出发,角度均匀地分布着12条串着点的线。360°除以12就是线与线从原点出发的夹角,为30°。每条线上有5个不同颜色的点,需要使用颜色列表实现。有线的循环,又有点的循环,所以需要使用嵌套循环语句。每条线上的点大小相同,间距相同。但每条线上的点不在一条直线上,而是在一个逆时针旋转的曲线上,也就是说,画完一个点后,画笔的朝向有所变化。
程序设计思路为:
img

5 程序设计

我们在Python的文件编辑器里,新建一个colorfuldots.py文件。五彩点图的程序代码如图16所示,在这个程序中,使用了colors颜色列表。在外层循环中,直接使用range(0,360,30)来生成12条线的初始朝向值,储存在循环变量i中,完成抬笔penup()、回到原点goto(0,0)、设置初始线条角度setheading(),变量a记录着画笔的朝向,变量m记录着颜色索引。进入内层循环后,使用函数forward()移动画笔,使用函数dot()画点,函数pendown()完成落笔以便下次内层循环时,留下画笔运行痕迹,每画完一个点,都要生成下次画笔的朝向a和下一个点的颜色索引m。最后使用hideturtle()函数来隐藏画笔。
img

图16 五彩点图的程序代码

6 运行结果

运行colorfuldots.py程序,输出结果如图17所示。
img

图17 程序运行结果:五彩点图

7 发散思考

(a)在程序中,如果画完每个点后改变画笔的朝向设置,会如何影响图形的效果?
把图16中的“a =10”改为“a =0”,程序运行结果如图18所示;改为“a-=20”,程序运行结果如图19所示。\
img

图18 程序运行结果:每串圆点朝向不变的五彩点图

img

图19 程序运行结果:顺时针旋转的五彩点图

(b)在程序中,如果画完每个点后减小画笔前移的距离,会如何影响图形的效果?
把图16中的forward(50)改为forward(25),程序运行结果如图20所示。

图20 程序运行结果:减小画笔前移距离的五彩点图

8 挑战自我

编写一个Python程序,实现如图21所示的点阵图。

图21 点阵图

参考程序

参考答案文件:squaredots.py,点阵图的程序代码如图22所示。

图22 点阵图的程序代码

 

本章小结

·数学知识:角、周角、线段。
·编程知识:函数setheading()和forward();
函数pensize()和pencolor();
函数hideturtle()和showturtle();
颜色列表的使用;
嵌套循环在画图中的应用;
在循环中调整画笔的大小、位置、颜色等属性。

发表评论