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