How to Align a vtk Cylinder to a Known Vector

Hi all, I’m looking to create a model of a cylinder and orient it along a known vector using python. More specifically, I have two control points, but I want to create a line that goes between them but extends past the control points along the same direction.

Any help with this is greatly appreciated.

I think the simplest way to achieve that would be the following:

• retrieve the existing control points as numpy arrays
• using those, compute the two endpoints of your desired line
• create a markupsLineNode with these new points as control points
• hide the label text and the new control points to only show the line

To do all that, I recommend looking at the examples in the script repository and/or search for previous answers in the discourse.

1 Like

Here is some rough but working code which I wrote a long time ago when I was trying to learn to do something similar that does almost exactly what you want. The only thing missing is calculating the extensions you want, which could be calculated in a pre-step, or modified into the function below.

``````def makeCylinderModelNode(
):
"""Make a cylinder surface, transform it so that the center of one end is endpoint1, and the other
is centered on endpoint2"""
import numpy as np

center = np.add(endpoint1, endpoint2) / 2.0
height = np.linalg.norm(np.subtract(endpoint2, endpoint1))
direction = np.subtract(endpoint2, endpoint1)
print(
"Center: (%0.2f, %0.2f, %0.2f)\nHeight: %0.2f\nDirection: (%0.2f, %0.2f, %0.2f)"
% (*center, height, *direction)
)
#
cyl = vtk.vtkCylinderSource()
cyl.SetResolution(numberOfSides)
cyl.SetHeight(height)
cyl.Update()  # don't know if this is necessary
#
initial_axis = [0, 1, 0]
#
# Create transform for it
# The initial axis direction is anterior/posterior (0,1,0) in RAS, we want to rotate that so that it
# points along the vector represented in "direction"
# Can determine this by finding the cross product, and angle from dot product
axis = np.cross(initial_axis, direction)
angle_deg = 180 / np.pi * np.arccos(np.dot(initial_axis, direction) / (np.linalg.norm(initial_axis) * np.linalg.norm(direction)))

#
print("Axis: (%0.2f, %0.2f, %0.2f)\nAngle: %0.2f deg" % (*axis, angle_deg))
#
vtkTform = vtk.vtkTransform()
vtkTform.Translate(center)
vtkTform.RotateWXYZ(angle_deg, axis)
vtkTform.Modified()  # don't know if this is necessary
#
# Create filter
vtkTformFilter = vtk.vtkTransformFilter()
vtkTformFilter.SetInputData(cyl.GetOutput())
vtkTformFilter.SetTransform(vtkTform)
vtkTformFilter.Update()  # don't know if this is necessary
#
# Create model node and connect it to the transformed cylinder