如何在 Matplotlib 中围绕旋转轴做一个 3D 圆

Posted

技术标签:

【中文标题】如何在 Matplotlib 中围绕旋转轴做一个 3D 圆【英文标题】:How to do a 3D circle in Matplotlib around a rotation axis 【发布时间】:2022-01-22 17:48:48 【问题描述】:

我正在尝试使用 matplotlib 绘制可以给出旋转轴的圆圈。我已经在堆栈溢出中找到了这个post,这里有人提供了一个用于旋转与 z 轴相切的代码。如何移动它以围绕原点旋转?目前,我的代码如下所示:

import matplotlib as mpl
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import matplotlib.pyplot as plt

def circ_3d(num_proj, start_rotation_axis, deg_list = [0,45,90]):

    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')

    theta = np.linspace(0, 2 * np.pi, num_proj)
    
    if start_rotation_axis == 'z':
       x = np.cos(theta)
       y = np.sin(theta)
       for i in range(len(deg_list)):
          degree = deg_list[i]
          phi = np.deg2rad(degree)
          ax.plot(x ,
                y, x*np.sin(phi)  )
    else:
        raise Exception("Enter a valid axis")

    ax.plot((0,0),(0,0), (-radius,radius), '-k', label='z-axis', color = 'green')
    ax.plot((-radius,radius),(0,0), (0,0), '-k', label='x-axis', color = 'cyan')
    ax.plot((0,0),(-radius,radius), (0,0), '-k', label='y-axis', color = 'red')
    ax.legend()
    plt.show()

通过调用circ_3d(200,'z'),我得到了这个picture。 有人可以帮助我了解这种转变的来源以及如何避免这种转变吗?

我更新了代码,现在得到了following。

所以剩下的问题是:给定 xy 平面中的一个圆(度数 = 0),我如何将下一个圆倾斜 45 度以上(xy 平面到 z 轴),这样圆的中心仍然是(0,0,0),它不会演变成椭圆。

提前致谢!

【问题讨论】:

“我已经在堆栈溢出中找到了这篇文章,其中有人提供了一个与 z 轴相切旋转的代码。如何移动它以围绕原点旋转?” 这没有多大意义。在 3d 中,您可以通过围绕轴旋转一个点来获得一个圆。 “原点”是一个点,而不是一个轴。 您询问的“转变”来自公式中的-radius。只需删除它,就不应该有任何转变。 所以,不清楚你想要什么。您只想围绕 x、y、z 三个轴画圆,还是想围绕任意轴画一个圆,以向量形式给出? 我更新并尝试简化我的问题,希望能更清楚。所以我想要的是为我的圆圈提供倾斜角度,而不是最初生活在 x-y 平面中,因此例如倾斜 90 度,圆圈位于 y-z 平面中。 我的问题是:倾斜度可以不是 90° 吗? 【参考方案1】:

最后,我自己找到了答案。有兴趣的朋友可以在这里发一下:

import matplotlib as mpl
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import matplotlib.pyplot as plt

def circ_3d(radius,num_proj, start_rotation_axis, cycle_list = [0]):

  fig = plt.figure()
  ax = fig.add_subplot(111, projection='3d')

  theta = np.linspace(0, 2 * np.pi, num_proj)
  degree_step = 360/len(cycle_list)
  if start_rotation_axis == 'x':
      y = np.cos(theta)
      z = np.sin(theta)
      for i in range(len(cycle_list)):
          degree = cycle_list[i]
          phi = np.deg2rad(degree +90)
          ax.plot(y*np.cos(phi),
                  y * np.sin(phi) , z , label = degree  )
  elif start_rotation_axis == 'y':
      x = np.cos(theta)
      z = np.sin(theta)
      for i in range(len(cycle_list)):
          degree = cycle_list[i]
          phi = np.deg2rad(degree +90)
          ax.plot(x * np.sin(phi), x * np.cos(phi)
                   , z, label = degree  )
  elif start_rotation_axis == 'z':
      x = np.cos(theta)
      y = np.sin(theta)
      for i in range(len(cycle_list)):
          degree = cycle_list[i]
          phi = np.deg2rad(degree + 90)
          ax.plot(x,y * np.sin(phi) ,
                   y*np.cos(phi), label = degree  )
  else:
      raise Exception("Enter a valid axis")

  ax.plot((0,0),(0,0), (-radius,radius), '-k', label='z-axis',   color = 'green')
  ax.plot((-radius,radius),(0,0), (0,0), '-k', label='x-axis', color = 'cyan')
  ax.plot((0,0),(-radius,radius), (0,0), '-k', label='y-axis', color = 'red')
  ax.legend()
  plt.show()

circ_3d(5,200,'x',[0,45,90])

通过运行这个脚本,你会得到这个plot。

【讨论】:

以上是关于如何在 Matplotlib 中围绕旋转轴做一个 3D 圆的主要内容,如果未能解决你的问题,请参考以下文章

如何绘制围绕特定点旋转的 NSAttributedString?

如何在 PyQt4 小部件中嵌入的 Axes3D (matplotlib) 中启用旋转?

如何围绕节点的 Y 轴旋转 SKSpriteNode?

如何在matplotlib中用旋转矩阵把一个图形旋转

如何制作用于围绕 z 轴旋转三角形的特征模型矩阵

如何使用 glm::rotate 围绕原点以外的点旋转对象?