# [csswg-drafts] [css-transforms] Quaternion calculation for 3D matrix decomposition (#3710)

Date: Wed, 06 Mar 2019 17:39:25 +0000

Message-ID: <issues.opened-417928368-1551893964-sysbot+gh@w3.org>
```kevers-google has just created a new issue for https://github.com/w3c/csswg-drafts:

== [css-transforms] Quaternion calculation for 3D matrix decomposition ==
Decomposition of a 3D matrix:
https://drafts.csswg.org/css-transforms-2/#decomposing-a-3d-matrix

The pseudocode for quaternion calculations contains the following:

// Now, get the rotations out
quaternion = 0.5 * sqrt(max(1 + row - row - row, 0))
quaternion = 0.5 * sqrt(max(1 - row + row - row, 0))
quaternion = 0.5 * sqrt(max(1 - row - row + row, 0))
quaternion = 0.5 * sqrt(max(1 + row + row + row, 0))

if (row > row)
quaternion = -quaternion
if (row > row)
quaternion = -quaternion
if (row > row)
quaternion = -quaternion

This implementation hits a degenerate case when off diagonal elements in the orthonormal matrix used for determining the sign are equal.

Consider the decomposition of matrix(1, 1, 1, 0, 0, 0)

Following the decomposition steps, the orthonormal matrix for computing the quaternion is:

[-0.7071   -0.7071   0]
[-0.7071    0.7071   0]
[     0              0      -1]

The off-diagonal elements are equal and we cannot determine, which elements in the quaternion should be negative.

Based on the algorithm in the spec, (x, y, z, w) = (0.382683, 0.92388, 0, 0) when it should be   (x, y, z, w) = (-0.382683, 0.92388, 0, 0)

A more robust algorithm is:

t = q_xx + q_yy + q_zz
if (t > 0)
r = sqrt(1.0 + t)
s = 0.5 / r
w = 0.5 * r
x = (q_zy - q_yz) * s
y = (q_xz - q_zx) * s
z = (q_yx - q_xy) * s
else if (q_xx > q_yy && q_xx > q_zz)
r = sqrt(1.0 + q_xx - q_yy - q_zz)
s = 0.5 / r
x = 0.5 * r
y = (q_xy + q_yx) * s
z = (q_xz + q_zx) * s
w = (q_zy - q_yz) * s
else if (q_yy > q_zz)
r = sqrt(1.0 - q_xx + q_yy - q_zz)
s = 0.5 / r
x = (q_xy + q_yx) * s
y = 0.5 * r
z = (q_yz + q_zy) * s
w = (q_xz - q_zx) * s
else
r = sqrt(1.0 - q_xx - q_yy + q_zz)
s = 0.5 / r
x = (q_xz + q_zx) * s
y = (q_yz + q_zy) * s
z = 0.5 * r
w = (q_yx - q_xy) * s

Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/3710 using your GitHub account
```
Received on Wednesday, 6 March 2019 17:39:27 UTC

This archive was generated by hypermail 2.4.0 : Thursday, 24 March 2022 20:26:57 UTC