在Python中制作移动圆柱体的3D动画最有效的方法是什么?
对于高度为h、半径为r的圆柱体(或类似圆柱体的对象),我有一个numpy数组a,它指定圆柱体在3D空间中的6度运动(沿x、y、z轴平移以及围绕x、y、z轴旋转) 我想使用A为圆柱体创建动画,并将其保存为视频文件 下面的代码就是我到目前为止得到的。 有没有办法以更快、更高效的方式实现我的代码已经完成的功能? 另外,如何添加或修改代码以将动画另存为视频文件在Python中制作移动圆柱体的3D动画最有效的方法是什么?,python,python-3.x,matplotlib,plot,geometry,Python,Python 3.x,Matplotlib,Plot,Geometry,对于高度为h、半径为r的圆柱体(或类似圆柱体的对象),我有一个numpy数组a,它指定圆柱体在3D空间中的6度运动(沿x、y、z轴平移以及围绕x、y、z轴旋转) 我想使用A为圆柱体创建动画,并将其保存为视频文件 下面的代码就是我到目前为止得到的。 有没有办法以更快、更高效的方式实现我的代码已经完成的功能? 另外,如何添加或修改代码以将动画另存为视频文件 # My Animation Code import matplotlib.pyplot as plt import numpy as np f
# My Animation Code
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
def RotZ(x):
return np.array([[np.cos(x), -np.sin(x), 0, 0], [np.sin(x), np.cos(x), 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]])
def RotY(x):
return np.array([[np.cos(x), 0, np.sin(x), 0], [0, 1, 0, 0], [-np.sin(x), 0, np.cos(x), 0], [0, 0, 0, 1]])
def RotX(x):
return np.array([[1, 0, 0, 0], [0, np.cos(x), -np.sin(x), 0], [0, np.sin(x), np.cos(x), 0], [0, 0, 0, 1]])
def Trans(x,y,z):
return np.array([[1, 0, 0, x], [0, 1, 0, y], [0, 0, 1, z], [0, 0, 0, 1]])
# Translation and Rotation Matrix in 3D space
def Matrix_Transform(x, y, z, qx, qy, qz):
return np.matmul(np.matmul(np.matmul(Trans(x,y,z), RotX(qx)), RotY(qy)), RotZ(qz))
# Translate and Rotate in 3D space
def Transform(Obj, Transform_Matrix):
transformed_vertex = np.zeros((3,len(Obj.vertex))) # array initialization
for i in range(0, len(Obj.vertex)):
arr = np.append(Obj.vertex[i],0)
vertex_rotated = np.matmul(Transform_Matrix, arr)
vertex_rotated_translated = vertex_rotated + Transform_Matrix[:,3]
transformed_vertex[:,i] = vertex_rotated_translated[:3]
return transformed_vertex
class AniObj:
def __init__(self, r, h):
self.vertex = np.array([[r , 0 , -h/2],
[r*np.cos(2 *np.pi/8), r*np.sin(2 *np.pi/8), -h/2],
[r*np.cos(4 *np.pi/8), r*np.sin(4 *np.pi/8), -h/2],
[r*np.cos(6 *np.pi/8), r*np.sin(6 *np.pi/8), -h/2],
[r*np.cos(8 *np.pi/8), r*np.sin(8 *np.pi/8), -h/2],
[r*np.cos(10*np.pi/8), r*np.sin(10*np.pi/8), -h/2],
[r*np.cos(12*np.pi/8), r*np.sin(12*np.pi/8), -h/2],
[r*np.cos(14*np.pi/8), r*np.sin(14*np.pi/8), -h/2],
[r , 0 , h/2],
[r*np.cos(2 *np.pi/8), r*np.sin(2 *np.pi/8), h/2],
[r*np.cos(4 *np.pi/8), r*np.sin(4 *np.pi/8), h/2],
[r*np.cos(6 *np.pi/8), r*np.sin(6 *np.pi/8), h/2],
[r*np.cos(8 *np.pi/8), r*np.sin(8 *np.pi/8), h/2],
[r*np.cos(10*np.pi/8), r*np.sin(10*np.pi/8), h/2],
[r*np.cos(12*np.pi/8), r*np.sin(12*np.pi/8), h/2],
[r*np.cos(14*np.pi/8), r*np.sin(14*np.pi/8), h/2]])
# Position and Rotation in time
A = np.array([[0, 0, 0, 0, 0, 0],
[0.01599998, 0, -0.0006239, 0, 0.01136968, 0],
[0.05403919, 0, 0.00676171, 0, 0.03658598, 0],
[0.10514987, 0, 0.03305278, 0, 0.06318129, 0],
[0.16226590, 0, 0.08316074, 0, 0.07898396, 0],
[0.22450262, 0, 0.15264478, 0, 0.07800290, 0],
[0.29704876, 0, 0.22760964, 0, 0.06264864, 0],
[0.37834865, 0, 0.29329005, 0, 0.03757572, 0],
[0.46285620, 0, 0.33771592, 0, 0.00815532, 0],
[0.54269669, 0, 0.35392964, 0, -0.0215355, 0]])
# Parameters
radius = 5
height = 1
# Figure Setup
fig = plt.figure()
ax = Axes3D(fig)
# Animation
for i in range(0, len(A)):
# Pause and clear window every iteration
plt.pause(0.001)
plt.cla()
# Cylinder Setup
CylinderObj = AniObj(radius, height)
M = Matrix_Transform(A[i,0], A[i,1], A[i,2], A[i,3], A[i,4], A[i,5])
CylinderObj.vertex = Transform(CylinderObj, M)
Cylinder_vertices = list(zip(*(CylinderObj.vertex.tolist())))
# Rendering in Poly3DCollection (list of list of triples)
# Top & Bottom
Cylinder_Top = [Cylinder_vertices[8:]]
Cylinder_Bottom = [Cylinder_vertices[:8]]
# Sides
Cylinder_Side1 = [list(zip(*zip(Cylinder_vertices[0 ], Cylinder_vertices[1 ], Cylinder_vertices[9 ], Cylinder_vertices[8 ])))]
Cylinder_Side2 = [list(zip(*zip(Cylinder_vertices[1 ], Cylinder_vertices[2 ], Cylinder_vertices[10], Cylinder_vertices[9 ])))]
Cylinder_Side3 = [list(zip(*zip(Cylinder_vertices[2 ], Cylinder_vertices[3 ], Cylinder_vertices[11], Cylinder_vertices[10])))]
Cylinder_Side4 = [list(zip(*zip(Cylinder_vertices[3 ], Cylinder_vertices[4 ], Cylinder_vertices[12], Cylinder_vertices[11])))]
Cylinder_Side5 = [list(zip(*zip(Cylinder_vertices[4 ], Cylinder_vertices[5 ], Cylinder_vertices[13], Cylinder_vertices[12])))]
Cylinder_Side6 = [list(zip(*zip(Cylinder_vertices[5 ], Cylinder_vertices[6 ], Cylinder_vertices[14], Cylinder_vertices[13])))]
Cylinder_Side7 = [list(zip(*zip(Cylinder_vertices[6 ], Cylinder_vertices[7 ], Cylinder_vertices[15], Cylinder_vertices[14])))]
Cylinder_Side8 = [list(zip(*zip(Cylinder_vertices[7 ], Cylinder_vertices[0 ], Cylinder_vertices[8 ], Cylinder_vertices[15])))]
# Plot Cylinder on Axis
ax.add_collection3d(Poly3DCollection(Cylinder_Bottom, alpha=0.5, linewidths=1, facecolors='darkcyan'), zs='z')
ax.add_collection3d(Poly3DCollection(Cylinder_Top , alpha=0.5, linewidths=1, facecolors='darkcyan'), zs='z')
ax.add_collection3d(Poly3DCollection(Cylinder_Side1 , alpha=0.5, linewidths=1, facecolors='teal'), zs='z')
ax.add_collection3d(Poly3DCollection(Cylinder_Side2 , alpha=0.5, linewidths=1, facecolors='darkcyan'), zs='z')
ax.add_collection3d(Poly3DCollection(Cylinder_Side3 , alpha=0.5, linewidths=1, facecolors='teal'), zs='z')
ax.add_collection3d(Poly3DCollection(Cylinder_Side4 , alpha=0.5, linewidths=1, facecolors='darkcyan'), zs='z')
ax.add_collection3d(Poly3DCollection(Cylinder_Side5 , alpha=0.5, linewidths=1, facecolors='teal'), zs='z')
ax.add_collection3d(Poly3DCollection(Cylinder_Side6 , alpha=0.5, linewidths=1, facecolors='darkcyan'), zs='z')
ax.add_collection3d(Poly3DCollection(Cylinder_Side7 , alpha=0.5, linewidths=1, facecolors='teal'), zs='z')
ax.add_collection3d(Poly3DCollection(Cylinder_Side8 , alpha=0.5, linewidths=1, facecolors='darkcyan'), zs='z')
# Set Window
ax.set_xlim((-5, 5))
ax.set_ylim((-5, 5))
ax.set_zlim((-5, 5))
# Show figure
plt.show()
您的代码此时未显示移动的圆柱体moment@ReblochonMasque我想是的,当使用
plt.ion()
时,OP可能正在幕后操作。你是对的,确实如此,谢谢你@ImportanceOfBeingErnest.@AndrewChey我认为这样的问题更适合,所以只需要一些提示:(1)不要使用交互模式,但是作为一个FuncAnimation
,(2)不清除每个步骤中的轴,而是只删除艺术家,甚至只更新集合的顶点。(3) 原则上,您可以创建一个多边形集合来承载所有“圆柱体”。当然,就这里提到的任何一个方面提出一个范围很广的问题,并进行合理的尝试,同样适用于这种情况。@ImportanceOfBeingErnest我明白了。谢谢你的建议!