Subject: | Imager::Matrix2d->rotate about (x, y) bug |
Date: | Sat, 1 Nov 2014 19:43:39 +0000 |
To: | bug-Imager [...] rt.cpan.org |
From: | Denis Howe <denis.howe [...] gmail.com> |
Thanks very much for your work on the fantastic Imager module.
The rotate() method in Imager::Matrix2d v1.011 (
http://search.cpan.org/~tonyc/Imager-0.98/) says:
return $class->translate('x'=>-$opts{'x'}, 'y'=>-$opts{'y'})
* $class->rotate(radians=>$angle)
* $class->translate('x'=>$opts{'x'}, 'y'=>$opts{'y'});
meaning to rotate around (x,y), first translate by (-x, -y) then rotate
around the origin then translate back by (x, y).
Makes sense, *but *when applying transformations represented as matrices,
you have to do it backwards:
http://en.wikipedia.org/wiki/Transformation_matrix#Composing_and_inverting_transformations
Yes, order of multiplication matters for matrices.
A work-around is to pass in (-x, -y) as the centre of rotation but the
correct fix is to do the multiplications in the opposite order.
The same would apply anywhere else you have composed transformation
matrices using "*". It would be worth adding a note to this effect to the
_mult() docs.
Since this is rather unexpected, you might also consider providing a "then"
operator or a "compose" function such that, for matrices M and N,
M then N === compose(M, N)
where
compose(M1, M2, M3, ...) === ...*M3*M2*M1
HtH
--
Denis Howe <denis.howe@gmail.com>
http://foldoc.org/
T: 020 8450 9448 M: 07950 686 615