# Model alignment to world coordinate system

**URL:** <https://discourse.slicer.org/t/model-alignment-to-world-coordinate-system/36725>\
**Category:** Support\
**Created:** [June 12, 2024, 2:19pm UTC](https://discourse.slicer.org/t/model-alignment-to-world-coordinate-system/36725 "2024-06-12T14:19:12Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Julian\_KC](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/julian_kc/32/18359_2.png) [@Julian\_KC](https://discourse.slicer.org/u/Julian_KC)\
**Post date:** [June 12, 2024, 2:19pm UTC](https://discourse.slicer.org/t/model-alignment-to-world-coordinate-system/36725/1 "2024-06-12T14:19:12Z")

</div>

Hello,

I’m a paleontologist working with surface model bones, and I need all my models to follow a certain alignment for analysis purposes.

I’m wondering if it’s possible to align a certain markup line to the world axis or to align certain points to the origin of the world?

Thank you so much in advance for your answer!

Julian KC

---

<div class="post-metadata">

**Author:** ![muratmaga](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/muratmaga/32/3622_2.png) [@muratmaga](https://discourse.slicer.org/u/muratmaga)\
**Post date:** [June 12, 2024, 3:57pm UTC](https://discourse.slicer.org/t/model-alignment-to-world-coordinate-system/36725/2 "2024-06-12T15:57:57Z")

</div>

> [@Julian\_KC](#):
>
> need all my models to follow a certain alignment for analysis purposes.

This is doable in many ways, couple easy options are:

1. Create a transform from set of points on a reference and target (ie., fiducial registration).

2. You can do it manually by using the interaction widget of the Transforms module.

> [@Julian\_KC](#):
>
> I’m wondering if it’s possible to align a certain markup line to the world axis or to align certain points to the origin of the world?

Do you want to do this interactively (using GUI) or from a python script? For GUI you can use the manual options I described above… Programmatically there might be some examples in Python script repository.

If you can give some examples (screenshots of what you are trying to do), it would be easier to give more concrete answers.

---

<div class="post-metadata">

**Author:** ![Julian\_KC](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/julian_kc/32/18359_2.png) [@Julian\_KC](https://discourse.slicer.org/u/Julian_KC)\
**Post date:** [June 13, 2024, 1:58pm UTC](https://discourse.slicer.org/t/model-alignment-to-world-coordinate-system/36725/3 "2024-06-13T13:58:59Z")

</div>

Thank you very much for your prompt response.

1. I apologize for not being clear earlier. I cannot manually align my models as it isn’t accurate enough for my needs.

2. I don’t mind whether it’s done with or without a GUI. I’m currently learning Python, so it would be great to use it for this task and enhance my skills.

You can see exactly what I want to achieve in the first image:

 ![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/c/8/c8b202b1e342d879c662a1955be08b9d51f09268.jpeg)

1. First, set the red point as the origin of the world coordinates (0,0,0).
2. Then, set the green line as the Z-axis of the world coordinates.

The second image shows exactly what I want, but it’s done using another software (Geomagic Wrap). I would prefer to use only open-source software for my study, but it should give you an idea.

 ![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/2/9/29f0b7143a747417e655ed18800dea9da0940045.jpeg)

You can see two circles; I want to achieve that in Slicer too. I think I can manage that on my own, but if I can’t, I’ll discuss it in another post… haha.

I hope I was clear enough. Thanks a lot in advance for your help!

---

<div class="post-metadata">

**Author:** ![muratmaga](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/muratmaga/32/3622_2.png) [@muratmaga](https://discourse.slicer.org/u/muratmaga)\
**Post date:** [June 13, 2024, 2:49pm UTC](https://discourse.slicer.org/t/model-alignment-to-world-coordinate-system/36725/4 "2024-06-13T14:49:31Z")

</div>

this post and specific answer seems relevant to your inquiry:

> [@Creating a new coordinate system](https://discourse.slicer.org/t/creating-a-new-coordinate-system/19446/16):
>
> You can define a coordinate system using a markups plane node: The advantage of using this instead of a transform that you can conveniently place the node using 3 points and then further adjust its position and orientation using interaction handles. Once you have defined the plane, you can get the the transform between this coordinate system and the RAS coordinate system like this: planeToWorld = vtk.vtkMatrix4x4() getNode('P').GetObjectToWorldMatrix(planeToWorld) If you concatenat…

---

<div class="post-metadata">

**Author:** ![Julian\_KC](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/julian_kc/32/18359_2.png) [@Julian\_KC](https://discourse.slicer.org/u/Julian_KC)\
**Post date:** [June 13, 2024, 3:10pm UTC](https://discourse.slicer.org/t/model-alignment-to-world-coordinate-system/36725/5 "2024-06-13T15:10:08Z")

</div>

Thanks for your answer,

I already saw that but I didn’t understood how to use it and apply it to my models,  
Sorry to ask that but can you be a little bit more specific ?

---

<div class="post-metadata">

**Author:** ![Julian\_KC](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/julian_kc/32/18359_2.png) [@Julian\_KC](https://discourse.slicer.org/u/Julian_KC)\
**Post date:** [June 14, 2024, 8:55am UTC](https://discourse.slicer.org/t/model-alignment-to-world-coordinate-system/36725/6 "2024-06-14T08:55:28Z")

</div>

I tried this code :

import slicer  
import numpy as np

# Fonction to Create a translate transform

def create\_translation\_transform(x, y, z):  
transform = slicer.mrmlScene.AddNewNodeByClass(“vtkMRMLTransformNode”)  
matrix = vtk.vtkMatrix4x4()  
matrix.SetElement(0, 3, -x)  
matrix.SetElement(1, 3, -y)  
matrix.SetElement(2, 3, -z)  
transform.SetMatrixTransformToParent(matrix)  
return transform

# Fonction to Align with Z axis

def create\_rotation\_transform(angle, axis):  
transform = slicer.mrmlScene.AddNewNodeByClass(“vtkMRMLTransformNode”)  
matrix = vtk.vtkMatrix4x4()  
axis = np.array(axis) / np.linalg.norm(axis)  
c, s = np.cos(angle), np.sin(angle)  
C = 1 - c  
x, y, z = axis  
matrix.SetElement(0, 0, x_x_C + c)  
matrix.SetElement(0, 1, x_y_C - z_s)  
matrix.SetElement(0, 2, x_z_C + y_s)  
matrix.SetElement(1, 0, y_x_C + z_s)  
matrix.SetElement(1, 1, y_y_C + c)  
matrix.SetElement(1, 2, y_z_C - x_s)  
matrix.SetElement(2, 0, z_x_C - y_s)  
matrix.SetElement(2, 1, z_y_C + x_s)  
matrix.SetElement(2, 2, z_z_C + c)  
transform.SetMatrixTransformToParent(matrix)  
return transform

# Define point to align with origin (0.0.0)

point\_origin = [13.311, -14.499, -1.052] # Remplacer par les coordonnées réelles du point

# Define point of the line to align with z axis

point1 = [16.183, 0.719, 11.181] # Remplacer par les coordonnées réelles du point 1  
point2 = [13.277, -14.627, -1.061] # Remplacer par les coordonnées réelles du point 2

# Compute line direction

line\_direction = np.array(point2) - np.array(point1)  
line\_direction = line\_direction / np.linalg.norm(line\_direction)

# Compute the angle of the line

axis\_z = np.array([0, 0, 1])  
angle = np.arccos(np.dot(line\_direction, axis\_z))

# Create and apply the fonction of translate transforme

translation\_transform = create\_translation\_transform(\*point\_origin)  
slicer.util.getNode(‘YourNodeName’).SetAndObserveTransformNodeID(translation\_transform.GetID())

# Create and apply rotate transform

rotation\_transform = create\_rotation\_transform(angle, np.cross(line\_direction, axis\_z))  
slicer.util.getNode(‘YourNodeName’).SetAndObserveTransformNodeID(rotation\_transform.GetID())

slicer.app.processEvents()

And this is note exactly the result I want :

Before

 ![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/b/5/b5d26c3818bd0f9983aee5e1a024d8b6dfe3e1fc.jpeg)

After

 ![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/1/a/1a9b5b2c2c35935ac1b1d308f39f8b109673980f.jpeg)

But it seems a bit better, but the bounding box and the markups not follow …

---

<div class="post-metadata">

**Author:** ![muratmaga](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/muratmaga/32/3622_2.png) [@muratmaga](https://discourse.slicer.org/u/muratmaga)\
**Post date:** [June 14, 2024, 5:21pm UTC](https://discourse.slicer.org/t/model-alignment-to-world-coordinate-system/36725/7 "2024-06-14T17:21:13Z")

</div>

You need to apply the same transform to the markups as well.

Also, if you want to recenter the bounding box to its new position, make sure the hit the center the FOV icon in 3D viewer.

---

<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:** [June 14, 2024, 5:24pm UTC](https://discourse.slicer.org/t/model-alignment-to-world-coordinate-system/36725/8 "2024-06-14T17:24:11Z")

</div>

> [@Julian\_KC](#):
>
> in the first image

If I rightly understood your requirement, this code snippet may help. You’ll need to add a Plane node anywhere in your scene. The Line guides everything else.

```auto

model = getNode("Model")
line = getNode("L")
# The plane is a wonderful node: it provides its orthogonal axes that we can immediately use. Calculating these axes can become irritating.
plane = getNode("P")

p1Line = [0.0] * 3
p2Line = [0.0] * 3
line.GetNthControlPointPositionWorld(0, p1Line)
line.GetNthControlPointPositionWorld(1, p2Line)

normal = [0.0] * 3
binormal = [0.0] * 3
tangent = [0.0] * 3
# Change the subtraction order if needed.
vtk.vtkMath().Subtract(p2Line, p1Line, normal)
vtk.vtkMath().Normalize(normal)

plane.SetNormalWorld(normal)
plane.SetNthControlPointPositionWorld(0, p2Line)

plane.GetAxesWorld(normal, binormal, tangent)

transform = vtk.vtkTransform()
matrix = transform.GetMatrix()
for r in range(3):
    matrix.SetElement(r, 0, normal[r])
    matrix.SetElement(r, 1, binormal[r])
    matrix.SetElement(r, 2, tangent[r])
    matrix.SetElement(r, 3, p2Line[r])

# Allows alignment of the plane's axes to world axes, and placement at origin.
matrix.Invert()

model.ApplyTransform(transform)
plane.ApplyTransform(transform)
line.ApplyTransform(transform)

```
