我试图绘制一个三次贝塞尔曲线但是,我对程序的最后一部分有困难。我似乎无法让tkinter真正画出曲线。它目前只是在tkinter窗口的左上角画一条小线,我不确定我是否以错误的方式做错。
from tkinter import *
root = Tk()
window = Canvas(root, width=800, height=800)
window.pack()
def bezier_curve():
#create empty list for points
p = []
#loops through 4 times to get 4 control points
for i in range(4):
while True:
#user input
p_input = input("Enter X,Y Coordinates for p" + str(i) + ":")
#splits the string into x and y coordinates
p_components = p_input.split(',')
#checks to see if user hasnt entered two coordinates
if len(p_components) != 2:
print("Missing coordinate please try again.")
p_input = input("Enter starting point X,Y Coordinates:")
#checks to see if the values can not be converted into floats.
try:
x = float(p_components[0])
y = float(p_components[1])
except ValueError:
print("Invalid coordinates", p_components, "please try again.")
#appends the x and y coordinates as a 2 dimensional array.
else:
p.append([float(p_components[0]), float(p_components[1])])
break
print(p[0][0])
#Start x and y coordinates, when t = 0
x_start = p[0][0]
y_start = p[0][1]
#loops through in intervals of 0.1
for t in range(0, 11, 1):
t = i/10
x=(p[0][0]*(1-t)**3+p[1][0]*3*t*(1-t)**2+p[2][0]*3*t**2*(1-t)+p[3][0]*t**3)
y=(p[0][1]*(1-t)**3+p[1][1]*3*t*(1-t)**2+p[2][1]*3*t**2*(1-t)+p[3][1]*t**3)
draw_line = window.create_line(x,y,x_start,y_start)
#updates initial values
x_start = x
y_start = y
bezier_curve()
root.mainloop()
答案 0 :(得分:2)
是;画线中的一个小错误:
#loops through in intervals of 0.1
for t in range(0, 11, 1):
t = i/10
您已将t
指定为循环变量,它应为i
。
for t in range(0, 11, 1):
^
This shoud be i
答案 1 :(得分:0)
@figbeam回答是正确的,并修复了你的问题 我发现你的输入机制很繁琐,所以我改变了它以允许在画布上点击以捕获贝塞尔曲线的控制点。
import tkinter as tk
def draw_bezier():
# Start x and y coordinates, when t = 0
x_start = control_points[0][0]
y_start = control_points[0][1]
p = control_points
# loops through
n = 50
for i in range(50):
t = i / n
x = (p[0][0] * (1-t)**3 + p[1][0] * 3 * t * (1-t)**2 + p[2][0] * 3 * t**2 * (1-t) + p[3][0] * t**3)
y = (p[0][1] * (1-t)**3 + p[1][1] * 3 * t * (1-t)**2 + p[2][1] * 3 * t**2 * (1-t) + p[3][1] * t**3)
canvas.create_line(x, y, x_start, y_start)
# updates initial values
x_start = x
y_start = y
def get_point(event):
global control_points
point = x, y = (event.x, event.y)
control_points.append(point)
canvas.create_oval(x, y, x+3, y+3)
if len(control_points) == 4:
draw_bezier()
control_points = []
if __name__ == '__main__':
control_points = []
root = tk.Tk()
canvas = tk.Canvas(root, width=800, height=800)
canvas.pack()
canvas.bind('<Button-1>', get_point)
root.mainloop()