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等美工,直观感受到单纯录制屏幕太过僵硬,就修饰了一下视屏,添加淡入淡出效果。顺便帮可爱的韫哲同学的博文排个版哈哈哈哈!

总而言之真的超级开心!

——钟碧娥

 

 

posted @ 2019-05-16 10:56  IlIlIlIl  阅读(633)  评论(0)    收藏  举报