由正方形向内深触内心,向外直达宇宙。
    1、语句结构与变量的出现契机
    使用turtle库里面的命令已经能够绘制一些简单的图案了,比如已经画过的正方形:

    1. import turtle
    2. turtle.fd(100)
    3. turtle.left(90)
    4. turtle.fd(100)
    5. turtle.left(90)
    6. turtle.fd(100)
    7. turtle.left(90)
    8. turtle.fd(100)
    9. turtle.left(90)
    10. turtle.done()

    那么如果想要再画一个正三边形呢,也就是正三角形,是不是一样的逻辑,并且程序更简单了,要比正四边形少两句。如果正三边形程序还能自己写,一行一行敲出来的话,那么正六边形呢?正100边形呢?难道还要一直复制粘贴吗?
    所以有没有一种方式能够让程序更加简捷一点呢,我们以正四边形的程序为例,这个程序里面有好多重复的地方,那么就可以约定一种方式来解决这个问题,这也是程序的意义。而这个方法就是for语句:(所有知识点都是这样出现的,都是为了解决当时的问题)

    1. import turtle
    2. for i in range(4):
    3. turtle.fd(100)
    4. turtle.left(90)
    5. turtle.done()

    有了for语句,就可以很快的绘制出正多边形了,比如正100边形:

    1. import turtle
    2. for i in range(100):
    3. turtle.fd(10)
    4. turtle.left(3.6)
    5. turtle.done()

    当然for语句不止是用来绘制正多边形的,在以后的很多地方都会发挥作用。它的写法就是:
    for i in range():
    其中for .. in ...:是for语句约定的结构,以英文的冒号结尾,i是会变化的,也就是变化的量,叫做变量,range()是变化范围,range(100)就是在100以内变化,range(100,200)就是在100到200之间变化。
    现在我们在对比画正四边形跟正100边形这两个程序,发现有些数字也变了。
    image.png
    这三个地方在数学中,一个是边数,一个是边长,最后一个是旋转角度。边长这里先不用管,可以任意长度,只不过太大的话可能会超过屏幕区域,为了更好的看到画出来的图形,我们用周长来限制它不要太大。所以如果要画的正多边形周长都是100,程序应该怎么改动呢?
    现在再来看边长和旋转角度的关系,在数学里面,正多边形的特性是什么?就是所有外角和永远都是360°。因此修改程序如下:

    1. import turtle
    2. for i in range(100):
    3. turtle.fd(100/100) #周长100作为限定
    4. turtle.left(360/100)
    5. turtle.done()

    那么现在想要再画另外一个正82边形,只需要改动边数就行:

    1. import turtle
    2. for i in range(82):
    3. turtle.fd(100/82) #周长100作为限定
    4. turtle.left(360/82)
    5. turtle.done()

    但发现还是得改动三处,那么有没有方法把这个也给优化一下呢?那就用一个字母代替吧,然后把这个字母给它一个设定好的值,后来把这种方法称为定义变量:

    1. import turtle
    2. a=82
    3. for i in range(a):
    4. turtle.fd(100/a) #周长100作为限定
    5. turtle.left(360/a)
    6. turtle.done()

    这样一来,只需要改变a的值,就可以随意的绘制正多边形了。
    2、函数的封装过程
    还记得turtle画圆的命令吗?turtle.circle(20)
    刚自己画的正100边形,正200边形有什么关系呢?对了,就是边数越多越逼近圆的形状。这里留一个练习,以此来求出数学中pi的值。
    当我们需要画一个圆的时候,可以选择去写一段正多边形的程序搞定,当然也可以一句命令turtle.circle()。我选后者。那么这两个有什么关系呢?或者有没有一种方式把一段程序封装成一句命令?
    其实turtle.circle()这句命令背后就是一段程序,只不过在turtle库里面放着,我们使用import进行了库的调用。现在假设我们是第一代程序员,这个编程语言是自己搞的,应该怎么做才能使以后编写程序的时候更加简便快捷呢?那就封装一个对象函数吧。首先起一个名字,就叫做正多边形(zhengduobianxing):

    1. import turtle
    2. def zhengduobianxing():
    3. a=82
    4. for i in range(a):
    5. turtle.fd(100/a) #周长100作为限定
    6. turtle.left(360/a)
    7. zhengduobianxing()
    8. turtle.done()

    下一步,把变量也放进去,每次要绘制任意正多边形只需要一句命令:

    1. import turtle
    2. def zhengduobianxing(a):
    3. for i in range(a):
    4. turtle.fd(100/a) #周长100作为限定
    5. turtle.left(360/a)
    6. zhengduobianxing(82)#正82边形
    7. zhengduobianxing(100)#正100边形
    8. zhengduobianxing(200)#正200边形
    9. turtle.done()

    那么圆形呢?用半径来表示:圆的周长公式是
    C=23.14r
    C=边长l边数a
    所以,半径与边数的关系就是a=C/l=(2
    3.14*r)/ l

    1. import turtle
    2. def circle(r):
    3. c = 2*3.14*r#周长公式
    4. a = c/10
    5. for i in range(a):
    6. turtle.fd(10) #边长为10
    7. turtle.left(360/a)
    8. circle(20)#半径为20的圆
    9. turtle.done()

    这里3.14可以替换为pi:

    1. import turtle
    2. import math #首先引入数学库
    3. def circle(r):
    4. c = 2*math.pi*r#周长公式
    5. a = c/10
    6. for i in range(a):
    7. turtle.fd(10) #边长为10
    8. turtle.left(360/a)
    9. circle(20)#半径为20的圆
    10. turtle.done()

    上面画圆的方式是以多边形变换过来的,也就是一张空白的纸上用笔随意画的一个正多边形而已,如果我们把这个圆放在坐标系中,用我们学过的圆的方程来确定其形状的话,该如何操作?首先我们在坐标系中要确定圆上点的坐标,然后这些点组成对应的圆。那么这些圆上的点的关系就是圆的方程,都跟圆的半径有关。
    也就是python教程--05代码的生长过程 - 图2,或者是python教程--05代码的生长过程 - 图3。这里我们选用后者,因为圆的产生就是一个点(A点)围绕另一个点(B点)转动留下的痕迹。也就是转动角度的变化影响到其坐标的变化。所以以该种方式画圆:

    1. from turtle import *
    2. import math
    3. def Acircle(r):
    4. for i in range(360):
    5. a = i/180*math.pi #python中三角函数是弧度制,得进行一下转换
    6. x = r*math.sin(a)
    7. y = r*math.cos(a)
    8. goto(x,y)

    想要改变圆心位置:python教程--05代码的生长过程 - 图4,在极坐标中就是python教程--05代码的生长过程 - 图5,程序如下:

    1. from turtle import *
    2. import math
    3. def Acircle(x0,y0,r):
    4. for i in range(360):
    5. a = i/180*math.pi
    6. x = r*math.sin(a)+x0
    7. y = r*math.cos(a)+y0
    8. goto(x,y)

    既然已经得到一个知道圆心和半径的圆,那么我们就可以控制这个圆做一些有趣的东西,比如逐渐变大变小的类似跳动的心,和运动的小球。
    我们首先来实现跳动的心,就是逐渐变大变小:

    1. from turtle import *
    2. import math
    3. def Acircle(x0,y0,r):
    4. for i in range(360):
    5. a = i/180*math.pi
    6. x = r*math.sin(a)+x0
    7. y = r*math.cos(a)+y0
    8. goto(x,y)
    9. for r in range(100):
    10. Acircle(0,0,r)

    上面程序运行之后,会发现有好多问题,其中一个就是会有绘制圆的过程太明显了,另一个就是每次画完一个圆之后并不会自动消失,而会出现一堆圆环。关于第一个问题,我们使用tracer()方法来解决,第二个问题使用clear()方法,也就是每次画完之后清屏。

    1. from turtle import *
    2. import math
    3. def Acircle(x0,y0,r):
    4. tracer(0)
    5. clear()
    6. for i in range(360):
    7. a = i/180*math.pi
    8. x = r*math.sin(a)+x0
    9. y = r*math.cos(a)+y0
    10. goto(x,y)
    11. tracer(1)
    12. while True:#一直循环
    13. for r in range(100):#逐渐变大
    14. Acircle(0,0,r)
    15. for r in range(100,0,-1):#逐渐变小
    16. Acircle(0,0,r)

    上面添加了逐渐变大和逐渐变小的程序,并且能够循环执行,但是显然还是有重复的命令,两个for语句太碍眼,能不能只留一个:

    1. from turtle import *
    2. import math
    3. def Acircle(x0,y0,r):
    4. tracer(0)
    5. clear()
    6. for i in range(360):
    7. a = i/180*math.pi
    8. x = r*math.sin(a)+x0
    9. y = r*math.cos(a)+y0
    10. goto(x,y)
    11. tracer(1)
    12. r = 0
    13. b = 1
    14. while True:#一直循环
    15. for i in range(100):
    16. Acircle(0,0,r)
    17. r = r + b
    18. b = -b

    至此一个简单跳动圆就完成了,可以基于该程序,改一下外形做一个跳动的心。
    那么往复运动的圆也是一样的:也基于该程序结合物理公式做一个自由落体的小球,弹起的小球呢,再把空气阻力考虑进去呢,做一个钟摆呢?做一个时钟呢?做一个月亮围绕地球转呢,地球围绕太阳转呢?那就再做一个太阳系吧。

    1. from turtle import *
    2. import math
    3. def Acircle(x0,y0,r):
    4. tracer(0)
    5. clear()
    6. for i in range(360):
    7. a = i/180*math.pi
    8. x = r*math.sin(a)+x0
    9. y = r*math.cos(a)+y0
    10. goto(x,y)
    11. tracer(1)
    12. s = 10
    13. b = 0
    14. while True:
    15. for i in range(10):
    16. Acircle(b,0,20)
    17. b = b + s
    18. sleep(0.05)
    19. s=-s