как закрасить пересечение прямоугольников
рисуются 2 или несколько прямоугольников нужно по нажатию кнопки закрасить их пересечение
from tkinter import *
def is_cross(a,b):
ax1,ay1,ax2,ay2 = a[0],a[1],a[2],a[3] # прямоугольник А
bx1, by1, bx2, by2 = b[0], b[1], b[2], b[3] # прямоугольник B
xA = [ax1,ax2] # координаты x обеих точек прямоугольника А
xB = [bx1,bx2] # координаты x обеих точке прямоугольника В
yA = [ay1, ay2] # координаты x обеих точек прямоугольника А
yB = [by1, by2] # координаты x обеих точек прямоугольника В
if max(xA)<min(xB) or max(yA) < min(yB) or min(yA) > max(yB):
return False # не пересекаются
elif max(xA)>min(xB) and min(xA)<min(xB):
dx = max(xA)-min(xB)
return True # пересекаются
else:
return True # пересекаются
def click(click_event):
global prev
try:
canvas.create_rectangle(prev.x, prev.y, click_event.x, click_event.y, width=2)
except:
prev = click_event
return
prev = click_event
master = Tk()
canvas = Canvas(master, width=600, height=300)
canvas.pack(padx=20, pady=20)
canvas.bind('<Button-1>', click)
but1 = Button(master, text='ок', command=is_cross );
mainloop()
Ответы (1 шт):
Автор решения: MiniMax
→ Ссылка
Вариант № 1.1
Прямоугольники рисуются двумя кликами мыши: первый клик - начало, второй клик - конец. Для хранения координат прямоугольников используются обыкновенный список.
#!/usr/bin/python3
import tkinter as tk
start = None
rectangles = []
def is_cross():
global rectangles
a, b = rectangles
a_left, a_bottom, a_right, a_top = a
b_left, b_bottom, b_right, b_top = b
if not (a_left >= b_right or a_bottom <= b_top or
b_left >= a_right or b_bottom <= a_top):
left = max(a_left, b_left)
right = min(a_right, b_right)
bottom = min(a_bottom, b_bottom)
top = max(a_top, b_top)
rectangle = (left, bottom, right, top)
canvas.create_rectangle(rectangle, fill="red")
rectangles = []
def click(click_event):
global start, rectangles
if start is None:
start = click_event
else:
left, right = (start.x, click_event.x) if start.x < click_event.x else (click_event.x, start.x)
top, bottom = (start.y, click_event.y) if start.y < click_event.y else (click_event.y, start.y)
rectangle = (left, bottom, right, top)
canvas.create_rectangle(rectangle)
rectangles.append(rectangle)
start = None
master = tk.Tk()
canvas = tk.Canvas(master, width=600, height=300)
canvas.pack()
canvas.bind('<Button-1>', click)
but1 = tk.Button(master, text='ок', command=is_cross);
but1.pack()
tk.mainloop()
Вариант № 1.2
В отличии от предыдущего варианта, прямоугольники (координаты) не хранятся в списке, а находятся по заданному тегу, после чего из них извлекаются координаты.
import tkinter as tk
start = None
def is_cross():
a, b = canvas.find_withtag("rctnlg")[-2:]
a_left, a_top, a_right, a_bottom = canvas.coords(a)
b_left, b_top, b_right, b_bottom = canvas.coords(b)
if not (a_left >= b_right or a_bottom <= b_top or
b_left >= a_right or b_bottom <= a_top):
left = max(a_left, b_left)
top = max(a_top, b_top)
right = min(a_right, b_right)
bottom = min(a_bottom, b_bottom)
rectangle = (left, top, right, bottom)
canvas.create_rectangle(rectangle, fill="red")
def click(click_event):
global start
if start is None:
start = click_event
else:
left, right = (start.x, click_event.x) if start.x < click_event.x else (click_event.x, start.x)
top, bottom = (start.y, click_event.y) if start.y < click_event.y else (click_event.y, start.y)
coords = (left, top, right, bottom)
canvas.create_rectangle(coords, tags=("rctnlg"))
start = None
master = tk.Tk()
canvas = tk.Canvas(master, width=600, height=300)
canvas.pack()
canvas.bind('<Button-1>', click)
but1 = tk.Button(master, text='ок', command=is_cross);
but1.pack()
tk.mainloop()
Вариант № 2
Прямоугольники рисуются с помощью растягивания мышкой. Взял и доработал код из этого ответа
import tkinter as tk
class App(tk.Frame):
def __init__(self, parent):
super().__init__(parent)
self._createVariables(parent)
self._createCanvas()
self._createCanvasBinding()
self.btn1 = tk.Button(self.parent, text='ок', command=self.is_cross);
self.btn1.grid(row=1, column=0)
def is_cross(self):
a, b = self.rectangles
a_left, a_bottom, a_right, a_top = a
b_left, b_bottom, b_right, b_top = b
if not (a_left >= b_right or a_bottom <= b_top or
b_left >= a_right or b_bottom <= a_top):
left = max(a_left, b_left)
right = min(a_right, b_right)
bottom = min(a_bottom, b_bottom)
top = max(a_top, b_top)
rectangle = (left, bottom, right, top)
self.canvas.create_rectangle(rectangle, fill="red")
self.rectangles = []
def _createVariables(self, parent):
self.parent = parent
self.rect_x0 = 0
self.rect_y0 = 0
self.rect_x1 = 0
self.rect_y1 = 0
self.rectid = None
self.rectangles = []
def _createCanvas(self):
self.canvas = tk.Canvas(self.parent, width = 800, height = 400, bg = "white" )
self.canvas.grid(row=0, column=0, sticky='nsew')
def _createCanvasBinding(self):
self.canvas.bind("<Button-1>", self.startRect )
self.canvas.bind("<ButtonRelease-1>", self.stopRect )
self.canvas.bind("<B1-Motion>", self.movingRect )
def startRect(self, event):
#Translate mouse screen x0,y0 coordinates to canvas coordinates
self.rect_x0 = self.canvas.canvasx(event.x)
self.rect_y0 = self.canvas.canvasy(event.y)
#Create rectangle
self.rectid = self.canvas.create_rectangle(self.rect_x0, self.rect_y0, self.rect_x0, self.rect_y0)
def movingRect(self, event):
#Translate mouse screen x1,y1 coordinates to canvas coordinates
self.rect_x1 = self.canvas.canvasx(event.x)
self.rect_y1 = self.canvas.canvasy(event.y)
#Modify rectangle x1, y1 coordinates
self.canvas.coords(self.rectid, self.rect_x0, self.rect_y0,
self.rect_x1, self.rect_y1)
def stopRect(self, event):
#Translate mouse screen x1,y1 coordinates to canvas coordinates
self.rect_x1 = self.canvas.canvasx(event.x)
self.rect_y1 = self.canvas.canvasy(event.y)
#Modify rectangle x1, y1 coordinates
self.canvas.coords(self.rectid, self.rect_x0, self.rect_y0,
self.rect_x1, self.rect_y1)
left, right = (self.rect_x0, self.rect_x1) if self.rect_x0 < self.rect_x1 else (self.rect_x1, self.rect_x0)
top, bottom = (self.rect_y1, self.rect_y0) if self.rect_y1 < self.rect_y0 else (self.rect_y0, self.rect_y1)
rectangle = (left, bottom, right, top)
self.rectangles.append(rectangle)
if __name__ == "__main__":
root = tk.Tk()
root.geometry("800x500")
app = App(root)
root.mainloop()
