```--- a
+++ b/lib/Panotools/Matrix.pm
@@ -0,0 +1,101 @@
+package Panotools::Matrix;
+
+
+Panotools::Matrix - Miscellaneous math for panoramic images
+
+
+\$matrix = rollpitchyaw2matrix (\$roll, \$pitch, \$yaw);
+
+All angles are in radians not degrees.
+
+
+rollpitchyaw2matrix returns a Math::Matrix object that encapsulates a
+transformation suitable for rotating a vector/point by three degrees of freedom
+(roll, pitch and yaw).
+
+roll is positive rotation around the x-axis
+
+pitch is negative rotation around the y-axis
+
+yaw is negative rotation around the z axis
+
+
+use Math::Matrix;
+
+use Panotools::Matrix;
+
+my \$point  = new Math::Matrix ([\$x1], [\$y1], [\$z1]);
+
+my \$matrix = rollpitchyaw2matrix (\$roll, \$pitch, \$yaw);
+
+my \$result = \$matrix->multiply (\$point);
+
+(\$x2, \$y2, \$z2) = (\$result->[0][0], \$result->[1][0], \$result->[2][0]);
+
+
+Requires Math::Matrix as this is all matrix mathematics.
+
+
+module is Free Software. It may be used, redistributed and/or modified under
+the same terms as Perl itself.
+
+This module is partly based on Math::Geometry by Greg McCarroll
+<greg@mccarroll.demon.co.uk>
+
+=cut
+
+use Math::Matrix;
+use Math::Trig;
+use strict;
+
+use Exporter;
+use vars qw(@ISA @EXPORT);
+@ISA = qw(Exporter);
+@EXPORT = qw(rollpitchyaw2matrix matrix2rollpitchyaw);
+
+sub rollpitchyaw2matrix {
+    my (\$roll, \$pitch, \$yaw) = @_;
+
+    my \$cosr = cos (\$roll);
+    my \$sinr = sin (\$roll);
+    my \$cosp = cos (\$pitch);
+    my \$sinp = sin (0 - \$pitch);
+    my \$cosy = cos (\$yaw);
+    my \$siny = sin (0 - \$yaw);
+
+    my \$rollm  = new Math::Matrix ([        1,       0,       0 ],
+                                   [        0,   \$cosr,-1*\$sinr ],
+                                   [        0,   \$sinr,   \$cosr ]);
+
+    my \$pitchm = new Math::Matrix ([    \$cosp,       0,   \$sinp ],
+                                   [        0,       1,       0 ],
+                                   [ -1*\$sinp,       0,   \$cosp ]);
+
+    my \$yawm   = new Math::Matrix ([    \$cosy,-1*\$siny,       0 ],
+                                   [    \$siny,   \$cosy,       0 ],
+                                   [        0,       0,       1 ]);
+
+    \$yawm->multiply (\$pitchm)->multiply (\$rollm);
+}
+
+# following copied from a spreadsheet by Stuart Milne
+
+sub matrix2rollpitchyaw
+{
+    my \$matrix = shift;
+    my \$roll = atan2 (\$matrix->[2]->[1], \$matrix->[2]->[2]);
+    my \$pitch = -1 * asin (-1 * \$matrix->[2]->[0]);
+    my \$yaw = atan2 (-1 * \$matrix->[1]->[0], \$matrix->[0]->[0]);
+    return (\$roll, \$pitch, \$yaw);
+}
+
+1;
+
```