在Tkinter中沿斜线绘制矩形
我有一个大项目,主要是展示物体的运动。我需要根据不同的形状进行绘制,但这个任务对我来说有点棘手。我花了很多天时间想要实现它,但始终没能正确绘制出来。如果有人能给我一个小示例,我就能自己完成剩下的部分。
我有一条线,两个端点分别是(x1,y1)和(x2,y2),这四个参数都是可以动态变化的,但有个条件是y2总是大于y1。换句话说,这条线的端点总是指向下方。我需要在这条线上的某个位置滑动一个给定宽度和高度的矩形。滑动的位置由用户指定,我们称之为位置。位置0是矩形的左上角与(x1,y1)接触的地方。上面我画了我所描述的内容,总共有7个参数。
滑动的矩形必须始终位于绘制的线的右侧。
总的来说,可能会有3种情况。上面展示了其中的2种,我没有画出垂直线的情况(即x1=x2),因为那种情况很容易想象出来。
如果有人能告诉我如何在Tkinter中实现这个,我将非常感激。
提前谢谢大家!
1 个回答
1
下面的代码块实现了我上面提到的功能。
import tkinter as tk
import math
def draw_line_and_rectangle():
# Clear the canvas
canvas.delete("all")
# Get user inputs for line coordinates
x1 = float(entry_x1.get())
y1 = float(entry_y1.get())
x2 = float(entry_x2.get())
y2 = float(entry_y2.get())
# Ensure y2 is greater than y1
if y2 < y1:
x1, y1, x2, y2 = x2, y2, x1, y1
# Draw the line
canvas.create_line(x1, y1, x2, y2)
# Get user inputs for rectangle dimensions and position
width = float(entry_width.get())
height = float(entry_height.get())
position = float(entry_position.get())
# Calculate the angle of the line
angle_rad = math.atan2(y2 - y1, x2 - x1)
# Calculate the length of the line
length = math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2)
# Calculate the position of the rectangle's left corner along the line
dx = position * length
# Calculate the coordinates of the rectangle's vertices
rect_angle_rad = angle_rad + math.pi / 2
rect_top_left_x = x1 - dx * math.cos(angle_rad)
rect_top_left_y = y1 - dx * math.sin(angle_rad)
rect_top_right_x = rect_top_left_x + width * math.cos(angle_rad)
rect_top_right_y = rect_top_left_y + width * math.sin(angle_rad)
rect_bottom_left_x = rect_top_left_x + height * math.cos(rect_angle_rad)
rect_bottom_left_y = rect_top_left_y + height * math.sin(rect_angle_rad)
rect_bottom_right_x = rect_bottom_left_x + width * math.cos(angle_rad)
rect_bottom_right_y = rect_bottom_left_y + width * math.sin(angle_rad)
# Calculate the mirrored coordinates of the rectangle
mirrored_rect_top_left_x = 2 * x1 - rect_top_left_x
mirrored_rect_top_left_y = 2 * y1 - rect_top_left_y
mirrored_rect_top_right_x = 2 * x1 - rect_top_right_x
mirrored_rect_top_right_y = 2 * y1 - rect_top_right_y
mirrored_rect_bottom_left_x = 2 * x1 - rect_bottom_left_x
mirrored_rect_bottom_left_y = 2 * y1 - rect_bottom_left_y
mirrored_rect_bottom_right_x = 2 * x1 - rect_bottom_right_x
mirrored_rect_bottom_right_y = 2 * y1 - rect_bottom_right_y
# Draw the mirrored rectangle
canvas.create_polygon(mirrored_rect_top_left_x, mirrored_rect_top_left_y, mirrored_rect_top_right_x,
mirrored_rect_top_right_y,
mirrored_rect_bottom_right_x, mirrored_rect_bottom_right_y, mirrored_rect_bottom_left_x,
mirrored_rect_bottom_left_y, fill='red')
# Create the main window
root = tk.Tk()
root.geometry("600x600")
root.title("Draw Line and Rectangle")
# Create a canvas
canvas = tk.Canvas(root, width=500, height=500, bg='white')
canvas.grid(row=0, column=0, columnspan=2)
# Entry widgets for line coordinates
label_x1 = tk.Label(root, text="X1:")
label_x1.grid(row=1, column=0)
entry_x1_var = tk.StringVar()
entry_x1_var.set("50") # Default value
entry_x1 = tk.Entry(root, textvariable=entry_x1_var)
entry_x1.grid(row=1, column=1)
label_y1 = tk.Label(root, text="Y1:")
label_y1.grid(row=2, column=0)
entry_y1_var = tk.StringVar()
entry_y1_var.set("50") # Default value
entry_y1 = tk.Entry(root, textvariable=entry_y1_var)
entry_y1.grid(row=2, column=1)
label_x2 = tk.Label(root, text="X2:")
label_x2.grid(row=3, column=0)
entry_x2_var = tk.StringVar()
entry_x2_var.set("350") # Default value
entry_x2 = tk.Entry(root, textvariable=entry_x2_var)
entry_x2.grid(row=3, column=1)
label_y2 = tk.Label(root, text="Y2:")
label_y2.grid(row=4, column=0)
entry_y2_var = tk.StringVar()
entry_y2_var.set("350") # Default value
entry_y2 = tk.Entry(root, textvariable=entry_y2_var)
entry_y2.grid(row=4, column=1)
# Entry widgets for rectangle dimensions and position
label_width = tk.Label(root, text="Rectangle Width:")
label_width.grid(row=5, column=0)
entry_width_var = tk.StringVar()
entry_width_var.set("60") # Default value
entry_width = tk.Entry(root, textvariable=entry_width_var)
entry_width.grid(row=5, column=1)
label_height = tk.Label(root, text="Rectangle Height:")
label_height.grid(row=6, column=0)
entry_height_var = tk.StringVar()
entry_height_var.set("30") # Default value
entry_height = tk.Entry(root, textvariable=entry_height_var)
entry_height.grid(row=6, column=1)
label_position = tk.Label(root, text="Position:")
label_position.grid(row=7, column=0)
entry_position_var = tk.StringVar()
entry_position_var.set("0.3") # Default value
entry_position = tk.Entry(root, textvariable=entry_position_var)
entry_position.grid(row=7, column=1)
# Button to draw the line and rectangle
button_draw = tk.Button(root, text="Draw Line and Rectangle", command=draw_line_and_rectangle)
button_draw.grid(row=8, column=0, columnspan=2)
root.mainloop()