2016-08-05 32 views
9

私はmayaviのtriangular_meshメソッドを使用して3Dメッシュをプロットしています。このデータは、3D空間にフェイスダウンで配置された人間のシルエットを表しています(cmapはカメラからの距離を示すために使用できます)。ここでMayavi:y軸を中心に回転

は、プロット(面と頂点が外部のオブジェクトから来て、ここに示すことがあまりにも多くがある)を生成するために使用されるコードです:カメラを動かすことなく

from mayavi import mlab 

import math 
import numpy as np 
import sys 
import os 


fig = mlab.figure(fgcolor=(0, 0, 0), bgcolor=(1, 1, 1), size=(1920, 980)) 

a = np.array(this_mesh.vertices - refC.conj().transpose()) # this_mesh is an object created from external data files 

this_mesh.faces = this_mesh.faces.astype(int) -1 # mesh data is generated by matlab, which is 1-indexed 

m = mlab.triangular_mesh(x, y, z, this_mesh.faces, opacity=0.75) 

mlab.axes(extent=[-1100, 1100, -1100, 1100, -1100, 1100]) 

を、シルエットが顔を産みます-ダウン。モデルを正面から見るために、カメラの方位角と仰角を変更して、グラフをトップダウンで見るようにしています。これは意図したシルエットを示しています。

mlab.view(azimuth=0, elevation=180) 
mlab.show() 

私の次の課題は、プロットの周りにカメラのパンは、右を向いシルエットで始まり、それが左に向けて仕上げた一連の画像を作成することです。

深度情報のカラーマップを取得するために、私は既にビューの方位角と仰角を移動しています(上記のコードを参照)。 Mayaviにはmatplotlibよりもカメラを移動するオプションがありますが、Y軸を中心に回転する方法はないようですので、方位角と仰角で複雑な計算を行う必要があります同じ結果ですが、どこから始めたらいいか分かりません(私は3D空間で作業するのが初めてですし、私の脳はまだそのようには思えません)。

誰でも正しい方向に向けることができますか?

答えて

1

それは、このための回避策のビットがありますが判明しました。

アクタは、カメラとは独立して軸上で回転させることができます。 (これは、データラベルとステップのうち可視化を投げるが、私は実際には図の座標軸を隠してるように、この場合には重要ではありません。)

すべてを行う必要がある:

m.actor.actor.rotate_y(desired_angle) 

...あなたはいいですね。

2

ここには数学が必要です。さて、ここではコードの面でそれを行う方法ですが、それは最良のコードではありませんが、私はそれを自明にしたいと思っていました。私はこれを達成するために、3Dで回転するRodriguesの公式を使用します.z_newとel_newは新しい視野角です。参照のあなたのフレーム内の異なる視野角を得るために、シータの値を変更し、私は以下のコードでは45度を使用しています

import numpy as np 
import math 

def rotation_matrix(axis, theta): 
    """ 
    Return the rotation matrix associated with counterclockwise rotation about 
    the given axis by theta radians. 
    """ 
    axis = np.asarray(axis) 
    theta = np.asarray(theta) 
    axis = axis/math.sqrt(np.dot(axis, axis)) 
    a = math.cos(theta/2.0) 
    b, c, d = -axis*math.sin(theta/2.0) 
    aa, bb, cc, dd = a*a, b*b, c*c, d*d 
    bc, ad, ac, ab, bd, cd = b*c, a*d, a*c, a*b, b*d, c*d 
    return np.array([[aa+bb-cc-dd, 2*(bc+ad), 2*(bd-ac)], 
        [2*(bc-ad), aa+cc-bb-dd, 2*(cd+ab)], 
        [2*(bd+ac), 2*(cd-ab), aa+dd-bb-cc]]) 


az = 90 
el = -75 

x = np.cos(np.deg2rad(el))*np.cos(np.deg2rad(az)) 
y = np.cos(np.deg2rad(el))*np.sin(np.deg2rad(az)) 
z = np.sin(np.deg2rad(el)) 

# So your viewing vector in x,y coordinates on unit sphere 
v = [x,y,z] 

# Since you want to rotate about the y axis from this viewing angle, we just increase the 
# elevation angle by 90 degrees to obtain our axis of rotation 

az2 = az 
el2 = el+90 

x = np.cos(np.deg2rad(el2))*np.cos(np.deg2rad(az2)) 
y = np.cos(np.deg2rad(el2))*np.sin(np.deg2rad(az2)) 
z = np.sin(np.deg2rad(el2)) 

axis = [x,y,z] 

# Now to rotate about the y axis from this viewing angle we use the rodrigues formula 
# We compute our new viewing vector, lets say we rotate by 45 degrees 
theta = 45 
newv = np.dot(rotation_matrix(axis,np.deg2rad(theta)), v) 

#Get azimuth and elevation for new viewing vector 
az_new = np.rad2deg(np.arctan(newv[1]/newv[0])) 
el_new = np.rad2deg(np.arcsin(newv[2])) 
+0

ありがとう、これは役に立ちます。私は月曜日にそれを試して、それがどのように機能するか見る。 – MassivePenguin

+0

うーん、そこにはない(間違った軸で回転している)。私はまったく異なるアプローチを試みなければならないかもしれません... – MassivePenguin

関連する問題