pythongeometryfibonaccitriangulationdelaunay

Delaunay triangulation of a Fibonacci sphere


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.


Solution

  • 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