matplotlib 使用Python在三维空间中绘制具有指定倾斜Angular 的圆

cedebl8k  于 2022-11-30  发布在  Python
关注(0)|答案(1)|浏览(250)

我想用Python在3D空间中画一个指定倾斜Angular 的圆。类似于下图:Image
我已经可以画圆在2D。我修改了我的程序通过参考下面的链接:Masking a 3D numpy array with a tilted disc

import numpy as np
import matplotlib.pyplot as plt

r = 5.0
a, b, c = (0.0, 0.0, 0.0)
angle = np.pi / 6 # "tilt" of the circle

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
ax.set_xlim(-10,10)
ax.set_ylim(-10,10)
ax.set_zlim(-10,10)

phirange = np.linspace(0, 2 * np.pi, 300) #to make a full circle

x = a + r * np.cos(phirange)
y = b + r * np.sin(phirange)
z=  c

ax.plot(x, y, z )
plt.show()

现在,我可以在3D空间中绘制圆,但无法使圆以所需的Angular 倾斜。
我试着修改代码中的Z部分,圆圈可以倾斜,但不是我想要的结果。

z = c + r * np.cos(phirange) * np.sin(angle)

结果图像:

X和Y部分也需要修改吗?怎么办?

更新:圆与其他轴倾斜

ffx8fchx

ffx8fchx1#

i = (1, 0, 0)j = (0, 1, 0),它们分别是x轴和y轴的方向向量,这两个向量形成水平面的标准正交基,这里“标准正交”意味着这两个向量是正交的,并且长度都为1。
在水平面上以C为圆心,以r为半径的圆包含所有可以写为C + r * (cos(theta) * i + sin(theta) * j)的点,对于[0, 2 pi]范围内的所有θ值。注意,这对ij有效,但它对水平面的任何其他正交基也同样有效。
任何其他平面中的圆都可以用完全相同的方式来描述,只要用形成该平面的标准正交基的两个向量来替换ij
根据您的图像,“Angular 为tilt的倾斜平面“具有以下标准正交基:

a = (cos(tilt), 0, sin(tilt))
b = (0, 1, 0)

你可以检查这两个向量在你的平面上,它们是正交的,并且它们的范数都是1,因此它们确实是你的平面的正交基。
因此,平面上圆心为C、半径为r的圆可以描述为所有点C + r * (cos(theta) * a + sin(theta) * b),其中theta[0, 2 pi]的范围内。
就x、y、z而言,这转化为以下三个参数方程的系统:

x = x_C + r * cos(theta) * x_a + r * sin(theta) * x_b
y = y_C + r * cos(theta) * y_a + r * sin(theta) * y_b
z = z_C + r * cos(theta) * z_a + r * sin(theta) * z_b

这简化了很多,因为x_b、y_a、z_b都等于0:

x = x_C + r * cos(theta) * x_a    # + sin(theta) * x_b,  but x_b == 0
y = y_C + r * sin(theta) * y_b    # + cos(theta) * y_a,  but y_a == 0
z = z_C + r * cos(theta) * z_a    # + sin(theta) * z_b,  but z_b == 0

用x_a、y_B和z_a的值替换它们:

x = x_C + r * cos(tilt) * cos(theta)
y = y_C + r * sin(theta)
z = z_C + r * sin(tilt) * cos(theta)

Python皮:

import numpy as np
import matplotlib.pyplot as plt

# parameters of circle
r = 5.0                         # radius
x_C, y_C, z_C = (0.0, 0.0, 0.0) # centre
tilt = np.pi / 6                # tilt of plane around y-axis

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
ax.set_xlim(-10,10)
ax.set_ylim(-10,10)
ax.set_zlim(-10,10)

theta = np.linspace(0, 2 * np.pi, 300) #to make a full circle

x = x_C + r * np.cos(tilt) * np.cos(theta)
y = y_C + r * np.sin(theta)
z = z_C + r * np.sin(tilt) * np.cos(theta)

ax.plot(x, y, z )
plt.show()

相关问题