Open kevers-google opened 5 years ago
I'm pretty sure this is a dupe of #3230.
I've been working through this trying to fix inconsistencies in Gecko but I'm having trouble understanding how this produces consistent results for 2D/3D for input such as matrix(1, 0, 0, -1, 0, 0)
.
As far as I can tell, the 3D decomposition would yield a quaternion of 0, 1, 0, 0
and debugging Gecko and Chrome I see they both give that.
However, using the algorithm above we have:
decomp3d.quaternion = [0, 0, sin(decomp2d.angle/2), cos(decomp2d.angle/2)]
Which is clearly never going to give 0, 1, 0, 0
.
Instead, applying the above logic in Gecko I get 0, 0, 0, 1
.
@kevers-google Is there something I'm missing here?
The 2D algorithm flips one scale factor if the determinant is negative whereas the specced 3D algorithm flips all scale factors. Both have the impact of making the matrix determinant positive -- though in the 3D case, this will lead to rotations in addition to the scaling as well as create a throbbing effect. If in the 3D algorithm a single axis was selected for scale inversion to address the negative determinant in a consistent manner to the 2D algorithm, the 2D and 3D results should align.
2D spec: https://drafts.csswg.org/css-transforms/#decomposing-a-2d-matrix 3D spec: https://drafts.csswg.org/css-transforms-2/#decomposing-a-3d-matrix
A minor tweak to a transformation matrix that alters the transform from 2D to 3D, or vice versa, should not radically alter the interpolation path.
In the 2D case, the decomposed matrix has a total of 9 parameters: 2 translate, 2 scale, an angle and a 2x2 matrix that corresponds to the skew. This feels over-specified as the skew should be expressible with at most 2 parameters.
Here is an alternative, which is more consistent with the 3D matrix decomposition:
The inconsistency in handling negative determinants is files as https://github.com/w3c/csswg-drafts/issues/3712.
The 3D counterpart to this 2D decomposition is:
decomp3d.scale = [decomp2d.scale[0], decomp2d.scale[1], 1] decomp3d.translate = [decomp2d.translate[0], decomp2d.translate[1], 0] decomp3d.skew = [decomp2d.skew, 0, 0] decomp3d.perspective = [0, 0, 0, 1] decomp3d.quaternion = [0, 0, sin(decomp2d.angle/2), cos(decomp2d.angle/2)]
Having this simple mapping facilitates blending a 2D and 3D transformation matrix.