4

I am trying to perform a rotation of my data about the X-axis. I figure out that I should use the mayavi.tools.pipeline.transform_data function but I can't figure out a way of using it...

I thing I need to apply a rotation matrix to the data but I can't figure how to the use the function... Any hint?

Løiten
  • 3,185
  • 4
  • 24
  • 36
TazgerO
  • 535
  • 6
  • 22
  • Which type are your data to rotate ? Do you need to perform your rotation using mayavi or can you use VTK methods and filters ? (in order to perform rotation before rendering) – Marcassin Jan 21 '14 at 10:28
  • I want to use the vtk filter to perform delaunay2D on x,z basis instead of x,y (hence the x-axis rotation). First before and then afterwards.. – TazgerO Jan 21 '14 at 14:20
  • Try to bind the output of `vtkTransform` to the input of your delaunay filter. Make the rotation in the transform filter with the`vtkTransform::RotateX (double angle)` method. A rotation around X axe may be performed on your data before processing the Delaunay filter – Marcassin Jan 21 '14 at 18:42
  • I cheat a bit and use the mlab.view to rotate the scene after using the delaunay data on my x,z data and y as elevation. I will maybe have a look at the vtkTransform but I am a bit disappointed by the complexity... – TazgerO Jan 31 '14 at 19:58

1 Answers1

6

Here is an example of rotating a built-in cylinder object using Mayavi transform_data:

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

# Main code

fig = mlab.figure()

engine = mlab.get_engine()

# Add a cylinder builtin source
cylinder_src = BuiltinSurface()
engine.add_source(cylinder_src)
cylinder_src.source = 'cylinder'
cylinder_src.data_source.center = np.array([ 0.,  0.,  0.])
cylinder_src.data_source.radius = 1.0
cylinder_src.data_source.capping = False
cylinder_src.data_source.resolution = 25

# 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((1,0,0), 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)

mlab.show()

In the above example, the line Rt[0:3,0:3] = rotMat3D((1,0,0), 0) creates a rotation matrix (no translation component is present in this example although it might as well be there) for rotating the object about the x-axis by zero degree (to show the no-rotation case). It can be any other value as will be shown below. Running the above code produces the following:

enter image description here

You can now rotate the object by 90 degrees by modifying the above line to Rt[0:3,0:3] = rotMat3D((1,0,0), 90) which will produce the following figure:

enter image description here

Note that you will most-likely also get an warning like so:

Warning: In C:\pisi\tmp\VTK-5.6.0-1\work\VTK\Common\vtkTransform.cxx, line 202 vtkTransform (000000000D3AB3A0): InternalUpdate: doing hack to support legacy code. This is deprecated in VTK 4.2. May be removed in a future version.

This is because Mayavi hasn't been updated to use the new VTK pipeline.