61d277bf5ac921963f4cbcddf51ad056caad787e
[platform/framework/native/appfw.git] / src / base / FBaseDoubleMatrix3.cpp
1 //
2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
3 //
4 // Licensed under the Apache License, Version 2.0 (the License);
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //     http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 /**
18  * @file        FBaseDoubleMatrix3.cpp
19  * @brief       This is the implementation for DoubleMatrix class.
20  */
21
22 #include <FBaseDoubleMatrix3.h>
23 #include <FBaseSysLog.h>
24
25 namespace Tizen { namespace Base
26 {
27
28 static const int MATRIX_SIZE = sizeof(double) * 9;
29 #define SWAP_VALUES(a, b, tmp) \
30         tmp = a; \
31         a = b; \
32         b = tmp;
33
34 DoubleMatrix3::DoubleMatrix3(void)
35         : __pImpl(null)
36 {
37         SetAsNull();
38 }
39
40 DoubleMatrix3::DoubleMatrix3(const DoubleMatrix3& rhs)
41         : __pImpl(null)
42 {
43         memcpy(matrix, rhs.matrix, MATRIX_SIZE);
44 }
45
46 DoubleMatrix3::DoubleMatrix3(const double matrix[3][3])
47         : __pImpl(null)
48 {
49         memcpy(this->matrix, matrix, MATRIX_SIZE);
50 }
51
52 DoubleMatrix3::~DoubleMatrix3(void)
53 {
54 }
55
56 bool
57 DoubleMatrix3::operator ==(const DoubleMatrix3& rhs) const
58 {
59         if (this == &rhs)
60         {
61                 return true;
62         }
63
64         return (matrix[0][0] == rhs.matrix[0][0] &&
65                         matrix[0][1] == rhs.matrix[0][1] &&
66                         matrix[0][2] == rhs.matrix[0][2] &&
67                         matrix[1][0] == rhs.matrix[1][0] &&
68                         matrix[1][1] == rhs.matrix[1][1] &&
69                         matrix[1][2] == rhs.matrix[1][2] &&
70                         matrix[2][0] == rhs.matrix[2][0] &&
71                         matrix[2][1] == rhs.matrix[2][1] &&
72                         matrix[2][2] == rhs.matrix[2][2]);
73 }
74
75 bool
76 DoubleMatrix3::operator !=(const DoubleMatrix3& rhs) const
77 {
78         return !(*this == rhs);
79 }
80
81 DoubleMatrix3&
82 DoubleMatrix3::operator =(const DoubleMatrix3& rhs)
83 {
84         if (this != &rhs)
85         {
86                 memcpy(matrix, rhs.matrix, sizeof(double) * 9);
87         }
88
89         return *this;
90 }
91
92 DoubleMatrix3&
93 DoubleMatrix3::operator =(double value)
94 {
95         matrix[0][0] = value;
96         matrix[1][0] = value;
97         matrix[2][0] = value;
98
99         matrix[0][1] = value;
100         matrix[1][1] = value;
101         matrix[2][1] = value;
102
103         matrix[0][2] = value;
104         matrix[1][2] = value;
105         matrix[2][2] = value;
106
107         return *this;
108 }
109
110 DoubleMatrix3
111 DoubleMatrix3::operator *(const DoubleMatrix3& rhs) const  // need to check performance
112 {
113         DoubleMatrix3 resultMatrix;
114
115         resultMatrix.matrix[0][0] = matrix[0][0] * rhs.matrix[0][0] + matrix[0][1] * rhs.matrix[1][0] + matrix[0][2] * rhs.matrix[2][0];
116         resultMatrix.matrix[0][1] = matrix[0][0] * rhs.matrix[0][1] + matrix[0][1] * rhs.matrix[1][1] + matrix[0][2] * rhs.matrix[2][1];
117         resultMatrix.matrix[0][2] = matrix[0][0] * rhs.matrix[0][2] + matrix[0][1] * rhs.matrix[1][2] + matrix[0][2] * rhs.matrix[2][2];
118
119         resultMatrix.matrix[1][0] = matrix[1][0] * rhs.matrix[0][0] + matrix[1][1] * rhs.matrix[1][0] + matrix[1][2] * rhs.matrix[2][0];
120         resultMatrix.matrix[1][1] = matrix[1][0] * rhs.matrix[0][1] + matrix[1][1] * rhs.matrix[1][1] + matrix[1][2] * rhs.matrix[2][1];
121         resultMatrix.matrix[1][2] = matrix[1][0] * rhs.matrix[0][2] + matrix[1][1] * rhs.matrix[1][2] + matrix[1][2] * rhs.matrix[2][2];
122
123         resultMatrix.matrix[2][0] = matrix[2][0] * rhs.matrix[0][0] + matrix[2][1] * rhs.matrix[1][0] + matrix[2][2] * rhs.matrix[2][0];
124         resultMatrix.matrix[2][1] = matrix[2][0] * rhs.matrix[0][1] + matrix[2][1] * rhs.matrix[1][1] + matrix[2][2] * rhs.matrix[2][1];
125         resultMatrix.matrix[2][2] = matrix[2][0] * rhs.matrix[0][2] + matrix[2][1] * rhs.matrix[1][2] + matrix[2][2] * rhs.matrix[2][2];
126
127         return resultMatrix;
128 }
129
130 DoubleMatrix3
131 DoubleMatrix3::operator *(double value) const
132 {
133         DoubleMatrix3 resultMatrix(matrix);
134
135         resultMatrix.matrix[0][0] *= value;
136         resultMatrix.matrix[0][1] *= value;
137         resultMatrix.matrix[0][2] *= value;
138
139         resultMatrix.matrix[1][0] *= value;
140         resultMatrix.matrix[1][1] *= value;
141         resultMatrix.matrix[1][2] *= value;
142
143         resultMatrix.matrix[2][0] *= value;
144         resultMatrix.matrix[2][1] *= value;
145         resultMatrix.matrix[2][2] *= value;
146
147         return resultMatrix;
148 }
149
150 DoubleMatrix3
151 DoubleMatrix3::operator +(const DoubleMatrix3& rhs) const
152 {
153         DoubleMatrix3 resultMatrix(matrix);
154
155         resultMatrix.matrix[0][0] += rhs.matrix[0][0];
156         resultMatrix.matrix[0][1] += rhs.matrix[0][1];
157         resultMatrix.matrix[0][2] += rhs.matrix[0][2];
158
159         resultMatrix.matrix[1][0] += rhs.matrix[1][0];
160         resultMatrix.matrix[1][1] += rhs.matrix[1][1];
161         resultMatrix.matrix[1][2] += rhs.matrix[1][2];
162
163         resultMatrix.matrix[2][0] += rhs.matrix[2][0];
164         resultMatrix.matrix[2][1] += rhs.matrix[2][1];
165         resultMatrix.matrix[2][2] += rhs.matrix[2][2];
166
167         return resultMatrix;
168 }
169
170 DoubleMatrix3
171 DoubleMatrix3::operator +(double value) const
172 {
173         DoubleMatrix3 resultMatrix(matrix);
174
175         resultMatrix.matrix[0][0] += value;
176         resultMatrix.matrix[0][1] += value;
177         resultMatrix.matrix[0][2] += value;
178
179         resultMatrix.matrix[1][0] += value;
180         resultMatrix.matrix[1][1] += value;
181         resultMatrix.matrix[1][2] += value;
182
183         resultMatrix.matrix[2][0] += value;
184         resultMatrix.matrix[2][1] += value;
185         resultMatrix.matrix[2][2] += value;
186
187         return resultMatrix;
188 }
189
190 DoubleMatrix3
191 DoubleMatrix3::operator -(const DoubleMatrix3& rhs) const
192 {
193         DoubleMatrix3 resultMatrix(matrix);
194
195         resultMatrix.matrix[0][0] -= rhs.matrix[0][0];
196         resultMatrix.matrix[0][1] -= rhs.matrix[0][1];
197         resultMatrix.matrix[0][2] -= rhs.matrix[0][2];
198
199         resultMatrix.matrix[1][0] -= rhs.matrix[1][0];
200         resultMatrix.matrix[1][1] -= rhs.matrix[1][1];
201         resultMatrix.matrix[1][2] -= rhs.matrix[1][2];
202
203         resultMatrix.matrix[2][0] -= rhs.matrix[2][0];
204         resultMatrix.matrix[2][1] -= rhs.matrix[2][1];
205         resultMatrix.matrix[2][2] -= rhs.matrix[2][2];
206
207         return resultMatrix;
208 }
209
210 DoubleMatrix3
211 DoubleMatrix3::operator -(double value) const
212 {
213         DoubleMatrix3 resultMatrix(matrix);
214
215         resultMatrix.matrix[0][0] -= value;
216         resultMatrix.matrix[0][1] -= value;
217         resultMatrix.matrix[0][2] -= value;
218
219         resultMatrix.matrix[1][0] -= value;
220         resultMatrix.matrix[1][1] -= value;
221         resultMatrix.matrix[1][2] -= value;
222
223         resultMatrix.matrix[2][0] -= value;
224         resultMatrix.matrix[2][1] -= value;
225         resultMatrix.matrix[2][2] -= value;
226
227         return resultMatrix;
228 }
229
230 DoubleMatrix3&
231 DoubleMatrix3::operator *=(const DoubleMatrix3& rhs)
232 {
233         *this = *this * rhs;
234         return *this;
235 }
236
237 DoubleMatrix3&
238 DoubleMatrix3::operator *=(double value)
239 {
240         *this = *this * value;
241         return *this;
242 }
243
244 DoubleMatrix3&
245 DoubleMatrix3::operator +=(const DoubleMatrix3& rhs)
246 {
247         *this = *this + rhs;
248         return *this;
249 }
250
251 DoubleMatrix3&
252 DoubleMatrix3::operator +=(double value)
253 {
254         *this = *this + value;
255         return *this;
256 }
257
258 DoubleMatrix3&
259 DoubleMatrix3::operator -=(const DoubleMatrix3& rhs)
260 {
261         *this = *this - rhs;
262         return *this;
263 }
264
265 DoubleMatrix3&
266 DoubleMatrix3::operator -=(double value)
267 {
268         *this = *this - value;
269         return *this;
270 }
271
272 DoubleMatrix3
273 operator +(const double& value, const DoubleMatrix3& rhs)
274 {
275         return rhs + value;
276 }
277
278 DoubleMatrix3
279 operator *(const double& value, const DoubleMatrix3& rhs)
280 {
281         return rhs * value;
282 }
283
284 DoubleMatrix3
285 operator -(const double& value, const DoubleMatrix3& rhs)
286 {
287         DoubleMatrix3 returnMatrix(rhs);
288         returnMatrix.Negate();
289         returnMatrix += value;
290         return returnMatrix;
291 }
292
293 bool
294 DoubleMatrix3::Equals(const Tizen::Base::Object& obj) const
295 {
296         const DoubleMatrix3* pMatrix = dynamic_cast <const DoubleMatrix3*>(&obj);
297
298         if (pMatrix == null)
299         {
300                 return false;
301         }
302
303         return (*this == *pMatrix);
304 }
305
306 int
307 DoubleMatrix3::GetHashCode(void) const
308 {
309         return (Tizen::Base::Double::GetHashCode(this->matrix[0][0]) + Tizen::Base::Double::GetHashCode(this->matrix[1][0]) +
310                         Tizen::Base::Double::GetHashCode(this->matrix[2][0]) + Tizen::Base::Double::GetHashCode(this->matrix[0][1]) +
311                         Tizen::Base::Double::GetHashCode(this->matrix[1][1]) + Tizen::Base::Double::GetHashCode(this->matrix[2][1]) +
312                         Tizen::Base::Double::GetHashCode(this->matrix[0][2]) + Tizen::Base::Double::GetHashCode(this->matrix[1][2]) +
313                         Tizen::Base::Double::GetHashCode(this->matrix[2][2]));
314 }
315
316 double
317 DoubleMatrix3::GetDeterminant(void) const
318 {
319         double a0 = matrix[1][1] * matrix[2][2] - matrix[2][1] * matrix[1][2];
320         double a1 = matrix[1][0] * matrix[2][2] - matrix[1][2] * matrix[2][0];
321         double a2 = matrix[1][0] * matrix[2][1] - matrix[1][1] * matrix[2][0];
322
323         return matrix[0][0] * a0 - matrix[0][1] * a1 + matrix[0][2] * a2;
324 }
325
326 DoubleMatrix3
327 DoubleMatrix3::GetInverse(void) const
328 {
329         double a0 = matrix[1][1] * matrix[2][2] - matrix[2][1] * matrix[1][2];
330         double a1 = matrix[1][0] * matrix[2][2] - matrix[1][2] * matrix[2][0];
331         double a2 = matrix[1][0] * matrix[2][1] - matrix[1][1] * matrix[2][0];
332
333         double determinant = matrix[0][0] * a0 - matrix[0][1] * a1 + matrix[0][2] * a2;
334
335         if (Tizen::Base::Double::Compare(determinant, 0.0f) == 0)
336         {
337                 return *this;
338         }
339
340         double inverseMatrix[3][3];
341
342         inverseMatrix[0][0] = (matrix[1][1] * matrix[2][2] - matrix[1][2] * matrix[2][1]) / determinant;
343         inverseMatrix[1][0] = (-matrix[1][0] * matrix[2][2] + matrix[1][2] * matrix[2][0]) / determinant;
344         inverseMatrix[2][0] = (matrix[1][0] * matrix[2][1] - matrix[1][1] * matrix[2][0]) / determinant;
345
346         inverseMatrix[0][1] = (-matrix[0][1] * matrix[2][2] + matrix[0][2] * matrix[2][1]) / determinant;
347         inverseMatrix[1][1] = (matrix[0][0] * matrix[2][2] - matrix[0][2] * matrix[2][0]) / determinant;
348         inverseMatrix[2][1] = (-matrix[0][0] * matrix[2][1] + matrix[0][1] * matrix[2][0]) / determinant;
349
350         inverseMatrix[0][2] = (matrix[0][1] * matrix[1][2] - matrix[0][2] * matrix[1][1]) / determinant;
351         inverseMatrix[1][2] = (-matrix[0][0] * matrix[1][2] + matrix[0][2] * matrix[1][0]) / determinant;
352         inverseMatrix[2][2] = (matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0]) / determinant;
353
354         return DoubleMatrix3(inverseMatrix);
355 }
356
357 double
358 DoubleMatrix3::GetTrace(void) const
359 {
360         return matrix[0][0] + matrix[1][1] + matrix[2][2];
361 }
362
363 DoubleMatrix3
364 DoubleMatrix3::GetTranspose(void) const
365 {
366         DoubleMatrix3 transposeMatrix(matrix);
367         transposeMatrix.Transpose();
368
369         return transposeMatrix;
370 }
371
372 bool
373 DoubleMatrix3::IsIdentity(void) const
374 {
375         if ((Tizen::Base::Double::Compare(matrix[0][0], 1.0f) != 0) || (Tizen::Base::Double::Compare(matrix[1][1], 1.0f) != 0) ||
376                 (Tizen::Base::Double::Compare(matrix[2][2], 1.0f) != 0))
377         {
378                 return false;
379         }
380
381         if ((Tizen::Base::Double::Compare(matrix[0][1], 0.0f) != 0) || (Tizen::Base::Double::Compare(matrix[0][2], 0.0f) != 0) ||
382                 (Tizen::Base::Double::Compare(matrix[1][0], 0.0f) != 0) || (Tizen::Base::Double::Compare(matrix[1][2], 0.0f) != 0) ||
383                 (Tizen::Base::Double::Compare(matrix[2][0], 0.0f) != 0) || (Tizen::Base::Double::Compare(matrix[2][1], 0.0f) != 0))
384         {
385                 return false;
386         }
387
388         return true;
389 }
390
391 bool
392 DoubleMatrix3::IsInvertible(void) const
393 {
394         if (Tizen::Base::Double::Compare(GetDeterminant(), 0.0f) == 0)
395         {
396                 return false;
397         }
398
399         return true;
400 }
401
402 void
403 DoubleMatrix3::Negate(void)
404 {
405         matrix[0][0] = -matrix[0][0];
406         matrix[0][1] = -matrix[0][1];
407         matrix[0][2] = -matrix[0][2];
408
409         matrix[1][0] = -matrix[1][0];
410         matrix[1][1] = -matrix[1][1];
411         matrix[1][2] = -matrix[1][2];
412
413         matrix[2][0] = -matrix[2][0];
414         matrix[2][1] = -matrix[2][1];
415         matrix[2][2] = -matrix[2][2];
416 }
417
418 void
419 DoubleMatrix3::SetAsIdentity(void)
420 {
421         matrix[0][0] = 1.0f;
422         matrix[0][1] = 0.0f;
423         matrix[0][2] = 0.0f;
424
425         matrix[1][0] = 0.0f;
426         matrix[1][1] = 1.0f;
427         matrix[1][2] = 0.0f;
428
429         matrix[2][0] = 0.0f;
430         matrix[2][1] = 0.0f;
431         matrix[2][2] = 1.0f;
432 }
433
434 result
435 DoubleMatrix3::Invert(void)
436 {
437         double a0 = matrix[1][1] * matrix[2][2] - matrix[2][1] * matrix[1][2];
438         double a1 = matrix[1][0] * matrix[2][2] - matrix[1][2] * matrix[2][0];
439         double a2 = matrix[1][0] * matrix[2][1] - matrix[1][1] * matrix[2][0];
440
441         double determinant = matrix[0][0] * a0 - matrix[0][1] * a1 + matrix[0][2] * a2;
442
443         SysTryReturnResult(NID_BASE, Tizen::Base::Double::Compare(determinant, 0.0f) != 0, E_INVALID_OPERATION,
444                 "The current instance is not invertible.");
445
446         double inverseMatrix[3][3];
447
448         inverseMatrix[0][0] = (matrix[1][1] * matrix[2][2] - matrix[1][2] * matrix[2][1]) / determinant;
449         inverseMatrix[1][0] = (-matrix[1][0] * matrix[2][2] + matrix[1][2] * matrix[2][0]) / determinant;
450         inverseMatrix[2][0] = (matrix[1][0] * matrix[2][1] - matrix[1][1] * matrix[2][0]) / determinant;
451
452         inverseMatrix[0][1] = (-matrix[0][1] * matrix[2][2] + matrix[0][2] * matrix[2][1]) / determinant;
453         inverseMatrix[1][1] = (matrix[0][0] * matrix[2][2] - matrix[0][2] * matrix[2][0]) / determinant;
454         inverseMatrix[2][1] = (-matrix[0][0] * matrix[2][1] + matrix[0][1] * matrix[2][0]) / determinant;
455
456         inverseMatrix[0][2] = (matrix[0][1] * matrix[1][2] - matrix[0][2] * matrix[1][1]) / determinant;
457         inverseMatrix[1][2] = (-matrix[0][0] * matrix[1][2] + matrix[0][2] * matrix[1][0]) / determinant;
458         inverseMatrix[2][2] = (matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0]) / determinant;
459
460         memcpy(matrix, inverseMatrix, MATRIX_SIZE);
461
462         return E_SUCCESS;
463 }
464
465 void
466 DoubleMatrix3::Transpose(void)
467 {
468         double tmp = 0.0f;
469         SWAP_VALUES(matrix[0][1], matrix[1][0], tmp);
470         SWAP_VALUES(matrix[0][2], matrix[2][0], tmp);
471
472         SWAP_VALUES(matrix[1][2], matrix[2][1], tmp);
473 }
474
475 void
476 DoubleMatrix3::SetAsNull(void)
477 {
478         matrix[0][0] = 0.0f;
479         matrix[0][1] = 0.0f;
480         matrix[0][2] = 0.0f;
481
482         matrix[1][0] = 0.0f;
483         matrix[1][1] = 0.0f;
484         matrix[1][2] = 0.0f;
485
486         matrix[2][0] = 0.0f;
487         matrix[2][1] = 0.0f;
488         matrix[2][2] = 0.0f;
489 }
490
491 }} // Tizen::Base