open-discussion > How to apply transformation matrix
Showing 1-8 of 8 posts
Dec 3, 2013 05:12 PM | Marc Lalancette - Montreal Neurological Institute
How to apply transformation matrix
Hello,
I'm starting to use GIFTI in a tool I'm writing and I didn't find anywhere a description of how the transformation matrix is to be applied to point coordinates. I assume it is meant to be like in NIFTI files, but I think it should be specified explicitly to avoid mistakes and thus incompatibilities between software. So if p is a column vector of (x, y, z, 1), and T is the transformation matrix, is it meant to be applied as:
A) T * p
as I suspect, or
B) p' * T
(p' being the transposed, row vector form of p) ?
Cheers,
Marc
I'm starting to use GIFTI in a tool I'm writing and I didn't find anywhere a description of how the transformation matrix is to be applied to point coordinates. I assume it is meant to be like in NIFTI files, but I think it should be specified explicitly to avoid mistakes and thus incompatibilities between software. So if p is a column vector of (x, y, z, 1), and T is the transformation matrix, is it meant to be applied as:
A) T * p
as I suspect, or
B) p' * T
(p' being the transposed, row vector form of p) ?
Cheers,
Marc
Dec 3, 2013 06:12 PM | John Harwell
RE: How to apply transformation matrix
From the GIFTI document:
2.8 MatrixData2.8.1 Description – Contains 16 text values representing a double- precision 4x4 transformation matrix. The values are listed as a one- dimensional array in row-major order which is used by most programming languages with the exception of FORTRAN and MATLAB. Note that OpenGL uses column-major order for its matrices.For example, the matrix below would appear as "m1 m2 m3 m4 m5 m6 m7 m8 m9 m10 m11 m12 m13 m14 m15 m16" is the MatrixData11 element.
m1 m2 m3 m4
m5 m6 m7 m8
m9 m10 m11 m12
m13 m14 m15 m16
Since the GIFTI transformation matrix is in row-major order, the translation values are in the bottom row (m13, m14, m15). I believe the NIFTI SFORM is column-major order (translation values are in the right-most column).
2.8 MatrixData2.8.1 Description – Contains 16 text values representing a double- precision 4x4 transformation matrix. The values are listed as a one- dimensional array in row-major order which is used by most programming languages with the exception of FORTRAN and MATLAB. Note that OpenGL uses column-major order for its matrices.For example, the matrix below would appear as "m1 m2 m3 m4 m5 m6 m7 m8 m9 m10 m11 m12 m13 m14 m15 m16" is the MatrixData11 element.
m1 m2 m3 m4
m5 m6 m7 m8
m9 m10 m11 m12
m13 m14 m15 m16
Since the GIFTI transformation matrix is in row-major order, the translation values are in the bottom row (m13, m14, m15). I believe the NIFTI SFORM is column-major order (translation values are in the right-most column).
Dec 3, 2013 07:12 PM | Marc Lalancette - Montreal Neurological Institute
RE: How to apply transformation matrix
Thanks John.
To confirm then, the correct transformation would be:
(x, y, z, 1) * T
which is not the same as with NIFTI sform.
Unless I'm missing something, row-major or column-major order only specifies how the data is stored (how to convert from a list to a 2d matrix). It does not imply anything about the meaning of the values in the matrix. And I didn't see any indication that (m13, m14, m15) were the translation values. So I really think this should be indicated in the documentation. I suspect I'm not the only one that would have assumed the "wrong way" of making the transformation.
Thanks again for your prompt reply!
Cheers
To confirm then, the correct transformation would be:
(x, y, z, 1) * T
which is not the same as with NIFTI sform.
Unless I'm missing something, row-major or column-major order only specifies how the data is stored (how to convert from a list to a 2d matrix). It does not imply anything about the meaning of the values in the matrix. And I didn't see any indication that (m13, m14, m15) were the translation values. So I really think this should be indicated in the documentation. I suspect I'm not the only one that would have assumed the "wrong way" of making the transformation.
Thanks again for your prompt reply!
Cheers
Dec 3, 2013 08:12 PM | John Harwell
RE: How to apply transformation matrix
OpenGL uses column-major order and an appendix in the OpenGL "Red
Book" (http://www.glprogramming.com/red/appendi...) shows the translation values in the right-most column.
Since the GIFTI spec indicates that the transformation matrix
data is in row-major order, the translation values must be in the
bottom row and hence values (m13, m14, m15).
I don't want to answer the pre- or post-multiply question. The best way is to create some data and test it.
I don't want to answer the pre- or post-multiply question. The best way is to create some data and test it.
Dec 3, 2013 11:12 PM | Marc Lalancette - Montreal Neurological Institute
RE: How to apply transformation matrix
Hmm... I'm getting more and more uncertain.
I think the meaningful object here is the matrix, not the storage order of elements. Thus if the OpenGL convention is to have the translation elements on the right of the matrix, and you want to follow that convention but with row-major order, shouldn't the translation elements not be in m13, 14, 15, but accordingly in m4, 8, 12? Then the transformation would be M * v (as in chapter 3 of that "red book"). But if you decided to have the convention of translation elements in 13, 14, 15, then the proper transformation would be M^T * v (or v^T * M).
Either way, the ambiguity seems a problem to me. If the GIFTI specification doesn't say, then different programs will decide to do it differently and thus be incompatible. As it stands, I'm still not sure.
You're right that if all I needed was to take GIFTI files created from a single other source, I could just try and figure out how they implemented it, but since I'm currently implementing my own, I have to decide how to encode and use this matrix. I could do it both ways and it would work. I just assumed that there would be a convention in the GIFTI format that I should follow.
I think the meaningful object here is the matrix, not the storage order of elements. Thus if the OpenGL convention is to have the translation elements on the right of the matrix, and you want to follow that convention but with row-major order, shouldn't the translation elements not be in m13, 14, 15, but accordingly in m4, 8, 12? Then the transformation would be M * v (as in chapter 3 of that "red book"). But if you decided to have the convention of translation elements in 13, 14, 15, then the proper transformation would be M^T * v (or v^T * M).
Either way, the ambiguity seems a problem to me. If the GIFTI specification doesn't say, then different programs will decide to do it differently and thus be incompatible. As it stands, I'm still not sure.
You're right that if all I needed was to take GIFTI files created from a single other source, I could just try and figure out how they implemented it, but since I'm currently implementing my own, I have to decide how to encode and use this matrix. I could do it both ways and it would work. I just assumed that there would be a convention in the GIFTI format that I should follow.
Dec 4, 2013 02:12 AM | Richard Reynolds
RE: How to apply transformation matrix
Hi Marc,
Transformation matrices T(x) are generally considered to
be applied as T*x, though there are some who prefer it
the other way. NIFTI (and therefore GIFTI) apply it in that
common way, as specified in the NIFTI standard.
The most detailed description of the NIFTI standard is in
the nifti1.h header file, here:
nifti.nimh.nih.gov
Search for either "Method 2" or "Method 3", though the
latter is more appropriate, as it applies directly to the stored
matrix, rather than one derived from a qform.
- rick
Transformation matrices T(x) are generally considered to
be applied as T*x, though there are some who prefer it
the other way. NIFTI (and therefore GIFTI) apply it in that
common way, as specified in the NIFTI standard.
The most detailed description of the NIFTI standard is in
the nifti1.h header file, here:
nifti.nimh.nih.gov
Search for either "Method 2" or "Method 3", though the
latter is more appropriate, as it applies directly to the stored
matrix, rather than one derived from a qform.
- rick
Dec 4, 2013 02:12 AM | Richard Reynolds
RE: How to apply transformation matrix
To be clear, GIFTI_Surface_Format.pdf does specify row-major
order, as is also used in NIFTI. That does not mean the offsets
are along the bottom row. The offsets are along the right column.
For an example, consider the FreeSurfer sample data, where the
matrix is not an identity. There the offsets are in the right column,
and the bottom row is 0, 0, 0, 1, as it should always be.
NIFTI and GIFTI use the same format, as they should.
- rick
order, as is also used in NIFTI. That does not mean the offsets
are along the bottom row. The offsets are along the right column.
For an example, consider the FreeSurfer sample data, where the
matrix is not an identity. There the offsets are in the right column,
and the bottom row is 0, 0, 0, 1, as it should always be.
NIFTI and GIFTI use the same format, as they should.
- rick
Dec 4, 2013 03:12 PM | Marc Lalancette - Montreal Neurological Institute
RE: How to apply transformation matrix
Thanks Richard. I'll go with that decisive statement. I
was familiar with the NIFTI documentation as I've been using it for
a few years. But I wanted confirmation that GIFTI was the
same given it wasn't stated in the documentation.
And given John's reply, maybe it's not as obvious as the developers might have thought.
Anyway, thanks for the help!
Cheers
And given John's reply, maybe it's not as obvious as the developers might have thought.
Anyway, thanks for the help!
Cheers