1 /* === S Y N F I G ========================================================= */ 2 /*! \file matrix.h 3 ** \brief Matrix definitions for 2D affine transformations 4 ** 5 ** $Id$ 6 ** 7 ** \legal 8 ** Copyright (c) 2008 Carlos López & Chirs Moore 9 ** 10 ** This package is free software; you can redistribute it and/or 11 ** modify it under the terms of the GNU General Public License as 12 ** published by the Free Software Foundation; either version 2 of 13 ** the License, or (at your option) any later version. 14 ** 15 ** This package is distributed in the hope that it will be useful, 16 ** but WITHOUT ANY WARRANTY; without even the implied warranty of 17 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 ** General Public License for more details. 19 ** \endlegal 20 */ 21 /* ========================================================================= */ 22 23 /* === S T A R T =========================================================== */ 24 25 #ifndef __SYNFIG_MATRIX_H 26 #define __SYNFIG_MATRIX_H 27 28 /* === H E A D E R S ======================================================= */ 29 30 #include "angle.h" 31 #include "real.h" 32 #include "vector.h" 33 #include "string.h" 34 #include <cassert> 35 #include <cmath> 36 #include <iostream> 37 #include <ETL/stringf> 38 39 /* === M A C R O S ========================================================= */ 40 41 #define COUT_MATRIX(m) \ 42 cout<<"["<<m.m00<<"]["<<m.m01<<"]["<<m.m02<<"]"<<endl; \ 43 cout<<"["<<m.m10<<"]["<<m.m11<<"]["<<m.m12<<"]"<<endl; \ 44 cout<<"["<<m.m20<<"]["<<m.m21<<"]["<<m.m22<<"]"<<endl 45 46 /* === T Y P E D E F S ===================================================== */ 47 48 /* === C L A S S E S & S T R U C T S ======================================= */ 49 50 namespace synfig { 51 52 /*! \class Matrix2 53 ** \todo writeme (Matrix 2x2) 54 */ 55 class Matrix2 56 { 57 public: 58 typedef Real value_type; 59 60 public: 61 //! The matrix array 62 union { 63 value_type m[2][2]; 64 struct 65 { 66 value_type m00, m01; 67 value_type m10, m11; 68 }; 69 }; 70 71 //!Default constructor makes an identity matrix Matrix2()72 Matrix2(): m00(1.0), m01(0.0), m10(0.0), m11(1.0) { } 73 Matrix2(value_type m00,value_type m01,value_type m10,value_type m11)74 Matrix2(value_type m00, value_type m01, value_type m10, value_type m11): 75 m00(m00), m01(m01), m10(m10), m11(m11) { } 76 Matrix2(const Vector & axis_x,const Vector & axis_y)77 Matrix2(const Vector &axis_x, const Vector &axis_y): 78 m00(axis_x[0]), m01(axis_x[1]), m10(axis_y[0]), m11(axis_y[1]) { } 79 get_axis_x()80 Vector get_axis_x()const { return Vector(m00, m01); } get_axis_y()81 Vector get_axis_y()const { return Vector(m10, m11); } 82 83 //!set_identity member. Set an identity matrix set_identity()84 Matrix2 &set_identity() 85 { return *this = Matrix2(); } 86 is_identity()87 bool is_identity() const 88 { return *this == Matrix2(); } 89 90 //!set_scale member function. Sets a scale matrix 91 //! @param sx Scale by X axis 92 //! @param sy Scale by Y axis 93 //! @return A matrix reference filled with the sx, sy values 94 Matrix2 &set_scale(const value_type &sx, const value_type &sy); 95 96 //!set_scale member fucntion. Sets a scale matrix 97 //! @param sxy Scale by X and Y axis 98 //! @return A matrix reference filled with the sxy values set_scale(const value_type & sxy)99 Matrix2 &set_scale(const value_type &sxy) 100 { return set_scale(sxy, sxy); } 101 102 //!set_scale member fucntion. Sets a scale matrix 103 //! @param s Vector that defines the scale 104 //! @return A matrix reference filled with the proper scale parameters set_scale(const Vector & s)105 Matrix2 &set_scale(const Vector &s) 106 { return set_scale(s[0], s[1]); } 107 108 //!set_rotate member function. Sets a rotate matrix 109 //! @param a Rotation angle counter clockwise 110 //! @return A matrix reference filled with the proper rotation parameters 111 Matrix2 &set_rotate(const Angle &a); 112 113 void get_transformed(value_type &out_x, value_type &out_y, const value_type x, const value_type y)const; 114 115 //!get_transformed member function. 116 //! @param v 2D Vector to transform 117 //! @return The Vector result get_transformed(const Vector & v)118 Vector get_transformed(const Vector &v)const 119 { Vector vv; get_transformed(vv[0], vv[1], v[0], v[1]); return vv; } 120 121 bool operator==(const Matrix2 &rhs) const; 122 bool operator!=(const Matrix2 &rhs) const 123 { return !(*this == rhs); } 124 125 //! operator*=. Multiplication and assignment of one matrix by another 126 //! @param rhs the right hand side of the multiplication operation 127 //! @return the modified resulting matrix 128 Matrix2 operator*=(const Matrix2 &rhs); 129 130 //! operator*=. Multiplication and assignment of one matrix by a scalar 131 //! @param rhs the number to multiply by 132 //! @return the modifed resulting matrix 133 Matrix2 operator*=(const value_type &rhs); 134 135 //! operator+=. Sum and assignment of two matrixes 136 //! @param rhs the matrix to sum 137 //! @return modified matrix with the summed matrix 138 Matrix2 operator+=(const Matrix2 &rhs); 139 140 //! operator*. Multiplication of one matrix by another 141 //! @param rhs the right hand side of the multiplication operation 142 //! @return the resulting matrix 143 Matrix2 operator*(const Matrix2 &rhs)const 144 { return Matrix2(*this) *= rhs; } 145 146 //! operator*. Multiplication of one matrix by a number 147 //! @param rhs the number to multiply by 148 //! @return the resulting matrix 149 Matrix2 operator*(const value_type &rhs)const 150 { return Matrix2(*this) *= rhs; } 151 152 //! operator+. Sum two matrixes 153 //! @param rhs the matrix to sum 154 //! @return the resulting matrix 155 Matrix2 operator+(const Matrix2 &rhs)const 156 { return Matrix2(*this) += rhs; } 157 158 bool is_invertible()const; 159 160 Matrix2 &invert(); 161 162 //!Get the string of the Matrix 163 //!@return String type. A string representation of the matrix 164 //!components. 165 String get_string(int spaces = 0, String before = String(), String after = String())const; 166 }; 167 168 169 /*! \class Matrix3 170 ** \todo writeme (Matrix 3x3) 171 */ 172 class Matrix3 173 { 174 public: 175 typedef Real value_type; 176 177 public: 178 //! The matrix array 179 union { 180 value_type m[3][3]; 181 struct 182 { 183 value_type m00, m01, m02; 184 value_type m10, m11, m12; 185 value_type m20, m21, m22; 186 }; 187 }; 188 189 // Index convention 190 // 00 01 02 191 // 10 11 12 192 // 20 21 22 193 // vectors are premultiplied when the matrix transformation is applied 194 // we consider the vectors as [1]x[3] arrays. 195 // [1]x[3] * [3]x[3] = [1]x[3] 196 // vector * matrix = vector 197 // In affine transformation matrixes the values of 198 // m02=0, m12=0 and m22=1 for non projective transformations. 199 200 //!Default constructor makes an identity matrix Matrix3()201 Matrix3(): 202 m00(1.0), m01(0.0), m02(0.0), 203 m10(0.0), m11(1.0), m12(0.0), 204 m20(0.0), m21(0.0), m22(1.0) { } 205 Matrix3(value_type m00,value_type m01,value_type m02,value_type m10,value_type m11,value_type m12,value_type m20,value_type m21,value_type m22)206 Matrix3( 207 value_type m00, value_type m01, value_type m02, 208 value_type m10, value_type m11, value_type m12, 209 value_type m20, value_type m21, value_type m22 210 ): 211 m00(m00), m01(m01), m02(m02), 212 m10(m10), m11(m11), m12(m12), 213 m20(m20), m21(m21), m22(m22) 214 { } 215 Matrix3(Vector axis_x,Vector axis_y,Vector offset)216 Matrix3(Vector axis_x, Vector axis_y, Vector offset): 217 m00(axis_x[0]), m01(axis_x[1]), m02(0.0), 218 m10(axis_y[0]), m11(axis_y[1]), m12(0.0), 219 m20(offset[0]), m21(offset[1]), m22(1.0) 220 { } 221 get_axis_x()222 Vector get_axis_x()const { return Vector(m00, m01); } get_axis_y()223 Vector get_axis_y()const { return Vector(m10, m11); } get_offset()224 Vector get_offset()const { return Vector(m20, m21); } 225 226 //!set_identity member. Set an identity matrix set_identity()227 Matrix3 &set_identity() 228 { return *this = Matrix3(); } 229 is_identity()230 bool is_identity() const 231 { return *this == Matrix3(); } 232 233 //!set_scale member function. Sets a scale matrix 234 //! @param sx Scale by X axis 235 //! @param sy Scale by Y axis 236 //! @return A matrix reference filled with the sx, sy values 237 Matrix3 &set_scale(const value_type &sx, const value_type &sy); 238 239 //!set_scale member fucntion. Sets a scale matrix 240 //! @param sxy Scale by X and Y axis 241 //! @return A matrix reference filled with the sxy values set_scale(const value_type & sxy)242 Matrix3 &set_scale(const value_type &sxy) 243 { return set_scale(sxy, sxy); } 244 245 //!set_scale member fucntion. Sets a scale matrix 246 //! @param s Vector that defines the scale 247 //! @return A matrix reference filled with the proper scale parameters set_scale(const Vector & s)248 Matrix3 &set_scale(const Vector &s) 249 { return set_scale(s[0], s[1]); } 250 251 //!set_rotate member function. Sets a rotate matrix 252 //! @param a Rotation angle counter clockwise 253 //! @return A matrix reference filled with the proper rotation parameters 254 Matrix3 &set_rotate(const Angle &a); 255 256 //!translate member function. Sets a translate matrix 257 //! @param t Vector that defines the translation 258 //! @return A matrix reference filled with the proper translation parameters set_translate(const Vector & t)259 Matrix3 &set_translate(const Vector &t) 260 { return set_translate(t[0], t[1]); } 261 262 //!translate member function. Sets a translate matrix 263 //! @param x Scalar that defines the x component of the translation 264 //! @param y Scalar that defines the y component of the translation 265 //! @return A matrix reference filled with the proper translation parameters 266 Matrix3 &set_translate(value_type x, value_type y); 267 268 void get_transformed(value_type &out_x, value_type &out_y, const value_type x, const value_type y, bool translate = true)const; 269 270 //!get_transformed member function. 271 //! @param v 2D Vector to transform 272 //! @return The Vector result 273 Vector get_transformed(const Vector &v, bool translate = true)const 274 { Vector vv; get_transformed(vv[0], vv[1], v[0], v[1], translate); return vv; } 275 276 bool operator==(const Matrix3 &rhs) const; 277 bool operator!=(const Matrix3 &rhs) const 278 { return !(*this == rhs); } 279 280 //! operator*=. Multiplication and assignment of one matrix by another 281 //! @param rhs the right hand side of the multiplication operation 282 //! @return the modified resulting matrix 283 Matrix3 operator*=(const Matrix3 &rhs); 284 285 //! operator*=. Multiplication and assignment of one matrix by a scalar 286 //! @param rhs the number to multiply by 287 //! @return the modifed resulting matrix 288 Matrix3 operator*=(const value_type &rhs); 289 290 //! operator+=. Sum and assignment of two matrixes 291 //! @param rhs the matrix to sum 292 //! @return modified matrix with the summed matrix 293 Matrix3 operator+=(const Matrix3 &rhs); 294 295 //! operator*. Multiplication of one matrix by another 296 //! @param rhs the right hand side of the multiplication operation 297 //! @return the resulting matrix 298 Matrix3 operator*(const Matrix3 &rhs)const 299 { return Matrix3(*this) *= rhs; } 300 301 //! operator*. Multiplication of one matrix by a number 302 //! @param rhs the number to multiply by 303 //! @return the resulting matrix 304 Matrix3 operator*(const value_type &rhs)const 305 { return Matrix3(*this) *= rhs; } 306 307 //! operator+. Sum two matrixes 308 //! @param rhs the matrix to sum 309 //! @return the resulting matrix 310 Matrix3 operator+(const Matrix3 &rhs)const 311 { return Matrix3(*this) += rhs; } 312 313 bool is_invertible()const; 314 315 // (m00 m01 0) 1 ( m11 ) ( -m01 ) ( 0 ) 316 // inverse (m10 m11 0) = ----- x ( -m10 ) ( m00 ) ( 0 ) 317 // (m20 m21 1) m00m11-m01m10 (m10m21-m11m20) (m01m20-m00m21) (m00m11-m01m10) 318 Matrix3 &invert(); 319 320 //!Get the string of the Matrix 321 //!@return String type. A string representation of the matrix 322 //!components. 323 String get_string(int spaces = 0, String before = String(), String after = String())const; 324 }; 325 326 typedef Matrix3 Matrix; 327 328 }; // END of namespace synfig 329 330 #endif 331