# -*- coding: utf-8 -*-
"""
Created on Thu Feb 24 19:21:54 2022
@author: Administrator
"""
"""
import sys, argparse
from PIL import Image
import numpy as np
from datetime import datetime
"""
import math
import random
import turtle
from fractions import gcd
#绘制万花筒的类
class Spiro:
#创建
def __init__(self, xc, yc, col, R, r, l):
#创建海龟对象
self.t = turtle.Turtle()
#设置游标的形状
self.t.shape('turtle')
#设置移动的角度
self.step = 5
#设置绘制完成的标记
self.drawingComplete = False
#设置参数
self.setparams(xc, yc, col, R, r, l)
#初始化
self.restart()
#创建——传参数方法(万花尺的参数)
def setparams(self, xc, yc, col, R, r, l):
self.xc = xc
self.yc = yc
self.col = col
self.R= int(R)
self.r = int(r)
self.l = l
#最大公约数gcdVal
gcdVal = gcd(self.r, self.R)
#在nRot圈数后,开始重复
self.nRot = self.r // gcdVal
# 计算半径之比
self.k = r / float(R)#?
#设置线条的颜色
self.t.color(*col)
#储存现在的角度
self.a = 0
#创建restart方法
def restart(self):
#将目前的万花尺归位为false
self.drawingComplete = False
#显示海龟光标
self.t.showturtle()
#将光标归到最开始的位置
self.t.up()
R, k, l = self.R, self.k, self.l
a = 0.0
x = R*((l-k)*math.cos(a)+l*k*math.cos((l-k)*a/k))
y = R*((l-k)*math.sin(a)-l*k*math.sin((l-k)*a/k))
self.t.setpos(self.xc+x, self.yc+y)
self.t.down()
#开始绘制曲线
def draw(self):
R, k, l = self.R, self.k, self.l
for i in range(0,360*self.nRot+1, self.step):
a = math.radians(i)
x = R*((l-k)*math.cos(a)+l*k*math.cos((l-k)*a/k))
y = R*((l-k)*math.sin(a)-l*k*math.sin((l-k)*a/k))
self.t.setpos(self.xc+x, self.yc+y)
self.t.hideturtle()
#绘制完成,因此隐藏海龟光标
def update(self):
if self.drawingComplete:
return
#增加当前的角度
self.a += self.step
a = math.radians(self.a)
R, k, l = self.R, self.k, self.l
x = R*( (l-k) * math.cos(a) + l*k*math.cos((l-k)*a/k))
y = R*( (l-k) * math.sin(a) - l*k*math.sin((l-k)*a/k))
self.t.setpos(self.xc + x, self.yc + y)
if self.a >= 360*self.nRot:
self.drawingComplete = True
#绘制完成,因此隐藏海龟光标
self.t.hideturtle()
def clear(self):
self.t.clear()
#创建随机绘制曲线的类
class SpiroAnimator:
def __init__(self, N):
#设置定时器(10毫秒)
self.deltaT = 5
#获取窗口的尺寸
self.width = turtle.window_width()
self.height = turtle.window_height()
#创建一个Sprio对象
self.spiros = []
for i in range(N):
#获取随机参数
rparams = self.genRandomParams()
#设置spiros对象并传入参数
spiro = Spiro(*rparams)#把spiro写出spiros,下一句的spiro也写成了spiros
self.spiros.append(spiro)
#设置定时器进行调用update
#放在循环里调用N次
turtle.ontimer(self.update,self.deltaT)
#对Spiro进行重新绘制
def restart(self):
for spiro in self.spiros:
spiro.clear()
#产生随机参数
rparams = self.genRandomParams()
#设置参数
spiro.setparams(*rparams)
#进行重新确定起点
spiro.restart()
#产生随机参数,并以元组形式返回
def genRandomParams(self):
width, height = self.width, self.height
#R = random.randint(300,500)
R = random.randint(50, min(width, height)/2)
r = random.randint(10, 9*R // 10)
#r = random.randint(100,200)
#l = random.uniform(0.1, 0.9)#???
l = random.uniform(0.1, 0.9)
xc = random.randint(-width // 2, width // 2)
#xc = random.randint(-250,250)
yc = random.randint(-height // 2, height // 2)
#yc = random.randint(-250,250)
col = (random.random(), random.random(),random.random())
return (xc, yc, col, R, r, l)
def update(self):
#更新所有的spiros
nComplete = 0
for spiro in self.spiros:
#依次调用每个spiro里的update方法
spiro.update()
#统计绘制完成的spiro数量
if spiro.drawingComplete == True:
nComplete += 1
#当所有的spiro都绘制完成,则重新开始
if nComplete == len(self.spiros):
self.restart()
#无限循化update
turtle.ontimer(self.update,self.deltaT)
#对海龟的显示与隐藏进行切换
def toggleTurtle(self):
for spiro in self.spiros:
if spiro.t.isvisible():
spiro.t.hideturtle()
else:
spiro.t.showturtle()
#写main函数
def main():
print("generating spirograph....")
#设置宽度为原宽度的80%
turtle.setup(width = 0.8)
#将游标形状设置为海龟形状
turtle.shape("turtle")
turtle.title("Spirographs!")
turtle.hideturtle()
SpiroAnimator(5)
"""
col = (0.0, 0.0, 0.0)
spiro = Spiro(0, 0, col, 300, 100, 0.9)
spiro.draw()
"""
if __name__ == '__main__':
main()
|