My problem
I want to rotate a mayavi.mlab.imshow
object with a 3x3 rotation matrix. The only method I could find for rotating this object is through setting the object's actor.orientation
to [pitch, roll, yaw]
(this order is inherited from vtk). My only problem is that I cannot find a way to convert a rotation matrix to the parameters requested by mayavi.
How do I rotate an object in mayavi with a rotation matrix or what transformation should I use to obtain the correct (pitch, roll and yaw) used by Mayavi/Vtk?
A near solution
I have found some code over here to transform a rotation matrix to different types of Euler angles (according to the order of rotation). Correct me at this point if I am wrong in assuming Euler angles is equivalent to pitch, roll, yaw. I have tried all the different conversions, but failed to find a correct one.
Trying every combination
I tested all the different transformations by rotating x, y and z vectors with my rotation matrix and testing the paramaters on the mayavi.mlab.imshow
object. I used all the available transforms on both R
and transpose(R)
along with using the Euler the parameters in all 9 available orders, but could not find a correct combination:
import pylab as pl
import cameraTools #my own lib
from mayavi import mlab
im = pl.imread('dice.png', format='png')[:,:,0]*255 #1 color channel
rot = pl.r_[30, 80, 230]
R_orig = cameraTools.composeRotation(*(rot*pl.pi/180))
RList = [R_orig, R_orig.T]
for ii, inOrder in enumerate(['sxyz','sxzx','syxz','szxz','rzyx','rxzx','rzxy','rzxz','sxyx','syzx','syxy','szyx','rxyx','rxzy','ryxy','rxyz','sxzy','syzy','szxy','szyz','ryzx','ryzy','ryxz','rzyz']):
tries = 0
for outOrder in [[0,1,2], [0,2,1], [1, 0, 2], [1, 2, 0], [2, 0, 1], [2, 1, 0]]:
for R in RList:
for vector, color in zip([[800, 0, 0], [0, 800, 0], [0, 0, 800]],
[(1., 0., 0.), (0., 1., 0.), (0., 0., 1.)]):
c = pl.c_[[0, tries*1000, ii*1000]]
if ii == 0 and tries == 0: vector = pl.r_[vector]*5 #point out the first vector
lin = R_orig.dot(pl.c_[[0,0,0], vector]) + c
mlab.plot3d(*lin,
color = color,
tube_radius=5)
lin3D = mlab.imshow(im, colormap="gray")
rxyz = pl.array(cameraTools.euler_from_matrix(R, inOrder))*180/pi
i,j,k = outOrder
lin3D.actor.orientation = [rxyz[i], rxyz[j], rxyz[k]]
lin3D.actor.position = c.flatten()
tries +=1
mlab.draw()
mlab.show()
Output from Mayavi, the top left item is the starting point.