[cairo] Extracting The Scaling Component Of A Matrix
Behdad Esfahbod
behdad.esfahbod at gmail.com
Mon Dec 14 03:20:58 PST 2015
On 15-12-13 11:15 PM, Lawrence D'Oliveiro wrote:
> On Sat, 12 Dec 2015 12:15:17 +0100, Behdad Esfahbod wrote:
>
>> On 15-12-11 01:51 AM, Lawrence D'Oliveiro wrote:
>>
>>> I construct a matrix that implements just the scaling component of
>>> the CTM in the Cairo context “ctx”:
>>>
>>> scaling = Matrix.scale(ctx.user_to_device_distance(Vector(1,
>>> 1)))
>>
>> This wouldn't do what you think it does for general matrices. Or
>> maybe I don't understand what you are trying to do. Are you only
>> interested in non-skewed matrices?
>
> import sys
> from qahirah import \
> Matrix, \
> Vector
>
> for \
> mat \
> in \
> (
> Matrix.scale(3),
> Matrix.skew((0, 1)) * Matrix.scale(3),
> Matrix.scale(3) * Matrix.skew((1, 0)),
> Matrix.skew((1, 1)),
> Matrix.skew((1, -1)) * Matrix.scale(3),
> Matrix.scale(3) * Matrix.skew((-1, 1)),
> ) \
> :
> sys.stdout.write \
> (
> "scaling part of {} = {}\n"
> .format
> (
> mat,
> mat.mapdelta(Vector(1, 1))
> )
> )
> #end for
>
> ...
>
> scaling part of Matrix(3, 0, 0, 3, 0, 0) = Vector(3, 3)
> scaling part of Matrix(3, 3, 0, 3, 0, 0) = Vector(3, 6)
> scaling part of Matrix(3, 0, 3, 3, 0, 0) = Vector(6, 3)
> scaling part of Matrix(1, 1, 1, 1, 0, 0) = Vector(2, 2)
> scaling part of Matrix(3, -3, 3, 3, 0, 0) = Vector(6, 0)
> scaling part of Matrix(3, 3, -3, 3, 0, 0) = Vector(0, 6)
>
> Hmmm ...
Yeah... You have to define what exactly you want. A 2D matrix like the ones
cairo uses can always be decomposed into a concatenation of the following
matrices:
- transform
- rotate
- skew
- scale
This has many useful properties, and you can derive those four transformations
from an arbitrary matrix easily. Here's my derivation:
https://readable-email.org/list/www-style/topic/better-matrix-decomposition-for-animation
This also describes the benefits of such decompositions:
http://research.cs.wisc.edu/graphics/Courses/838-s2002/Papers/polar-decomp.pdf
If you transform a circle with a matrix, you get an ellipse. If you are
interested in the major and minor axes of that ellipse, that's a Singular
Value Decomposition of the 2D matrix. I've put code here for doing that:
https://github.com/behdad/cairo/blob/color-emoji/doc/tutorial/src/singular.c
Cheers,
behdad
More information about the cairo
mailing list