python画螺线_《Think Python》练习4-5:用turtle画螺线

要求:阅读螺线(spiral)的相关知识; 然后编写一个绘制阿基米德螺线(或者其他种类的螺线)的程序。

阿基米德螺线

import turtle

from math import sin, cos, pi

bob = turtle.Turtle() # create a Turtle object

bob.delay = 0.01 # 设置延迟值

def spiral(t, a, n, w=6):

''' 画阿基米德螺线

t: Turtle

a: 每转w度增加的内径长度

n: 圈数

w: 精度.默认为6(每次转过的角度)(角度值)

'''

theta = 0 # 转过角度初始化

m = int(360 / w) * n # 精度w下转n圈所需循环次数

#t.lt(w / 2) # 练习4-1第2问

for i in range(m):

dtheta = pi * w/ 180 # 精度变为弧度制

# 勾股定理得到要移动的小距离

length = pow((a*sin(dtheta)*(theta + dtheta))**2 +

(a*cos(dtheta)*(theta + dtheta) - a * theta)**2, 0.5)

#t.lt(w)

t.fd(length)

t.lt(w)

theta += dtheta # 为弧度制

#t.rt(w / 2) #练习4-1第2问

#t.lt(90)

#t.fd(200)

spiral(bob, 5, 3, 6)

turtle.mainloop()

这题参考了 九月初夏 的文章 https://blog.csdn.net/nineth9t/article/details/90322356 还有 4-1的练习 https://blog.csdn.net/nineth9t/article/details/90676590 写的很明了。

然后这里主要记录自己在搞这个螺线时的一些疑惑。

因为看了4-1练习的关于停止点偏离思考那篇文章,然后发现里面polyline函数跟螺线的实现函数很像。因为一开始很不明白这个走一小段然后转一小个角度这是怎么实现画阿基米德螺线的。但是看了文章后就明白了。

因为在那之前,我的函数是这样的:

import turtle

def draw_spiral(t, n, w, a=0.05):

'''画阿基米德螺线

t: Turtle

n: 循环次数(越大圈数越多)

w: 每条弧对应的角度

a: 每转1度增加的内径长 (默认值为0.05)

'''

r = 0

b = 0.1

c = 0 # 转过的角度

for i in range(n):

r = a * c + b

t.circle(r, 1)

c += w

bob = turtle.Turtle()

bob.delay = 0.001

draw_spiral(bob, 1000, 6, 0.05)

思路主要是看了阿基米德螺线的数学关系后得出的:

阿基米德螺线 r=aθ + b

然后在一个小角度内处理成为半径不变的弧,然后画出来。

结果就是画的速度乌龟一样慢,并且怎么调参数也不会得到作者大大写的函数的画的蚊香…只能是松松的蚊香 = =

顺便提醒一句要记得 turtle.mainloop() 不然在不是IDLE环境下运行会画完光速关系窗口了…

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1l1bm9TYXdhbm8=,size_16,color_FFFFFF,t_70

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1l1bm9TYXdhbm8=,size_16,color_FFFFFF,t_70

然后看了一遍作者的函数代码。发现没有用circle这种画弧的方法ORZ

然后拜读了 九月初夏 的文章(上面贴的)后才理解了。

ORZ数学不是很好,然后还是没有明白作者在这里的思路。

欢迎来交流~要是弄出来了,再回来更新。

附作者的代码:

from __future__ import print_function, division

import turtle

def draw_spiral(t, n, length=3, a=0.1, b=0.0002):

"""Draws an Archimedian spiral starting at the origin.

Args:

n: how many line segments to draw

length: how long each segment is

a: how loose the initial spiral starts out (larger is looser)

b: how loosly coiled the spiral is (larger is looser)

http://en.wikipedia.org/wiki/Spiral

"""

theta = 0.0

for i in range(n):

t.fd(length)

dtheta = 1 / (a + b * theta)

t.lt(dtheta)

theta += dtheta

# create the world and bob

bob = turtle.Turtle()

draw_spiral(bob, 300, 3, 0.1, 0.0002)

turtle.mainloop()

上了stackoverflow看了一下,虽然没有还是没有理解上面的。

用平面直角坐标系法画:

import turtle

from math import cos, sin, pi

def spiral(t, rotations=3, a=0.0, b=5):

theta = 0.0

while theta < rotations * 2 * pi:

radius = a + b * theta

x, y = radius * cos(theta), radius * sin(theta)

turtle.goto(x, y)

theta += 0.1

bob = turtle.Turtle()

spiral(bob)

turtle.mainloop()

然后有因为混着莫名其妙看了4-1的文章,然后就有了以下的莫名其妙关于停止点的偏离的思考。因为一开始我也感觉不出来 arc 函数修改前和修改后会有多大影响…然后看了文章后又对自己的螺线试了一番。

这是没有用 rt (angle / 2) 和 lt(angle / 2) 的,把之前的代码这两行解除注释来画条直线来看到停止点与起始点的距离

#t.lt(90)

#t.fd(200)

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1l1bm9TYXdhbm8=,size_16,color_FFFFFF,t_70

然后用了rt (angle / 2) 和 lt(angle / 2):

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1l1bm9TYXdhbm8=,size_16,color_FFFFFF,t_70对上去了~大概跟画字母J的弧对上去是差不多的意思。

然后还有一个疑惑,就是为什么是先前进再转Δθ呢。

然后就画了先转Δθ然后再走的…(注释了转一半角的误差调整下)

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1l1bm9TYXdhbm8=,size_16,color_FFFFFF,t_70

emmmmmm跟第一张先走一段距离再转一个角度比起来竟然有这么多的差别,虽然只是终点偏离的有点远。螺线结构虽然人眼好像看不出有什么差别就是了ORZ

具体在误差上有什么差别还没有去深入探讨过。有的话再回来更新。

斐波那契螺线

def FibonacciSpiral(t, n):

'''画斐波那契螺线

t: Turtle

n: 循环次数

'''

r = a = b = 1

# draw the first half circle

arc(bob, r, 180)

# Draw the 1/4 circle

for i in range(n):

r = a + b # 斐波那契数列

b = a

a = r

arc(bob, r, 90)

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1l1bm9TYXdhbm8=,size_16,color_FFFFFF,t_70

阅读了斐波那契螺线后画的。

欢迎围观和有什么错误可以跟我一起交流~

原文链接:https://blog.csdn.net/YunoSawano/article/details/105238691

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值