生成具有特定数量同心圆的光滑线球。

huangapple go评论78阅读模式
英文:

Generate smooth wire sphere with specific number of concentric

问题

我想在Python中生成一个具有特定数量同心圆的线球(3个水平和22个垂直)。

我该如何做呢?我在这里尝试了一些代码,但为了让球看起来好看,需要使用大量的圆,例如200个。我需要这个来生成一个6个成员的环糖浮动图。

如果在圆之间的每个交点处都有一个点,那也很好。我尝试了一些Python代码,但线球不够平滑。

英文:

I would like to generate in python a wire sphere with specific number of concentric circles, (3 horizontal and 22 vertical).

How can I do this? I have tried some code in here but to make the sphere look nice it is necessary to use a large number, e.g., 200. I need this to generate a 6-member ring sugar puckering diagram.

I would also be nice if at each intercepting point between the circles there would be a point. I tried some python code but the wire sphere is not smooth

答案1

得分: 1

以下是已翻译好的部分:

解决方案

有几种方法可以解决这个问题。首先是使用 ax.plot_wireframe(...),但对于这么少的水平圆圈,这看起来不太吸引人。另一种(更好的)方法是在循环中分别绘制每个圆。下面是我包含的方法。

请注意,即使对于更好的方法,我仍然使用了 np.mgrid(...)。这将给您提供 (x,y,z) 坐标的数组,可以用于访问交点。

示例输出

生成具有特定数量同心圆的光滑线球。

代码

# %matplotlib notebook # 如果使用jupyter notebook,请取消注释
import matplotlib as mpl
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import matplotlib.pyplot as plt

# 创建图形
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')

# 描述您的球体的参数
numVertCircles = 22
numHorizCircles = 3
radius = 10

theta = np.linspace(0, 2 * np.pi, 201)

# 生成垂直圆的数据
xy = radius*np.cos(theta)
z = radius*np.sin(theta)

# 生成水平圆的数据
u1, v1 = np.mgrid[0:2*np.pi:numVertCircles*1j, 0:np.pi:(numHorizCircles+2)*1j]
x1 = radius*np.cos(u1)*np.sin(v1)
y1 = radius*np.sin(u1)*np.sin(v1)
z1 = radius*np.cos(v1)

horizRadii = np.amax(x1,axis=0) # 半径数组(每个水平圆一个)
uniqueZs = np.unique(z1) # z值数组(每个水平圆一个)

# 绘制垂直圆
for i in range(numVertCircles):
    phi = i*np.pi/numVertCircles
    ax.plot(xy*np.sin(phi), xy*np.cos(phi), z, color ='#15B05E')

# 绘制水平圆
for j in range(numHorizCircles):
    ax.plot(np.cos(theta)*horizRadii[j+1], 
            np.sin(theta)*horizRadii[j+1], 
            np.full(201,uniqueZs[j+1]), color ='#15B05E')

# 显示交点
# 注意:在球体的两极有大量重叠的点
ax.scatter(x1.flatten(),y1.flatten(),z1.flatten(), color='red')
plt.show()

plt.savefig('wireFrameSphere.png', bbox_inches='tight', pad_inches=0.1)
英文:

Solution

There are a few ways to go about this. The first is using ax.plot_wireframe(...) but that doesn't look very visually appealing with such a small number of horizontal circles. Another (better) method is plotting each circle individually in a for loop. This is the method I have included below.

Note that I still used np.mgrid(...) even for the better method. This will give you arrays of (x,y,z) coordinates which can be used to access intersection points.

Example Output

生成具有特定数量同心圆的光滑线球。

Code

# %matplotlib notebook # uncomment if you use jupyter notebook
import matplotlib as mpl
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import matplotlib.pyplot as plt
# creating figure
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')
# parameters to describe your sphere
numVertCircles = 22
numHorizCircles = 3
radius = 10
theta = np.linspace(0, 2 * np.pi, 201)
# generating data for vertical circles
xy = radius*np.cos(theta)
z = radius*np.sin(theta)
# generating data for horizontal circles
u1, v1 = np.mgrid[0:2*np.pi:numVertCircles*1j, 0:np.pi:(numHorizCircles+2)*1j]
x1 = radius*np.cos(u1)*np.sin(v1)
y1 = radius*np.sin(u1)*np.sin(v1)
z1 = radius*np.cos(v1)
horizRadii = np.amax(x1,axis=0) # array of radii (1 per horizontal circle)
uniqueZs = np.unique(z1) # array of z vals (1 per horizontal circle)
# plotting vertical circles
for i in range(numVertCircles):
phi = i*np.pi/numVertCircles
ax.plot(xy*np.sin(phi), xy*np.cos(phi), z, color ='#15B05E')
# plotting horizontal circles
for j in range(numHorizCircles):
ax.plot(np.cos(theta)*horizRadii[j+1], 
np.sin(theta)*horizRadii[j+1], 
np.full(201,uniqueZs[j+1]), color ='#15B05E')
# showing the intesection points
# NOTE: There are a bunch of overlapping points at the poles of the sphere
ax.scatter(x1.flatten(),y1.flatten(),z1.flatten(), color='red')
plt.show()
plt.savefig('wireFrameSphere.png', bbox_inches='tight', pad_inches=0.1)

huangapple
  • 本文由 发表于 2023年5月10日 19:34:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/76217913.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定