#!/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}')