turtle 绘图比赛《凛冬之下,缤纷之城》
20181004110,黄韫哲
20180301129,钟碧娥
#------------------------------------------------------------------------------ #------------------------------需要用到的库------------------------------------ import turtle as t import random import math import time #------------------------------------------------------------------------------ #-----------------------------需要用到的函数----------------------------------- def go(x): '''直线 属性:颜色color(加入了渐变色选项) 倍率size(可以控制图形的大小)属性全部由图形函数继承 渐变周期T(实际周期为T*size) 角度angel 容错开关switch(关闭时为0无法画长度比1更小的线段,精度为1,等级为1时精度为0.1,以此类推) 参数:x为长度''' global r,b,g,T,size,color,angel#注意定义全局变量color,size,T,angel,其实可以不全声明,声明防止出错。 t.left(angel) if color=='渐变色': T=int(T/6)*6#周期分为六等分,所以T取6的倍数防止出错。 t.pd() for i in range(int(x*10**switch)):#对于渐变色功能可以优化,如添加控制渐变范围等功能。 if i%10**switch==0: if r==T/6 and g==0 and b<T/6: b=b+1 elif b==T/6 and g==0 and r>0: r=r-1 elif r==0 and b==T/6 and g<T/6: g=g+1 elif g==T/6 and r==0 and b>0: b=b-1 elif g==T/6 and b==0 and r<T/6: r=r+1 elif r==T/6 and b==0 and g>0: g=g-1 t.color(r*6/T,b*6/T,g*6/T) t.fd(size/10**switch) t.pu() else: t.pd() t.pencolor(color) for i in range(int(x*10**switch)): t.fd(size/10**switch) t.pu() def yuan(R,sa,angel0): '''圆弧 属性:颜色color(加入了渐变色选项) 倍率size(可以控制图形的大小,由图形函数继承) 渐变周期T(实际周期为T*size) 角度angel 参数:R为半径,sa为起始角度,a为圆弧角度''' global r,b,g,T,size,color,angel T=int(T/6)*6#周期分为六等分,所以T取6的倍数防止出错。 t.setheading(sa-180) t.left(angel) if angel0>=0: fuhao=1 else: fuhao=-1 if color=='渐变色': t.pd() for i in range(int(math.pi*2*R/360*angel0*fuhao)):#需引入math库 if r==T/6 and g==0 and b<T/6: b=b+1 elif b==T/6 and g==0 and r>0: r=r-1 elif r==0 and b==T/6 and g<T/6: g=g+1 elif g==T/6 and r==0 and b>0: b=b-1 elif g==T/6 and b==0 and r<T/6: r=r+1 elif r==T/6 and b==0 and g>0: g=g-1 t.color(r*6/T,b*6/T,g*6/T) t.circle(R,-360/2/math.pi/R*fuhao) t.pu() else: t.pd() for i in range(int(math.pi*2*R/360*angel0)): t.pencolor(color) t.circle(R,-360/2/math.pi/R*fuhao) t.pu() def d(x): t.setheading(0) go(x) def w(x): t.setheading(90) go(x) def a(x): t.setheading(180) go(x) def s(x): t.setheading(270) go(x) #四个正方向,用wasd控制。 def wd(x): t.setheading(45) go(int(x*2**0.5)) def dw(x): t.setheading(45) go(int(x*2**0.5)) def wa(x): t.setheading(135) go(int(x*2**0.5)) def aw(x): t.setheading(135) go(int(x*2**0.5)) '''def as(x): setheading(225) go(x*2**0.5)''' ##########注意不能重复定义内置函数!!!!!!!! def sa(x): t.setheading(225) go(int(x*2**0.5)) def sd(x): t.setheading(315) go(int(x*2**0.5)) def ds(x): t.setheading(315) go(int(x*2**0.5)) #四个偏方向,八个函数增加容错,正输入反输入效果相同。 def xy(x,y):#注:需要引入math库 s=(x**2+y**2)**0.5 a=math.atan(y/x) a=math.degrees(a) t.setheading(a) if x<0: t.right(180) go(int(s)) #任意方向的直线 def zhouqi(t0):#t0为想要的周期,转换后返回值赋予T。 global size t0=t0/size return t0 num=4 def suhua(str0):#处理字符串转换为函数代码并运行。 global num str1='' str2='-0123456789.' for i in range(len(str0)-1):#加上括号 if str0[i] in str2 and str0[i+1] not in str2: str1=str1+str0[i]+') ' elif str0[i] not in str2 and str0[i+1] in str2: str1=str1+str0[i]+'(' elif str0[i] not in str2 and str0[i+1] not in str2: str1=str1+str0[i] elif str0[i] in str2 and str0[i+1] in str2: str1=str1+str0[i] str1=str1+str0[-1]+')' list1=str1.split(' ') for i in range(len(list1)):#把'c'变为'yuan' if 'c' in list1[i]: list2=list(list1[i]) list2[0]='yuan' str3=' '.join(list2) str4='' for j in range(len(str3)): if str3[j]!=' ': str4=str4+str3[j] list1[i]=str4 for i in range(len(list1)):#把'as'变为'sa' if 'as' in list1[i]: list2=list(list1[i]) list2[0]='s' list2[1]='a' str3=' '.join(list2) str4='' for j in range(len(str3)): if str3[j]!=' ': str4=str4+str3[j] list1[i]=str4 for i in range(len(list1)):#把'.'变为',' if '.' in list1[i]: list2=list(list1[i]) for j in range(len(list2)): if list2[j]=='.': list2[j]=',' str3=' '.join(list2) str4='' for k in range(len(str3)): if str3[k]!=' ': str4=str4+str3[k] list1[i]=str4 for i in range(len(list1)):#执行所有函数代码 num=num+1 aa='daima'+str(num) dict1[aa]=list1[i]#记录转换后的代码 '''print(dict1[aa])'''#输出转换后的代码 eval(dict1[aa])#执行转换后的代码 def chengshi():#图形为城市的函数,每个图形只需定义属性后输入str0和suhua函数。 str0='d20w50xy29.26w19d2w30d2s17d2s5d3s10d2s18xy29.-25s50s1sd1s3d16s97'#第一栋楼 str0=str0+'d3w2d2w3d5w2d7xy8.1w2d19sd4d15w172dw7d2w12d11w27dw5d1w15xy10.7w25d2w24d2s24d5s24xy7.-6s44sd9s186d41'#第二栋楼 str0=str0+'xy1.-3xy1.-3d5xy3.1dw3w31c87.60.60w55c55.70.70d3w20d1s20d28s30c5.-45.180w2d48sd16'#楼群(一) str0=str0+'xy13.20w57dw3d12sd5dw8d3w24d2s24d7s3d9w31d2s35d1sd8s12d3xy39.24w34d2s34d1d9s32sd29s42xy10.4xy-6.-7d9sd3s33d2'#楼群(二) str0=str0+'w55xy13.5w140d13w3d23s5d5s141d4s8d4s8d4s8d4s8d4s25xy2.-7xy8.27c15.90.90d5w22d2s22c15.0.90d7w117d10w37c31.75.40'#高矮楼(一) str0=str0+'w74d2s74d11xy5.-10d5s49d6s18d4s65d23s58c20.90.60d15w41d8w4d5w37d2s37d15s31c66.-60.30d60'#高矮楼(二) str0=str0+'w200dw11w19d12s16sd23s14d10s11d9xy9.5xy9.-5xy9.-5xy9.-5d19w7d16s144d21'#大楼(一) str0=str0+'w128d5w37d61xy-6.-11s19d17s124'#大楼(二) str0=str0+'d43xy7.28c33.160.140w156c24.160.150w41c11.160.140w32d4w85d2s85d6s32c11.-20.140s41c24.-10.150s156c33.-15.145xy7.-28d21xy11.7'#东方明珠 str0=str0+'d15w45xy22.31s54d7w16d15s81d2w200a7w5d7w50a6w4d6w35a5w4d5w14a5d7w50a6w4d6w9a5w5d4w3a4w5d5w3a5w5d7w21c40.90.75w15d3w15d3w2d2w23d2s23d2s2d3s15d3s15c40.-20.75s21d7s5a5s3d5s5a4s3d4s5a5s9d5s14a5s7d5s14a5s4d5s35a6s4d6s50a7s5d7s200'#世贸大厦及左边小楼 str0=str0+'d22w213sd33s180d14xy9.4w23d7w481xy52.-235xy4.-54d2xy-4.54xy-52.235w31xy15.-20xy12.-45d30w45a40xy-15.20d67s506'#金融中心及左边小楼 str0=str0+'d8s36w196d15w20sd47d16w27d26w67xy12.4d32xy27.-9s85d29s40d39s100d100'#最后一栋楼 suhua(str0) def xuehuajiao(s,n=2,m=2):# s决定雪花大小 t.pd() if n==0: t.fd(s*(1/3)**m)#这里没有用go函数,是因为只需要go函数调整角度的功能,但是会大幅度牺牲效率。 else: xuehuajiao(s,n-1,m) t.left(60) xuehuajiao(s,n-1,m) t.right(120) xuehuajiao(s,n-1,m) t.left(60) xuehuajiao(s,n-1,m) t.pu() def xuehua(s,a,x,y):#a决定雪花角度,x,y决定雪花坐标 t.goto(x,y) t.setheading(a) r=random.randint(635,655)/1000 g=1.21*r b=1.48*r t.color(r,g,b)#以冰蓝色为基准,随机雪花颜色 for i in range(3): xuehuajiao(s) t.right(120) def xiaxue(x1,x2,y1,y2,p):#x1,x2,y1,y2决定下雪范围,p决定下雪大小 y=y2-y1 y1=y2 for i in range(int(y/20)):#雪花由上到下 y2=y1 y1=y1-20 for i in range(int((x2-x1)*(y2-y1)/10000*p)):#每10000像素p片雪花 x=random.randint(x1,x2) y=random.randint(y1,y2) a=random.randint(0,60) s=random.randint(6,8) xuehua(s,a,x,y) def xingxing(s,x,y):#画一颗星星 c=random.randint(0,10)#颜色随机 if c<=2: t.color(random.randint(85,95)/255,0,1) elif c<=4: t.color('blue') else: t.color('pink') t.goto(x,y) t.pd() t.dot(s) t.pu() def fanxing(x1,x2,y1,y2,p):#x1,x2,y1,y2决定星星范围,p决定星星密度 for i in range(int((x2-x1)*(y2-y1)/10000*p*0.65)):#每10000像素0.65p颗星星 x=random.randint(x1,x2) y=random.randint(y1,y2) s=random.randint(200,250)/100 xingxing(s,x,y) for i in range(int((x2-x1)*(y2-y1)/10000*p*0.35)):#每10000像素0.35p颗星星 x=random.randint(x1,x2) y=random.randint(y1,y2) s=random.randint(250,300)/100 xingxing(s,x,y) def yueliang(x,y,r):#不能画半径135以上的月亮,可以优化 t.setheading(0) for i in range(r): t.goto(0+x,i+y) t.color(1,(270-2*r+i)/270,0) t.pd() t.fd(((r**2-(50-i)**2)*4)**0.5/2) t.pu() for i in range(r): t.goto(0+x,i+r+y) t.color(1,(270-r+i)/270,0) t.pd() t.fd(((r**2-i**2)*4)**0.5/2) t.pu() t.setheading(180) for i in range(r): t.goto(0+x,i+y) t.color(1,(270-2*r+i)/270,0) t.pd() t.fd(((r**2-(50-i)**2)*4)**0.5/2) t.pu() for i in range(r): t.goto(0+x,i+r+y) t.color(1,(270-r+i)/270,0) t.pd() t.fd(((r**2-i**2)*4)**0.5/2) t.pu() def suxie(str1,str2,x,y,s,t1):#速写函数,x,y决定起始位置,s决定字体大小,str2决定书写顺序,t1决定每个字的停顿时间。 list1=str1.split(''' ''') if str2=='横正写': for i in range(len(list1)): for j in range(len(list1[i])): t.goto(s*2*j+x,-s*1.7*i+y) t.pd() t.write(list1[i][j],font=("Times","30","bold",)) t.pu() time.sleep(t1) elif str2=='竖正写': for i in range(len(list1)): for j in range(len(list1[i])): t.goto(s*2*i+x,-s*1.7*j+y) t.pd() t.write(list1[i][j],font=("Times","30","bold",)) t.pu() time.sleep(t1) elif str2=='横倒写': for i in range(len(list1)): for j in range(len(list1[i])): t.goto(-s*2*j+x,-s*1.7*i+y) t.pd() t.write(list1[i][j],font=("Times","30","bold",)) t.pu() time.sleep(t1) else: for i in range(len(list1)): for j in range(len(list1[i])): t.goto(-s*2*i+x,-s*1.7*j+y) t.pd() t.write(list1[i][j],font=("Times","30","bold",)) t.pu() time.sleep(t1) #------------------------------------------------------------------------------ #------------------------------建立画板选择参数-------------------------------- t.setup(1600,790,0,0)#建立画板 t.pensize(1)#画笔粗细 t.ht()#隐藏画笔 t.speed(0)#速度最快 t.tracer(100,1)#速度更快 t.pu() t.bgcolor(0,0,0)#底色为黑 switch=0#精度为10**0,精度越高,画的越慢,需要调整t.tracer调节速度。 size=0.75#图形比例 color='渐变色'#颜色 angel=0#图形延申方向,0度为向正东。 dict1={}#字典作用为保存字符串转换的函数代码 T=zhouqi(600)#渐变周期 r=int(T/6)#从红色开始渐变 b=0#三原色 g=0 #-----------------------------------开始画------------------------------------- #------------------------------凛冬之下,缤纷之城------------------------------ t.tracer(False) fanxing(-500,800,145,395,2)#繁星 fanxing(-500,100,-185,145,2) fanxing(600,800,-150,145,2) yueliang(610,235,50)#月亮 t.tracer(100,1) t.goto(-780,-260)#起始位置 chengshi()#画一个城市(上海外滩) t.tracer(50,1) xiaxue(-500,800,-5,395,1.3)#下雪 xiaxue(-800,800,-395,-5,1.3) t.tracer(True) t.color(1,1,1) suxie('''雪颜拂尘笑靥中 暮色映彩烟火浓 千渡街巷不若此 昭昭美城逸春风''','竖倒写',-580,330,30,0.4) t.exitonclick()
超棒的视频:
https://www.bilibili.com/video/av52591260?share_medium=android&share_source=qq&bbid=XY60FA1688F21BDB602F88DB41EF657D0AE5D&ts=1557971868540
后记在此:
先附上一张草稿图和三张草稿纸吧:
一开始想自己画个坐标系测量的,但是转念一想画图的坐标不是现成的吗。于是就在画图上剪切放大以后边测边记,
用了向量的简易记法,然后转换成了文本格式。像这样:
你没看错,就是WASD控制方向,超级马里奥玩过没有?
可是这么一堆乱码我看得懂计算机看不懂啊,怎么办呢?那就用字符串,列表,字典的处理方法把它转换成可以运行的代码,再用eval()运行呗。所以定义了一个速画函数用于转换和执行。可是我想画的是渐变色的城市啊,这turtle库也没这选项啊。没关系,自己动手,丰衣足食,定义一go()函数,给他加个渐变色的选项,那渐变色都加了,为了以后方便就多加几个属性吧,所以加了倍率,渐变周期等几个属性。这几个属性会被画向量的函数继承,进而被图形继承,这样画出来的图形修改起来方便很多。
下雪和繁星都大同小异,用随机函数让大小,颜色,位置,角度几个属性随机就可以了。当然为了改起来方便给这两个函数加了几个参数。
然后是月亮,看了几张图片后决定用由黄到红的渐变色,试了几十次改了其中的一些值之后找到了比较合适的。
最后是加文本,同样为了改起来方便定义了速写函数。(顺带一提,go()函数在画高阶雪花时遇到了问题,就是高阶雪花最小精度高,而初始的go()函数最小精度是1,所以又加了switch,来决go()函数的最小精度,后面的雪花因为用不到渐变色,所以直接用了fd()函数,以增加效率)
本作品的最大特点就是高度的函数化,使得后期处理简便了许多。当然也有很多没有发现的BUG,但至少实现现阶段的功能没有问题。
——黄韫哲
作为一个抱紧大佬大腿的文科生,在他的设计里面我看到了很多想法,也学到了很多东西。大部分是韫哲同学做的,线条勾勒的城市是他一开始就呈现给我的图,我觉得超级厉害啊,不能当猪队友,他就把雪花包揽给我了,但是我除了画一个教材的上静止的科赫曲线真是百无一用,后来他还让我思考因为雪花太小会只呈现六角形,应该把雪花肢解分成三个部分,画出一个部分最后旋转合成,不过最后还是没有做,哈哈哈哈因为太蠢了,于是雪花和雪花的random也还是他做的。
很好玩的是一起熬夜写作业,深沉的夜晚和安定下的灵魂或许就适合写作业,但是我发现写作业不重要,重要的是“一起”写作业,每个夜晚他都在雕琢自己的作品,添加月亮、诗词,问我配色和渐变是否美观,自己尝试完新的技能后会分享给我,今天凌晨还想让雪花等元素进行运动,但最后发现运动不能带上颜色,只能是黑色。
我也尝试去了解一些东西,比如说修改字体,在网上查的到的资料原来那么少,以至于找到了字体名称汇总被韫哲同学夸哈哈哈哈,然后我也小小的修改了原本粗细不同的字体。无脑的操作,比如说录制视屏,就是让我来的,但是鉴于这学期学了Pr等美工,直观感受到单纯录制屏幕太过僵硬,就修饰了一下视屏,添加淡入淡出效果。顺便帮可爱的韫哲同学的博文排个版哈哈哈哈!
总而言之真的超级开心!
——钟碧娥