#!/usr/bin/python3
# ===================================================================
# Draw spirograph
#
# The following is left for the student complete:
# Convert this program to draw a lines rather than points
# ===================================================================
import sys
import graphics as gr
import draw_axes as ax
import user_interface as ui
import coordinate_conversion as cc
from time import sleep
from math import radians, sin, cos
window_width = 801
window_height = 801
color = ['red','green','blue','black','purple']
R = 160 # default raidus of large circle
r = 20 # default raidus of small circle
d = 60 # default distance from drawing point
# to center of small circle
# -------------------------------------------------------------------
# --- calculate x,y coordinates of the spirograph drawing point
# --- return x,y as integers
# -------------------------------------------------------------------
def xy_coords(a,R,r,d):
rad = radians(a)
x = ((R-r)*cos(rad)) + (d*cos(((R-r)/r)*rad))
y = ((R-r)*sin(rad)) + (d*sin(((R-r)/r)*rad))
return (round(x),round(y))
# -------------------------------------------------------------------
# ---- draw a line
# -------------------------------------------------------------------
def draw_line(win,x1,y1,x2,y2,color):
wx1,wy1 = cc.center_to_win_coords(x1,y1,
window_width,window_height)
wx2,wy2 = cc.center_to_win_coords(x2,y2,
window_width,window_height)
l = gr.Line(gr.Point(wx1,wy1),gr.Point(wx2,wy2))
l.setWidth(3)
l.setFill(color)
l.draw(win)
# ---------------------------------------------------------------
# ---- draw a point
# ---------------------------------------------------------------
def draw_point(win,x,y,raidus=3,color='black'):
wx,wy = cc.center_to_win_coords(x,y,win.width,win.height)
c = gr.Circle(gr.Point(wx,wy),raidus)
c.setFill(color)
c.draw(win)
# -------------------------------------------------------------------
# ---- draw spirograph design
# -------------------------------------------------------------------
def draw_spirograph(win,R,r,d):
a = 0
startx,starty = xy_coords(a,R,r,d)
draw_point(win,startx,starty)
while True:
a += 1
x,y = xy_coords(a,R,r,d)
if startx == x and starty == y:
break
draw_point(win,x,y)
sleep(0.01)
# -------------------------------------------------------------------
# ---- get it from the user
# -------------------------------------------------------------------
def get_it_from_the_user(prompt,default):
ui.clear_screen()
print()
print('Enter nothing for default value')
print('Enter q or Q to quit program')
while(True):
print()
s = ui.get_user_input(prompt)
if not s:
return default
if s[0] == 'q' or s[0] == 'Q':
print()
sys.exit()
x,n = ui.is_integer(s)
if not x or n < 1:
print()
print('Illegal input value - try again')
continue
return n
# -------------------------------------------------------------------
# --- main
# -------------------------------------------------------------------
if __name__ == '__main__':
R = get_it_from_the_user(f'Enter large circle raidus [{R}]: ',R)
r = get_it_from_the_user(f'Enter small circle raidus [{r}]: ',r)
d = get_it_from_the_user(f'Enter drawing point distance [{d}]: ',d)
win = gr.GraphWin("Spirograph Design",window_width,window_height)
win.setBackground("white")
ax.draw_xy_axes(win,True)
draw_spirograph(win,R,r,d)
ui.pause()
win.close()
print()