我的代码中的逻辑不是绝对的。我尝试通过将直径端点作为 1)距原点最远的点和 2)距 (1) 最远的点来找到边界圆的中心坐标和半径。 但这并不能在所有情况下给我实际的结果。 请不要介意缩进(我使用制表符并复制了我的代码。)
from tkinter import *
class point2D:
def __init__(self, x=0, y=0):
self.__x = x
self.__y = y
def x(self):
return self.__x
def y(self):
return self.__y
def setx(self, x):
self.__x = x
def sety(self, y):
self.__y = y
def __str__(self):
return f"({self.__x}, {self.__y})"
def distance(self, other):
return ((self.__x-other.__x)**2 + (self.__y-other.__y)**2) ** 0.5
class box:
def __init__(self):
root = Tk()
root.title("Bounding Circle")
width, height = 600, 600
root.geometry(f"{width}x{height}")
self.canvas = Canvas(root, width=width, height=height, bg="white")
self.canvas.pack()
self.canvas.bind("<Button-1>", self.addpoint)
self.origin = point2D()
self.points = []
root.mainloop()
def addpoint(self, event):
radius = 5
self.canvas.create_oval(event.x - radius, event.y - radius,
event.x + radius, event.y + radius, fill = "black")
self.points.append(point2D(event.x, event.y))
self.getboundingcircle()
def getboundingcircle(self):
if len(self.points) == (1 or 0):
return
#Finding the point farthest from origin (0,0 in canvas)
d, start = self.points[0].distance(self.origin), 0
for i in range(1, len(self.points)):
x = self.points[i].distance(self.origin)
if x > d:
d = x
start = i
#Finding the point farthest from points[start]
d, end = 0, 0
for i in range(len(self.points)):
if i == start:
continue
x = self.points[i].distance(self.points[start])
if x > d:
d = x
end = i
center_x = (self.points[start].x() + self. points[end].x()) / 2
center_y = (self.points[start].y() + self. points[end].y()) / 2
radius = self.points[start].distance(self.points[end]) / 2
self.canvas.delete("circle")
self.canvas.create_oval(center_x - radius, center_y - radius,
center_x + radius, center_y + radius, outline = "red", tags = "circle")
box()
我认为修改盒子类中的
getboundingcircle
函数可能会达到你想要的效果。我不太明白这是否是预期的行为,但这是一种可能的行为。
你应该在开始时导入数学:
from tkinter import *
import math
然后替换你当前的函数:
def getboundingcircle(self):
if len(self.points) < 2:
return
# Find the two farthest points
max_dist = 0
start, end = 0, 1 # Initialize start and end
for i in range(len(self.points)):
for j in range(i + 1, len(self.points)):
dist = self.points[i].distance(self.points[j])
if dist > max_dist:
max_dist = dist
start = i
end = j
center_x = (self.points[start].x() + self.points[end].x()) / 2
center_y = (self.points[start].y() + self.points[end].y()) / 2
radius = self.points[start].distance(self.points[end]) / 2
self.canvas.delete("circle")
self.canvas.create_oval(center_x - radius, center_y - radius,
center_x + radius, center_y + radius,
outline="red", tags="circle")