《Think Python》练习 4-5:用函数画阿基米德螺旋

第4章 案例研究:接口设计

练习 4-5 用函数画阿基米德螺旋

在百度百科阅读关于螺旋线(spiral)的信息,接着编写一段程序来画出阿基米德螺旋(或者其他某种螺旋线)。
《Think Python》练习 4-5:用函数画阿基米德螺旋_第1张图片
【求解】
Step.1 确认组件
由于《Think Python》到本章为止并没有介绍笛卡尔坐标用法,所以本人不会使用笛卡尔坐标来绘制阿基米德螺旋,本解法基于已经出现过的 polyline 函数实现(绝不超纲)。

#多边线
def polyline(t, n, length, angle):
    for i in range(n):
        t.fd(length)
        t.lt(angle)

Step.2 抽象问题

这里提一下 导数 概念:
当函数 y = f ( x ) y=f(x) y=f(x) 的自变量 x x x 在一点 x 0 x_0 x0上产生一个增量 Δ x Δx Δx 时,函数输出值的增量 Δ y Δy Δy 与自变量增量 Δ x Δx Δx 的比值在 Δ x Δx Δx 趋于 0 0 0 时的极限 a a a 如果存在, a a a 即为在 x 0 x_0 x0 处的导数,记作 f ′ ( x 0 ) f'(x_0) f(x0) d f ( x ) d x ∣ x = x 0 \frac{df(x)}{dx}|_{x=x_0} dxdf(x)x=x0

函数 polyline(t, n, length, angle) 在模拟曲线时,实际上就是画的一小段一小段很短的切线,将精度调整到肉眼看不大出来的时候,画出来就是“曲线”了(实际上,如你所见《Think Python》练习 4-2:用函数画花朵 中的花朵也坑坑洼洼的)。

而我们现在要做的就是:确认一个微小变量(乌龟每次转过的微小角度),根据阿基米德螺旋公式,计算出在这个微小变量下的短小线段的 长度( l l l )

Step.3 问题求解
已知阿基米德螺公式: r = a + b θ r=a+bθ r=a+bθ
希望乌龟从画布的中间开始画,这样好看点,故去掉起点至画布中心的距离,将阿基米德螺线公式简化为: r = a θ r=aθ r=aθ
《Think Python》练习 4-5:用函数画阿基米德螺旋_第2张图片
由阿基米德曲线公式 r = a θ r=aθ r=aθ 可知,当角度增加 Δ θ Δθ Δθ,半径从 a θ aθ aθ 变为 a ( θ + Δ θ ) a(θ+Δθ) a(θ+Δθ),即:
r 1 = a θ r_1=aθ r1=aθ
r 2 = a ( θ + Δ θ ) r_2=a(θ+Δθ) r2=a(θ+Δθ)

已知:三角形两边 r 1 r_1 r1 r 2 r_2 r2 及夹角 Δ θ Δθ Δθ
求:三角形对边 l l l
解:
求高: h = s i n Δ θ ⋅ r ′ = s i n Δ θ ⋅ a ( θ + Δ θ ) h=sinΔθ·r'=sinΔθ·a(θ+Δθ) h=sinΔθr=sinΔθa(θ+Δθ)
求顶点到高的距离与 r 1 r_1 r1 的差: m = c o s Δ θ ⋅ r ′ − r = c o s Δ θ ⋅ a ( θ + Δ θ ) − a θ m =cosΔθ·r'-r=cosΔθ·a(θ+Δθ)-aθ m=cosΔθrr=cosΔθa(θ+Δθ)aθ
勾股定理求对边 l l l l = m 2 + h 2 l=\sqrt{m^2+h^2} l=m2+h2

Step.4 完成代码

"""
《Think Python》练习 4-5:用函数画阿基米德螺旋(蚊香线)

r = aθ
由于用乌龟画,从中间开始旋转比较好看,故没有考虑起点与坐标原点的距离
绘图精度(乌龟每次转过的微小角度):Δθ = π/30 = 6°
绘制的阿基米德螺旋线圈数 (不可能让乌龟无限的画下去):n

theta:阿基米德螺旋角度 θ,从0开始
m:短线条数,根据精度 Δθ 与圈数 n 计算
length:短线长度
angle:短线间的夹角,即精度 Δθ = π/30 = 6°
"""

#引入数学模块、乌龟模块
import math
import turtle

#调用乌龟画图、提高画弧速度
bob = turtle.Turtle()
bob.delya = 0.01

#阿基米德螺旋
def spiral(t, a, n):
    theta = 0
    m = int(n * 60)
    for i in range(m):
        length = math.sqrt( ( math.cos(math.pi/30) * a * ( theta + math.pi/30 ) - a * theta )**2 + ( math.sin(math.pi/30) * a * ( theta + math.pi/30 ) )**2 )
        angle = 6
        t.fd(length)
        t.lt(angle)
        theta = theta + math.pi / 30
        
spiral(bob, 10, 3.25)
turtle.mainloop()

附草稿:
《Think Python》练习 4-5:用函数画阿基米德螺旋_第3张图片

你可能感兴趣的:(《Think,Python》课后实现)