在 Tkinter Python 中在斜线上绘制矩形

问题描述 投票:0回答:1

我有一个显示物体运动的大项目。我根据彼此绘制了许多形状,但这个对我来说有点棘手。我花了很多天来实现它,但我无法正确绘制它。如果有人给我看一个小演示,剩下的我就可以自己完成。

我有一条有 2 个端点的线。 (x1,y1)(x2,y2) s.t.所有 4 个参数都可以随着 y2 始终大于 y1 的条件而动态变化。换句话说,线的端点始终指向下方。我需要在绘制的线上滑动一个具有给定 widthheight 的矩形。斜线上的滑动位置也由用户给出。我们将其称为位置。位置 0 点是下图中矩形左角与 x1,y1 相接触的位置。我画了上面解释的内容。上面一共有7个参数。

滑动矩形必须始终位于所画线的右侧。

总共可能有3种情况。其中 2 个如上所示,我没有画垂直线,其中 x1=x2,因为很容易想象它会是什么样子。

如果有人向我展示如何在 Tkinter 中做到这一点,我将非常感激。

提前致谢!

python tkinter canvas shapes trigonometry
1个回答
0
投票

下面的代码块完成了我上面的要求。

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()
© www.soinside.com 2019 - 2024. All rights reserved.