
# goldScatter3D.py
'''
Plot the golden spiral as a series of 3D points.

Note that the inverse cosine is required for the same reason that the sqrt is required in goldScatter2D.py.

https://extremelearning.com.au/how-to-evenly-distribute-points-on-a-sphere-more-effectively-than-the-canonical-fibonacci-lattice/

https://stackoverflow.com/questions/9600801/evenly-distributing-n-points-on-a-sphere
'''

import random, math
import matplotlib.pyplot as plt
from fibsLib import *
import numpy as np

NUM_PTS = 1000

def drawSphere(ax):
  alphas, thetas = np.mgrid[0.0:np.pi:100j, 
                          0.0:2.0*np.pi:100j]
  xcs = radius*np.cos(thetas)*np.sin(alphas)
  ycs = radius*np.sin(thetas)*np.sin(alphas)
  zcs = radius*np.cos(alphas)
  ax.plot_surface(xcs, ycs, zcs,  
               rstride=1, cstride=1, color='c', 
               alpha=0.3, linewidth=0)


xs = [0]*NUM_PTS
ys = [0]*NUM_PTS
zs = [0]*NUM_PTS
radius = 1
for i in range(NUM_PTS):
  theta = math.pi*(i*PHI_F)
  alpha = math.acos(1-2*(i/NUM_PTS))   # for uniformity
  xs[i] = radius*math.cos(theta)*math.sin(alpha)
  ys[i] = radius*math.sin(theta)*math.sin(alpha)
  zs[i] = radius*math.cos(alpha)

fig = plt.figure(figsize=(7, 7))
ax = fig.add_subplot(projection='3d')

drawSphere(ax)
ax.scatter(xs, ys, zs, color="k",s=10)

ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')
plt.axis('scaled')
plt.title("Golden Spiral 3D Points")
plt.show()
