- From: Brendan Kenny <bckenny@gmail.com>
- Date: Tue, 27 Apr 2010 16:59:46 -0500
- To: public-fx@w3.org
While these interfaces will probably never be the most widely used methods of accessing transformation functionality, I think it would be beneficial if they shared the same basic mechanics and nomenclature. The interfaces don't need to be identical, it would just be nice to not have to remember which object you are using and have to adjust the order of operations accordingly. I'm referring, of course, to the old, dreaded (and unfortunately poorly defined) "row-major" vs "column-major" matrix representations. I'm going to use "column-major" to mean matrices that are used to transform vectors represented as columns, and "row-major" to mean the transpose of "column-major." Unfortunately this often does not correspond to the other meaning of the terms, which describes the array representations of tabular data (like matrices). Here are the current definitions of the interfaces: http://www.w3.org/TR/SVG/coords.html#InterfaceSVGMatrix http://www.w3.org/TR/css3-2d-transforms/#cssmatrix-interface (the editor's draft's interface appears to be unchanged from this version) Based on the "Nested Transformations" section of the SVG spec http://www.w3.org/TR/SVG/coords.html#NestedTransformations it is very clear that SVG's matrices are column-major. This means that when composing an existing transformation and a new transformation--when the new transformation is to take place *within* the space defined by the existing one--the two matrices are multiplied with the new transformation on the right (there are several examples at the last link if that explanation is not helpful to you). There is no place (that I see) in the CSS 2d transform spec that explicitly states the matrix representation to be used. This might actually be ideal, because in most cases it doesn't really matter in terms of the exposed interface. The "matrix(a, b, c, d, e, f)" transformation function is a good example of this; regardless of implementation, [a, b] (or [a, b, 0]) is the x basis vector, [c,d] the y, and [e,f] the translation vector. However, it is clear that the reference algorithms are in reference to a row-major matrix representation, and this is backed up by the Webkit implementation (the only one, I think). This means that even though firstMatrix.multiply(secondMatrix); does the multiplication with secondMatrix on the right in both frameworks, the resulting SVGMatrix will have the secondMatrix nested within the firstMatrix while the resulting (WebKit)CSSMatrix will have the firstMatrix nested within the secondMatrix. -------------- I see at least two possible solutions. Both should be fairly easy to implement since the interface is so small, and aside from written descriptions in the spec(s), should only affect the matrix interfaces (for instance, the "transform" attribute/property is already agreed to composite in list order). 1) Standardize on one kind of exposed matrix representation. This is less urgent now (especially with the a-f attributes), but will be difficult to avoid with a 3d matrix interface. Column-major matrices are pretty standard in mathematics and recent (last ~20 years) computer graphics, but row-major matrices have a very long historical CG precedent. 2) Remain representation neutral. multiply() could then just be defined in terms of the second matrix applying to the "local" or "user" coordinate space defined by the first. This would also ensure that the other methods would be defined in terms of multiply(), e.g. var result = mat.scale(5); would be equivalent to var s = identityMatrix.scale(5); var result = mat.multiply(s); Since both interfaces specify that multiply() leaves the underlying matrix unaffected, I think having one multiplication method should be sufficient (i.e. matA.multiplyView(matB) saves nothing over matB.multiply(matA)). This solution also avoids the (for me, at least) confusing use of "post-multiply" as a verb in a sentence. Even in the SVG spec, where the effect of post-multiplication is well described, it can be difficult to parse which matrix is the subject and which the object of the operation. ----------------- Either way, this would be a significant change, but I think one that would be beneficial going forward. Please let me know your thoughts.
Received on Tuesday, 27 April 2010 22:00:23 UTC