Python turtle库图形绘制——毛笔简笔画和平鸽

一、绘制毛笔笔划的方法

毛笔简笔画与普通简笔画有明显的不同,普通简笔画绘制线条的粗细是相同的,而用毛笔绘制的线条粗细是变化的,如图1所示。

 

图1 毛笔简笔画局部(线条的粗细变化)

先来看一下曲线汉字字库。其实汉字也类似,由各种不同形状的笔划组成,如图2是宋体汉字“微”,横竖撇捺折都是带笔锋的,目前用的基本上是曲线字库,而字库中只存储了字的轮廓,包括水平线、垂直线、曲线等,其中曲线用少量坐标点再用二次B样条曲线或三次B样条曲线拟合,可以无级放大、缩小、旋转、变形等变换。图2左侧是各笔划的轮廓,图2右侧是各笔划经填色形成的对应汉字。

 

图2 宋体汉字“微”

如图3是楷体汉字“瑞”,横竖撇捺折都是带笔锋的,楷体字是正楷毛笔字,图3左侧是各笔划的轮廓,图3右侧是各笔划笔顺和经填色形成的对应汉字。

 

图3 楷体汉字“瑞”

再来看图1,可以将其轮廓化为图4,然后再填色。用turtle绘图则无法用B样条曲线绘制,只能用不同半径及转角的圆弧、直线来近似表达。

 

图4 将图1轮廓化

图5是来自“百度图片”的一幅的简笔画,为了使turtle绘图比较正确地还原此图片,可以先在原图的重要位置上画上一些圆弧或直线(见图6),用以测量圆弧的半径,角度可以先估算,然后在绘图时根据误差进行修正(调整),其他线段可以与已标的圆弧半径进行比较进行半径预估。

 

图5 毛笔简笔画——和平鸽

 

图6 在原画上画上一些圆弧或直线,方便测量圆弧半径并预估角度

二、毛笔简笔画——和平鸽的绘制

turtle库是Python内置的图形化模块,是Python标准库之一,常用方法有以下几种:

1. 画笔控制方法

以下出现“|”表示或者,如penup() | pu() | up(),标准方法是penup(),也可以用其缩写方法pu()或up()。

penup() | pu() | up()——抬起画笔(抬笔后只移动画笔,不绘制线条)

pendown() | pd() | down()——落下画笔(落笔后移动画笔,就会绘制线条)

pensize(width) | width(width)——画笔宽度(宽度用像素表示,默认width=1)

pencolor(color)——画笔颜色(color可以是字符串颜色名,如'red';也可以是r, g, b形式的RGB颜色,如255, 0, 0等)

2. 运动控制方法

forward(d) | fd(d)——沿当前海龟方向向前运动d个像素(如d为负数则向后运动)

circle(radius, extent=None, steps=None)——绘制半径为radius,角度为extent°的弧形或steps边内接边。如省略extent和steps,则画圆,radius为正,圆心在海龟方向左侧,radius为负,则圆心在海龟方向右侧;如指定extent,按角度°绘制圆弧,radius为正,圆心在海龟方向左侧,radius为负,则圆心在海龟方向右侧;如只指定steps,则绘制圆的内接正steps边形,如指定extent和steps,则绘制圆指定圆弧的内接正steps边折线。

3. 方向控制方法

setheading(angle) | seth(angle)——改变前进方向(如angle为正,从海龟0°方向向角度正方向转到angle°(绝对度数);如angle为负,从海龟0°方向向角度负方向转到angle°(绝对角度)。默认水平方向向右为0°,逆时针方向为正,顺时针方向为负)

left(angle) | lt(angle)——海龟左转angle°(相对度数)

right(angle) | rt(angle)——海龟右转angle°(相对度数)

4. 填色控制方法

begin_fill()——在绘制要填充的形状之前调用。启动填色模式

end_fill()——填充调用begin_fill()后绘制的形状。如形状不封闭,则先连接起点和终点然后再填色,填色后终止填色模式

完整源代码如下:

###############################################
# 设计 Zhang Ruilin     创建 2021-10-06 23:18 #
#                       修订 2022-07-31 07:54 #
# turtle 绘简笔画——毛笔风格衔橄榄枝的和平鸽 #
###############################################
import turtle as tl
tl.speed(0)			# 设置最快绘图速度
tl.setup(780, 650)		# 设置画面尺寸
tl.title('海龟绘图——毛笔风格衔橄榄枝的和平鸽简笔画')
tl.pu()
R = 1/3				# 设置比例因子, 用数据的1/3大小绘制
x0, y0 = R*1250, R*1000		# 设置位置偏移量, 使图像处于窗口中间
draw_color='green'		# 定义线条颜色(绿色)
fill_color=('green')		# 定义填充颜色(绿色), 即橄榄枝颜色
tl.color(draw_color, fill_color)# 设置线条颜色和填充颜色
tl.goto(R*1030-x0, y0-R*1040)	# 移动至橄榄枝柄起点坐标
tl.pd()
tl.lt(90)
tl.begin_fill()			# 橄榄枝填色开始
tl.circle(200*R, 50)		# 画橄榄枝柄起笔
tl.circle(345*R, 25)
tl.circle(-520*R, 35)
tl.circle(-330*R, 40)
tl.rt(162)
tl.circle(550*R, 55)
tl.circle(-450*R, 30)
tl.circle(-150*R, 25)
tl.circle(-60*R, 95)
tl.end_fill()			# 橄榄枝填色, 并终止填色模式
tl.seth(100)
tl.pu()
tl.fd(500*R)			# 移动到第一片橄榄枝叶
tl.lt(110)
tl.pd()
tl.begin_fill()			# 第一片橄榄叶填色开始
tl.circle(170*R, 95)		# 第一片橄榄枝叶
tl.lt(100)
tl.circle(170*R, 55)
tl.end_fill()			# 第一片橄榄叶填色, 并终止填色模式
tl.seth(170)
tl.pu()
tl.fd(100*R)			# 移动到第二片橄榄枝叶
tl.lt(120)
tl.pd()
tl.begin_fill()
tl.circle(-100*R, 95)		# 第二片橄榄枝叶
tl.rt(75)
tl.circle(-180*R, 95)
tl.end_fill()
tl.seth(170)
tl.pu()
tl.fd(160*R)
tl.lt(40)
tl.pd()
tl.begin_fill()
tl.circle(100*R, 50)		# 第三片橄榄枝叶
tl.circle(170*R, 60)
tl.lt(85)
tl.circle(100*R, 60)
tl.fd(110*R)
tl.circle(-90*R, 20)
tl.end_fill()
tl.seth(120)
tl.pu()
tl.fd(110*R)
tl.pd()
tl.begin_fill()
tl.circle(10*R, 110)		# 第四片橄榄枝叶
tl.fd(100*R)
tl.circle(80*R, 90)
tl.fd(20*R)
tl.lt(80)
tl.circle(175*R, 40)
tl.end_fill()
tl.seth(160)
tl.pu()
tl.fd(175*R)
tl.rt(150)
tl.pd()
tl.begin_fill()
tl.circle(90*R, 85)		# 顶尖橄榄枝叶
tl.circle(170*R, 43)
tl.lt(115)
tl.fd(100*R)
tl.circle(160*R, 35)
tl.end_fill()
tl.seth(200)
tl.pu()
tl.fd(155*R)
tl.lt(140)
tl.pd()
tl.begin_fill()
tl.fd(90*R)
tl.circle(-140*R, 55)		# 下第一片橄榄枝叶
tl.rt(90)
tl.circle(-150*R, 100)
tl.end_fill()
tl.seth(-70)
tl.pu()
tl.fd(210*R)
tl.lt(65)
tl.pd()
tl.begin_fill()
tl.fd(150*R)			# 下第二片橄榄枝叶
tl.circle(-90*R, 70)
tl.rt(100)
tl.fd(120*R)
tl.circle(-90*R, 90)
tl.end_fill()
tl.seth(-22)
tl.pu()
tl.fd(360*R)
tl.rt(110)
tl.pd()
tl.begin_fill()
tl.circle(-180*R, 80)		# 下第三片橄榄枝叶
tl.rt(120)
tl.fd(90*R)
tl.circle(-140*R, 60)
tl.end_fill()
tl.lt(10)
tl.pu()
tl.fd(150*R)
tl.rt(100)
tl.pd()
tl.begin_fill()
tl.fd(60*R)
tl.circle(-130*R, 80)		# 下第四片橄榄枝叶
tl.rt(110)
tl.fd(90*R)
tl.circle(-140*R, 60)
tl.end_fill()
tl.pu()
tl.fd(90*R)
tl.seth(90)
tl.pd()
tl.color('black', 'black')	# 设置线条颜色和填充颜色均为黑色
tl.begin_fill()
tl.fd(10*R)			# 鸽头
tl.circle(-25*R, 45)
tl.fd(20*R)
tl.circle(100*R, 45)
tl.circle(-120*R, 70)
tl.circle(-160*R, 40)
tl.circle(-360*R, 20)
tl.fd(150*R)
tl.rt(105)
tl.circle(100*R, 25)
tl.rt(105)
tl.fd(135*R)
tl.circle(300*R, 30)
tl.circle(120*R, 60)
tl.circle(110*R, 60)
tl.rt(60)
tl.fd(70*R)
tl.lt(165)
tl.fd(80*R)
tl.lt(170)
tl.end_fill()
tl.seth(60)
tl.pu()
tl.fd(70*R)
tl.lt(10)
tl.color('red')			# 设置鸽眼颜色为红色
tl.pd()
tl.begin_fill()
tl.fd(20*R)			# 眼睛
tl.circle(-35*R, 90)
tl.rt(65)
tl.fd(20*R)
tl.end_fill()
tl.seth(223)
tl.pu()
tl.fd(200*R)
tl.color('black')
tl.pd()
tl.begin_fill()
tl.lt(165)
tl.fd(30*R)			# 腹部
tl.circle(-60*R, 110)
tl.fd(200*R)
tl.circle(715*R, 20)
tl.circle(380*R, 40)
tl.lt(120)
tl.fd(50*R)
tl.lt(58)
tl.circle(-380*R, 40)
tl.circle(-710*R, 20)
tl.fd(150*R)
tl.circle(65*R, 110)
tl.fd(50*R)
tl.end_fill()
tl.seth(-53)
tl.pu()
tl.fd(700*R)
tl.pd()
tl.begin_fill()
tl.rt(35)
tl.circle(700*R, 20)		# 尾巴
tl.circle(210*R, 40)
tl.circle(38*R, 90)
tl.rt(130)
tl.fd(70*R)
tl.circle(80*R, 120)
tl.rt(100)
tl.fd(40*R)
tl.circle(40*R, 150)
tl.rt(135)
tl.circle(150*R, 80)
tl.lt(68)
tl.circle(90*R, 45)
tl.circle(-700*R, 64)
tl.lt(45)
tl.fd(50*R)
tl.lt(131)
tl.circle(700*R, 73)
tl.rt(140)
tl.circle(-250*R, 40)
tl.lt(90)
tl.fd(20*R)
tl.circle(-30*R, 130)
tl.fd(50*R)
tl.lt(110)
tl.circle(-70*R, 120)
tl.fd(90*R)
tl.lt(120)
tl.circle(-50*R, 105)
tl.circle(-400*R, 20)
tl.end_fill()
tl.seth(93.5)
tl.pu()
tl.fd(590*R)
tl.lt(85)
tl.pd()
tl.begin_fill()
tl.circle(-56*R, 90)		# 前翅膀
tl.circle(-160*R, 50)
tl.circle(-700*R, 20)
tl.circle(900*R, 45)
tl.circle(100*R, 20)
tl.circle(-100*R, 30)
tl.rt(90)
tl.circle(-100*R, 51)
tl.circle(-470*R, 20)
tl.lt(150)
tl.circle(-50*R, 150)
tl.circle(-400*R, 12)
tl.circle(-800*R, 10)
tl.lt(150)
tl.circle(-170*R, 15)
tl.rt(100)
tl.circle(-150*R, 35)
tl.fd(90*R)
tl.lt(120)
tl.circle(-60*R, 82)
tl.circle(-150*R, 20)
tl.circle(-200*R, 35)
tl.lt(125)
tl.circle(-50*R, 120)
tl.circle(-300*R, 20)
tl.lt(150)
tl.circle(-40*R, 120)
tl.circle(-150*R, 22)
tl.circle(-300*R, 23)
tl.circle(-600*R, 36)
tl.rt(90)
tl.fd(20*R)
tl.rt(90)
tl.circle(580*R, 36)
tl.circle(270*R, 20)
tl.circle(90*R, 40)
tl.circle(35*R, 115)
tl.rt(150)
tl.fd(90*R)
tl.circle(100*R, 25)
tl.circle(35*R, 115)
tl.rt(115)
tl.fd(105*R)
tl.circle(100*R, 25)
tl.circle(60*R, 110)
tl.rt(145)
tl.fd(105*R)
tl.circle(90*R, 30)
tl.circle(35*R, 100)
tl.rt(120)
tl.fd(70*R)
tl.circle(450*R, 20)
tl.circle(30*R, 110)
tl.circle(300*R, 10)
tl.rt(121)
tl.circle(450*R, 25)
tl.lt(130)
tl.circle(150*R, 8)
tl.circle(700*R, 8)
tl.circle(-700*R, 40)
tl.fd(220*R)
tl.circle(510*R, 20)
tl.circle(115*R, 80)
tl.end_fill()
tl.seth(103)
tl.pu()
tl.fd(260*R)
tl.rt(50)
tl.pd()
tl.begin_fill()
tl.lt(3)
tl.circle(-780*R, 18)		# 后翅膀
tl.fd(150*R)
tl.circle(750*R, 30)
tl.circle(-200*R, 30)
tl.rt(95)
tl.circle(-150*R, 30)
tl.circle(-250*R, 30)
tl.lt(120)
tl.fd(50*R)
tl.circle(-30*R, 105)
tl.circle(-200*R, 20)
tl.circle(-400*R, 10)
tl.lt(140)
tl.circle(-270*R, 10)
tl.rt(100)
tl.circle(-150*R, 50)
tl.circle(-4*R, 150)
tl.circle(-200*R, 10)
tl.circle(25*R, 120)
tl.circle(200*R, 5)
tl.rt(125)
tl.circle(800*R, 5)
tl.circle(400*R, 7)
tl.circle(200*R, 15)
tl.lt(90)
tl.circle(200*R, 25)
tl.rt(125)
tl.circle(400*R, 20)
tl.circle(150*R, 22)
tl.lt(107)
tl.circle(80*R, 35)
tl.circle(-790*R, 35)
tl.circle(780*R, 24.5)
tl.end_fill()
tl.pu()
# 绘制文字
tl.goto(-200, -80)		# 坐标移至(-200, 250)文字中心处
tl.write('衔\n着', align='center', font=('汉仪行楷繁', 30))
tl.goto(-240, -160)		# 坐标移至(-200, 250)文字中心处
tl.write('橄\n榄\n枝\n的', align='center', font=('汉仪行楷繁', 30))
tl.goto(-280, -160)		# 坐标移至(-200, 250)文字中心处
tl.write('和\n平\n鸽', align='center', font=('汉仪行楷繁', 30))
tl.goto(-340,-270)
tl.write('任\n寅\n兰\n月\n瑞\n林\n制\n作\n于\n杭\n州',font=('华文行楷',16,'normal'))
tl.pensize(1)			# 绘印章
tl.seth(-45)
tl.goto(-345,-300)
tl.pd()
tl.color('red')			# 写标题的颜色(蓝色)
tl.circle(20,360,4)		# 绘外框
tl.lt(45)
tl.fd(3)
tl.write('瑞\n林',font=('印章篆体',10,'normal'))
tl.fd(13)
tl.write('张\n印',font=('印章篆体',10,'normal'))

tl.ht()				# 隐藏turtle形状
tl.done()

执行结果:(见图7)

 

图7 用turtle库绘制的“衔橄榄枝的和平鸽”

猜你喜欢

转载自blog.csdn.net/hz_zhangrl/article/details/128528945