2 Copyright 2005, 2006 Computer Vision Lab,
3 Ecole Polytechnique Federale de Lausanne (EPFL), Switzerland.
6 This file is part of BazAR.
8 BazAR is free software; you can redistribute it and/or modify it under the
9 terms of the GNU General Public License as published by the Free Software
10 Foundation; either version 2 of the License, or (at your option) any later
13 BazAR is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
15 PARTICULAR PURPOSE. See the GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License along with
18 BazAR; if not, write to the Free Software Foundation, Inc., 51 Franklin
19 Street, Fifth Floor, Boston, MA 02110-1301, USA
24 #include "linear_algebra.h"
25 #include <general/general.h>
29 /////////////////////////////////////////////////////////////////////////////////////////////////
32 double gfla_norme(double v1
, double v2
, double v3
)
34 return sqrt(v1
* v1
+ v2
* v2
+ v3
* v3
);
37 double gfla_normalize_3(double v
[3])
39 double norme
= sqrt(v
[0] * v
[0] + v
[1] * v
[1] + v
[2] * v
[2]);
44 double inv_norme
= 1. / norme
;
53 void gfla_scale_3(const double s
, double v
[3])
60 void gfla_scale_3(const double s
, const double v
[3], double sv
[3])
67 void gfla_opp_3(double v
[3])
74 void gfla_add_3(const double u
[3], const double v
[3], double w
[3])
81 void gfla_sub_3(const double u
[3], const double v
[3], double w
[3])
88 void gfla_cross_product(const double v1
[3], const double v2
[3], double v1v2
[3])
90 v1v2
[0] = v1
[1] * v2
[2] - v1
[2] * v2
[1];
91 v1v2
[1] = v1
[2] * v2
[0] - v1
[0] * v2
[2];
92 v1v2
[2] = v1
[0] * v2
[1] - v1
[1] * v2
[0];
95 double gfla_dot_product(const double v1
[3], const double v2
[3])
97 return v1
[0] * v2
[0] + v1
[1] * v2
[1] + v1
[2] * v2
[2];
101 void gfla_copy_3(const double v
[3], double copy
[3])
103 for(int i
= 0; i
< 3; i
++)
108 void gfla_copy_3x3(const double M
[3][3], double copy
[3][3])
110 for(int i
= 0; i
< 3; i
++)
111 for(int j
= 0; j
< 3; j
++)
112 copy
[i
][j
] = M
[i
][j
];
115 void gfla_copy_3x4(const double M
[3][4], double copy
[3][4])
117 for(int i
= 0; i
< 3; i
++)
118 for(int j
= 0; j
< 4; j
++)
119 copy
[i
][j
] = M
[i
][j
];
121 /////////////////////////////////////////////////////////////////////////////////////////////////
124 double gfla_det(const double M
[3][3])
126 return M
[0][0] * M
[1][1] * M
[2][2] -
127 M
[0][0] * M
[1][2] * M
[2][1] -
128 M
[1][0] * M
[0][1] * M
[2][2] +
129 M
[1][0] * M
[0][2] * M
[2][1] +
130 M
[2][0] * M
[0][1] * M
[1][2] -
131 M
[2][0] * M
[0][2] * M
[1][1];
134 double gfla_det(const double M11
, const double M12
,
135 const double M21
, const double M22
)
137 return M11
* M22
- M12
* M21
;
140 double gfla_det(const double M11
, const double M12
, const double M13
,
141 const double M21
, const double M22
, const double M23
,
142 const double M31
, const double M32
, const double M33
)
144 return M11
* M22
* M33
- M11
* M23
* M32
-
145 M21
* M12
* M33
+ M21
* M13
* M32
+
146 M31
* M12
* M23
- M31
* M13
* M22
;
149 void gfla_get_rotation_from_kappa(double R
[3][3], const double kappa
)
151 R
[0][0] = cos(kappa
); R
[0][1] = sin(kappa
); R
[0][2] = 0.;
152 R
[1][0] = -sin(kappa
); R
[1][1] = cos(kappa
); R
[1][2] = 0.;
153 R
[2][0] = 0.; R
[2][1] = 0.; R
[2][2] = 1.;
156 void gfla_get_rotation_from_phi(double R
[3][3], const double phi
)
158 R
[0][0] = cos(phi
); R
[0][1] = 0.; R
[0][2] = -sin(phi
);
159 R
[1][0] = 0.; R
[1][1] = 1.; R
[1][2] = 0.;
160 R
[2][0] = sin(phi
); R
[2][1] = 0.; R
[2][2] = cos(phi
);
163 void gfla_get_rotation_from_omega(double R
[3][3], const double omega
)
165 R
[0][0] = 1.; R
[0][1] = 0.; R
[0][2] = 0.;
166 R
[1][0] = 0.; R
[1][1] = cos(omega
); R
[1][2] = sin(omega
);
167 R
[2][0] = 0.; R
[2][1] = -sin(omega
); R
[2][2] = cos(omega
);
171 R = R(kappa) * R(phi) * R(omega)
173 void gfla_get_rotation_from_euler_angles(double R
[3][3], const double omega
, const double phi
, const double kappa
)
186 R
[0][1] = t4
*t6
+t11
*t8
;
187 R
[0][2] = t1
*t6
-t15
*t8
;
189 R
[1][1] = t4
*t8
-t11
*t6
;
190 R
[1][2] = t1
*t8
+t15
*t6
;
196 int gfla_get_euler_angles_from_rotation(const double R
[3][3], double * omega
, double * phi
, double * kappa
)
198 if (fabs(R
[2][2]) < 1e-6 && fabs(R
[2][1]) < 1e-6)
200 /* Degenerate case: When phi = +/- 90 degrees, then we cannot seperate omega and kappa */
201 *omega
= atan2(R
[1][2], R
[1][1]);
212 *omega
= atan2(-R
[2][1], R
[2][2]);
213 *phi
= atan2(R
[2][0], sqrt(R
[0][0] * R
[0][0] + R
[1][0] * R
[1][0]));
214 *kappa
= atan2(-R
[1][0], R
[0][0]);
220 /////////////////////////////////////////////////////////////////////////////////////////////////
223 void gfla_mul_scale_mat_3x3(double s
, double M
[3][3], double sM
[3][3])
225 sM
[0][0] = s
* M
[0][0]; sM
[0][1] = s
* M
[0][1]; sM
[0][2] = s
* M
[0][2];
226 sM
[1][0] = s
* M
[1][0]; sM
[1][1] = s
* M
[1][1]; sM
[1][2] = s
* M
[1][2];
227 sM
[2][0] = s
* M
[2][0]; sM
[2][1] = s
* M
[2][1]; sM
[2][2] = s
* M
[2][2];
230 void gfla_mul_mat_vect_3x3(const double M
[3][3], const double v
[3], double Mv
[3])
234 Mv
[0] = M
[0][0] * v
[0] + M
[0][1] * v
[1] + M
[0][2] * v
[2];
235 Mv
[1] = M
[1][0] * v
[0] + M
[1][1] * v
[1] + M
[1][2] * v
[2];
236 Mv
[2] = M
[2][0] * v
[0] + M
[2][1] * v
[1] + M
[2][2] * v
[2];
242 Mv_temp
[0] = M
[0][0] * v
[0] + M
[0][1] * v
[1] + M
[0][2] * v
[2];
243 Mv_temp
[1] = M
[1][0] * v
[0] + M
[1][1] * v
[1] + M
[1][2] * v
[2];
244 Mv_temp
[2] = M
[2][0] * v
[0] + M
[2][1] * v
[1] + M
[2][2] * v
[2];
252 void gfla_mul_T_mat_vect_3x3(const double M
[3][3], const double v
[3], double tMv
[3])
254 for(int i
= 0; i
< 3; i
++)
256 tMv
[i
] = M
[0][i
] * v
[0];
257 for(int j
= 1; j
< 3; j
++)
258 tMv
[i
] += M
[j
][i
] * v
[j
];
262 void gfla_mul_mat_vect_3x4(const double M
[3][4], const double v
[3], double Mv
[3])
264 for(int i
= 0; i
< 3; i
++)
266 Mv
[i
] = M
[i
][0] * v
[0];
267 for(int j
= 1; j
< 4; j
++)
268 Mv
[i
] += M
[i
][j
] * v
[j
];
272 void gfla_mul_mat_3x3x4(const double M
[3][3], const double N
[3][4], double MN
[3][4])
274 for(int i
= 0; i
< 3; i
++)
275 for(int j
= 0; j
< 4; j
++)
278 for(int k
= 0; k
< 3; k
++)
279 MN
[i
][j
] += M
[i
][k
] * N
[k
][j
];
283 /////////////////////////////////////////////////////////////////////////////////////////////////
286 void gfla_inverse_3(double A
[3][3], double invA
[3][3])
321 t26
= 1/(t9
*t2
-t11
*t5
-t15
*t2
+t18
*t5
+t21
*t4
-t23
*t1
);
322 invA
[0][0] = (t1
*t2
-t4
*t5
)*t26
;
323 invA
[0][1] = -(t14
*t2
-t17
*t5
)*t26
;
324 invA
[0][2] = -(-t14
*t4
+t17
*t1
)*t26
;
325 invA
[1][0] = -(t13
*t2
-t4
*t20
)*t26
;
326 invA
[1][1] = (t8
*t2
-t23
)*t26
;
327 invA
[1][2] = -(t11
-t18
)*t26
;
328 invA
[2][0] = -(-t13
*t5
+t1
*t20
)*t26
;
329 invA
[2][1] = -(t8
*t5
-t21
)*t26
;
330 invA
[2][2] = (t9
-t15
)*t26
;
335 /////////////////////////////////////////////////////////////////////////////////////////////////
338 void gfla_print_mat_3x3(ostream
& o
, double M
[3][3])
340 for(int i
= 0; i
< 3; i
++)
342 for(int j
= 0; j
< 3; j
++)
343 o
<< M
[i
][j
] << "\t";
348 void gfla_print_mat_3x4(ostream
& o
, double M
[3][4])
350 for(int i
= 0; i
< 3; i
++)
352 for(int j
= 0; j
< 4; j
++)
353 o
<< M
[i
][j
] << "\t";
358 void gfla_print_mat_4x4(ostream
& o
, double * M
)
360 for(int i
= 0; i
< 4; i
++)
362 for(int j
= 0; j
< 4; j
++)
363 o
<< M
[4 * i
+ j
] << "\t";