#ifndef MATRIX_H // -*- c++ -*- #define MATRIX_H /// // Copyright (C) 2002 - 2004, Fredrik Arnerup & Rasmus Kaj, See COPYING /// #include "vector.h" #include // forward declaration namespace Gnome { namespace Art { class AffineTrans; } } namespace Error { struct SingularMatrix : public std::runtime_error { SingularMatrix(const std::string& when) : std::runtime_error("Singular matrix"), msg_(when + ": Singular matrix") {} ~SingularMatrix() throw() {} const char* what() const throw() { return msg_.c_str(); } private: SingularMatrix(); // no default constructor const std::string msg_; }; // scaling a pagent by zero is not allowed } // transformations are performed in the following order: // 1. Shearing // 2. Scaling // 3. Rotation // 4. Translation struct Matrix { double rep[6]; //rep[0] rep[1] 0 //rep[2] rep[3] 0 //rep[4] rep[5] 1 Matrix(); // the identity matrix static Matrix shearing(double shcoeff); static Matrix scaling(double xfactor, double yfactor); static Matrix rotation(double angle); static Matrix translation(const Vector& offset); static Matrix translation(double xoffset, double yoffset); /** * Get this same transform in Gnome::Art format. * Due to differences in reference system, the transforms are kind of * reverse copies of each other. */ const Gnome::Art::AffineTrans gaTransform() const; // making sense out of matrices: // may throw Error::SingularMatrix bool is_plain() const; // true iff this is only scale and translate. double tr_x() const; // translation x double tr_y() const; // translation y Vector tr() const; // translation double rot() const; // rotation double sc_x() const; // scale x double sc_y() const; // scale y double sh() const; // shearing Matrix& set_tr_x(double val); Matrix& set_tr_y(double val); Matrix& set_tr(const Vector& offset); Matrix& set_rot(double val); Matrix& set_scale(double sc_x, double sc_y); Matrix& set_sc_x(double val); Matrix& set_sc_y(double val); Matrix& set_sh(double val); // aliases double a() const {return rep[0];} double b() const {return rep[1];} double c() const {return rep[2];} double d() const {return rep[3];} // conversions static double rad2deg(double rad); static double deg2rad(double deg); // operations Vector transform(Vector v) const; Matrix operator * (const Matrix& m) const; bool operator == (const Matrix& m) const; double det() const; Matrix inv() const; // may throw Error::SingularMatrix // debug function void print() const; friend std::ostream& operator<< (std::ostream& out, const Matrix&); friend std::istream& operator>> (std::istream& in, Matrix&); }; inline Matrix& operator *= (Matrix& m1, const Matrix& m2) { m1 = m1 * m2; return m1; } inline bool operator != (const Matrix& m1, const Matrix& m2) { return !(m1 == m2); } #endif