Search code examples
turtle-graphicspython-turtle

Is there a way to store circle coordinates and move them around in python turtle?


I know it's possible to store polygons in a dictionary since they have definitive coordinates, but is there a way to store the coordinates of a circle into a dictionary and move them around? My program consists of detecting whether a mouse click is within a circle and from there, gets the coordinate of that circle moving it to wherever the user desires with another mouse click (the get.poly function, instead of moving the current circle that I already drew, makes another copy). Below is an incomplete snippet of what I want to do:

def buttonclick(x, y): # detects mouseclick
    return pen.goto(x, y)

def check(ctr, pt): # check whether the click is within the circle
    if (pt[0] - ctr[0])** 2 + (pt[1] - ctr[1])**2 < 5**2:
        return True

if check((0,5), mouseclick coordinates): # if true, move circle to next click
    # pen = the circle thats detected
    # move circle coordinates to next mouseclick
    # break 

I tried with the code provided by /u/cdlane as follows and here is what I meant by generating a new copy

pen.goto(0,0)
pen.pd()
pen.begin_poly()
pen.circle(radius)
pen.end_poly()
shape.addcomponent(pen.get_poly(), 'red', 'black')
screen.register_shape('1', shape)
pen = Turtle(shape = '1')
pen.pu()

Function does exactly what I need it to do but using an existing circle instead of generating a new copy

Function does exactly what I need it to do but using an existing circle instead of generating a new copy.


Solution

  • Rather than fix your implementation, I'm going to suggest a different implementation to achieve what you describe.

    The circles themselves will be turtles, and clicking on one will "select" it. Clicking anywhere on the screen after that will move it. However, we don't want turtle.onclick() active at the same time as screen.onclick() since they both will get invoked, causing complications. Below is my two turtle example:

    from turtle import Screen, Turtle
    from functools import partial
    
    selected = None
    
    def on_screen_click(x, y):
        global selected
    
        screen.onclick(None)
    
        selected.goto(x, y)
        outline, fill = selected.color()
        selected.color(fill, outline)
        selected = None
    
        for turtle in screen.turtles():
            turtle.onclick(partial(on_turtle_click, turtle))
    
    def on_turtle_click(self, x, y):
        global selected
    
        for turtle in screen.turtles():
            turtle.onclick(None)
    
        selected = self
        outline, fill = selected.color()
        selected.color(fill, outline)
    
        # (re)enable screen onclick handler after this function, not during
        screen.ontimer(partial(screen.onclick, on_screen_click))
    
    screen = Screen()
    
    turtle_1 = Turtle()
    turtle_1.shape('circle')
    turtle_1.color('red', 'black')
    turtle_1.penup()
    
    turtle_2 = turtle_1.clone()
    turtle_2.goto(100, 100)
    
    for turtle in screen.turtles():
        turtle.onclick(partial(on_turtle_click, turtle))
    
    screen.mainloop()