Animating an object to move in a circular path in Tkinter Animating an object to move in a circular path in Tkinter tkinter tkinter

Animating an object to move in a circular path in Tkinter


Here's something that shows one way to do what you want using the tkinter after method to update both the position of the object and the associated canvas oval object. It uses a generator function to compute coordinates along a circular path representing the orbit of one of the Celestial instances (named planet_obj1).

import mathtry:    import tkinter as tkexcept ImportError:    import Tkinter as tk  # Python 2DELAY = 100CIRCULAR_PATH_INCR = 10sin = lambda degs: math.sin(math.radians(degs))cos = lambda degs: math.cos(math.radians(degs))class Celestial(object):    # Constants    COS_0, COS_180 = cos(0), cos(180)    SIN_90, SIN_270 = sin(90), sin(270)    def __init__(self, x, y, radius):        self.x, self.y = x, y        self.radius = radius    def bounds(self):        """ Return coords of rectangle surrounding circlular object. """        return (self.x + self.radius*self.COS_0,   self.y + self.radius*self.SIN_270,                self.x + self.radius*self.COS_180, self.y + self.radius*self.SIN_90)def circular_path(x, y, radius, delta_ang, start_ang=0):    """ Endlessly generate coords of a circular path every delta angle degrees. """    ang = start_ang % 360    while True:        yield x + radius*cos(ang), y + radius*sin(ang)        ang = (ang+delta_ang) % 360def update_position(canvas, id, celestial_obj, path_iter):    celestial_obj.x, celestial_obj.y = next(path_iter)  # iterate path and set new position    # update the position of the corresponding canvas obj    x0, y0, x1, y1 = canvas.coords(id)  # coordinates of canvas oval object    oldx, oldy = (x0+x1) // 2, (y0+y1) // 2  # current center point    dx, dy = celestial_obj.x - oldx, celestial_obj.y - oldy  # amount of movement    canvas.move(id, dx, dy)  # move canvas oval object that much    # repeat after delay    canvas.after(DELAY, update_position, canvas, id, celestial_obj, path_iter)top = tk.Tk()top.title('Circular Path')canvas = tk.Canvas(top, bg='black', height=500, width=500)canvas.pack()sol_obj = Celestial(250, 250, 25)planet_obj1 = Celestial(250+100, 250, 15)sol = canvas.create_oval(sol_obj.bounds(), fill='yellow', width=0)planet1 = canvas.create_oval(planet_obj1.bounds(), fill='blue', width=0)orbital_radius = math.hypot(sol_obj.x - planet_obj1.x, sol_obj.y - planet_obj1.y)path_iter = circular_path(sol_obj.x, sol_obj.y, orbital_radius, CIRCULAR_PATH_INCR)next(path_iter)  # prime generatortop.after(DELAY, update_position, canvas, planet1, planet_obj1, path_iter)top.mainloop()

Here's what it looks like running:

animated image showing it running