本节书摘来自异步社区《Python极客项目编程 》一书中的第2章,第2.4节,作者 [美] Mahesh Venkitachalam,王海鹏 译,更多章节内容可以访问云栖社区“异步社区”公众号查看。

2.4 完整代码

下面是完整的万花尺程序。也可以从https://github.com/electronut/pp/blob/master/ spirograph/spiro.py 下载该项目的代码。

import sys, random, argparse
import numpy as np
import math
import turtle
import random
from PIL import Image
from datetime import datetime
from fractions import gcd# a class that draws a Spirograph
class Spiro:# constructordef __init__(self, xc, yc, col, R, r, l):# create the turtle objectself.t = turtle.Turtle()# set the cursor shapeself.t.shape('turtle')# set the step in degreesself.step = 5# set the drawing complete flagself.drawingComplete = False# set the parametersself.setparams(xc, yc, col, R, r, l)# initialize the drawingself.restart()# set the parametersdef setparams(self, xc, yc, col, R, r, l):# the Spirograph parametersself.xc = xcself.yc = ycself.R = int(R)self.r = int(r)self.l = lself.col = col# reduce r/R to its smallest form by dividing with the GCDgcdVal = gcd(self.r, self.R)self.nRot = self.r//gcdVal# get ratio of radiiself.k = r/float(R)# set the colorself.t.color(*col)# store the current angleself.a = 0# restart the drawingdef restart(self):# set the flagself.drawingComplete = False# show the turtleself.t.showturtle()# go to the first pointself.t.up()R, k, l = self.R, self.k, self.la = 0.0x = R*((1-k)*math.cos(a) + l*k*math.cos((1-k)*a/k))y = R*((1-k)*math.sin(a) - l*k*math.sin((1-k)*a/k))self.t.setpos(self.xc + x, self.yc + y)self.t.down()# draw the whole thingdef draw(self):# draw the rest of the pointsR, k, l = self.R, self.k, self.lfor i in range(0, 360*self.nRot + 1, self.step):a = math.radians(i)x = R*((1-k)*math.cos(a) + l*k*math.cos((1-k)*a/k))y = R*((1-k)*math.sin(a) - l*k*math.sin((1-k)*a/k))self.t.setpos(self.xc + x, self.yc + y)# drawing is now done so hide the turtle cursorself.t.hideturtle()# update by one stepdef update(self):# skip the rest of the steps if doneif self.drawingComplete:return# increment the angleself.a += self.step# draw a stepR, k, l = self.R, self.k, self.l# set the anglea = math.radians(self.a)x = self.R*((1-k)*math.cos(a) + l*k*math.cos((1-k)*a/k))y = self.R*((1-k)*math.sin(a) - l*k*math.sin((1-k)*a/k))self.t.setpos(self.xc + x, self.yc + y)# if drawing is complete, set the flagif self.a >= 360*self.nRot:self.drawingComplete = True# drawing is now done so hide the turtle cursorself.t.hideturtle()# clear everythingdef clear(self):self.t.clear()# a class for animating Spirographs
class SpiroAnimator:# constructordef __init__(self, N):# set the timer value in millisecondsself.deltaT = 10# get the window dimensionsself.width = turtle.window_width()self.height = turtle.window_height()# create the Spiro objectsself.spiros = []for i in range(N):# generate random parametersrparams = self.genRandomParams()# set the spiro parametersspiro = Spiro(*rparams)self.spiros.append(spiro)# call timerturtle.ontimer(self.update, self.deltaT)# restart spiro drawingdef restart(self):for spiro in self.spiros:# clearspiro.clear()# generate random parametersrparams = self.genRandomParams()# set the spiro parametersspiro.setparams(*rparams)# restart drawingspiro.restart()# generate random parametersdef genRandomParams(self):width, height = self.width, self.heightR = random.randint(50, min(width, height)//2)r = random.randint(10, 9*R//10)l = random.uniform(0.1, 0.9)xc = random.randint(-width//2, width//2)yc = random.randint(-height//2, height//2)col = (random.random(),random.random(),random.random())return (xc, yc, col, R, r, l)def update(self):# update all spirosnComplete = 0for spiro in self.spiros:# updatespiro.update()# count completed spirosif spiro.drawingComplete:nComplete += 1# restart if all spiros are completeif nComplete == len(self.spiros):self.restart()# call the timerturtle.ontimer(self.update, self.deltaT)# toggle turtle cursor on and offdef toggleTurtles(self):for spiro in self.spiros:if spiro.t.isvisible():spiro.t.hideturtle()else:spiro.t.showturtle()# save drawings as PNG files
def saveDrawing():# hide the turtle cursorturtle.hideturtle()# generate unique filenamesdateStr = (datetime.now()).strftime("%d%b%Y-%H%M%S")fileName = 'spiro-' + dateStrprint('saving drawing to %s.eps/png' % fileName)# get the tkinter canvascanvas = turtle.getcanvas()# save the drawing as a postscipt imagecanvas.postscript(file = fileName + '.eps')# use the Pillow module to convert the poscript image file to PNGimg = Image.open(fileName + '.eps')img.save(fileName + '.png', 'png')# show the turtle cursorturtle.showturtle()# main() function
def main():# use sys.argv if neededprint('generating spirograph...')# create parserdescStr = """This program draws Spirographs using the Turtle module.When run with no arguments, this program draws random Spirographs.Terminology:R: radius of outer circler: radius of inner circlel: ratio of hole distance to r"""parser = argparse.ArgumentParser(description=descStr)# add expected argumentsparser.add_argument('--sparams', nargs=3, dest='sparams', required=False,help="The three arguments in sparams: R, r, l.")# parse argsargs = parser.parse_args()# set the width of the drawing window to 80 percent of the screen widthturtle.setup(width=0.8)# set the cursor shape to turtleturtle.shape('turtle')# set the title to Spirographs!turtle.title("Spirographs!")# add the key handler to save our drawingsturtle.onkey(saveDrawing, "s")# start listeningturtle.listen()# hide the main turtle cursorturtle.hideturtle()# check for any arguments sent to --sparams and draw the Spirographif args.sparams:params = [float(x) for x in args.sparams]# draw the Spirograph with the given parameterscol = (0.0, 0.0, 0.0)spiro = Spiro(0, 0, col, *params)spiro.draw()else:# create the animator objectspiroAnim = SpiroAnimator(4)# add a key handler to toggle the turtle cursorturtle.onkey(spiroAnim.toggleTurtles, "t")# add a key handler to restart the animationturtle.onkey(spiroAnim.restart, "space")# start the turtle main loopturtle.mainloop()# call main
if __name__ == '__main__':main()

《Python极客项目编程 》——2.4 完整代码相关推荐

  1. python极客项目编程pdf微盘下载_《Python极客项目编程 》——2.4 完整代码

    本节书摘来自异步社区<Python极客项目编程 >一书中的第2章,第2.4节,作者 [美] Mahesh Venkitachalam,王海鹏 译,更多章节内容可以访问云栖社区"异 ...

  2. python极客项目编程_Python极客项目编程 ([美]Mahesh Venkitachalam) 中文pdf完整版

    Python是一种解释型.面向对象.动态数据类型的高级程序设计语言.通过Python编程,我们能够解决现实生活中的很多任务.Python极客项目编程通过14个有趣的项目,帮助和鼓励读者探索Python ...

  3. 《Python极客项目编程 》——第2章 万花尺 2.1 参数方程

    本节书摘来自异步社区<Python极客项目编程 >一书中的第2章,第2.1节,作者 [美] Mahesh Venkitachalam,王海鹏 译,更多章节内容可以访问云栖社区"异 ...

  4. 《Python极客项目编程 》——2.5 运行万花尺动画

    本节书摘来自异步社区<Python极客项目编程 >一书中的第2章,第2.5节,作者 [美] Mahesh Venkitachalam,王海鹏 译,更多章节内容可以访问云栖社区"异 ...

  5. python极客项目编程 豆瓣_《Python极客项目编程》

    感受编程的魅力~ Python是一种解释型.面向对象.动态数据类型的高级程序设计语言.通过Python编程,我们能够解决现实生活中的很多任务.本书通过14个有趣的项目,帮助和鼓励读者探索Python编 ...

  6. python微控制器编程从零开始 pdf_Python极客项目编程_(美)Mahesh Venkitachalam.pdf

    开发有趣的极客项目,掌握实用的Python编程技能 极客项目编程 Python极客项目编程 Python [美] Mahesh Venkitachalam  著  王海鹏  译 Python极客项目编 ...

  7. 机器人 python 极客入门_机器人Python极客编程入门与实战

    Python是一种面向对象.解释型的计算机程序设计语言,其简洁实用.高效,拥有众多模块库,可移植,跨平台,简单易学,易于上手.随着计算机深入发展,Python逐渐成为最适合青少年做创意设计的语言,也同 ...

  8. 机器人python极客pdf_机器人Python极客编程入门与实战

    编辑推荐 有了先进的软件.硬件开发平台,剩下的只是创意.中国人,特别是中国的年轻人,是全球富有创业.创新精神的一群人,这样的一个群体难道还会缺乏创意吗? "青少年学编程系列丛书"只 ...

  9. python机器人编程与操作_机器人Python极客编程入门与实战 PDF 完整目录版

    给大家带来的一篇关于Python编程相关的电子书资源,介绍了关于机器人.Python.极客编程.入门.实战方面的内容,本书是由电子工业出版社出版,格式为PDF,资源大小25.8MB,Python极客团 ...

  10. 国内第一本micropython的书出版《机器人Python极客编程入门与实战》

    第一本micropython的书<机器人Python极客编程入门与实战>. 购买地址:https://item.taobao.com/item.htm?spm=2013.1.w4018-1 ...

最新文章

  1. 读javascript高级程序设计06-面向对象之继承
  2. 【Paper】Origin绘制误差棒图(标准差围绕均值)
  3. win7查看某个端口被占用的解决方法
  4. python绘制正态分布函数_学好正态分布有多重要?
  5. 作者:陈维政,男,北京大学博士生。
  6. 【英语学习】【Level 08】U01 Let's Read L4 Hot off the press
  7. 多核环境下pthread调度执行bthread的过程
  8. nginx 根据目录指定root_CentOS(7.6)基本操作与Nginx配置
  9. MPLS virtual private network路由信息的发布过程
  10. 康佳电视应用助手服务器连接超时,TV盒子助手如何连接智能电视远程推送软件?解决方法如下...
  11. 制作NUGET包制作nupkg包
  12. java.lang.ClassNotFoundException: org.jaxen.JaxenException 解决方法
  13. html5一个圆圈旋转,Javascript实现可旋转的圆圈实例代码
  14. 【华为机试真题 Python实现】黑板上的数字涂颜色【2022 Q1 Q2 |100分】
  15. Spring复习——B站
  16. webpack-theme-color-replacer自定义element-ui主题
  17. Red Hat linux9 初装配置
  18. PAP和CHAP的区别
  19. matlab工程应用基础,Matlab工程应用基础_2_214090
  20. LWN:如何保护虚拟机不受恶意来源的攻击?

热门文章

  1. Object.freeze( ) 阻止Vue无法实现 响应式系统
  2. Matlab函数——dct2
  3. chrome安装测试打包插件
  4. 一例WINDOWS系统上的JAVA UI卡死
  5. 外星人绝对不会入侵地球,看不上
  6. 2019年5月,国际计量单位实施新定义
  7. 解决办法:C代码中明明有,为什么编译时提示未定义的引用
  8. 由数字规律谈历史的前定
  9. DeepStream运行范例出错,提示缺少libnvinfer.so怎么办?
  10. shiro 拦截未登录的ajax_Springboot+thymeleaf+Shiro继承,亲测可用