I am trying to write a code where I can move two circles around using left mouse button. Most of the code is working, but I am missing one part; There should be a minimum distance of 100 pixels between the circles (not allowed to bring them closer apart than that). I tried using while length > 70 with the function def mouseMoved(self, event) but it did not work. I hope someone can help me on my way.
from tkinter import *
import math
class Circle:
def __init__(self, x, y, radius):
self.x = x
self.y = y
self.radius = radius
def isInside(self, x, y):
return distance(self.x, self.y, x, y) <= self.radius
class MainGUI:
def __init__(self):
window = Tk()
window.title("Two Balls")
self.canvas = Canvas(width = 400, height = 250)
self.canvas.pack()
self.c1 = Circle(20, 20, 20)
self.c2 = Circle(120, 50, 20)
self.canvas.create_line(self.c1.x, self.c1.y, self.c2.x, self.c2.y, tags = "line")
self.getLength()
self.paint(self.c1, "red", "c1")
self.paint(self.c2, "red", "c2")
self.canvas.bind("<B1-Motion>", self.mouseMoved)
window.mainloop()
def getLength(self):
length = round(math.sqrt((self.c1.x-self.c2.x)**2 (self.c1.y-self.c2.y)**2), 2)
self.canvas.create_text((self.c1.x self.c2.x)/2, (self.c1.y self.c2.y)/2, text = length, tags = "text")
return length
def mouseMoved(self, event):
self.canvas.delete("line")
self.canvas.delete("text")
if self.c2.isInside(event.x, event.y):
self.c2.x = event.x
self.c2.y = event.y
self.canvas.delete("c2")
self.paint(self.c2, "red", "c2")
if self.c1.isInside(event.x, event.y):
self.c1.x = event.x
self.c1.y = event.y
self.canvas.delete("c1")
self.paint(self.c1, "red", "c1")
self.canvas.create_line(self.c1.x, self.c1.y, self.c2.x, self.c2.y, tags = "line")
self.getLength()
def paint(self, c, color, tags = "stable"):
self.canvas.create_oval(c.x - c.radius, c.y - c.radius, c.x c.radius, c.y c.radius, fill = color, tags = tags)
def distance(x1, y1, x2, y2):
return ((x1 - x2) * (x1 - x2) (y1 - y2) * (y1 - y2)) ** 0.5
MainGUI()
CodePudding user response:
You need to calculate the distance between the two circles after one of them is moved, perform the actual move only if the distance is greater than 100 pixels:
def mouseMoved(self, event):
f2 = self.c2.isInside(event.x, event.y)
f1 = self.c1.isInside(event.x, event.y)
# Is one of the circles is selected?
if f1 or f2:
# calculate the distance between the two circles after one of them is moved
if f1:
length = distance(event.x, event.y, self.c2.x, self.c2.y)
else:
length = distance(event.x, event.y, self.c1.x, self.c1.y)
# Only perform the move if the distance > 100 pixels
if length > 100:
self.canvas.delete("text")
self.canvas.delete("line")
if f2:
self.c2.x = event.x
self.c2.y = event.y
self.canvas.delete("c2")
self.paint(self.c2, "red", "c2")
else:
self.c1.x = event.x
self.c1.y = event.y
self.canvas.delete("c1")
self.paint(self.c1, "red", "c1")
self.canvas.create_line(self.c1.x, self.c1.y, self.c2.x, self.c2.y, tags="line")
self.getLength(length)
CodePudding user response:
The problem is with the indentation
from tkinter import *
import math
class Circle:
def __init__(self, x, y, radius):
self.x = x
self.y = y
self.radius = radius
def isInside(self, x, y):
return distance(self.x, self.y, x, y) <= self.radius
class MainGUI:
def __init__(self):
window = Tk()
window.title("Two Balls")
self.canvas = Canvas(width = 400, height = 250)
self.canvas.pack()
self.c1 = Circle(20, 20, 20)
self.c2 = Circle(120, 50, 20)
self.canvas.create_line(self.c1.x, self.c1.y, self.c2.x, self.c2.y, tags = "line")
self.getLength()
self.paint(self.c1, "red", "c1")
self.paint(self.c2, "red", "c2")
self.canvas.bind("<B1-Motion>", self.mouseMoved)
window.mainloop()
def getLength(self):
length = round(math.sqrt((self.c1.x-self.c2.x)**2 (self.c1.y-self.c2.y)**2), 2)
self.canvas.create_text((self.c1.x self.c2.x)/2, (self.c1.y self.c2.y)/2, text = length, tags = "text")
return length
def mouseMoved(self, event):
self.canvas.delete("line")
self.canvas.delete("text")
if self.c2.isInside(event.x, event.y):
self.c2.x = event.x
self.c2.y = event.y
self.canvas.delete("c2")
self.paint(self.c2, "red", "c2")
if self.c1.isInside(event.x, event.y):
self.c1.x = event.x
self.c1.y = event.y
self.canvas.delete("c1")
self.paint(self.c1, "red", "c1")
self.canvas.create_line(self.c1.x, self.c1.y, self.c2.x, self.c2.y, tags = "line")
self.getLength()
def paint(self, c, color, tags = "stable"):
self.canvas.create_oval(c.x - c.radius, c.y - c.radius, c.x c.radius, c.y c.radius, fill = color, tags = tags)
def distance(x1, y1, x2, y2):
return ((x1 - x2) * (x1 - x2) (y1 - y2) * (y1 - y2)) ** 0.5
MainGUI()
