Theodorus (Square Root) Spiral

Description the Algorithm

image missing

Polar Coordinates

Polar coordinates define a point's location using a distance from a reference point and a counterclockwise angle from a reference direction.

  1. The reference point is the origin (0,0) of Cartesian coordinates.
  2. The reference direction is the positive x axis of Cartesian coordinates.

Code

#!/usr/bin/python3 # ============================================================== # draw a Theodorus spiral (a square root spiral) # ============================================================== import graphics as gr import coordinate_conversion as cc import math import sys DEBUG = False # -------------------------------------------------------------- # ---- convert polar to Cartesian coordinates # ---- convert Cartesian to polar coordinates # -------------------------------------------------------------- def polar2cart(rho:[int|float],phi:[int|float]) -> tuple: ''' convert polar to Cartesian coordinates ''' x = rho * math.cos(phi) y = rho * math.sin(phi) return (x,y) def cart2polar(x,y): ''' convert Cartesian to polar coordinates (add try...catch... to catch division by zero, etc) ''' rho = np.sqrt(x**2 + y**2) phi = np.arctan2(y,x) return (rho,phi) # -------------------------------------------------------------- # ---- create a graphics window # -------------------------------------------------------------- def create_a_graphics_window(width:[int|float], height:[int|float], axes:bool=False, title:str='Graph') -> gr.GraphWin: ''' create graphics window and maybe Cartesian axes ''' # ---- create window win = gr.GraphWin(title,width,height) win.setBackground("white") # ---- draw axes? if axes: # ---- X,Y axes origin in window coordinates xaxis = round(width/2.0) yaxis = round(height/2.0) # ---- draw X axis (line) xl = gr.Line(gr.Point(0,yaxis),gr.Point(width-1,yaxis)) xl.setWidth(1) xl.setFill("black") xl.draw(win) # ---- draw Y axis (line) yl = gr.Line(gr.Point(xaxis,0),gr.Point(xaxis,height-1)) yl.setWidth(1) yl.setFill("black") yl.draw(win) return win # -------------------------------------------------------------- # ---- create a list of points on a square root spiral # ---- return polar coordinates: # ---- distance, angle (radians), angles (degrees) # -------------------------------------------------------------- # ---- + sin(x) = a/h # ---- /| cos(x) = b/h # ---- / | # ---- h / | a h = math.sqrt(a**2 + b**2) # ---- / | # ---- / | # ---- / x | # ---- +------+ # ---- b # ---- # -------------------------------------------------------------- def create_square_root_spiral_points(loops:int=16) -> list: ''' create a list of points on a square root spiral ''' # ---- initial conditions pts = [] # list of spiral point a = 1 # triangle side - opposite the angle b = math.sqrt(1.0) # triangle side - adjacent the angle angle_rad = 0.0 # initial angle - radians angle_deg = 0.0 # initial angle - degrees # ---- initial (starting) triangle # ---- note: math.sqrt(1.0) == 1.0 pts.append((1.0,0.0,0.0)) # ---- calculate each of the spiral point for loop in range(loops): # ---- calculate hypotenuse h = math.sqrt(a**2 + b**2) angle_rad += math.asin(a/h) angle_deg += math.degrees(angle_rad) if DEBUG: print() print(f'loop {loop}') print(f'a = {a:.6f}') print(f'b = {b:.6f}') print(f'h = {h:.6f}') print(f'sin = {a/h:.6f}') print(f'angle rad = {angle_rad:.6f}') print(f'angle deg = {angle_deg:.6f}') pts.append((h,angle_rad,angle_deg)) # ---- the hypotenuse becomes side 'b' for the # ---- next triangle (side 'a' does not change) b = h return pts # -------------------------------------------------------------- # ---- draw a spiral (this code is incomplete. finish it) # -------------------------------------------------------------- def draw_spiral(win:gr.GraphWin,pts:list) -> None: ''' draw the spiral's lines (incomplete code) ''' for pt in pts: x,y = polar2cart(pt[0],pt[1]) x = x*100 # scale the coordinate y = y*100 # scale the coordinate # ---- convert cartesian coords to window coords cx1,cy1 = cc.center_to_win_coords(x,y, win.width,win.height) cx2,cy2 = cc.center_to_win_coords(0.0,0.0, win.width,win.height) # ---- draw a line (from point to origin) l = gr.Line(gr.Point(cx1,cy1),gr.Point(cx2,cy2)) l.setWidth(1) l.setFill('black') l.draw(win) return # -------------------------------------------------------------- # ---- main # -------------------------------------------------------------- if __name__ == '__main__': # ---- square root spiral plot/drawing points pts = create_square_root_spiral_points() # ---- graphics window win = create_a_graphics_window(801,801, title="Theodorus (Square Root) Spiral") # ---- draw a Theodorus (square root) spiral draw_spiral(win,pts) # ---- wait for a mouse click in window, then exit click = win.getMouse() win.close() sys.exit()