Python turtle 绘制抛物线

Python turtle 绘制抛物线

Python turtle 库未提供画抛物线的函数,但可通过解析函数( y 2 = 2 p x y^2=2px y2=2px x 2 = 2 p y x^2=2py x2=2py)描点连线实现抛物线的绘制。所计算的点越多,图像就越接近抛物线。

具体实现

# 海龟绘图绘制抛物线
# author: 小喾苦
# date: 2022-5-14
# author's github: https://github.com/xkk1
# author's bilibili: https://space.bilibili.com/513689605
import turtle


if "turtle" not in locals().keys():
    turtle = None

def parabola_x(begin, end, step=10, endstart=False, t=turtle):
    """
    绘制开口朝向x轴(左右开口)的抛物线 y²=2px 的一半
    parabola_x(begin, end, step=10, endstart=False, t=turtle)
        begin 开始坐标、抛物线的顶点(x₁,y₁)
        end 结束坐标(x₂,y₂)
        step 精度,为一个整数,数越小精度越高速度越慢
        endstart 是否从结束坐标开始绘制(True是\False否)
        t turtle库的名称
    """
    p = ( (end[1]-begin[1])**2/abs(end[0]-begin[0]) )/2 # 计算抛物线p的大小
    if end[0]-begin[0] < 0: # 确定抛物线p的正负号
        p = -p
    if begin[1] > end[1]: # 确定精度的正负号
        step = -step
    t.pu() # 抬笔
    if endstart == True: # 如果从结束坐标开始绘制
        t.goto(end[0], end[1]) # 前往结束坐标
        start = end[1]+1
        stop = begin[1]
        step = -step
    else:
        start = begin[1]
        stop = end[1]+1
        t.goto(begin[0], begin[1]) # 前往初始坐标
    t.pd() # 放笔
    for y in range(start ,stop ,step): # 相当于画函数图像的列表
        x = ((y-begin[1])**2)/(2*p) + begin[0] # 计算x坐标
        t.goto(x, y) # 相当于画函数图像的描点、连线
    if endstart == True:
        t.goto(begin[0], begin[1]) # 前往初始坐标
    else:
        t.goto(end[0], end[1]) # 前往结束坐标
    return None

def parabola_y(begin, end, step=10, endstart=False, t=turtle):
    """
    绘制开口朝向y轴(上下开口)的抛物线 x²=2py 的一半
    parabola_y(begin, end, step=10, t=turtle)
        begin 开始坐标、抛物线的顶点(x₁,y₁)
        end 结束坐标(x₂,y₂)
        step 精度,为一个整数,数越小精度越高速度越慢
        endstart 是否从结束坐标开始绘制(True是\False否)
        t turtle库的名称
    """
    p = ( (end[0]-begin[0])**2/abs(end[1]-begin[1]) )/2 # 计算抛物线p的大小
    if end[1]-begin[1] < 0: # 确定抛物线p的正负号
        p = -p
    if begin[0] > end[0]: # 确定精度的正负号
        step = -step
    t.pu() # 抬笔
    if endstart == True: # 如果从结束坐标开始绘制
        t.goto(end[0], end[1]) # 前往结束坐标
        start = end[0]+1
        stop = begin[0]
        step = -step
    else:
        start = begin[0]
        stop = end[0]+1
        t.goto(begin[0], begin[1]) # 前往初始坐标
    t.pd() # 放笔
    for x in range(start ,stop ,step): # 相当于画函数图像的列表
        y = ((x-begin[0])**2)/(2*p) + begin[1] # 计算y坐标
        t.goto(x, y) # 相当于画函数图像的描点、连线
    if endstart == True:
        t.goto(begin[0], begin[1]) # 前往初始坐标
    else:
        t.goto(end[0], end[1]) # 前往结束坐标
    return None

调用

通过调用函数 parabola_x() 绘制左右开口的抛物线,调用函数 parabola_y()绘制上下开口的抛物线。例如:

绘制效果

parabola_y((-400,400), (400,0)) # 绘制以(-400,400)开始(400,0)结束开口朝向下的抛物线
parabola_x((-400,0), (400,-400),step=20 ,endstart=True) # 绘制以(-400,0)开始(400,-400)结束开口朝向右的抛物线(其中每隔20像素横坐标计算一次纵坐标,从结束向起点绘制)

示例

绘制数学抛物线效果

# 海龟绘图绘制数学抛物线
# author: 小喾苦
# date: 2022-5-14
# author's github: https://github.com/xkk1
# author's bilibili: https://space.bilibili.com/513689605
import turtle as t


if "turtle" not in locals().keys():
    turtle = None

def parabola_x(begin, end, step=10, endstart=False, t=turtle):
    """
    绘制开口朝向x轴(左右开口)的抛物线 y²=2px 的一半
    parabola_x(begin, end, step=10, endstart=False, t=turtle)
        begin 开始坐标、抛物线的顶点(x₁,y₁)
        end 结束坐标(x₂,y₂)
        step 精度,为一个整数,数越小精度越高速度越慢
        endstart 是否从结束坐标开始绘制(True是\False否)
        t turtle库的名称
    """
    p = ( (end[1]-begin[1])**2/abs(end[0]-begin[0]) )/2 # 计算抛物线p的大小
    if end[0]-begin[0] < 0: # 确定抛物线p的正负号
        p = -p
    if begin[1] > end[1]: # 确定精度的正负号
        step = -step
    t.pu() # 抬笔
    if endstart == True: # 如果从结束坐标开始绘制
        t.goto(end[0], end[1]) # 前往结束坐标
        start = end[1]+1
        stop = begin[1]
        step = -step
    else:
        start = begin[1]
        stop = end[1]+1
        t.goto(begin[0], begin[1]) # 前往初始坐标
    t.pd() # 放笔
    for y in range(start ,stop ,step): # 相当于画函数图像的列表
        x = ((y-begin[1])**2)/(2*p) + begin[0] # 计算x坐标
        t.goto(x, y) # 相当于画函数图像的描点、连线
    if endstart == True:
        t.goto(begin[0], begin[1]) # 前往初始坐标
    else:
        t.goto(end[0], end[1]) # 前往结束坐标
    return None

def parabola_y(begin, end, step=10, endstart=False, t=turtle):
    """
    绘制开口朝向y轴(上下开口)的抛物线 x²=2py 的一半
    parabola_y(begin, end, step=10, t=turtle)
        begin 开始坐标(x₁,y₁)
        end 结束坐标(x₂,y₂)
        step 精度,为一个整数,数越小精度越高速度越慢
        endstart 是否从结束坐标开始绘制(True是\False否)
        t turtle库的名称
    """
    p = ( (end[0]-begin[0])**2/abs(end[1]-begin[1]) )/2 # 计算抛物线p的大小
    if end[1]-begin[1] < 0: # 确定抛物线p的正负号
        p = -p
    if begin[0] > end[0]: # 确定精度的正负号
        step = -step
    t.pu() # 抬笔
    if endstart == True: # 如果从结束坐标开始绘制
        t.goto(end[0], end[1]) # 前往结束坐标
        start = end[0]+1
        stop = begin[0]
        step = -step
    else:
        start = begin[0]
        stop = end[0]+1
        t.goto(begin[0], begin[1]) # 前往初始坐标
    t.pd() # 放笔
    for x in range(start ,stop ,step): # 相当于画函数图像的列表
        y = ((x-begin[0])**2)/(2*p) + begin[1] # 计算y坐标
        t.goto(x, y) # 相当于画函数图像的描点、连线
    if endstart == True:
        t.goto(begin[0], begin[1]) # 前往初始坐标
    else:
        t.goto(end[0], end[1]) # 前往结束坐标
    return None


# 示例
t.setup(850,850) # 设置屏幕大小
t.title("Python turtle海龟绘图绘制数学抛物线 by 小喾苦") # 设置窗口标题
t.pensize(5) # 设置画笔粗细

#画坐标轴
t.speed(10) # 设置画笔速度
def draw_axis(string=""):
    "画一个做坐标轴"
    t.fd(400)
    t.rt(90)
    t.pu()
    t.fd(40)
    t.write(string, font=("Arial", 20, "normal"))
    t.bk(40)
    t.pd()
    t.lt(90)
    t.lt(135)
    t.fd(20)
    t.bk(20)
    t.lt(90)
    t.fd(20)
    t.bk(20)
    t.rt(45)
    t.fd(800)
    t.bk(400)
    t.rt(180)

draw_axis("X") # 画x轴
t.lt(90)
draw_axis("y") # 画y轴
t.lt(135)
t.pu()
t.fd(40)
t.write("o", font=("Arial", 20, "normal")) # 标原点


# 画抛物线
t.speed(6) # 设置画笔速度
t.pencolor("blue")  # 设置画笔颜色
parabola_y((0,0), (-400,400), endstart=True,t=t) # 绘制开口朝向y轴的抛物线
parabola_y((0,0), (400,400),t=t) # 绘制开口朝向y轴的抛物线

t.pencolor("red")  # 设置画笔颜色
parabola_x((0,0), (400,400), step=20 ,endstart=True,t=t) # 绘制开口朝向x轴的抛物线
parabola_x((0,0), (400,-400), step=20 ,t=t) # 绘制开口朝向x轴的抛物线

t.done() # 开始事件循环

附 Python turtle 官方文档链接 https://docs.python.org/zh-cn/3.8/library/turtle.html

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值