我使用斐波那契球算法生成了一组单位球上的(x,y,z)坐标。通过3D散点图绘制,它们看起来还不错。
首先,我通过迭代点并使用以下公式将坐标转换为球面坐标(以度为单位)。
(Node是一个简单的类,具有名称、经度、纬度和邻居)
然后我将坐标转换回笛卡尔坐标系,然后将它们散点绘制。对于每个节点,我遍历其邻居并在它们之间画一条线。
令我惊讶的是,我得到了以下结果。它看起来有点像核桃或大脑形状,其中有两个半球,三角剖分工作得很好,但由于某种原因中间部分在一个平面上有些挤压: 这是什么原因导致的呢?是三角测量的某些限制吗?还是斐波那契球上的点在某种程度上不是周期性的?或者是我的代码有问题吗?我有点迷茫,因为球面和平面之间的转换似乎工作正常,并且绘图也没有出现意外。
https://i.imgur.com/OsQo0CC.gif
我现在想要用边连接它们,也就是三角剖分。如如何在斐波那契球的点之间绘制三角形?中建议的那样,我选择了Delaunay三角剖分。为此,我使用了Python包stripy
,该包提供了球面上的三角剖分。首先,我通过迭代点并使用以下公式将坐标转换为球面坐标(以度为单位)。
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
我获得vertices_spherical
,一个形状为(n, 3)
的数组,其中n
是点的数量。我们不需要半径,所以我将其丢弃,然后得到形状为(n, 2)
的数组。
然后我将其转换为弧度,并构建三角剖分,然后生成一个图形:
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是一个简单的类,具有名称、经度、纬度和邻居)
然后我将坐标转换回笛卡尔坐标系,然后将它们散点绘制。对于每个节点,我遍历其邻居并在它们之间画一条线。
令我惊讶的是,我得到了以下结果。它看起来有点像核桃或大脑形状,其中有两个半球,三角剖分工作得很好,但由于某种原因中间部分在一个平面上有些挤压: 这是什么原因导致的呢?是三角测量的某些限制吗?还是斐波那契球上的点在某种程度上不是周期性的?或者是我的代码有问题吗?我有点迷茫,因为球面和平面之间的转换似乎工作正常,并且绘图也没有出现意外。