#!/usr/bin/python3 # ==================================================================== # draw the golden ratio spiral # # use Catesian coordinates # # | # Q2 | Q1 # --------+-------- # Q3 | Q4 # | # # Note: A golden spiral gets wider (or further from its origin) # by a factor of φ for every quarter turn it makes. # ==================================================================== import math from graphics import * import coordinate_conversion as cc GOLDENRATIO = (1 + math.sqrt(5))/2 # ------------------------------------------------------------------- # ---- draw X,Y axes (center/Cartesian coordinates) # ------------------------------------------------------------------- def draw_xy_axes(win,linewidth=1,linecolor="black"): wx = win.width # window width wy = win.height # window height wcx = round(wx/2.0) # window center X wcy = round(wy/2.0) # window center Y # ---- X axis xl = Line(Point(0,wcy),Point(wx-1,wcy)) xl.setWidth(linewidth) xl.setFill(linecolor) xl.draw(win) # ---- Y axis yl = Line(Point(wcx,0),Point(wcx,wy-1)) yl.setWidth(linewidth) yl.setFill(linecolor) yl.draw(win) # ------------------------------------------------------------------- # ---- draw a circle # ------------------------------------------------------------------- # ---- win graphics window # ---- pt graphics point # ---- dia circle diameter # ---- color circle color #-------------------------------------------------------------------- def draw_circle(win,x,y,dia=3,color='black'): x = round(x) y = round(y) wx,wy = cc.center_to_win_coords(x,y,win.width,win.height) if wx < 0 or wx > win.width or wy < 0 or wy > win.height: return None c = Circle(Point(wx,wy),dia) c.setFill(color) c.setOutline(color) c.setWidth(1) c.draw(win) return c # ------------------------------------------------------------------ # ---- draw a line # ------------------------------------------------------------------ # ---- win graphics window # ---- cx1 start of line X coordinate # ---- cy1 start of line Y coordinate # ---- cx2 end of line X coordinate # ---- cy2 end of line Y coordinate # ---- ll leg length (for documentation only) # ---- linewidth line width (pixels) # ---- linecolor line color #-------------------------------------------------------------------- def draw_line(win,cx1,cy1,cx2,cy2,ll=None, linewidth = 2, linecolor="black"): wx1,wy1 = cc.center_to_win_coords(cx1,cy1,win.width,win.height) wx2,wy2 = cc.center_to_win_coords(cx2,cy2,win.width,win.height) l = Line(Point(wx1,wy1),Point(wx2,wy2)) l.setWidth(linewidth) l.setFill(linecolor) l.draw(win) return l # ------------------------------------------------------------------ # ---- draw quarter of circle (90 degrees) # ------------------------------------------------------------------ def draw_quarter(win,start_ang,start_len,steps=10): start_ang = start_ang % 360.0 delta_a = 90.0/steps end_len = start_len * GOLDENRATIO delta_l = (end_len - start_len)/steps i = 0 while i < steps: a = start_ang + (delta_a * i) l = start_len + (delta_l * i) x = l * math.cos(math.radians(a)) y = l * math.sin(math.radians(a)) if draw_circle(win,x,y) is None: return -1 i += 1 return end_len # ending length; new starting length # ------------------------------------------------------------------ # ---- main # ------------------------------------------------------------------- if __name__ == '__main__': # ---- create graphics window win = GraphWin("Golden Ratio", 801, 801) win.setBackground("white") draw_xy_axes(win) # ---- draw spirial a = 0 l = 30 s = 5 while True: l = draw_quarter(win,a,l,s) if l < 0: break a = a + 90 s = s + 5 # ---- pause for click in window win.getMouse() win.close()