[whatwg] Canvas transform() and matrix element notation

Boris Zbarsky bzbarsky at MIT.EDU
Mon Jul 19 13:54:23 PDT 2010


On 7/19/10 4:13 PM, David Flanagan wrote:
> The spec describes the transform() method as follows:
>
>> The transform(m11, m12, m21, m22, dx, dy) method must multiply the
>> current transformation matrix with the matrix described by:
>>
>> m11 m21 dx
>> m12 m22 dy
>> 0 0 1
>
> The first number in these argument names is the column number and the
> second is the row number.

I agree that this is somewhat weird at first glance, but it seems to be 
not uncommon for graphics libraries.  For example, for cairo the call

   cairo_matrix_init(m, a, b, c, d, e, f);

creates a matrix which represents the affine transformation [1]:

  x_new = a*x + c*y + e;
  y_new = b*x + d*y + f;

As another example, in CoreGraphics CGAffineTransformMake(a, b, c, d, e, 
f) [2] produces a trasformation that does [3]:

   x_new = a*x + c*y + e;
   y_new = b*x + d*y + f;

I think the issue here is that these graphics libraries think in terms 
of row vectors and right-multiplication by transformation matrices; see 
the nice matrices written out in the CoreGraphics documentation.  In 
that context the component specification order is in fact the "sensible" 
one.

In practice, I assume the initial canvas implementation just called into 
CoreGraphics directly, hence the treatment of the argument order.  And 
now that's the argument order we have.

> 2) Java's java.awt.geom.AffineTransform class also lists the row index
> first, as in the following javadoc excerpt:
>
>> [ x']   [ m00 m01 m02 ] [ x ] [ m00x + m01y + m02 ]
>> [ y'] = [ m10 m11 m12 ] [ y ] = [ m10x + m11y + m12 ]
>> [ 1 ]   [ 0    0   1 ] [ 1 ] [ 1 ]

While true, if you look at the way one constructs an AffineTransform by 
passing in the matrix entries [4]:

   AffineTransform(double m00, double m10, double m01, double m11,
                   double m02, double m12)

which is worse than the CoreGraphics setup, even: the convention is the 
same but the example is misleading, unlike the CoreGraphics example with 
a row vector.

> It would be nice if this spec was not inconsistent with other usage.

It seems that it's not, if "other usage" means "other things in the 
computer world that use affine transformation matrices"...

I do think the spec could benefit from an example akin to the one in the 
CoreGraphics documentation.

By the way, 100% agreed that the multiplication order needs to be 
defined here.

-Boris

[1] http://www.cairographics.org/manual/cairo-matrix.html#cairo-matrix-init

[2] 
http://developer.apple.com/mac/library/documentation/GraphicsImaging/Reference/CGAffineTransform/Reference/reference.html#//apple_ref/c/func/CGAffineTransformMake

[3] 
http://developer.apple.com/mac/library/documentation/GraphicsImaging/Reference/CGAffineTransform/Reference/reference.html#//apple_ref/doc/c_ref/CGAffineTransform





More information about the whatwg mailing list