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