要求:
- 显示窗口,接收用户点击
- 每点击4次记录为一个四边形顶点
- 判断新绘制的四边形是否与其他四边形重叠,重叠则使用红色绘制新四边形,否则使用绿色
- 对用户点击的顶点坐标排序,避免边与边相交的情况
程序运行效果:
以下列举了本文中实现代码的替换方案,可根据需要选择
- 绘制多边形(本文使用的是排序后的四个点坐标)
self.canvas.create_polygon(coords, outline=color, width=1, fill="")
此处可采用OpenCV的cv2.polylines()函数,示例如下:
cv2.polylines(img,[pts],True,(0,255,255),2)
- 判断多边形是否相交
本文是采用的是遍历已绘制的多边形,使用Shapely的intersects方法来检查当前绘制的多边形与已绘制的多边形是否重叠。该方法使用示例如下:
polygon1.intersects(polygon2)
具体代码如下:
import tkinter as tk
from math import atan2
from shapely.geometry import Polygon
class DrawingApp:
def __init__(self, root):
self.root = root
self.root.title("多边形绘制程序")
self.canvas = tk.Canvas(root, width=600, height=400, bg="white")
self.canvas.pack()
self.polygons = []
self.current_polygon = None
self.canvas.bind("<Button-1>", self.on_click)
def on_click(self, event):
x, y = event.x, event.y
if self.current_polygon is None:
self.current_polygon = [(x, y)]
self.draw_point(x, y)
else:
self.current_polygon.append((x, y))
self.draw_point(x, y)
if len(self.current_polygon) == 4:
self.sort_vertices()
self.draw_polygon()
self.current_polygon = None
def draw_point(self, x, y):
self.canvas.create_oval(x-2, y-2, x+2, y+2, fill="black")
def sort_vertices(self):
# 对多边形的顶点进行排序,确保按照逆时针或顺时针顺序排列
centroid = (sum(x for x, y in self.current_polygon) / 4, sum(y for x, y in self.current_polygon) / 4)
sorted_vertices = sorted(self.current_polygon, key=lambda v: (atan2(v[1] - centroid[1], v[0] - centroid[0])))
self.current_polygon = sorted_vertices
def draw_polygon(self):
coords = self.current_polygon
poly = Polygon(coords)
color = "red" if self.check_overlap(poly) else "green"
self.polygons.append((poly, color))
self.canvas.create_polygon(coords, outline=color, width=1, fill="")
def check_overlap(self, new_poly):
for poly, _ in self.polygons:
if new_poly.intersects(poly):
return True
return False
def main():
root = tk.Tk()
app = DrawingApp(root)
root.mainloop()
if __name__ == "__main__":
main()