Reputation: 143
I have a big project that shows movement of objects. I draw many of shapes according to each other but this one is little bit tricky for me. I spent many days to achieve it but I couldn't draw it correctly. If anyone shows me a small demo, I can do the rest by myself.
I have a line with 2 endpoints. (x1,y1) and (x2,y2) s.t. all 4 parameters may dynamically change with the condition y2 is always greater than y1. In other words, endpoint of the line is always pointing down. I need to slide a rectangle with the given width and height on the drawn line. Sliding position on the angled line is also given by the user. Let's call it as position. Position 0 point is where the left corner of the rectangle touches x1,y1 in the below picture. I drew what I explained above. There are total 7 parameters bolted above.
Sliding rectangle must be always at the right side of the drawn line.
Total, there could be 3 cases. 2 of them are shown above, and I didn't draw vertical line case where x1=x2 since it's quite easy to imagine how it is going to look like.
If anyone shows me how to do it in Tkinter, I would be very appreciated.
Thanks in advance!
Upvotes: 0
Views: 90
Reputation: 143
The code block below does what I asked above.
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()
Upvotes: 1