2016-06-13 3 views
0

Mayavi mlab을 사용하여 지구 회전 애니메이션을 시도하고 있습니다. 나는 지구의 BuiltinSurface 표현을 중심으로 카메라를 회전시킴으로써 과거에 성공했지만, 프레임에 다른 많은 물체 (우주선, 별 등)를 그려야 할 때 불편해진다. 아래의 코드는 "거의"작동하는 것처럼 보입니다. Windows 10 컴퓨터에서는 8 번 반복 실행되고 애니메이션이 멈 춥니 다. 이 코드를 수정하려면 어떻게해야합니까? 아니면 일반적으로 BuiltinSurface에 애니메이션을 적용하는 더 좋은 방법이 있습니까?Mayavi mlab에서 BuiltinSurface를 애니메이트하는 방법은 무엇입니까?

import numpy as np 
from mayavi import mlab 
from mayavi.sources.builtin_surface import BuiltinSurface 
from mayavi.modules.surface import Surface 
from mayavi.filters.transform_data import TransformData 


def rotMat3D(axis, angle, tol=1e-12): 
    """Return the rotation matrix for 3D rotation by angle `angle` degrees about an 
    arbitrary axis `axis`. 
    """ 
    t = np.radians(angle) 
    x, y, z = axis 
    R = (np.cos(t))*np.eye(3) +\ 
    (1-np.cos(t))*np.matrix(((x**2,x*y,x*z),(x*y,y**2,y*z),(z*x,z*y,z**2))) + \ 
    np.sin(t)*np.matrix(((0,-z,y),(z,0,-x),(-y,x,0))) 
    R[np.abs(R)<tol]=0.0 
    return R 



@mlab.show  
@mlab.animate(delay=200) 
def anim(): 

    fig = mlab.figure() 

    engine = mlab.get_engine() 

    # Add a cylinder builtin source 
    cylinder_src = BuiltinSurface() 
    engine.add_source(cylinder_src) 
    cylinder_src.source = 'earth' 
    # Add transformation filter to rotate cylinder about an axis 
    transform_data_filter = TransformData() 
    engine.add_filter(transform_data_filter, cylinder_src) 
    Rt = np.eye(4) 
    Rt[0:3,0:3] = rotMat3D((0,0,1), 0) # in homogeneous coordinates 
    Rtl = list(Rt.flatten()) # transform the rotation matrix into a list 

    transform_data_filter.transform.matrix.__setstate__({'elements': Rtl}) 
    transform_data_filter.widget.set_transform(transform_data_filter.transform) 
    transform_data_filter.filter.update() 
    transform_data_filter.widget.enabled = False # disable the rotation control further. 

    # Add surface module to the cylinder source 
    cyl_surface = Surface() 
    engine.add_filter(cyl_surface, transform_data_filter) 
    #add color property 
    #cyl_surface.actor.property.color = (1.0, 0.0, 0.0) 

    ind=1 
    while ind<90: 
     print ind 
     Rt[0:3,0:3] = rotMat3D((0,0,1), ind) # in homogeneous coordinates 
     Rtl = list(Rt.flatten()) # transform the rotation matrix into a list 

     transform_data_filter.transform.matrix.__setstate__({'elements': Rtl}) 
     transform_data_filter.widget.set_transform(transform_data_filter.transform) 
     transform_data_filter.filter.update() 
     transform_data_filter.widget.enabled = False # disable the rotation control further. 

     # Add surface module to the cylinder source 
     cyl_surface = Surface() 
     engine.add_filter(cyl_surface, transform_data_filter) 
     # add color property 
     #cyl_surface.actor.property.color = (1.0, 0.0, 0.0) 

     yield 
     ind+=1 


anim() 

답변

0

Mayavi를 사용하여 이러한 문제를 해결할 수있는 방법을 찾아 내지 못했습니다. 그러나 Vpython은이 작업을 수행하는 데 훨씬 더 적합합니다. 아래에 몇 가지 다른 기능과 함께 회전 지구를 만들기위한 예제 코드 섹션을 게시했습니다.

from visual import * 

def destroy(): 
    for obj in scene.objects: 
     obj.visible = False 
     del obj 

R = 6378. # radius of sphere 
angle=0. 
scene.range = 10000. 
SunDirection=vector(.77,.77,0) 
# scene.fov = 0.5 
scene.center = (0,0,0) 
scene.forward = (-1,0,-1) 
scene.up = (0,0,1) 
scene.lights=[distant_light(direction=SunDirection, color=color.gray(0.8)), 
       distant_light(direction=-SunDirection, color=color.gray(0.3))] 
x=0 
y=0 

while True: 
    rate(10) 

    angle=angle+1.*pi/180. 

    destroy() 
    s = sphere(pos=(x,y,0), radius=R, material=materials.BlueMarble) 
    s.rotate(angle=90.*pi/180.,axis=(1,0,0)) # Always include this to rotate Earth into correct ECI x y z frame 
    s.rotate(angle=90.*pi/180.,axis=(0,0,1)) # Always include this to rotate Earth into correct ECI x y z frame 
    s.rotate(angle=angle, axis=(0,0,1)) # This rotation causes Earth to spin on its axis 

    xaxis = arrow(pos=(0,0,0), axis=vector(1,0,0)*7000, shaftwidth=100, color=color.red) 
    yaxis = arrow(pos=(0,0,0), axis=vector(0,1,0)*7000, shaftwidth=100, color=color.green) 
    zaxis = arrow(pos=(0,0,0), axis=vector(0,0,1)*7000, shaftwidth=100, color=color.blue) 

    ST = cone(pos=(0,8000,0),axis=(0,700,0),radius=700*tan(10*pi/180),color=color.blue,opacity=1) 
관련 문제