乌龟编程精讲版-61

程序·创造

软件·就是世界

万花尺,也叫繁花曲线规,是一种绘图玩具。相信许多人小时候都玩过!它由外图板及内圆图板两部分组成。内圆图板像一个齿轮,沿圆心不同半径的位置带有许多笔洞,外图板为一类似为内齿轮的大型圆孔,内圆板放在外图板的圆洞中,循着圆周转动,以铅笔或圆珠笔从笔洞可以画出像花朵一样规则图案。

万花尺画图中

万花尺配和不同半径的内圆图板,可以画出各种各样美妙的图案。回想起我们本系列教程前面给大家介绍的各色spiral螺旋线的画法,其实和这个万花尺的效果差不多。所以,我们今天就用turtle模块来模拟万花尺的效果,让turtle小乌龟代替万花尺画出各种各样的神奇图案。

数学方程

万花尺画出的复杂而奇妙的对称曲线,其实是可以用“数学方程”来表示的。有一种叫做“参数方程”——什么是“参数方程”呢?定义并不重要,举例来说,比如考虑用半径r来描述一个圆的方程,圆心位于二维平面坐标的原点(0,0)x、 y坐标满足该方程的所有点构成了圆。于是这个半径为r的圆形我们就可以用下面这样一个“参数方程”来表示:

圆心在原点的圆参数方程

圆的参数方程就是上面了——其中角θ参数。这方程中( X, Y)的任何值都满足圆的方程X2 + Y2= R2(这个称为圆的“直角坐标方程”)。如果让θ从 0 变到 2π(是弧度,等于角度0到360度),就可以用这个方程来计算圆上对应的xy坐标。

圆心在原点的圆参数方程

大家要了解的是:上面这两个方程适用于圆心在坐标系原点的圆。将圆心转换到任意点比如(a, b),就需要修改一下上面的方程了。最终更一般的圆参数方程就变成x = a + r cos(θ)y = b + r cos(θ)。现在,让我们先让小乌龟来画出这个圆。

小乌龟来画圆

画圆,你会说:太简单了!一个命令circle就可以了!但今天我们偏不要这么画,因为我们要给大家展示的就是“参数方程”——我们要用上面更一般的圆的参数方程来指挥“乌龟”画画。我们要实现的是:在坐标系任意一个位置(x,y)处画一个半径为r的圆形。代码见下面。

任意位置画圆的代码

上面我们建立了一个叫做drawCircleTurtle(x,y,r)的函数——第6行是先让小乌龟走到起点位置(想想起点位置为什么是x+r,y呢?),然后写一个for循环(0到365度,每5度一个阶梯往上涨),第9行将圆形的“角度”i转换成“弧度”a(因为一般计算机只认识弧度),第10行的代码的设置位置函数setposition里的两个公式是不是很熟呢?对了,就是上面说的圆的参数方程:x = a + r cos(θ)y = b + r cos(θ)

运行的结果怎么样呢?你可以试一下。很简单的一个圆形是不是就出来了呢!但仔细想一想:利用前面的参数方程计算圆的每个点坐标(每5度取一个点),依次设置相应的海龟位置(用setposition函数),这样就从海龟上一个位置画线到新计算的位置,但从技术上讲,我们产生的是 N 边多边形,但因为用了很小的角度(每5度取一个点), N 将非常大,多边形看起来像一个圆,是这样吧?

万花尺的参数方程

方程确实是个很伟大的东西,上帝创造人类的时候可能用的就是方程呵,因为方程几乎可以描述任何东西——我们称为“建模”,我们将万花尺用“参数方程”表示出来,然后不就可以用turtle让它画各种美妙的图形了吗?下面的图形展示了类似万花尺运动的数学模型

万花尺的简化模型

在图中,C是较小的圆的圆心,P是笔尖。较大的圆半径为R,较小的圆半径为r。半径之比表示如下:

将线段PC与小圆半径r之比作为变量ll = PC / r),它决定了笔尖离小圆圆心有多远。然后,组合这些变量来表示P的运动,得到如下的参数方程

万花尺的参数方程

上面的参数方程希望不要吓到你!看起来很难的样子其实它应该说比较容易。如果你对数学很感兴趣那你可以搜索"维基百科"看下它的推导过程。不是很难哦(网址是https://en.wikipedia.org/wiki/Spirograph,)这里我们不再推导了。

看到上面的万花尺参数方程,我们需要知道的是:它的参数就是3个:R,r,和l。当我们定了上面的三个参数就会产生一条曲线;如果我们改变上面的3个参数,就又产生了各种变化无穷的迷人曲线!

真正玩过万花尺就知道,万花尺可能需要许多转数来完成一个完整的图案。那什么时候停止绘图呢?就要利用万花尺的周期性(即万花尺图案多久开始重复),研究内外圆的半径之比:

分子分母除以它们的最大公约数( GCD),化简该分数,分子就告诉我们需要多少圈才能完成曲线了。而化简后的分母告诉我们小圆围绕其中心旋转的圈数,它提示了曲线的形状。

你的万花尺来了

好了,你根本不用买万花尺了。根据上面万花尺的参数方程,我们用turtle模块就能简单的写出下面的代码了:

万花尺代码

随意改变spiroDrawing(R,r,l)函数中的三个参数吧,你就能画出各种奇妙的图形来了,比如下面这些。自己改变三个参数,画出更多美丽的图案,have fun!

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20181024G08JAK00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券