https://rt.cpan.org/Ticket/Display.html?id=56513
- add the matrix() method to Imager::Matrix2d to allow creation of a
- matrix with specified co-efficients.
+ matrix with specified co-efficients. You can now multiple an
+ Imager::Matrix2d object by a 9 element array ref or a number.
https://rt.cpan.org/Ticket/Display.html?id=29938
Imager 0.80 - 17 Jan 2011
package Imager::Matrix2d;
use strict;
use vars qw($VERSION);
+use Scalar::Util qw(reftype looks_like_number);
+use Carp qw(croak);
$VERSION = "1.009";
an Imager::Matrix2d.
=cut
+
sub _mult {
my ($left, $right, $order) = @_;
- if (ref($right) && UNIVERSAL::isa($right, __PACKAGE__)) {
- if ($order) {
- ($left, $right) = ($right, $left);
- }
- my @result;
- for my $i (0..2) {
- for my $j (0..2) {
- my $accum = 0;
- for my $k (0..2) {
- $accum += $left->[3*$i + $k] * $right->[3*$k + $j];
- }
- $result[3*$i+$j] = $accum;
+ if (ref($right)) {
+ if (reftype($right) eq "ARRAY") {
+ @$right == 9
+ or croak "9 elements required in array ref";
+ if ($order) {
+ ($left, $right) = ($right, $left);
}
+ my @result;
+ for my $i (0..2) {
+ for my $j (0..2) {
+ my $accum = 0;
+ for my $k (0..2) {
+ $accum += $left->[3*$i + $k] * $right->[3*$k + $j];
+ }
+ $result[3*$i+$j] = $accum;
+ }
+ }
+ return bless \@result, __PACKAGE__;
+ }
+ else {
+ croak "multiply by array ref or number";
}
+ }
+ elsif (defined $right && looks_like_number($right)) {
+ my @result = map $_ * $right, @$left;
+
return bless \@result, __PACKAGE__;
}
else {
- # presumably N * matrix or matrix * N
- return undef; # for now
+ # something we don't handle
+ croak "multiply by array ref or number";
}
}
#!perl -w
use strict;
-use Test::More tests => 13;
+use Test::More tests => 23;
use Imager;
BEGIN { use_ok('Imager::Matrix2d', ':handy') }
ok(!Imager::Matrix2d->matrix(), "bad custom matrix");
is(Imager->errstr, "9 co-efficients required", "check error");
+{
+ my @half = ( 0.5, 0, 0,
+ 0, 0.5, 0,
+ 0, 0, 1 );
+ my @quart = ( 0, 0.25, 0,
+ 1, 0, 0,
+ 0, 0, 1 );
+ my $half_matrix = Imager::Matrix2d->matrix(@half);
+ my $quart_matrix = Imager::Matrix2d->matrix(@quart);
+ my $result = $half_matrix * $quart_matrix;
+ is_deeply($half_matrix * \@quart, $result, "mult by unblessed matrix");
+ is_deeply(\@half * $quart_matrix, $result, "mult with unblessed matrix");
+
+ my $half_three = Imager::Matrix2d->matrix(1.5, 0, 0, 0, 1.5, 0, 0, 0, 3);
+ is_deeply($half_matrix * 3, $half_three, "mult by three");
+ is_deeply(3 * $half_matrix, $half_three, "mult with three");
+
+ {
+ # check error handling - bad ref type
+ my $died =
+ !eval {
+ my $foo = $half_matrix * +{};
+ 1;
+ };
+ ok($died, "mult by hash ref died");
+ like($@, qr/multiply by array ref or number/, "check message");
+ }
+
+ {
+ # check error handling - bad array
+ $@ = '';
+ my $died =
+ !eval {
+ my $foo = $half_matrix * [ 1 .. 8 ];
+ 1;
+ };
+ ok($died, "mult by short array ref died");
+ like($@, qr/9 elements required in array ref/, "check message");
+ }
+
+ {
+ # check error handling - bad value
+ $@ = '';
+ my $died =
+ !eval {
+ my $foo = $half_matrix * "abc";
+ 1;
+ };
+ ok($died, "mult by bad scalar died");
+ like($@, qr/multiply by array ref or number/, "check message");
+ }
+
+}
+
+
sub almost_equal {
my ($m1, $m2) = @_;