
# baravelle.py
# Andrew Davison, ad@coe.psu.ac.th, April 2025
'''
  Baravelle spirals.

  Draw four colored triangles that start at the corners
  of a large square, and spiral into the origin by rotating
  and shrinking.

  In addition, the lengths of the sides of the triangles
  used in one spiral are printed. This confirms the area
  reduction of the square formed by the four spirals at
  each step.

  See:
    Sums of Infinite Series: Baravelle Spirals
    https://old.nationalcurvebank.org/baravelle/baravelle.htm
      - click on "Draw Squares"
  and
    "Exploring Infinite Series Using Baravelle Spirals"
    Suzanne Harper, available at ResearchGate
    (https://www.researchgate.net/)
'''

import math
import matplotlib.pyplot as plt
from matplotlib.patches import Polygon
from HC2Mat import *


ANGLE = 45  # for rotating the triangles
SCALE = 1/math.sqrt(2)  # for shrinking the triangles
SIZE = 100  # initial triangle size
STEPS = 12  # number of steps in a spiral


def createColorCoords():
  coords = [ (0,0), (SIZE,0), (SIZE,SIZE)] # basic triangle
  '''
    set start positions of triangles at the
    four corners of a 2*SIZE square centered at origin
  '''
  m = multMatsList([ transMat(SIZE,0), rotMat(90) ]) # top right
  coords0 = [applyMat(m, c) for c in coords]
  
  m = multMatsList([ transMat(0,SIZE), rotMat(180) ]) # top left
  coords1 = [applyMat(m, c) for c in coords]
  
  m = multMatsList([ transMat(-SIZE,0), rotMat(270) ]) # bottom left
  coords2 = [applyMat(m, c) for c in coords]
  
  m = multMatsList([ transMat(0,-SIZE) ])   # bottom right
  coords3 = [applyMat(m, c) for c in coords]
  
  # specify a fill color for each triangle
  return  [(coords0,'skyblue'), (coords1,'lightgreen'), 
           (coords2, 'violet'), (coords3, 'salmon')]


def moveIn(coords):
  pt0 = coords[0]
  nPt0 = tuple((a+b)/2 for a, b in zip(coords[0], coords[2]))
         # midpoint of diagonal
  m = multMatsList([ transMat(nPt0[0], nPt0[1]), 
         rotMat(ANGLE), scaleMat(SCALE, SCALE),
         transMat(-pt0[0], -pt0[1])  ])  # right to left
  return [applyMat(m, c) for c in coords]


def drawPoly(ax, coords, color):
  poly = Polygon(coords, closed=True, color=color)
  ax.add_patch(poly)


fig, ax = plt.subplots(figsize=(6, 6))
ax.set_aspect('equal')
ax.set_xlim(-SIZE, SIZE)
ax.set_ylim(-SIZE, SIZE)
ax.axis('off')

# spiralLens = [0]*(STEPS+1) # lengths along spiral

# draw four colored spirals move into the origin
cCoords = createColorCoords()
for coords, color in cCoords:
  drawPoly(ax, coords, color)
  for i  in range(STEPS):
    coords = moveIn(coords)
    drawPoly(ax, coords, color)

'''
print("Spiral edge lengths:")
for n in spiralLens:
  print(f"{n:.2f}", end = ' ')
print()
'''

plt.show()
