You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

绘制三次贝塞尔曲线遇阻:Tkinter无法正常生成曲线

三次贝塞尔曲线绘制问题修复

我帮你找到了代码里的两个关键问题,修复后就能正常生成三次贝塞尔曲线了:

1. 核心错误:t变量赋值错误

在生成曲线的循环中,你错误地使用了之前收集控制点的循环变量i来计算t的值:

t = i/10

因为i最后一次循环后的值是3,所以每次循环t都会被固定为0.3,导致整个循环只计算了同一个坐标点,自然只能在左上角画出一小段重复的线段。

正确的做法是用当前循环的t变量(从0到10的整数)除以10,转换成0到1之间的浮点数:

t_val = t / 10.0

然后在贝塞尔公式中使用t_val代替原来的t

2. 输入逻辑的小问题

当用户第一次输入格式错误时,你第二次调用input的提示文本不正确(显示"Enter starting point...",但实际应该提示当前控制点p[i]的坐标),而且第二次输入后没有重新执行拆分和验证逻辑,可能会跳过检查直接进入转换步骤,导致程序报错。

我们可以把输入验证的逻辑统一在while True循环内,不需要额外的input调用。


修复后的完整代码

from tkinter import *
root = Tk()
window = Canvas(root, width=800, height=800)
window.pack()

def bezier_curve():
    # 创建存储控制点的空列表
    p = []
    # 循环4次获取4个控制点
    for i in range(4):
        while True:
            # 用户输入当前控制点的坐标
            p_input = input(f"Enter X,Y Coordinates for p{i}:")
            # 拆分坐标字符串
            p_components = p_input.split(',')
            # 检查是否输入了两个坐标
            if len(p_components) != 2:
                print("Missing coordinate please try again.")
                continue
            # 尝试转换为浮点数
            try:
                x = float(p_components[0])
                y = float(p_components[1])
            except ValueError:
                print(f"Invalid coordinates {p_components}, please try again.")
            else:
                p.append([x, y])
                break

    # 初始化起始点为第一个控制点(t=0时的位置)
    x_start, y_start = p[0][0], p[0][1]
    # 以0.1为步长遍历t从0到1
    for t in range(0, 11):
        t_val = t / 10.0
        # 计算贝塞尔曲线上当前t值对应的x坐标
        x = (p[0][0]*(1-t_val)**3 +
             p[1][0]*3*t_val*(1-t_val)**2 +
             p[2][0]*3*t_val**2*(1-t_val) +
             p[3][0]*t_val**3)
        # 计算贝塞尔曲线上当前t值对应的y坐标
        y = (p[0][1]*(1-t_val)**3 +
             p[1][1]*3*t_val*(1-t_val)**2 +
             p[2][1]*3*t_val**2*(1-t_val) +
             p[3][1]*t_val**3)
        # 绘制从起始点到当前点的线段
        window.create_line(x_start, y_start, x, y)
        # 更新起始点为当前点,用于下一段线段的绘制
        x_start, y_start = x, y

bezier_curve()
root.mainloop()

内容的提问来源于stack exchange,提问作者Zestyy99

火山引擎 最新活动