vtkで任意の向きの円柱をつくる

actorの例として, 円柱を作ってみる.

def create_cylinder(radius, height, res=30):
    cylinder = vtk.vtkCylinderSource()
    cylinder.SetResolution(res)
    cylinder.SetHeight(height)
    cylinder.SetRadius(radius)

    mapper = vtk.vtkPolyDataMapper()
    mapper.SetInput(cylinder.GetOutput())

    actor = vtk.vtkActor()
    actor.SetMapper(mapper)
    return actor

resが大きいと表示が美しくなるが, 描画は遅くなる. これだと, 重心が原点で, Y軸を軸とする円柱になる.
任意の位置に, 任意の軸で表示したい. その場合は,

import numpy
import numpy.linalg


def move_actor(actor, pos, axis):
    theta = numpy.arccos(axis[1] / numpy.linalg.norm(axis))
    v = numpy.array([axis[2], 0, -axis[0]])
    actor.RotateWXYZ(theta / numpy.pi * 180, v[0], v[1], v[2])
    actor.SetPosition(pos)
    return actor

ベクトルvはY軸とaxisの外積であり, このvを軸としてY軸とaxisがなす角thetaだけ回転させる.
より正しくはこういったことをするためのクラスがあるようだが, よくわからなかったので.