# How to Align a vtk Cylinder to a Known Vector

**URL:** <https://discourse.slicer.org/t/how-to-align-a-vtk-cylinder-to-a-known-vector/35880>\
**Category:** Development\
**Tags:** python\
**Created:** [May 2, 2024, 6:31pm UTC](https://discourse.slicer.org/t/how-to-align-a-vtk-cylinder-to-a-known-vector/35880 "2024-05-02T18:31:39Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Teresa\_Marotta](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/teresa_marotta/32/69440_2.png) [@Teresa\_Marotta](https://discourse.slicer.org/u/Teresa_Marotta)\
**Post date:** [May 2, 2024, 6:31pm UTC](https://discourse.slicer.org/t/how-to-align-a-vtk-cylinder-to-a-known-vector/35880/1 "2024-05-02T18:31:39Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![rfenioux](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/rfenioux/32/70007_2.png) [@rfenioux](https://discourse.slicer.org/u/rfenioux)\
**Post date:** [May 3, 2024, 7:57am UTC](https://discourse.slicer.org/t/how-to-align-a-vtk-cylinder-to-a-known-vector/35880/2 "2024-05-03T07:57:22Z")

</div>

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](https://slicer.readthedocs.io/en/latest/developer_guide/script_repository.html) and/or search for previous answers in the discourse.

---

<div class="post-metadata">

**Author:** ![mikebind](https://avatars.discourse-cdn.com/v4/letter/m/71e660/32.png) [@mikebind](https://discourse.slicer.org/u/mikebind)\
**Post date:** [May 3, 2024, 4:15pm UTC](https://discourse.slicer.org/t/how-to-align-a-vtk-cylinder-to-a-known-vector/35880/3 "2024-05-03T16:15:39Z")

</div>

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.

```auto
def makeCylinderModelNode(
    endpoint1, endpoint2, radiusMm=0.25, numberOfSides=20
):
    """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.SetRadius(radiusMm)
    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
    model_node = slicer.modules.models.logic().AddModel(vtkTformFilter.GetOutput())
    return model_node

```

---

<div class="post-metadata">

**Author:** ![chir.set](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/chir.set/32/66982_2.png) [@chir.set](https://discourse.slicer.org/u/chir.set)\
**Post date:** [May 3, 2024, 7:01pm UTC](https://discourse.slicer.org/t/how-to-align-a-vtk-cylinder-to-a-known-vector/35880/4 "2024-05-03T19:01:05Z")

</div>

You may also draw a cylinder using the ExtraMarkups extension.

Then you may set the control points defining the axis of the cylinder using python since you know the coordinates of your 2 control points. Next ajust the radius.

You may finally calculate the coordinates of a point beyond the line defined by your pair of control points using vtkMath::GetPointAlongLine(). Then draw a line as suggested [here](https://discourse.slicer.org/t/how-to-align-a-vtk-cylinder-to-a-known-vector/35880/2).
