I have generated a set of (x,y,z)
coordinates on a unit sphere using the Fibonacci sphere algorithm. Plotted with a 3d scatter plot, they look alright:
https://i.imgur.com/OsQo0CC.gif
I now want to connect them with edges, i.e. a triangulation. As suggested in How do i draw triangles between the points of a fibonacci sphere? I went for Delaunay triangulation. For that I used the stripy
Python package, which provides triangulations on a sphere.
First I convert the coords to spherical (degrees) by iterating over the points and using the following formula:
r = float(sqrt(x * x + y * y + z * z))
theta = float(acos(z / r)) # to degrees
phi = float(atan2(y, x))
return r, theta, phi
I obtain vertices_spherical
, an array of shape (n, 3)
where n
is the number of points. We don't need the radius, so I discard it, and I have an array of shape (n, 2)
.
Then I convert to radians and build the triangulation, then make a graph out of it:
vertices_lon = np.radians(vertices_spherical.T[0])
vertices_lat = np.radians(vertices_spherical.T[1])
spherical_triangulation = stripy.sTriangulation(lons=vertices_lon, lats=vertices_lat, permute=True)
# Build the graph
graph: List[Node] = []
for i in range(spherical_triangulation.npoints):
node = Node(name=f'{vertices_spherical.T[0][i]}, {vertices_spherical.T[1][i]}',
lon=spherical_triangulation.lons[i],
lat=spherical_triangulation.lats[i])
graph.append(node)
segs = spherical_triangulation.identify_segments()
for s1, s2 in segs:
graph[s1].add_neighbor(graph[s2])
return graph
(Node is a simple class with a name, lon, lat, and neighbors)
I then convert the coordinates back to cartesian, then scatter plot them. For each node, I iterate over its neighbors and draw a line between them. And to my suprise, I get the following result. It seems kind of walnut- or brain-shaped, where there are two hemispheres where the triangulation worked fine, but for some reason the middle is sorta scrunched up along one plane:
https://i.imgur.com/AIlLTmS.gif
What could be causing this? Is it simply because of some limitation in how triangulation works? Is it because the points on a Fibonacci sphere are not periodical in some way? Or some mistake in my code? Kind of at a loss here, since the conversion to spherical and back seems to work fine, and there are no surprises with the plotting.
Fixed it! The issue was that my latitudes were between 0 and pi, whereas stripy.sTriangulation
expects them to be between -pi/2 and pi/2.
If this happens to anyone else, just know that stripy.sTriangulation
expects latitudes between -pi/2 and pi/2, and longitudes between 0 and 2pi. So check if that's what you are providing it.
Here's an animation showing the fixed sphere: https://imgur.com/JiGyegj.gif