前言总得说点什么。疫情在家,慕课上学习北理工嵩天等老师的《python语言程序设计》[1],觉得turtle画图,挺有意思,既然骑不了自行车,那就画个自行车。思路嘛,理了理,最后决定使用坐标点标记最为简单,此时可以利用turtle.xcor()和turtle.ycor()获得当前标记点的turtle坐标,即笛卡尔坐标的(x,y)。形状方面,都采用最简单的几何图形,对于复杂曲线可以按需使用贝塞尔曲线,这里简单起见没有涉及。
代码没有进行太多整理,思维走到哪就写到哪。
'''Draw a bike
By WDL 2020-3-6'''
import turtle as te
import numpy as np
Width=800
Height=800 #设置窗口大小
te.setup(Width,Height,200,200)
te.speed(13)
def Moveto(x,y): #移动到svg坐标下的(x,y)
te.penup()
te.goto(-Width / 2 + x, Height / 2 - y)
def Linkto(x,y):
te.goto(-Width / 2 + x, Height / 2 - y) #连接到移动到svg坐标下的(x,y)
def BickDraw(xleftwheel,yleftwheel,axisdis,radis): #画自行车
te.seth(0)#恢复初始朝向
Moveto(xleftwheel,yleftwheel)#定位左前轮位置 坐标为SVG坐标
te.color('gray', 'purple') # 指定边界颜色和填充颜色
te.pendown()
for i in range(4): #左轮
te.begin_fill()
te.fd(radis)
te.right(90)
te.circle(-1*radis, 45)
te.right(90)
te.fd(radis)
te.end_fill()
te.left(135)
Moveto(xleftwheel+8, yleftwheel)#左圆心 8为小圆半径
te.pendown()
te.seth(-90)
te.pensize(4)
te.fillcolor("black")
te.begin_fill()
te.circle(-8)
te.end_fill()
Moveto(xleftwheel+radis, yleftwheel)
te.pendown()
te.seth(-90)
te.pensize(10)
te.pencolor("black")
te.circle(-1*radis)
te.seth(0) # 恢复初始朝向
Moveto(xleftwheel+axisdis, yleftwheel) #右大圆心
te.color('gray', 'purple') # 指定边界颜色和填充颜色
te.pensize(1)
te.pendown()
for i in range(4): #右轮
te.begin_fill()
te.fd(radis)
te.right(90)
te.circle(-1*radis, 45)
te.right(90)
te.fd(radis)
te.end_fill()
te.left(135)
Moveto(xleftwheel+axisdis+8, yleftwheel)#右圆心 8为小圆半径
te.pendown()
te.seth(-90)
te.pensize(4)
te.fillcolor("black")
te.begin_fill()
te.circle(-8)
te.end_fill()
Moveto(xleftwheel+axisdis+radis, yleftwheel)
te.pendown()
te.seth(-90)
te.pensize(10)
te.pencolor("black")
te.circle(-1*radis)
Moveto(xleftwheel, yleftwheel)#画前叉
te.color('black', 'gray')
te.begin_fill()
te.pendown()
te.pensize(4)
te.seth(80)#设定角度80度
te.fd(2*radis)
te.seth(135)
te.pensize(10)
te.fd(40)
te.seth(45)
te.fd(20)
te.bk(20)
te.right(90)
te.fd(40+15+40)
te.seth(45)
te.fd(20)
te.bk(20)
te.left(90)
te.fd(40)
te.pensize(4)
Linkto(xleftwheel, yleftwheel) #连接到原始坐标点
te.end_fill()
te.seth(80) #画斜杠
te.color('black', 'gray')
te.fd(120)
xtemp=te.xcor()
ytemp=te.ycor() #记录左前叉坐标,注意此为海龟坐标
#需要考虑坐标变换 画脚蹬
xrtwheel= -Width / 2 + (xleftwheel + axisdis)
yrtwheel= Height / 2 - yleftwheel #转换为海龟坐标系
te.penup()
te.goto(xrtwheel-np.abs(xtemp-xrtwheel) / 2, yrtwheel)# 假设座子初始位置 位于距离1/2处
te.pendown()
te.seth(90)
te.fd(np.abs(ytemp - yrtwheel)) #到达相应高度
smark = te.xcor()
te.seth(0)
te.color('black','gray')
te.begin_fill()
te.fd(10)
te.seth(-90)
te.fd(np.abs(ytemp - yrtwheel) + 20)
te.seth(180)
te.fd(10)
te.goto(smark, ytemp)
te.seth(90)
for i in range(5):
te.fd(10)
te.right(90)
te.seth(-180)#画座子
te.fd(20)
te.seth(30)
te.fd(50)
te.seth(-90)
te.fd(50/2)
te.goto(smark, ytemp+10)
te.seth(-90)
te.fd(20)
#画前杠和后杠
te.goto(xtemp, ytemp)
te.goto(smark,ytemp)
te.seth(0)
te.fd(10)
te.goto(xrtwheel,yrtwheel)
te.goto(smark, ytemp)
te.end_fill()
te.penup()#画牙盘
te.goto(xtemp,ytemp)
te.pendown()
te.seth(0)
te.begin_fill()
te.fd(15)
te.goto(smark,yrtwheel)
te.goto(xtemp,ytemp)
te.end_fill()
te.penup()
te.goto(smark,yrtwheel)
te.pendown()
te.begin_fill()
te.seth(30)
te.fd(12)
te.goto(xrtwheel,yrtwheel)
te.goto(smark,yrtwheel)
te.seth(-90)
te.fd(20)
te.seth(0)
te.circle(20)
te.end_fill()
te.penup()#画脚蹬
te.goto(smark,yrtwheel)
te.pendown()
te.seth(-135)
te.fd(20+15)
te.right(90)
te.fd(20)
te.left(90)
te.fd(10)
te.left(90)
te.fd(30)
te.left(90)
te.fd(30+5)
BickDraw(300,400,250,80)
Moveto(300+250,400)
te.pendown()
te.seth(-80)
te.fd(20)
te.seth(60)
te.fd(15)
te.seth(-60)
te.fd(15)
te.seth(80)
te.fd(20)
te.penup()
te.seth(0)
te.fd(10)
te.pendown()
te.circle(-10,180)
te.seth(90)
te.fd(20)
te.penup()
te.seth(0)
te.fd(20)
te.pendown()
te.seth(-90)
te.fd(20)
te.left(90)
te.fd(10)
te.ht()
te.done()
效果自我感觉还算可以。
参考文献
[1]嵩天等,《python语言程序设计》,慕课. http://www.icourse163.org/course/BIT-268001