Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Transforms

Western University, Canada

In linear algebra, transform (or transformation matrix) is used to specify the geometrical relationship between two cartesian coordinate system. There are many use cases:

  • Co-registration between CT and {term}`MRI> volumes

  • Specify the 3D location of an object using tracking systems,

  • Tool calibration, e.g. specifying the location of the tip of surgical drill with respect to the tracking sensor, etc.

That is, in an IGI surgical workflow, there are always multiple rigid bodies, i.e. cartesian coordinate system present:

  • Target anatomy (spine),

  • Surgical tool (needle),

  • Live image or video US) and

  • Geometrical model or representation of anatomy (e.g. surface model derived from CT)

We must keep track of them all the time by understanding how each of these cartesian coordinate system are related with each other.

Translation

The simplest transform is moving a object from one location to another, i.e. a translation.

Let the initial position of an object be pp, and let vv be a translation vector, then the new position of the object qq after translation by vv is:

q=p+vq = p + v

If both pp and vv are multi-dimensional, then this is equivalant to vector addition. In 3D, we have $$

qx=qx+vxqy=qy+vyqz=qz+vz\begin{align} q_x & = & q_x + v_x\\ q_y & = & q_y + v_y\\ q_z & = & q_z + v_z \end{align}

$$

In Python, we can simply use the standard addition operation:

import math
import numpy as np 
import numpy.matlib

p = np.array([ 1, 0, 0 ])      # This is a ROW vector
p = p.reshape(-1, 1)           # this is a COLUMN vector
p = np.array([ [0],[1],[0] ])  # alternative

v = np.array( [4, 5, 6] ).reshape(-1,1)
q = p + v

print("The initial position is:\n", p, 
"\nafter translation by:\n", v,
"\nis now located at:\n", q)
The initial position is:
 [[0]
 [1]
 [0]] 
after translation by:
 [[4]
 [5]
 [6]] 
is now located at:
 [[4]
 [6]
 [6]]

For visualization and other implementations, consult the following tutorial.

Rotation

In 3D, rotation is specified as 3×33 \times 3 matrix RR, and using colomn vector, a point p=(x,y,z)p=(x,y,z) is rotated by RR into q=(x,y,z)q=(x',y',z') as:

$$

A=[abcdefghi]q=Ap=[abcdefghi][xyz]=[xyz]x=ax+by+czy=dx+ey+fzz=gx+hy+iz\begin{align} A & = & \begin{bmatrix} a & b & c\\ d & e & f\\ g & h & i \end{bmatrix} \\ q & = & A p\\ & = & \begin{bmatrix} a & b & c\\ d & e & f\\ g & h & i \end{bmatrix} \begin{bmatrix} x\\ y\\ z \end{bmatrix} = \begin{bmatrix} x'\\ y'\\ z' \end{bmatrix} \\ x' & = & a x + b y + c z\\ y' & = & d x + e y + f z \\ z' & = & g x + h y + i z \end{align}

$$

Rigid Rotation

We are particularly interested in rigid rotation, that that simply rotates an object but do not change its geometry (length, volumen, etc.,). For a 3×33 \times 3 matrix to be a rigid rotation, the following properties must be satisfied:

  1. Each row and each column is a unit vector,

  2. The dot product between each row with every other is 0.

In other word, a rigid rotation is akin to set up an orthonormal axes: each axis has a unit length one, and each axis is perpendicular with each other.

One consequence of these two properties is:

  1. The determinant of a rigid rotation is 1.

Let’s look at some examples.

Rotation about z-axis

Perhaps the most familiar rotation is in fact the rotation about the zz-axis. Most of us are used to perform or study rotation in 2D, i.e. the x-y plane, which is in fact equivalent to rotation about the zz-axis.

The rotation is performed about an axis, called the axis of rotation, by an angle θ\theta. Using the RHR, and when looking from the positive towards the negative of the axis of rotation, the CCW rotation is the positive angle.

That is, if the right-thumb points to the positive direction of the axis of rotation, then the curve of the fingers is the positive rotation.

It should be noted that a point on the axis of rotation is invariant under rotation.

Using the RHR, rotation about zz-axis is thus defined as:

Rz(θ)=[cosθsinθ0sinθcosθ0001]R_z(\theta) = \begin{bmatrix} \cos{\theta} & -\sin{\theta} & 0\\ \sin{\theta} & \cos{\theta} & 0\\ 0 & 0 & 1 \end{bmatrix}

Let’s visualize this: suppose a point p=(1,0,0)p=(1,0,0) and q=(0,1,0)q=(0,1,0) is located on the xx- and yy-axis, respective, and after rotation, we have

p=[cosθsinθ0sinθcosθ0001][100]=[cosθsinθ0]q=[cosθsinθ0sinθcosθ0001][010]=[sinθcosθ0]\begin{align} p' & = & \begin{bmatrix} \cos{\theta} & -\sin{\theta} & 0\\ \sin{\theta} & \cos{\theta} & 0\\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} 1\\ 0 \\ 0 \end{bmatrix} = \begin{bmatrix} \cos{\theta} \\ \sin{\theta} \\ 0 \end{bmatrix} \\ q' & = & \begin{bmatrix} \cos{\theta} & -\sin{\theta} & 0\\ \sin{\theta} & \cos{\theta} & 0\\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} 0\\ 1 \\ 0 \end{bmatrix} = \begin{bmatrix} -\sin{\theta} \\ \cos{\theta} \\ 0 \end{bmatrix} \end{align}
Rotation about z-axis

Figure 1:Rotation about zz-axis visualized.

And for any point r=(0,0,z)r=(0,0,z) on the zz-axis, rotation about the zz-axis does not move rr:

r=[cosθsinθ0sinθcosθ0001][00z]=[00z]=rr' = \begin{bmatrix} \cos{\theta} & -\sin{\theta} & 0\\ \sin{\theta} & \cos{\theta} & 0\\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} 0\\ 0 \\ z \end{bmatrix} = \begin{bmatrix} 0 \\ 0 \\ z \end{bmatrix} = r

It can be implemented in Python as:

import numpy as np
import math

def rotZ3x3( angle_rad ):
    # return a 3x3 rotation about z-axis, where angle is specified in radian

    c = math.cos( angle_rad )
    s = math.sin( angle_rad )
    # a 3x3 identity matrix
    R = np.identity(3)

    # specify the elements of the rotation
    R[0,0] =  c
    R[0,1] = -s
    R[1,0] =  s
    R[1,1] =  c
    return R

A simple test:

p = np.array([1,0,0]).reshape(-1,1)

# rotation by 90 degree
print( np.around( np.matmul( rotZ3x3( math.pi/2 ) , p) ) )
# print( rotZ3x3( math.pi/2 )@p )  # short cut, the @ sign is matrix multiplication
[[0.]
 [1.]
 [0.]]

Inverse Rotation

What happens if, instead rotation by θ\theta, one rotates by θ-\theta instead?

Rz(θ)=[cosθsinθ0sinθcosθ0001]Rz(θ)=[cosθsinθ0sinθcosθ0001]=[cosθsinθ0sinθcosθ0001]\begin{align} R_z(\theta) & = &\begin{bmatrix} \cos{\theta} & -\sin{\theta} & 0\\ \sin{\theta} & \cos{\theta} & 0\\ 0 & 0 & 1 \end{bmatrix}\\ R_z(-\theta) & = & \begin{bmatrix} \cos{-\theta} & -\sin{-\theta} & 0\\ \sin{-\theta} & \cos{-\theta} & 0\\ 0 & 0 & 1 \end{bmatrix}\\ & = & \begin{bmatrix} \cos{\theta} & \sin{\theta} & 0\\ -\sin{\theta} & \cos{\theta} & 0\\ 0 & 0 & 1 \end{bmatrix}\\ \end{align}

Suppose you rotate an object by an angle θ\theta, and immediately rotate it by an angle θ-\theta: nothing changes. Is it true numerically?

Rz(θ)Rz(θ)=[cosθsinθ0sinθcosθ0001][cosθsinθ0sinθcosθ0001]R_z(-\theta) \cdot R_z(\theta) = \begin{bmatrix} \cos{\theta} & \sin{\theta} & 0\\ -\sin{\theta} & \cos{\theta} & 0\\ 0 & 0 & 1 \end{bmatrix} \cdot \begin{bmatrix} \cos{\theta} & -\sin{\theta} & 0\\ \sin{\theta} & \cos{\theta} & 0\\ 0 & 0 & 1 \end{bmatrix}
Rz(θ)Rz(θ)=[cosθsinθ0sinθcosθ0001][cosθsinθ0sinθcosθ0001]=[cosθcosθ+sinθsinθcosθsinθ+cosθsinθ0cosθsinθ+cosθsinθsinθsinθ+cosθcosθ0001]=[cosθ2+sinθ2000sinθ2+cosθ20001]=[100010001]\begin{align} R_z(-\theta) \cdot R_z(\theta) & = & \begin{bmatrix} \cos{\theta} & \sin{\theta} & 0\\ -\sin{\theta} & \cos{\theta} & 0\\ 0 & 0 & 1 \end{bmatrix} \cdot \begin{bmatrix} \cos{\theta} & -\sin{\theta} & 0\\ \sin{\theta} & \cos{\theta} & 0\\ 0 & 0 & 1 \end{bmatrix} \\ & = & \begin{bmatrix} \cos{\theta} \cos{\theta} + \sin{\theta} \sin{\theta} & -\cos{\theta} \sin{\theta} + \cos{\theta} \sin{\theta} & 0\\ -\cos{\theta} \sin{\theta} + \cos{\theta} \sin{\theta} & \sin{\theta} \sin{\theta} + \cos{\theta} \cos{\theta} & 0\\ 0 & 0 & 1 \end{bmatrix}\\ & = & \begin{bmatrix} \cos{\theta}^2 + \sin{\theta}^2 & 0 & 0\\ 0 & \sin{\theta}^2 + \cos{\theta}^2 & 0\\ 0 & 0 & 1 \end{bmatrix}\\ & = & \begin{bmatrix} 1 & 0 & 0\\ 0 & 1 & 0\\ 0 & 0 & 1 \end{bmatrix} \end{align}

You should also notice that Rz(θ)=Rz(θ)TR_z(-\theta)=R_z(\theta)^T, the transpose.

# rotation by pi/4 followed by rotation by -pi/4
print( np.around( np.matmul( rotZ3x3( -math.pi/4 ) , rotZ3x3( math.pi/4)) ) )
[[1. 0. 0.]
 [0. 1. 0.]
 [0. 0. 1.]]

Rotation about xx-axis

To visualize how to perform rotation about the xx-axis, position yourself at +x+x direction looking towards the origin.

Rotation about x-axis

Figure 2:Rotation about xx-axis visualized.

Again, a point on the xx-axis remains invariant under rotation about the xx-axis.

Using this visualization, one can infer that the 3×33\times 3 rotation about the xx-axis by an angle θ\theta is:

Rx(θ)=[1000cosθsinθ0sinθcosθ]R_x(\theta) = \begin{bmatrix} 1 & 0 & 0\\ 0 & \cos{\theta} & -\sin{\theta}\\ 0 & \sin{\theta} & \cos{\theta} \end{bmatrix}
def rotX3x3( angle_rad ):
    # return a 3x3 rotation about z-axis, where angle is specified in radian

    c = math.cos( angle_rad )
    s = math.sin( angle_rad )
    # a 3x3 identity matrix
    R = np.identity(3)

    # specify the elements of the rotation
    R[1,1] =  c
    R[1,2] = -s
    R[2,1] =  s
    R[2,2] =  c
    return R
[[ 1.  0.  0.]
 [ 0.  0. -1.]
 [ 0.  1.  0.]]

Rotation about yy-axis

To visualize how to perform rotation about the yy-axis, position yourself at +y+y direction looking towards the origin.

Rotation about y-axis

Figure 3:Rotation about yy-axis visualized.

Again, a point on the yy-axis remains invariant under rotation about the yy-axis.

Using this visualization, one can infer that the 3×33\times 3 rotation about the yy-axis by an angle θ\theta is:

Ry(θ)=[cosθ0sinθ010sinθ0cosθ]R_y(\theta) = \begin{bmatrix} \cos{\theta} & 0 & \sin{\theta}\\ 0 & 1 & 0\\ -\sin{\theta} & 0 & \cos{\theta} \end{bmatrix}
def rotY3x3( angle_rad ):
    # return a 3x3 rotation about z-axis, where angle is specified in radian

    c = math.cos( angle_rad )
    s = math.sin( angle_rad )
    # a 3x3 identity matrix
    R = np.identity(3)

    # specify the elements of the rotation
    R[0,0] =  c
    R[0,2] =  s
    R[2,0] = -s
    R[2,2] =  c
    return R

Successive Rotations

Suppose you are interested in rotating an object pp about the xx-axis by an angle α\alpha, and further by rotating the rotated object about the yy-axis by an angle β\beta, how would this be achieved?

Let pp' be the rotated object after the rotation about the xx-axis by an angle α\alpha:

p3×1=Rx(α)3×3p3×1p'_{3\times 1} = R_x(\alpha)_{3\times 3} \cdot p_{3\times 1}

and pp'' be the rotated object after the rotation about the yy-axis by an angle β\beta:

p3×1=Ry(β)3×3p3×1p''_{3 \times 1} = R_y(\beta)_{3 \times 3} \cdot p'_{3\times 1}

Thus

p3×1=Ry(β)3×3p3×1=Ry(β)3×3Rx(α)3×3p3×1\begin{align} p''_{3 \times 1} & = & R_y(\beta)_{3 \times 3} \cdot p'_{3\times 1}\\ & = & R_y(\beta)_{3 \times 3} \cdot R_x(\alpha)_{3\times 3} \cdot p_{3\times 1} \end{align}

Because matrix multiplication is associative, we can indeed define a combined rotation matrix:

R3×3=Ry(β)3×3Rx(α)3×3R_{3 \times 3} = R_y(\beta)_{3 \times 3} \cdot R_x(\alpha)_{3\times 3}

and

p3×1=R3×3p3×1p''_{3 \times 1}=R_{3 \times 3} \cdot p_{3\times 1}

That is, instead of thinking about successive rotations as a series of rotations, it is often more intuitive to think of it as just one rotation about an axis of rotation instead.

For visualization and other implementations, consult the following tutorial.

Rotation About an Unit Vector

One omission in the above introduction to rotation, one is often done, is that rotation is performed about a vector. In the previous examples, i.e. rotation about xx-, yy-, and zz-axis, is in fact rotation about the orthonormal basis located at the origin.

That is, rotation about the xx-axis should been seen as rotation about the unit i=(1,0,0)i=(1,0,0) originated at (0,0,0)(0,0,0)

In fact, the rotation can be perform about an arbitrary axis in space. The axis of rotation is specified as a unit orientation vector v=(vx,vy,vz)v=(v_x,v_y,v_z) anchord at a point p=(px,py,pz)p=(p_x,p_y,p_z).

If the axis of rotation vv is originated at the origin (0,0,0)(0,0,0), than rotation about the unit vector v=(vx,vy,vz)v=(v_x,v_y,v_z) by an angle θ\theta can be represented as a 3×33\times 3 rotation matrix using the following formula:

R(v,θ)=[vxvx(1cosθ)+cosθvxvy(1cosθ)vzsinθvxvz(1cosθ)+vysinθvyvx(1cosθ)+vzsinθvyvy(1cosθ)+cosθvyvz(1cosθ)vxsinθvzvx(1cosθ)vysinθvzvy(1cosθ)+vxsinθvzvz(1cosθ)+cosθ]R(v,\theta) = \begin{bmatrix} v_x \cdot v_x \cdot (1-\cos{\theta}) + \cos{\theta} & v_x \cdot v_y \cdot (1-\cos{\theta}) - v_z \cdot \sin{\theta} & v_x \cdot v_z \cdot (1-\cos{\theta}) + v_y \cdot \sin{\theta}\\ v_y \cdot v_x \cdot (1-\cos{\theta}) + v_z \cdot \sin{\theta} & v_y \cdot v_y \cdot (1-\cos{\theta}) + \cos{\theta} & v_y \cdot v_z \cdot (1-\cos{\theta}) - v_x \cdot \sin{\theta}\\ v_z \cdot v_x \cdot (1-\cos{\theta}) - v_y \cdot \sin{\theta} & v_z \cdot v_y \cdot (1-\cos{\theta}) + v_x \cdot \sin{\theta} & v_z \cdot v_z \cdot (1-\cos{\theta}) + \cos{\theta}\\ \end{bmatrix}
def axang2rotm( anang ):
    #
    # Convert the axis-angle rotation into a 3x3 rotation matrix
    #
    # The name is the same as the equivalent function in Matlab (under Navigation Toolbox)
    #
    # Assumes that axang is a row vector of 4:
    #
    # axanx = numpy.array([vx, vy, vz, angle])
    #
    #    where (vx,vy,vz) is axis of rotation, and
    #          angle in radian
    #

    # extract components from the input vector
    x     = anang[0]
    y     = anang[1]
    z     = anang[2]
    angle = anang[3]

    # make sure that and axis of rotation is a unit vector
    l = math.sqrt(x*x + y*y + z*z)
    x = x/l
    y = y/l
    z = z/l
    
    R = np.identity(3)
    
    xx = x * x
    xy = x * y
    xz = x * z

    yy = y * y
    yz = y * z
    
    zz = z * z
    
    ca = math.cos( angle )
    sa = math.sin( angle )
    vers_a = 1 - ca # versine(angle) = 2 * sin^2(angle/2)
    
    R[0,0] = xx * vers_a +     ca
    R[0,1] = xy * vers_a - z * sa
    R[0,2] = xz * vers_a + y * sa
    
    R[1,0] = xy * vers_a + z * sa
    R[1,1] = yy * vers_a +     ca
    R[1,2] = yz * vers_a - x * sa
    
    R[2,0] = xz * vers_a - y * sa
    R[2,1] = yz * vers_a + x * sa
    R[2,2] = zz * vers_a +     ca
    
    return R

You can verify if we can use the above function to reproduce rotation about xx-, yy-, and zz-axis:

print( "rotation about x-axis by 90 degree is:\n", np.around(axang2rotm(np.array([1,0,0,math.pi/2]))))
print( "rotation about y-axis by 90 degree is:\n", np.around(axang2rotm(np.array([0,1,0,math.pi/2]))))
print( "rotation about z-axis by 90 degree is:\n", np.around(axang2rotm(np.array([0,0,1,math.pi/2]))))
rotation about x-axis by 90 degree is:
 [[ 1.  0.  0.]
 [ 0.  0. -1.]
 [ 0.  1.  0.]]
rotation about y-axis by 90 degree is:
 [[ 0.  0.  1.]
 [ 0.  1.  0.]
 [-1.  0.  0.]]
rotation about z-axis by 90 degree is:
 [[ 0. -1.  0.]
 [ 1.  0.  0.]
 [ 0.  0.  1.]]

We can verify our formulation against vtkTransform

import math
import numpy as np

from vtkmodules.vtkCommonTransforms import vtkTransform
myTransform = vtkTransform()
myTransform.PostMultiply()
myTransform.Identity()
myTransform.RotateWXYZ( 33, 1, 2, 3) # angle in degree

print("Our implementation: \n", axang2rotm(np.array([1,2,3,33*math.pi/180])), "\n")
print("VTK implementation: \n", myTransform.GetMatrix())
Our implementation: 
 [[ 0.8501941  -0.41363565  0.3256924 ]
 [ 0.45972978  0.88476469 -0.07641972]
 [-0.25655122  0.21470209  0.94238235]] 

VTK implementation: 
 vtkMatrix4x4 (000002829DD518B0)
  Debug: Off
  Modified Time: 84
  Reference Count: 2
  Registered Events: (none)
  Elements:
    0.850194 -0.413636 0.325692 0 
    0.45973 0.884765 -0.0764197 0 
    -0.256551 0.214702 0.942382 0 
    0 0 0 1 


What If the Axis of Rotation does not Originate from the Origin?

If the axis of rotation vv does not originate from the origin, i.e. OP+vtO\ne P + v t for any tt and a fixed point PP on the line, then rotation about P+vtP+v t by an angle θ\theta is performe in 3 steps:

  1. Translate by P-P, i.e. so now the rotation is performed about vv that is originated from the origin O=(0,0,0)O=(0,0,0),

  2. Perform rotation about vv by θ\theta, followed by

  3. Translate by PP

Homogeneous Transformation

Suppower you want to rotate an object (e.g. a point) aa about a vector P+vtP+v t that does not originate from the origin (i.e. P(0,0,0)P\ne (0,0,0)), base on this discussion you would need to perform the following operation in succession:

  1. Translate by P-P, i.e.

    a=1P+aa' = -1 * P + a
  2. Rotate by vv by θ\theta, i.e.

    a=R(v,θ)3×3aa'' = R(v,\theta)_{3\times 3} \cdot a'
  3. Translate by +P+P, i.e.

    a=P+aa''' = P + a''

    which involves 1×31\times 3 column vectors (translation) and 3×33\times 3 square matrices (rotation), with two operators (vectors addition and matrix multiplication). For a longer, successive operations of translations and rotation, both the notation and mathematical operation will become intractable very quickly.

The solution is to work in homogeneous coordinates instead. That is, instead of using 3×33\times 3 matrix and 1×31\times 3 vector to represent rotation and translation, respectively, one use 4×44 \times 4 matrix to represent both.

Translation

Traslation by an amount t=(tx,ty,tz)t=(t_x,t_y,t_z) is represented by

T(t)=[100tx010ty001tz0001]4×4T(t) = \begin{bmatrix} 1&0&0&t_x\\ 0&1&0&t_y\\ 0&0&1&t_z\\ 0 & 0 & 0&1 \end{bmatrix}_{4 \times 4}

Rotation

Rotation about a vector vv originalted from the origin by an angle θ\theta is represented by

T(v,θ)=[R(v,θ)3×301×303×11]4×4T(v,\theta) = \begin{bmatrix} R(v,\theta)_{3\times 3} & 0_{1\times 3}\\ 0_{3\times 1} & 1 \end{bmatrix}_{4 \times 4}

For example, rotation about xx-axis by an angle θ\theta is now represented as:

Rx(θ)=[10000cosθsinθ00sinθcosθ00001]R_x(\theta) = \begin{bmatrix} 1 & 0 & 0 & 0\\ 0 & \cos{\theta} & -\sin{\theta} & 0\\ 0 & \sin{\theta} & \cos{\theta} & 0\\ 0&0&0&1 \end{bmatrix}

Rotation about yy-axis by an angle θ\theta is:

Ry(θ)=[cosθ0sinθ00100sinθ0cosθ00001]R_y(\theta) = \begin{bmatrix} \cos{\theta} & 0 & \sin{\theta} & 0\\ 0 & 1 & 0 & 0\\ -\sin{\theta} & 0 & \cos{\theta} &0\\ 0&0&0&1 \end{bmatrix}

Rotation about zz-axis by an angle θ\theta is:

Rz(θ)=[cosθsinθ00sinθcosθ0000100001]R_z(\theta) = \begin{bmatrix} \cos{\theta} & -\sin{\theta} & 0 & 0\\ \sin{\theta} & \cos{\theta} & 0 & 0\\ 0 & 0 & 1 & 0\\ 0&0&0&1 \end{bmatrix}

Successive Transforms

Notice that both translation and rotation are now represented as 4×44\times 4 matrices. Apply either the translation or the rotation operation is now performed as matrix multiplication. To translate a point P=Px,Py,PzP={P_x,P_y,P_z} by t=tx,ty,tzt={t_x,t_y,t_z}, append a 1 as the 4th4^{th} column:

P=[PxPyPz1]1×4=[100tx010ty001tz0001]4×4[PxPyPz1]1×4P' = \begin{bmatrix} P'_x \\ P'_y \\ P'_z \\ 1\end{bmatrix}_{1\times 4} = \begin{bmatrix} 1&0&0&t_x\\ 0&1&0&t_y\\ 0&0&1&t_z\\ 0 & 0 & 0&1 \end{bmatrix}_{4 \times 4} \cdot \begin{bmatrix} P_x \\ P_y \\ P_z \\ 1 \end{bmatrix}_{1 \times 4}

and after matrix multiplication:

Px=Px+txPy=Py+tyPz=Pz+tz\begin{align} P'_x & = & P_x + t_x \\ P'_y & = & P_y + t_y \\ P'_z & = & P_z + t_z \end{align}

which is same as before.

Similiarly, rotation by the xx-axis by an angle θ\theta is:

P=[PxPyPz1]1×4=Rx(θ)=[10000cosθsinθ00sinθcosθ00001][PxPyPz1]1×4P' = \begin{bmatrix} P'_x \\ P'_y \\ P'_z \\ 1\end{bmatrix}_{1\times 4} = R_x(\theta) = \begin{bmatrix} 1 & 0 & 0 & 0\\ 0 & \cos{\theta} & -\sin{\theta} & 0\\ 0 & \sin{\theta} & \cos{\theta} & 0\\ 0&0&0&1 \end{bmatrix} \cdot \begin{bmatrix} P_x \\ P_y \\ P_z \\ 1\end{bmatrix}_{1\times 4}
Px=PxPy=cosθPysinθPzPz=sinθPy+sinθPz\begin{align} P'_x & = & P_x \\ P'_y & = & \cos{\theta} P_y - \sin{\theta} P_z \\ P'_z & = & \sin{\theta} P_y + \sin{\theta} P_z \end{align}

which is same as before.

Successive transformations such as rotation about an arbitrary vector P+vtP + v \cdot t is now represented as matrices multiplication:

b=[bxbybz1]1×4=[100Px010Py001Pz0001]4×4[R(v,θ)03×101×31]4×4[100Px010Py001Pz0001]4×4[axayaz1]1×4b = \begin{bmatrix} b_x \\ b_y \\ b_z \\ 1\end{bmatrix}_{1\times 4} = \begin{bmatrix} 1&0&0&P_x\\ 0&1&0&P_y\\ 0&0&1&P_z\\ 0 & 0 & 0&1 \end{bmatrix}_{4 \times 4} \begin{bmatrix} R(v,\theta) & 0_{3\times 1}\\ 0_{1\times 3}&1 \end{bmatrix}_{4\times 4} \begin{bmatrix} 1&0&0&-P_x\\ 0&1&0&-P_y\\ 0&0&1&-P_z\\ 0 & 0 & 0&1 \end{bmatrix}_{4 \times 4} \begin{bmatrix} a_x \\ a_y \\ a_z \\ 1\end{bmatrix}_{1\times 4}

Moreover, the inverse transform can be trivially found by computing the inverse of the matrices. This left as an exercise for you. You may wish to consult this old but concise document for detail.

For visualization and other implementations, consult the following tutorial.

Change of Persectives

Suppose Alice and Bob are sitting on a couch watching TV. The TV is directly in front of Alice, and Bob sits on the right of Alice. Where is the TV from Bob’s perspective?

For the purpose of the discussion, let the COG of the TV denotes the position of the TV. If we assign a cartesian coordinate system to Bob, we can specify a coordinate the location of the TV from Bob’s perspective. For this trivial example, suppose the TV is located at p=(0,5,0)p=(0,5,0) at the coordinate system associated with Bob

Location of TV from Bob's perspective

Figure 4:The position, denoted as a red circle, is specified from Bob’s perspective.

Suppose Alice is sitting sitting at a=(3,0,0)a=(-3,0,0) (from Bob’s perspective). We can also assign a cartesian coordinate system to Alice: for the moment, assume that the orientation of Alice’s and Bob’s cartesian coordinate system have the same orientation. That is, both of their +x+x-axis point to the same direction, and both their +y+y-axis point to the same direction.

Location of TV from Alice's perspective

Figure 5:Alice sits next to Bob.

Where is the TV (pp) from Alice’s perspective?

From Figure 5 you may infer that, because Bob is at (3,0,0)(3,0,0) (i.e. inverse of where Alice is from Bob), and the TV is located at (0,5,0)(0,5,0) from Bob, the TV is located at (3,5,0)(3,5,0) from Alice.

But how do we express this mathematically?

Transformation: Translation

Let BobTAlice^{Bob}T_{Alice} denote the geometrical relationship between Alice and Bob from Bob’s perspective:

BobTAlice=[1003010000100001]^{Bob}T_{Alice} = \begin{bmatrix} 1 & 0 & 0 & -3\\ 0 & 1 & 0 & 0\\ 0 & 0 & 1 & 0\\ 0 & 0 & 0 & 1 \end{bmatrix}

We adopt the notation of superscript^{superscript} and subscript_{subscript} to indicate the transformation from_{from} one coordinate system to another^{another}. For example, the location of Alice, (0,0,0)(0,0,0), in her local coordinate system can be brought from Alice_{Alice} to Bob^{Bob} via:

Bob[3001]=Bob[1003010000100001]AliceAlice[0001]^{Bob}\begin{bmatrix} -3 \\ 0 \\ 0 \\ 1 \end{bmatrix} = ^{Bob}\begin{bmatrix} 1 & 0 & 0 & -3\\ 0 & 1 & 0 & 0\\ 0 & 0 & 1 & 0\\ 0 & 0 & 0 & 1 \end{bmatrix}_{Alice} \cdot ^{Alice}\begin{bmatrix} 0 \\ 0 \\ 0 \\ 1 \end{bmatrix}

Conversely, from Alice’s point of view, Bob is located at (3,0,0)(3,0,0), and

AliceTBob=[1003010000100001]^{Alice}T_{Bob} = \begin{bmatrix} 1 & 0 & 0 & 3\\ 0 & 1 & 0 & 0\\ 0 & 0 & 1 & 0\\ 0 & 0 & 0 & 1 \end{bmatrix}

Notice that AliceTBob^{Alice}T_{Bob} is the inverse of BobTAlice^{Bob}T_{Alice} (You should verify this by computing the inverse of the matrices themselves). Notice that the position of the TV is p=(0,5,0)p=(0,5,0) from Bob’s perspective, we can compute where it is from Alice’s perspective using the transformation:

Alice[3501]=Alice[1003010000100001]BobBob[0501]^{Alice}\begin{bmatrix} 3\\5\\0\\1\end{bmatrix} = ^{Alice}\begin{bmatrix} 1 & 0 & 0 & 3\\ 0 & 1 & 0 & 0\\ 0 & 0 & 1 & 0\\ 0 & 0 & 0 & 1 \end{bmatrix}_{Bob} \cdot ^{Bob}\begin{bmatrix} 0\\5\\0\\1\end{bmatrix}

One Key to help you in writing down this sequence os matrix multiplication is to note that the successive subscript_{subscript} and superscript^{superscript} must match.

Location of TV from Alice's perspective

Figure 6:Location of TV from Alice’s perspective.

To illustrate this point one more time, now we know that the TV, from Alice’s perspective, is located at (3,5,0)(3,5,0). To find out where it is from Bob’s perspective, we use:

Bob[0501]=Bob[1003010000100001]AliceAlice[3501]^{Bob}\begin{bmatrix} 0 \\ 5 \\ 0 \\ 1\end{bmatrix} = ^{Bob}\begin{bmatrix} 1 & 0 & 0 & -3\\ 0 & 1 & 0 & 0\\ 0 & 0 & 1 & 0\\ 0 & 0 & 0 & 1 \end{bmatrix}_{Alice} \cdot ^{Alice}\begin{bmatrix} 3 \\ 5 \\ 0 \\ 1 \end{bmatrix}

Transformation: Rotation and Translation

In the previous discussion, the transform only involves a simple translation (between Alice and Bob). What if Alice defines her local coordinate system differently than Bob (say, she’s left handed and Bob is right handed?).

Alice's rotated perspective

Figure 7:The orientation of the local coordinate system of Alice is different than that of Bob.

You will notice that there is a rotation about the zz-axis by 90°90\degree between Alice’s and Bob’s coordinate systems:

BobTAlice=[0103100000100001]^{Bob}T_{Alice} = \begin{bmatrix} 0 & -1 & 0 & -3\\ 1 & 0 & 0 & 0\\ 0 & 0 & 1 & 0\\ 0 & 0 & 0 & 1 \end{bmatrix}

and

AliceTBob=[0100100300100001]^{Alice}T_{Bob} = \begin{bmatrix} 0 & 1 & 0 & 0\\ -1 & 0 & 0 & -3\\ 0 & 0 & 1 & 0\\ 0 & 0 & 0 & 1 \end{bmatrix}

And in this new coordinate system of Alice, the location of the TV p(0,5,0)p(0,5,0) is now:

Alice[5301]=Alice[0100100300100001]BobBob[0501]^{Alice}\begin{bmatrix} 5\\-3\\0\\1\end{bmatrix} = ^{Alice}\begin{bmatrix} 0 & 1 & 0 & 0\\ -1 & 0 & 0 & -3\\ 0 & 0 & 1 & 0\\ 0 & 0 & 0 & 1 \end{bmatrix}_{Bob} \cdot ^{Bob}\begin{bmatrix} 0\\5\\0\\1\end{bmatrix}
TV from Alice's perspective

Figure 8:The coordinate of the TV from Alice’s perspective.

But How?

To walk you through the process of constructing the transform that links one coordinate system with another, refer to Figure 8. To construct the transformation BobTAlice^{Bob}T_{Alice} that see what Alice sees from Bob’s perspective, consider

  1. How are the base vectors of Alice’s coordinate system mapped to Bob’s, and

  2. How is the origin of Alice’s coordinate system mapped to Bob’s.

We proceed by noticing that

  1. The +x+x-axis of Alice’s coordinate system, which maps to Bob’s +y+y-axis (1st1^{st} colume of BobTAlice^{Bob}T_{Alice}),

  2. The +y+y-axis of Alice’s coordinate system, which maps to Bob’s x-x-axis (2nd2^{nd} colume of BobTAlice^{Bob}T_{Alice}),

  3. The +z+z-axis of Alice’s coordinate system, which maps to Bob’s +z+z-axis (3rd3^{rd} colume of BobTAlice^{Bob}T_{Alice}, i.e. no change), and

  4. The origin of Alice’s coordinate system is located at (3,0,0)(-3,0,0) from Bob’s point of view (4th4^{th} column of BobTAlice^{Bob}T_{Alice}).

That is,

  1. The rotational component of the transformation is to map the base axes from one another, and

  2. The translational component of the transformation is the translation of the origins.