lytico / xwt

MIT License
1 stars 2 forks source link

matrix change from append to prepend #19

Closed lytico closed 10 years ago

lytico commented 11 years ago

http://cairographics.org/manual/cairo-cairo-matrix-t.html http://cgit.freedesktop.org/cairo/tree/src/cairo-matrix.c quotes from cairo-matrix.c:

/**

/**

/**

hwthomas commented 11 years ago

Referencing the same Cairo source code as you have above, any transform (such as 'rotate' that you show) first initialises a temporary matrix &tmp, then multiplies 'this' by it - that is, the 'a' matrix above is &tmp, 'b' is 'this', and r = a * b is equivalent to this = &tmp * this . The matrix multiplication code above is identical to Prepend from the Xwt.Matrix code:-

public void Prepend (Matrix matrix)
{
    var _m11 = matrix.M11 * M11 + matrix.M12 * M21;
    var _m12 = matrix.M11 * M12 + matrix.M12 * M22;
    var _m21 = matrix.M21 * M11 + matrix.M22 * M21;
    var _m22 = matrix.M21 * M12 + matrix.M22 * M22;

    var _offsetX = matrix.OffsetX * M11 + matrix.OffsetY * M21 + OffsetX;
    var _offsetY = matrix.OffsetX * M12 + matrix.OffsetY * M22 + OffsetY;

    M11 = _m11;
    M12 = _m12;
    M21 = _m21;
    M22 = _m22;
    OffsetX = _offsetX;
    OffsetY = _offsetY;
}

where the Xwt and Cairo matrix components correspond as:

M11 = xx,  M12 = yx,
M12 = xy,  M22 = yy. 

This confirms that Cairo uses Prepend for each successive transform that is applied to the matrix ('this'). This is also the way that all the Backend Context transforms behave, and I've recently added a Drawing page to the Wiki which I hope clarifies things a bit more.

What isn't clear to me is why the System.Media.Matrix code, from which Xwt.Matrix is taken, uses Append as the default mode for all its transforms (Scale, Rotate, Translate, Skew), but provides Prepend as well.

lytico commented 11 years ago

sorry, i have red params order of multiply as a,b,result, so i got append, which is wrong. its really hard to read code on smartphone screens :-(

hwthomas commented 11 years ago

Thanks, lytico, for your input on this one. It gets confusing because different backends can use a different matrix layout for Affine Transforms (as per Java), and if the transposed one is used, the order needs to be Append! However, the Xwt.Matrix code corresponds to using a Row Vector, and the normal layout that I've described in the Wiki Drawing page. Hope it's not intruded on your holiday/travelling too much!