Projection Quaternion
Are there projection quaternions like projection matricies? I''ve been working with the idea and was curious if anyone had heard of it before.
That's just my understanding; I could be wrong.
I''m not an expert in quaternions so I may be wrong, but as I understand it a unit quaternion can represent a rotation matrix. Because a projection matrix is not a rotation matrix then I would think that quaternions are not suitable.
I was doing more experiments with quaternion's when I thought of this and I started messing around with equations. This is what I did.
My rotation matrix is defined as so (the inverse of an OpenGL matrix):
; 1st row
Matrix[0] = 2 / (right - left)
Matrix[4] = 0
Matrix[8] = 0
Matrix[12]= - (right + left) / (right - left)
; 2nd row
Matrix[1] = 0
Matrix[5] = 2 / (top - bottom)
Matrix[9] = 0
matrix[13]= - (top + bottom) / (top - bottom)
; 3rd row
Matrix[2] = 0
Matrix[6] = 0
Matrix[10]= - 2 / (far - near)
Matrix[14]= - (far + near) / (far - near)
; 4th row
Matrix[3] = 0
Matrix[7] = 0
Matrix[11]= 0
Matrix[15]= 1
And the lengthy pseudo-code for converting a matrix to a quaternion is:
T = Matrix[0] + Matrix[5] + Matrix[10] + 1
If (T > 0) Then
s = 0.5 / sqrt(T)
x = (Matrix[9] - Matrix[6]) * s
y = (Matrix[2] - Matrix[8]) * s
z = (Matrix[4] - Matrix[1]) * s
w = 0.25 / s
ElseIf (Scale of 1st row is largest) Then
s = 2 * sqrt(Matrix[0] - Matrix[5] - Matrix[10] + 1)
x = 0.5 / s
y = (Matrix[1] + Matrix[4]) / s
z = (Matrix[2] + Matrix[8]) / s
w = (Matrix[6] + Matrix[9]) / s
ElseIf (Scale of 2nd row is largest) Then
s = 2 * sqrt(Matrix[5] - Matrix[0] - Matrix[10] + 1)
x = (Matrix[1] + Matrix[4]) / s
y = 0.5 / s
z = (Matrix[6] + Matrix[9]) / s
w = (Matrix[2] + Matrix[8]) / s
ElseIf (Scale of 3rd row is largest) Then
s = 2 * sqrt(Matrix[10] - Matrix[0] - Matrix[5] + 1)
x = (Matrix[2] + Matrix[8]) / s
y = (Matrix[6] + Matrix[9]) / s
z = 0.5 / s
w = (Matrix[1] + Matrix[4]) / s
EndIf
Substitue the matrix to get:
T = (2 / (right - left)) + (2 / (top - bottom)) + (- 2 / (far - near)) + 1
If (T > 0) Then
s = 0.5 / sqrt(T)
x = (0 - 0) * s
y = (0 - 0) * s
z = (0 - 0) * s
w = 0.25 / s
ElseIf (Scale of 1st row is largest) Then
s = 2 * sqrt((2 / (right - left)) - (2 / (top - bottom)) - (- 2 / (far - near)) + 1)
x = 0.5 / s
y = (0 + 0) / s
z = (0 + 0) / s
w = (0 + 0) / s
ElseIf (Scale of 2nd row is largest) Then
s = 2 * sqrt((2 / (top - bottom)) - (2 / (right - left)) - (- 2 / (far - near)) + 1)
x = (0 + 0) / s
y = 0.5 / s
z = (0 + 0) / s
w = (0 + 0) / s
ElseIf (Scale of 3rd row is largest) Then
s = 2 * sqrt((- 2 / (far - near)) - (2 / (right - left)) - (2 / (top - bottom)) + 1)
x = (0 + 0) / s
y = (0 + 0) / s
z = 0.5 / s
w = (0 + 0) / s
EndIf
Get rid of the redundant bits:
T = (2 / (right - left)) + (2 / (top - bottom)) + (- 2 / (far - near)) + 1
If (T > 0) Then
s = 0.5 / sqrt(T)
w = 0.25 / s
ElseIf (Scale of 1st row is largest) Then
s = 2 * sqrt((2 / (right - left)) - (2 / (top - bottom)) - (- 2 / (far - near)) + 1)
x = 0.5 / s
ElseIf (Scale of 2nd row is largest) Then
s = 2 * sqrt((2 / (top - bottom)) - (2 / (right - left)) - (- 2 / (far - near)) + 1)
y = 0.5 / s
ElseIf (Scale of 3rd row is largest) Then
s = 2 * sqrt((- 2 / (far - near)) - (2 / (right - left)) - (2 / (top - bottom)) + 1)
z = 0.5 / s
EndIf
Optimized it a bit:
sx = 2 / (right - left)
sy = 2 / (top - bottom)
sz = - 2 / (far - near)
s = 0.5 / sqrt(sx + sy + sz + 1)
w = 0.25 / s
s = 2 * sqrt(sx - sy - sz + 1)
x = 0.5 / s
s = 2 * sqrt(sy - sx - sz + 1)
y = 0.5 / s
s = 2 * sqrt(sz - sx - sy + 1)
And Simplify
sx = 2 / (right - left)
sy = 2 / (top - bottom)
sz = - 2 / (far - near)
w = sqrt(sx + sy + sz + 1) * 0.5
x = sqrt(sx - sy - sz + 1) * 0.25
y = sqrt(sy - sx - sz + 1) * 0.25
z = sqrt(sz - sx - sy + 1) * 0.25
I'm no expert on quaternion's either, just curious and experimental. There is probably something wrong with this code, expecially the fact that I can't acount of the translation column in the quaternion, but I supposed those values can be held separately until needed. I haven't been able to write a method of testing this yet, but I'll work on it eventually. If anyone has some code they can throw it in now to test that would cool. I'm curious to see if this works.
[edited by - MindCode on January 14, 2003 1:36:56 PM]
My rotation matrix is defined as so (the inverse of an OpenGL matrix):
; 1st row
Matrix[0] = 2 / (right - left)
Matrix[4] = 0
Matrix[8] = 0
Matrix[12]= - (right + left) / (right - left)
; 2nd row
Matrix[1] = 0
Matrix[5] = 2 / (top - bottom)
Matrix[9] = 0
matrix[13]= - (top + bottom) / (top - bottom)
; 3rd row
Matrix[2] = 0
Matrix[6] = 0
Matrix[10]= - 2 / (far - near)
Matrix[14]= - (far + near) / (far - near)
; 4th row
Matrix[3] = 0
Matrix[7] = 0
Matrix[11]= 0
Matrix[15]= 1
And the lengthy pseudo-code for converting a matrix to a quaternion is:
T = Matrix[0] + Matrix[5] + Matrix[10] + 1
If (T > 0) Then
s = 0.5 / sqrt(T)
x = (Matrix[9] - Matrix[6]) * s
y = (Matrix[2] - Matrix[8]) * s
z = (Matrix[4] - Matrix[1]) * s
w = 0.25 / s
ElseIf (Scale of 1st row is largest) Then
s = 2 * sqrt(Matrix[0] - Matrix[5] - Matrix[10] + 1)
x = 0.5 / s
y = (Matrix[1] + Matrix[4]) / s
z = (Matrix[2] + Matrix[8]) / s
w = (Matrix[6] + Matrix[9]) / s
ElseIf (Scale of 2nd row is largest) Then
s = 2 * sqrt(Matrix[5] - Matrix[0] - Matrix[10] + 1)
x = (Matrix[1] + Matrix[4]) / s
y = 0.5 / s
z = (Matrix[6] + Matrix[9]) / s
w = (Matrix[2] + Matrix[8]) / s
ElseIf (Scale of 3rd row is largest) Then
s = 2 * sqrt(Matrix[10] - Matrix[0] - Matrix[5] + 1)
x = (Matrix[2] + Matrix[8]) / s
y = (Matrix[6] + Matrix[9]) / s
z = 0.5 / s
w = (Matrix[1] + Matrix[4]) / s
EndIf
Substitue the matrix to get:
T = (2 / (right - left)) + (2 / (top - bottom)) + (- 2 / (far - near)) + 1
If (T > 0) Then
s = 0.5 / sqrt(T)
x = (0 - 0) * s
y = (0 - 0) * s
z = (0 - 0) * s
w = 0.25 / s
ElseIf (Scale of 1st row is largest) Then
s = 2 * sqrt((2 / (right - left)) - (2 / (top - bottom)) - (- 2 / (far - near)) + 1)
x = 0.5 / s
y = (0 + 0) / s
z = (0 + 0) / s
w = (0 + 0) / s
ElseIf (Scale of 2nd row is largest) Then
s = 2 * sqrt((2 / (top - bottom)) - (2 / (right - left)) - (- 2 / (far - near)) + 1)
x = (0 + 0) / s
y = 0.5 / s
z = (0 + 0) / s
w = (0 + 0) / s
ElseIf (Scale of 3rd row is largest) Then
s = 2 * sqrt((- 2 / (far - near)) - (2 / (right - left)) - (2 / (top - bottom)) + 1)
x = (0 + 0) / s
y = (0 + 0) / s
z = 0.5 / s
w = (0 + 0) / s
EndIf
Get rid of the redundant bits:
T = (2 / (right - left)) + (2 / (top - bottom)) + (- 2 / (far - near)) + 1
If (T > 0) Then
s = 0.5 / sqrt(T)
w = 0.25 / s
ElseIf (Scale of 1st row is largest) Then
s = 2 * sqrt((2 / (right - left)) - (2 / (top - bottom)) - (- 2 / (far - near)) + 1)
x = 0.5 / s
ElseIf (Scale of 2nd row is largest) Then
s = 2 * sqrt((2 / (top - bottom)) - (2 / (right - left)) - (- 2 / (far - near)) + 1)
y = 0.5 / s
ElseIf (Scale of 3rd row is largest) Then
s = 2 * sqrt((- 2 / (far - near)) - (2 / (right - left)) - (2 / (top - bottom)) + 1)
z = 0.5 / s
EndIf
Optimized it a bit:
sx = 2 / (right - left)
sy = 2 / (top - bottom)
sz = - 2 / (far - near)
s = 0.5 / sqrt(sx + sy + sz + 1)
w = 0.25 / s
s = 2 * sqrt(sx - sy - sz + 1)
x = 0.5 / s
s = 2 * sqrt(sy - sx - sz + 1)
y = 0.5 / s
s = 2 * sqrt(sz - sx - sy + 1)
And Simplify
sx = 2 / (right - left)
sy = 2 / (top - bottom)
sz = - 2 / (far - near)
w = sqrt(sx + sy + sz + 1) * 0.5
x = sqrt(sx - sy - sz + 1) * 0.25
y = sqrt(sy - sx - sz + 1) * 0.25
z = sqrt(sz - sx - sy + 1) * 0.25
I'm no expert on quaternion's either, just curious and experimental. There is probably something wrong with this code, expecially the fact that I can't acount of the translation column in the quaternion, but I supposed those values can be held separately until needed. I haven't been able to write a method of testing this yet, but I'll work on it eventually. If anyone has some code they can throw it in now to test that would cool. I'm curious to see if this works.
[edited by - MindCode on January 14, 2003 1:36:56 PM]
That's just my understanding; I could be wrong.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement