Before I answer that question, I will give a brief summary. So far, we have computed a rotation that takes the 2D plane (the XY plane at Z=0, which will be the output of vtkImageReslice) and rotates it so that it becomes parallel with the 3D slice plane. The next thing we have to do is translate the rotated 2D plane so that is in the same position as the 3D slice plane.
The fourth column of the 4x4 matrix gives the translation.
So the quick answer to your question is: yes, setting the translation to the plane “Origin” is a solution. This works because the point (0,0,0) is on the 2D plane (obviously!), and if we rotate that point it is still (0,0,0), and if we then translate that point by (Origin[0], Origin[1], Origin[2]), then it moves to the vtkPlane’s Origin.
A longer answer is that setting the translation to “Origin” is a bad solution. It is bad because (0,0,0) is usually the corner of the 2D plane (the vtkImageReslice output), and “Origin” is usually the center of the slice plane (controlled by vtkImplicitPlaneWidget2).
It is better to translate the center of the 2D plane to the center of the slice plane.
Let’s define the following variables:
- q = center of 2D plane (center computed from the dimensions of the slice)
- p = center of 3D slice plane (Origin of the vtkPlane)
- R = 3x3 rotation matrix that we computed previously
- t = translation
And write this transformation equation:
Solve for t:
This gives the general solution, if we expand the matrix multiplication:
resliceMatrix->Element[0][3] = origin[0] - center[0]*v1[0] - center[1]*v2[0] - center[2]*normal[0];
resliceMatrix->Element[1][3] = origin[1] - center[0]*v1[1] - center[1]*v2[1] - center[2]*normal[1];
resliceMatrix->Element[2][3] = origin[2] - center[0]*v1[2] - center[1]*v2[2] - center[2]*normal[2];
resliceMatrix->Element[3][3] = 1.0;
In case you are wondering how to compute ‘center’, the answer is that first you must decide on the dimensions of your output slice. For example, if your input volume is 512x512 and voxel spacing is 1 millimeter, then you will probably want to use something like this:
int n = 512; // size in pixels
double s = 1.0; // size of each pixel
reslice->SetOutputOrigin(0.0, 0.0, 0.0);
reslice->SetOutputExtent(0, n-1, 0, n-1, 0, 0);
reslice->SetOutputSpacing(s, s, s);
double center[3] = { 0.5*(n-1)*s, 0.5*(n-1)*s, 0.0 };
You can choose ‘n’ to be whatever you want. If you want to avoid cropping any of the volume when you slice it, then make ‘n’ to be 1.5 times the largest volume dimension.