#!/usr/bin/python3 # ==================================================================== # create an animated GIF file # ==================================================================== import math from PIL import Image, ImageDraw # -------------------------------------------------------------------- # ---- convert x,y Cartesian coordinates to image coordinates # ---- Cartesian coordinate's origin is in the center of the image # -------------------------------------------------------------------- def coord_convert(cx,cy,image_size): wx = image_size[0]/2 + cx wy = image_size[1]/2 - cy return (wx,wy) # -------------------------------------------------------------------- # create a new image for the GIF # -------------------------------------------------------------------- def new_image(angle,radius,image_size): # ---- new image image = Image.new('RGB', image_size, 'white') # ---- create a draw object draw = ImageDraw.Draw(image) # ---- draw x axis xy = (0,image_size[1]/2,image_size[0],image_size[1]/2) draw.line(xy,fill='black',width=2) # ---- draw y axis xy = (image_size[0]/2,0,image_size[0]/2,image_size[1]) draw.line(xy,fill='black',width=2) # ---- draw a circle (x1 <= x2 and y1 <= y2) x1,y1 = coord_convert(-radius,radius,image_size) x2,y2 = coord_convert(radius,-radius,image_size) xy = (x1,y1,x2,y2) ##print(xy) draw.ellipse(xy, outline='black', fill=None, width=3) # ---- draw the point on the circle and # ---- perpendicular lines to the axes rad = math.radians(angle) x = raidus * math.cos(rad) y = raidus * math.sin(rad) # ---- draw horizontal line wx1,wy1 = coord_convert(0,y,image_size) wx2,wy2 = coord_convert(x,y,image_size) xy = (wx1,wy1,wx2,wy2) color = 'black' if x < 0: color = 'red' draw.line(xy,fill=color,width=2) # ---- draw vertical line wx1,wy1 = coord_convert(x,0,image_size) wx2,wy2 = coord_convert(x,y,image_size) xy = (wx1,wy1,wx2,wy2) color = 'black' if y < 0: color = 'red' draw.line(xy,fill=color,width=2) # ---- draw dot on the circle wx,wy = coord_convert(x,y,image_size) xy = (wx-6,wy-6,wx+6,wy+6) draw.ellipse(xy, outline='black', fill='black', width=0) return image # -------------------------------------------------------------------- # ---- make animated GIF with multiple images # -------------------------------------------------------------------- def make_gif(raidus,image_size,file_name): c = 0 frames = [] # ---- create and image for each angle in the loop for angle in range(0,360,5): c += 1 frames.append(new_image(angle,raidus,image_size)) # ---- collect the images into a GIF frame_one = frames[0] frame_one.save(file_name,format='GIF', append_images=frames[1:len(frames)], save_all=True, duration=200, loop=0) # ---- return the image count in the GIF return c # -------------------------------------------------------------------- # ---- main # -------------------------------------------------------------------- if __name__ == "__main__": raidus = 300.0 image_size = (800,800) file_name = './gif-images/circle.gif' c = make_gif(raidus,image_size,file_name) print() print(f'{c} images in GIF file {file_name}')