00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <iomanip>
00027 #include "fob/matrix.h"
00028
00030 const math::matrix4 math::matrix4::IDENTITY(
00031 1.0, 0.0, 0.0, 0.0,
00032 0.0, 1.0, 0.0, 0.0,
00033 0.0, 0.0, 1.0, 0.0,
00034 0.0, 0.0, 0.0, 1.0
00035 );
00036
00038 const math::matrix4 math::matrix4::ZERO(
00039 0.0, 0.0, 0.0, 0.0,
00040 0.0, 0.0, 0.0, 0.0,
00041 0.0, 0.0, 0.0, 0.0,
00042 0.0, 0.0, 0.0, 0.0
00043 );
00044
00046 math::matrix4::matrix4( void )
00047 { }
00048
00050 math::matrix4::matrix4(
00051 real_t d00, real_t d01, real_t d02,
00052 real_t d10, real_t d11, real_t d12,
00053 real_t d20, real_t d21, real_t d22 )
00054 {
00055 m_data[ 0 ][ 0 ] = d00;
00056 m_data[ 0 ][ 1 ] = d01;
00057 m_data[ 0 ][ 2 ] = d02;
00058 m_data[ 0 ][ 3 ] = 0.0;
00059
00060 m_data[ 1 ][ 0 ] = d10;
00061 m_data[ 1 ][ 1 ] = d11;
00062 m_data[ 1 ][ 2 ] = d12;
00063 m_data[ 1 ][ 3 ] = 0.0;
00064
00065 m_data[ 2 ][ 0 ] = d20;
00066 m_data[ 2 ][ 1 ] = d21;
00067 m_data[ 2 ][ 2 ] = d22;
00068 m_data[ 2 ][ 3 ] = 0.0;
00069
00070 m_data[ 3 ][ 0 ] = 0.0;
00071 m_data[ 3 ][ 1 ] = 0.0;
00072 m_data[ 3 ][ 2 ] = 0.0;
00073 m_data[ 3 ][ 3 ] = 1.0;
00074 }
00075
00077 math::matrix4::matrix4(
00078 real_t d00, real_t d01, real_t d02, real_t d03,
00079 real_t d10, real_t d11, real_t d12, real_t d13,
00080 real_t d20, real_t d21, real_t d22, real_t d23,
00081 real_t d30, real_t d31, real_t d32, real_t d33 )
00082 {
00083 m_data[ 0 ][ 0 ] = d00;
00084 m_data[ 0 ][ 1 ] = d01;
00085 m_data[ 0 ][ 2 ] = d02;
00086 m_data[ 0 ][ 3 ] = d03;
00087
00088 m_data[ 1 ][ 0 ] = d10;
00089 m_data[ 1 ][ 1 ] = d11;
00090 m_data[ 1 ][ 2 ] = d12;
00091 m_data[ 1 ][ 3 ] = d13;
00092
00093 m_data[ 2 ][ 0 ] = d20;
00094 m_data[ 2 ][ 1 ] = d21;
00095 m_data[ 2 ][ 2 ] = d22;
00096 m_data[ 2 ][ 3 ] = d23;
00097
00098 m_data[ 3 ][ 0 ] = d30;
00099 m_data[ 3 ][ 1 ] = d31;
00100 m_data[ 3 ][ 2 ] = d32;
00101 m_data[ 3 ][ 3 ] = d33;
00102 }
00103
00105 math::matrix4::matrix4( const math::matrix4& m )
00106 {
00107 for( unsigned int r = 0; r < 4; ++r ) {
00108 for( unsigned int c = 0; c < 4; ++c ) {
00109 m_data[ r ][ c ] = m.m_data[ r ][ c ];
00110 }
00111 }
00112 }
00113
00115 math::matrix4&
00116 math::matrix4::operator= ( const math::matrix4& m )
00117 {
00118 for( unsigned int r = 0; r < 4; ++r ) {
00119 for( unsigned int c = 0; c < 4; ++c ) {
00120 m_data[ r ][ c ] = m.m_data[ r ][ c ];
00121 }
00122 }
00123 return *this;
00124 }
00125
00127 void
00128 math::matrix4::set(
00129 real_t d00, real_t d01, real_t d02,
00130 real_t d10, real_t d11, real_t d12,
00131 real_t d20, real_t d21, real_t d22 )
00132 {
00133 m_data[ 0 ][ 0 ] = d00;
00134 m_data[ 0 ][ 1 ] = d01;
00135 m_data[ 0 ][ 2 ] = d02;
00136 m_data[ 0 ][ 3 ] = 0.0;
00137
00138 m_data[ 1 ][ 0 ] = d10;
00139 m_data[ 1 ][ 1 ] = d11;
00140 m_data[ 1 ][ 2 ] = d12;
00141 m_data[ 1 ][ 3 ] = 0.0;
00142
00143 m_data[ 2 ][ 0 ] = d20;
00144 m_data[ 2 ][ 1 ] = d21;
00145 m_data[ 2 ][ 2 ] = d22;
00146 m_data[ 2 ][ 3 ] = 0.0;
00147
00148 m_data[ 3 ][ 0 ] = 0.0;
00149 m_data[ 3 ][ 1 ] = 0.0;
00150 m_data[ 3 ][ 2 ] = 0.0;
00151 m_data[ 3 ][ 3 ] = 1.0;
00152 }
00153
00155 void
00156 math::matrix4::set(
00157 real_t d00, real_t d01, real_t d02, real_t d03,
00158 real_t d10, real_t d11, real_t d12, real_t d13,
00159 real_t d20, real_t d21, real_t d22, real_t d23,
00160 real_t d30, real_t d31, real_t d32, real_t d33 )
00161 {
00162 m_data[ 0 ][ 0 ] = d00;
00163 m_data[ 0 ][ 1 ] = d01;
00164 m_data[ 0 ][ 2 ] = d02;
00165 m_data[ 0 ][ 3 ] = d03;
00166
00167 m_data[ 1 ][ 0 ] = d10;
00168 m_data[ 1 ][ 1 ] = d11;
00169 m_data[ 1 ][ 2 ] = d12;
00170 m_data[ 1 ][ 3 ] = d13;
00171
00172 m_data[ 2 ][ 0 ] = d20;
00173 m_data[ 2 ][ 1 ] = d21;
00174 m_data[ 2 ][ 2 ] = d22;
00175 m_data[ 2 ][ 3 ] = d23;
00176
00177 m_data[ 3 ][ 0 ] = d30;
00178 m_data[ 3 ][ 1 ] = d31;
00179 m_data[ 3 ][ 2 ] = d32;
00180 m_data[ 3 ][ 3 ] = d33;
00181 }
00182
00184 math::vector3
00185 math::matrix4::operator* ( const math::vector3& v ) const
00186 {
00187 math::vector3 res;
00188 for( unsigned int i = 0; i < 3; ++i ) {
00189 res( i ) =
00190 m_data[ i ][ 0 ] * v.x( ) +
00191 m_data[ i ][ 1 ] * v.y( ) +
00192 m_data[ i ][ 2 ] * v.z( ) +
00193 m_data[ i ][ 3 ];
00194 }
00195 return res;
00196 }
00197
00199 math::matrix4
00200 math::matrix4::operator*( const math::matrix4& rhs ) const
00201 {
00202 math::matrix4 dest;
00203 for( unsigned int r = 0; r < 4; ++r ) {
00204 for( unsigned int c = 0; c < 4; ++c ) {
00205 dest.m_data[ r ][c ] =
00206 m_data[ r ][ 0 ] * rhs.m_data[ 0 ][ c ] +
00207 m_data[ r ][ 1 ] * rhs.m_data[ 1 ][ c ] +
00208 m_data[ r ][ 2 ] * rhs.m_data[ 2 ][ c ] +
00209 m_data[ r ][ 3 ] * rhs.m_data[ 3 ][ c ];
00210 }
00211 }
00212 return dest;
00213 }
00214
00216 math::matrix4
00217 math::matrix4::operator+( const math::matrix4& rhs ) const
00218 {
00219 math::matrix4 dest;
00220 for( unsigned int r = 0; r < 4; ++r ) {
00221 for( unsigned int c = 0; c < 4; ++c ) {
00222 dest.m_data[ r ][ c ] = m_data[ r ][ c ] + rhs.m_data[ r ][ c ];
00223 }
00224 }
00225 return dest;
00226 }
00227
00229 math::matrix4
00230 math::matrix4::operator-( const math::matrix4& rhs ) const
00231 {
00232 math::matrix4 dest;
00233 for( unsigned int r = 0; r < 4; ++r ) {
00234 for( unsigned int c = 0; c < 4; ++c ) {
00235 dest.m_data[ r ][c ] = m_data[ r ][ c ] - rhs.m_data[ r ][ c ];
00236 }
00237 }
00238 return dest;
00239 }
00240
00242 void
00243 math::matrix4::transpose( void )
00244 {
00245 for( unsigned int r = 0; r < 4; ++r ) {
00246 for( unsigned int c = r; c < 4; ++c ) {
00247 math::swap( m_data[ r ][ c ], m_data[ c ][ r ] );
00248 }
00249 }
00250 }
00251
00253 math::vector3
00254 math::operator* ( const math::vector3& v, const math::matrix4& m )
00255 {
00256 math::vector3 res;
00257 for( unsigned int i = 0; i < 3; ++i ) {
00258 res( i ) =
00259 m.m_data[ 0 ][ i ] * v.x( ) +
00260 m.m_data[ 1 ][ i ] * v.y( ) +
00261 m.m_data[ 2 ][ i ] * v.z( ) +
00262 m.m_data[ 3 ][ i ];
00263 }
00264 return res;
00265 }
00266
00268 void
00269 math::matrix4::from_angle_axis( real_t radians, const math::vector3& axis )
00270 {
00271 real_t rcos = cos( radians );
00272 real_t rsin = sin( radians );
00273 real_t xy = axis.x( ) * axis.y( );
00274 real_t xz = axis.x( ) * axis.z( );
00275 real_t yz = axis.y( ) * axis.z( );
00276 real_t t = 1.0 - rcos;
00277
00278 m_data[ 0 ][ 0 ] = rcos + axis.x( ) * axis.x( ) * t;
00279 m_data[ 0 ][ 1 ] = -axis.z( ) * rsin + xy * t;
00280 m_data[ 0 ][ 2 ] = axis.y( ) * rsin + xz * t;
00281 m_data[ 0 ][ 3 ] = 0.0;
00282
00283 m_data[ 1 ][ 0 ] = axis.z( ) * rsin + xy * t;
00284 m_data[ 1 ][ 1 ] = rcos + axis.y( ) * axis.y( ) * t;
00285 m_data[ 1 ][ 2 ] = -axis.x( ) * rsin + yz * t;
00286 m_data[ 1 ][ 3 ] = 0.0;
00287
00288 m_data[ 2 ][ 0 ] = -axis.y( ) * rsin + xz * t;
00289 m_data[ 2 ][ 1 ] = axis.x( ) * rsin + yz * t;
00290 m_data[ 2 ][ 2 ] = rcos + axis.z( ) * axis.z( ) * t;
00291 m_data[ 2 ][ 3 ] = 0.0;
00292
00293 m_data[ 3 ][ 0 ] = 0.0;
00294 m_data[ 3 ][ 1 ] = 0.0;
00295 m_data[ 3 ][ 2 ] = 0.0;
00296 m_data[ 3 ][ 3 ] = 1.0;
00297 }
00298
00300
00301 math::matrix4
00302 math::matrix4::get_inverted_rotation( void ) const
00303 {
00304 math::matrix4 inv( IDENTITY );
00305 inv.m_data[ 0 ][ 0 ] = m_data[ 1 ][ 1 ] * m_data[ 2 ][ 2 ] -
00306 m_data[ 1 ][ 2 ] * m_data[ 2 ][ 1 ];
00307 inv.m_data[ 0 ][ 1 ] = m_data[ 0 ][ 2 ] * m_data[ 2 ][ 1 ] -
00308 m_data[ 0 ][ 1 ] * m_data[ 2 ][ 2 ];
00309 inv.m_data[ 0 ][ 2 ] = m_data[ 0 ][ 1 ] * m_data[ 1 ][ 2 ] -
00310 m_data[ 0 ][ 2 ] * m_data[ 1 ][ 1 ];
00311 inv.m_data[ 1 ][ 0 ] = m_data[ 1 ][ 2 ] * m_data[ 2 ][ 0 ] -
00312 m_data[ 1 ][ 0 ] * m_data[ 2 ][ 2 ];
00313 inv.m_data[ 1 ][ 1 ] = m_data[ 0 ][ 0 ] * m_data[ 2 ][ 2 ] -
00314 m_data[ 0 ][ 2 ] * m_data[ 2 ][ 0 ];
00315 inv.m_data[ 1 ][ 2 ] = m_data[ 0 ][ 2 ] * m_data[ 1 ][ 0 ] -
00316 m_data[ 0 ][ 0 ] * m_data[ 1 ][ 2 ];
00317 inv.m_data[ 2 ][ 0 ] = m_data[ 1 ][ 0 ] * m_data[ 2 ][ 1 ] -
00318 m_data[ 1 ][ 1 ] * m_data[ 2 ][ 0 ];
00319 inv.m_data[ 2 ][ 1 ] = m_data[ 0 ][ 1 ] * m_data[ 2 ][ 0 ] -
00320 m_data[ 0 ][ 0 ] * m_data[ 2 ][ 1 ];
00321 inv.m_data[ 2 ][ 2 ] = m_data[ 0 ][ 0 ] * m_data[ 1 ][ 1 ] -
00322 m_data[ 0 ][ 1 ] * m_data[ 1 ][ 0 ];
00323
00324 real_t det = m_data[ 0 ][ 0 ] * inv.m_data[ 0 ][ 0 ] +
00325 m_data[ 0 ][ 1 ] * inv.m_data[ 1 ][ 0 ] +
00326 m_data[ 0 ][ 2 ] * inv.m_data[ 2 ][ 0 ];
00327
00328 if( math::equals( det, 0.0 ) ) {
00329
00330 return IDENTITY;
00331 }
00332
00333 det = 1.0 / det;
00334 for( unsigned int r = 0; r < 3; ++r ) {
00335 for( unsigned int c = 0; c < 3; ++c ) {
00336 inv.m_data[ r ][ c ] *= det;
00337 }
00338 }
00339
00340 return inv;
00341 }
00342
00344
00345 math::vector3
00346 math::matrix4::get_radians( void )
00347 {
00348 real_t x, y, z, c, rx, ry;
00349
00350 y = asin( m_data[ 0 ][ 2 ] );
00351 c = cos( y );
00352
00353 if( fabs( c ) > 0.005 ) {
00354 rx = m_data[ 2 ][ 2 ] / c;
00355 ry = -m_data[ 1 ][ 2 ] / c;
00356
00357 x = atan2( ry, rx );
00358
00359 rx = m_data[ 0 ][ 0 ] / c;
00360 ry = -m_data[ 0 ][ 1 ] / c;
00361
00362 z = atan2( ry, rx );
00363 } else {
00364
00365 x = 0;
00366 rx = m_data[ 1 ][ 1 ];
00367 ry = m_data[ 1 ][ 0 ];
00368 z = atan2( ry, rx );
00369 }
00370
00371 return math::vector3( x, y, z );
00372 }
00373
00375 math::vector3
00376 math::matrix4::get_degrees( void )
00377 {
00378 math::vector3 degs = get_radians( );
00379 degs *= (180.0 / M_PI);
00380 degs( 0 ) = math::angle_normalize_360( degs( 0 ) );
00381 degs( 1 ) = math::angle_normalize_360( degs( 1 ) );
00382 degs( 2 ) = math::angle_normalize_360( degs( 2 ) );
00383 return degs;
00384 }
00385
00387 void
00388 math::matrix4::from_matrix3( const real_t *mat )
00389 {
00390 set(
00391 mat[ 0 ], mat[ 1 ], mat[ 2 ],
00392 mat[ 3 ], mat[ 4 ], mat[ 5 ],
00393 mat[ 6 ], mat[ 7 ], mat[ 8 ]
00394 );
00395 }
00396
00398 void
00399 math::matrix4::from_matrix4( const real_t *mat )
00400 {
00401 set(
00402 mat[ 0 ], mat[ 1 ], mat[ 2 ], mat[ 3 ],
00403 mat[ 4 ], mat[ 5 ], mat[ 6 ], mat[ 7 ],
00404 mat[ 8 ], mat[ 9 ], mat[ 10 ], mat[ 11 ],
00405 mat[ 12 ], mat[ 13 ], mat[ 14 ], mat[ 15 ]
00406 );
00407 }
00408
00409
00411 std::ostream&
00412 math::operator<< ( std::ostream& o, const math::matrix4& m )
00413 {
00414 for( unsigned int r = 0; r < 3; ++r ) {
00415 o << std::setw( 5 ) << m.m_data[ r ][ 0 ] << " "
00416 << std::setw( 5 ) << m.m_data[ r ][ 1 ] << " "
00417 << std::setw( 5 ) << m.m_data[ r ][ 2 ] << " "
00418 << std::setw( 5 ) << m.m_data[ r ][ 3 ] << " "
00419 << std::endl;
00420 }
00421
00422
00423 o << std::setw( 5 ) << m.m_data[ 3 ][ 0 ] << " "
00424 << std::setw( 5 ) << m.m_data[ 3 ][ 1 ] << " "
00425 << std::setw( 5 ) << m.m_data[ 3 ][ 2 ] << " "
00426 << std::setw( 5 ) << m.m_data[ 3 ][ 3 ] << " ";
00427 return o;
00428 }