使用python中的turtle库同时画两只兔兔,方法是创建多线程。
设置双画笔
(调用的函数放在最后面)
y = turtle.Pen() # 绘制左边的画笔
d = turtle.Pen() # 绘制右边的画笔
turtle.bgcolor(0.5, 0.5, 0.5) # 背景色
turtle.screensize(1800, 1000) # 画布尺寸
turtle.hideturtle() # 隐藏画笔
# y._tracer(0, 0) # 如果不想看动画直接看结果,把注释去掉
t1 = threading.Thread(target=white_rabbit)
t2 = threading.Thread(target=black_rabbit)
t1.start()
t2.start()
turtle.exitonclick()
此篇只贴图形函数代码,整个程序完整效果图:

动画效果是先画完树和雪花,再草地雪地,然后两只兔子,每一步都创建两个线程使两边并发绘制,最后加上中间爱心。因为在每个环节中某一边可能会更快画完,所以要用到两个互斥锁,控制一支画笔等另一只画完,保证下个环节依旧同时进行。这里用兔子绘制函数做演示:
mutex1 = threading.Lock()
mutex2 = threading.Lock()
def white_rabbit():
mutex1.acquire() # 上第一把锁
...
mutex2.release() # 解第二把锁
def black_rabbit():
mutex2.acquire() # 上第二把锁
...
mutex1.release() # 解第一把锁
樱花树和雪花都属于分型几何,分形是描述复杂几何形体结构的一种数学概念。分形几何的特点是:客观事物具有自相似的层次结构。在设计算法中主要运用的是迭代思想。
樱花树绘制函数
def cherry(self, n, len):
'''
樱花二叉树
:param n: 树迭代层数
:param len: 树枝长度
:return:
'''
y.pd()
# 阴影效果
t = cos(radians(y.heading() + 45)) / 8 + 0.25
y.pencolor(t, t, t)
y.pensize(n / 3)
y.forward(len) # 画树枝
if n > 0:
b = random() * 15 + 10 # 右分支偏转角度
c = random() * 15 + 10 # 左分支偏转角度
d = len * (random() * 0.25 + 0.7) # 下一个分支的长度
y.right(b) # 右转一定角度,画右分支
self.cherry(n - 1, d)
y.left(b + c) # 左转一定角度,画左分支
self.cherry(n - 1, d)
y.right(c) # 转回来
else:
# 画叶子
y.right(90)
n = cos(radians(y.heading() - 45)) / 4 + 0.5
y.pencolor(n, n * 0.8, n * 0.8)
y.circle(3)
y.left(90)
# 添加0.3倍的飘落叶子
if (random() > 0.7):
y.pu()
# 飘落
t = y.heading()
an = -40 + random() * 40
y.setheading(an)
dis = int(800 * random() * 0.5 + 400 * random() * 0.3 + 200 * random() * 0.2)
y.forward(dis)
y.setheading(t)
# 画叶子
y.pd()
y.right(90)
n = cos(radians(y.heading() - 45)) / 4 + 0.5
y.pencolor(n * 0.5 + 0.5, 0.4 + n * 0.4, 0.4 + n * 0.4)
y.circle(2)
y.left(90)
y.pu()
# 返回
t = y.heading()
y.setheading(an)
y.backward(dis)
y.setheading(t)
y.pu()
y.backward(len)
def draw_cherry(self):
y.pu()
y.goto(-520, -380)
y.seth(0)
y.left(90)
y.pd()
y.pensize(4)
y.pencolor('black')
y.forward(80)
y.pu()
self.cherry(12, 100)
科赫雪花绘制函数
def Koch_curve(self, n, len):
'''
科赫曲线(三分之一的雪花)
:param n: 分形次数
:param len: 一段线段长度
:return:
'''
if n == 0:
d.forward(len)
else:
for i in [0, 60, -120, 60]:
d.left(i)
self.Koch_curve(n-1, len/3)
def Koch_snowflake(self, n, len):
# 循环三次科赫曲线得到雪花
for a in range(3):
self.Koch_curve(n, len)
d.right(120)
def draw_snowflake(self):
# 画了三朵雪花
d.pensize(2)
d.color('white')
d.pu()
d.goto(300, 100)
d.pd()
self.Koch_snowflake(5, 400)
d.pu()
d.goto(100, 300)
d.pd()
self.Koch_snowflake(4, 200)
d.pu()
d.goto(700, 400)
d.pd()
self.Koch_snowflake(3, 100)
黑白兔绘制函数
RADIUS = 50
ANGLE = 50
W_X = -200
W_Y = -340
B_X = 200
B_Y = -340
def white_rabbit():
y.hideturtle()
y.speed(4)
y.pensize(3)
# 头部
y.color('white')
y.pu()
y.goto(W_X, W_Y)
y.seth(0)
y.pd()
y.begin_fill()
y.circle(RADIUS, 360)
y.end_fill()
# 耳朵
y.pu()
y.goto(RADIUS * sin(2 * ANGLE) + W_X, RADIUS * cos(2 * ANGLE) + RADIUS + W_Y)
y.pd()
y.seth(120)
y.begin_fill()
y.circle(-50, 60)
y.circle(-10, 120)
y.circle(-50, 55)
y.pu()
y.seth(0)
y.forward(15)
y.pd()
y.seth(120)
y.circle(-50, 55)
y.circle(-10, 120)
y.circle(-50, 62)
y.end_fill()
# 眼睛
y.color('red')
y.pu()
y.seth(0)
y.goto(-RADIUS * sin(ANGLE) + W_X, RADIUS + W_Y)
y.pd()
y.begin_fill()
y.circle(5)
y.pu()
y.forward(2 * RADIUS * sin(ANGLE))
y.pd()
y.circle(-5)
y.end_fill()
# 身体
y.color('white')
y.pu()
y.seth(0)
y.goto(-RADIUS * sin(ANGLE) + 10 + W_X, 10 + W_Y)
y.seth(-50)
y.pd()
y.begin_fill()
y.circle(-130, 30) # 1
y.circle(-12, 140) # 2
y.circle(160, 40) # 3
y.circle(50, 75) # 5
y.circle(-10, 140) # 6
y.circle(-100, 45) # 7
# 尾巴
y.seth(0)
y.circle(10)
# 背部
y.seth(25)
y.circle(-160, 35)
y.end_fill()
# 前腿
y.pu()
y.goto(W_X, -42 + W_Y)
y.pd()
y.seth(-130)
y.begin_fill()
y.fd(25)
y.circle(-8, 110)
y.fd(40)
y.end_fill()
# 后腿
y.pu()
y.goto(-145 + W_X, -50 + W_Y)
y.pd()
y.seth(-95)
y.begin_fill()
y.fd(15)
y.circle(5, 150)
y.fd(3)
y.end_fill()
def black_rabbit():
d.hideturtle()
d.speed(4)
d.pensize(3)
# 头部
d.color('black')
d.pu()
d.goto(B_X, B_Y)
d.pd()
d.begin_fill()
d.circle(RADIUS, 360)
d.end_fill()
# 耳朵
d.pu()
d.goto(RADIUS * sin(2 * ANGLE) + B_X, RADIUS * cos(2 * ANGLE) + RADIUS + B_Y)
d.pd()
d.seth(120)
d.begin_fill()
d.circle(-50, 60)
d.circle(-10, 120)
d.circle(-50, 55)
d.pu()
d.seth(0)
d.forward(15)
d.pd()
d.seth(120)
d.circle(-50, 55)
d.circle(-10, 120)
d.circle(-50, 62)
d.end_fill()
# 眼睛
d.color('red')
d.pu()
d.seth(0)
d.goto(RADIUS * sin(ANGLE) + B_X, RADIUS + B_Y)
d.pd()
d.begin_fill()
d.circle(-5)
d.pu()
d.forward(2 * RADIUS * sin(ANGLE))
d.pd()
d.circle(5)
d.end_fill()
# 身体
d.color('black')
d.pu()
d.seth(0)
d.goto(RADIUS * sin(ANGLE) - 10 + B_X, 10 + B_Y)
d.seth(-130)
d.pd()
d.begin_fill()
d.circle(130, 30) # 1
d.circle(12, 140) # 2
d.circle(-160, 40) # 3
d.circle(-50, 75) # 5
d.circle(10, 140) # 6
d.circle(100, 45) # 7
# 尾巴
d.seth(0)
d.circle(10)
# 背部
d.seth(155)
d.circle(160, 35)
d.end_fill()
# 前腿
d.pu()
d.goto(B_X, -42 + B_Y)
d.pd()
d.seth(-50)
d.begin_fill()
d.fd(25)
d.circle(8, 110)
d.fd(40)
d.end_fill()
# 后腿
d.pu()
d.goto(145 + B_X, -50 + B_Y)
d.pd()
d.seth(-85)
d.begin_fill()
d.fd(15)
d.circle(-5, 150)
d.fd(3)
d.end_fill()
草地绘制函数
def ground():
for i in range(100):
y.pensize(randint(6, 12))
x_zhou = randint(-SCREEN_LENGTH / 2, 0)
y_zhou = randint(-SCREEN_WIDTH / 2, -SCREEN_WIDTH / 2 + 100)
g = -y_zhou / 1000 # 颜色随y轴变幻
y.pencolor(0, g, 0)
y.pu()
y.goto(x_zhou, y_zhou)
y.pd()
y.seth(0)
y.left(randint(80, 100))
y.forward(randint(10, 20))
雪地绘制函数
def snowfield():
for i in range(150):
d.pensize(randint(10, 18))
x_zhou = randint(0, SCREEN_LENGTH / 2)
y_zhou = randint(-SCREEN_WIDTH / 2, -SCREEN_WIDTH / 2 + 100)
d.pencolor('white')
d.pu()
d.goto(x_zhou, y_zhou)
d.pd()
d.seth(0)
d.forward(randint(20, 50))
爱心绘制函数
def heart_shaped(self):
# 画笔名叫love
love.speed(2)
love.pu()
love.goto(-20, -100)
love.seth(-90)
love.pd()
love.begin_fill()
love.left(135)
love.right(90)
love.forward(50)
love.left(90)
love.forward(50)
love.left(45)
love.circle(17.67, 180)
love.left(180)
love.circle(17.67, 180)
love.end_fill()
这篇博客通过Python的turtle库和多线程技术,同时绘制两只兔子,背景中伴有樱花树和雪花的分形几何图案。使用互斥锁确保绘制同步,展现了分形几何的自相似性和迭代思想。代码中包含樱花树、科赫雪花的绘制函数,以及黑白兔子的详细绘制过程,创造出丰富的视觉效果。

2198

被折叠的 条评论
为什么被折叠?



