Remove spaces and tabs at end of lines.
[synfig.git] / synfig-core / trunk / src / synfig / matrix.h
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) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
9 **      Copyright (c) 2008 Carlos López
10 **
11 **      This package is free software; you can redistribute it and/or
12 **      modify it under the terms of the GNU General Public License as
13 **      published by the Free Software Foundation; either version 2 of
14 **      the License, or (at your option) any later version.
15 **
16 **      This package is distributed in the hope that it will be useful,
17 **      but WITHOUT ANY WARRANTY; without even the implied warranty of
18 **      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 **      General Public License for more details.
20 **      \endlegal
21 */
22 /* ========================================================================= */
23
24 /* === S T A R T =========================================================== */
25
26 #ifndef __SYNFIG_MATRIX_H
27 #define __SYNFIG_MATRIX_H
28
29 /* === H E A D E R S ======================================================= */
30
31 #include "angle.h"
32 #include "real.h"
33 #include "vector.h"
34 #include <math.h>
35
36 /* === M A C R O S ========================================================= */
37
38
39 #ifdef WIN32
40 #include <float.h>
41 #ifndef isnan
42 extern "C" { int _isnan(double x); }
43 #define isnan _isnan
44 #endif
45 #endif
46
47 // For some reason isnan() isn't working on macosx any more.
48 // This is a quick fix.
49 #if defined(__APPLE__) && !defined(SYNFIG_ISNAN_FIX)
50 #ifdef isnan
51 #undef isnan
52 #endif
53 inline bool isnan(double x) { return x != x; }
54 inline bool isnan(float x) { return x != x; }
55 #define SYNFIG_ISNAN_FIX 1
56 #endif
57
58
59 /* === T Y P E D E F S ===================================================== */
60
61 /* === C L A S S E S & S T R U C T S ======================================= */
62
63 namespace synfig {
64
65 /*!     \class Matrix
66 **      \todo writeme
67 */
68 class Matrix
69 {
70 public:
71         typedef Real value_type;
72
73 private:
74         //! The matrix array
75         value_type m00, m01, m02;
76         value_type m10, m11, m12;
77         value_type m20, m21, m22;
78         // Index convention
79         // 00 01 02
80         // 10 11 12
81         // 20 21 22
82         // vectors are premultiplied when the matrix transformation is applied
83         // we consider the vectors as [1]x[3] arrays.
84         // [1]x[3] * [3]x[3] = [1]x[3]
85         // vector  * matrix  = vector
86         // In affine transformation matrixes the values of
87         // m02=0, m12=0 and m22=1 for non projective transformations.
88
89 public:
90         //!Deafult constructor makes a identity matrix
91         Matrix() {
92                 m00=1.0; m01=0.0; m02=0.0;
93                 m10=0.0; m11=1.0; m12=0.0;
94                 m20=0.0; m21=0.0; m22=1.0;
95                 }
96
97         //!Constructor from Angle create a rotate matrix
98         Matrix(const Angle &a){
99                 (*this).set_rotate(a);
100                 }
101         //!set_identity member. Set an identity matrix
102         Matrix &
103         set_identity(){
104                 m00=1.0; m01=0.0; m02=0.0;
105                 m10=0.0; m11=1.0; m12=0.0;
106                 m20=0.0; m21=0.0; m22=1.0;
107                  return (*this);
108                  }
109         //!set_scale member fucntion. Sets a scale matrix
110         //! @param sx Scale by X axis
111         //! @param sy Scale by Y axis
112         //! @return A matrix reference filled with the sx, sy values
113         Matrix &
114         set_scale(const value_type &sx, const value_type &sy){
115                 m00=sx;  m01=0.0; m02=0.0;
116                 m10=0.0; m11=sy;  m12=0.0;
117                 m20=0.0; m21=0.0; m22=1.0;
118                  return (*this);
119                 }
120         //!set_rotate member function. Sets a rotate matrix
121         //! @param a Rotation angle counterclock wise
122         //! @return A matrix reference filled with the proper rotation parameters
123         Matrix &
124         set_rotate(const Angle &a){
125                 value_type c(Angle::cos(a).get());
126                 value_type s(Angle::sin(a).get());
127                 m00= c;     m01=s;    m02=0.0;
128                 m10=-1.0*s; m11=c;    m12=0.0;
129                 m20=0.0;    m21=0.0;  m22=1.0;
130                  return (*this);
131                 }
132         //!traslate member function. Sets a translate matrix
133         //! @param t Vector that defines the translation
134         //! @return A matrix reference filled with the proper translation parameters
135         Matrix &
136         set_translate(const Vector &t){
137                 m00=1.0;  m01=0.0;  m02=0.0;
138                 m10=0.0;  m11=1.0;  m12=0.0;
139                 m20=t[0]; m21=t[1]; m22=1.0;
140                  return (*this);
141                 }
142
143         //!get_transformed member function.
144         //! @param v 2D Vector to transform
145         //! @return The Vector result
146         Vector
147         get_transformed(const Vector &v){
148                  return Vector(v[0]*m00+v[1]*m10+m20,v[0]*m01+v[1]*m11+m21);
149                  }
150
151         //! operator *. Multiplication of one matrix by other
152         //! @param rhs the right hand side of the multiplication operation
153         //! @return the resulting multiplication matrix
154         Matrix
155         operator *(const Matrix &rhs){
156                 Matrix ret;
157                 ret.m00=m00*rhs.m00 + m01*rhs.m10 + m02*rhs.m20;
158                 ret.m01=m00*rhs.m01 + m01*rhs.m11 + m02*rhs.m21;
159                 ret.m02=m00*rhs.m02 + m01*rhs.m12 + m02*rhs.m22;
160
161                 ret.m10=m10*rhs.m00 + m11*rhs.m10 + m12*rhs.m20;
162                 ret.m11=m10*rhs.m01 + m11*rhs.m11 + m12*rhs.m21;
163                 ret.m12=m10*rhs.m02 + m11*rhs.m12 + m12*rhs.m22;
164
165                 ret.m20=m20*rhs.m00 + m21*rhs.m10 + m22*rhs.m20;
166                 ret.m21=m20*rhs.m01 + m21*rhs.m11 + m22*rhs.m21;
167                 ret.m22=m20*rhs.m02 + m21*rhs.m12 + m22*rhs.m22;
168                 return ret;
169                 }
170
171         //! operator *=. Multiplication and assign of one matrix by a number
172         //! @param rhs the number to multiply by
173         //! @return the modifed resulting multiplicated by number matrix
174         Matrix
175         operator *=(const value_type &rhs){
176                 m00*=rhs;
177                 m01*=rhs;
178                 m02*=rhs;
179
180                 m10*=rhs;
181                 m11*=rhs;
182                 m12*=rhs;
183
184                 m20*=rhs;
185                 m21*=rhs;
186                 m22*=rhs;
187                 return *this;
188         }
189
190         //! operator +=. Sum and assign of two matrixes
191         //! @param rhs the matrix to sum
192         //! @return modified matrix with the summed matrix
193         Matrix
194         operator +=(const Matrix &rhs){
195                 m00+=rhs.m00;
196                 m01+=rhs.m01;
197                 m02+=rhs.m02;
198
199                 m10+=rhs.m10;
200                 m11+=rhs.m11;
201                 m12+=rhs.m12;
202
203                 m20+=rhs.m20;
204                 m21+=rhs.m21;
205                 m22+=rhs.m22;
206                 return *this;
207                 }
208
209         //! operator *. Multiplication of one matrix by a number
210         //! @param rhs the number to multiply by
211         //! @return the resulting multiplicated by number matrix
212         Matrix
213         operator *(const value_type &rhs){
214         return Matrix(*this)*=rhs;
215                 }
216
217         //! operator +=. Sum and assign of two matrixes
218         //! @param rhs the matrix to sum
219         //! @return modified matrix with the summed matrix
220         Matrix
221         operator +(const Matrix &rhs){
222         return Matrix(*this)+=rhs;
223                 }
224
225 };
226
227 }; // END of namespace synfig
228
229 #endif