matrix_transform.h

Go to the documentation of this file.
00001 /* -*- C++ -*- ------------------------------------------------------------
00002  
00003 Copyright (c) 2007 Jesse Anders and Demian Nave http://cmldev.net/
00004 
00005 The Configurable Math Library (CML) is distributed under the terms of the
00006 Boost Software License, v1.0 (see cml/LICENSE for details).
00007 
00008  *-----------------------------------------------------------------------*/
00013 #ifndef matrix_transform_h
00014 #define matrix_transform_h
00015 
00016 #include <cml/mathlib/matrix_basis.h>
00017 #include <cml/mathlib/matrix_rotation.h>
00018 #include <cml/mathlib/matrix_translation.h>
00019 
00020 /* Functions for building matrix transforms other than rotations
00021  * (matrix_rotation.h) and viewing projections (matrix_projection.h).
00022  */
00023 
00024 namespace cml {
00025 
00027 // 3D translation
00029 
00031 template < typename E, class A, class B, class L > void
00032 matrix_translation(matrix<E,A,B,L>& m, E x, E y, E z)
00033 {
00034     identity_transform(m);
00035     matrix_set_translation(m,x,y,z);
00036 }
00037 
00039 template < typename E, class A, class B, class L > void
00040 matrix_translation(matrix<E,A,B,L>& m, E x, E y)
00041 {
00042     identity_transform(m);
00043     matrix_set_translation(m,x,y);
00044 }
00045 
00047 template < typename E, class A, class B, class L, class VecT > void
00048 matrix_translation(matrix<E,A,B,L>& m, const VecT& translation)
00049 {
00050     identity_transform(m);
00051     matrix_set_translation(m,translation);
00052 }
00053 
00055 // 2D translation
00057 
00059 template < typename E, class A, class B, class L > void
00060 matrix_translation_2D(matrix<E,A,B,L>& m, E x, E y)
00061 {
00062     identity_transform(m);
00063     matrix_set_translation_2D(m,x,y);
00064 }
00065 
00067 template < typename E, class A, class B, class L, class VecT > void
00068 matrix_translation_2D(matrix<E,A,B,L>& m, const VecT& translation)
00069 {
00070     identity_transform(m);
00071     matrix_set_translation_2D(m, translation);
00072 }
00073 
00075 // 3D scale
00077 
00079 template < typename E, class A, class B, class L > void
00080 matrix_uniform_scale(matrix<E,A,B,L>& m, E scale) {
00081     matrix_scale(m,scale,scale,scale);
00082 }
00083 
00085 template < typename E, class A, class B, class L > void
00086 matrix_scale(matrix<E,A,B,L>& m, E scale_x, E scale_y, E scale_z)
00087 {
00088     /* Checking */
00089     detail::CheckMatLinear3D(m);
00090     
00091     identity_transform(m);
00092     
00093     m.set_basis_element(0,0,scale_x);
00094     m.set_basis_element(1,1,scale_y);
00095     m.set_basis_element(2,2,scale_z);
00096 }
00097 
00099 template < typename E, class A, class B, class L, class VecT > void
00100 matrix_scale(matrix<E,A,B,L>& m, const VecT& scale)
00101 {
00102     /* Checking */
00103     detail::CheckVec3(scale);
00104     
00105     matrix_scale(m, scale[0], scale[1], scale[2]);
00106 }
00107 
00109 // 2D scale
00111 
00113 template < typename E, class A, class B, class L > void
00114 matrix_uniform_scale_2D(matrix<E,A,B,L>& m, E scale) {
00115     matrix_scale_2D(m,scale,scale);
00116 }
00117 
00119 template < typename E, class A, class B, class L > void
00120 matrix_scale_2D(matrix<E,A,B,L>& m, E scale_x, E scale_y)
00121 {
00122     /* Checking */
00123     detail::CheckMatLinear2D(m);
00124     
00125     identity_transform(m);
00126     
00127     m.set_basis_element(0,0,scale_x);
00128     m.set_basis_element(1,1,scale_y);
00129 }
00130 
00132 template < typename E, class A, class B, class L, class VecT > void
00133 matrix_scale_2D(matrix<E,A,B,L>& m, const VecT& scale)
00134 {
00135     /* Checking */
00136     detail::CheckVec2(scale);
00137     
00138     matrix_scale_2D(m, scale[0], scale[1]);
00139 }
00140 
00142 // 3D scale along axis
00144 
00146 template < typename E, class A, class B, class L, class VecT > void
00147 matrix_scale_along_axis(matrix<E,A,B,L>&m, const VecT& axis, E scale)
00148 {
00149     typedef matrix<E,A,B,L> matrix_type;
00150     typedef typename matrix_type::value_type value_type;
00151 
00152     /* Checking */
00153     detail::CheckVec3(axis);
00154 
00155     matrix<E,fixed<3,3>,B,L> outer_p = outer(axis,axis)*(scale-value_type(1));
00156     outer_p(0,0) += value_type(1);
00157     outer_p(1,1) += value_type(1);
00158     outer_p(2,2) += value_type(1);
00159 
00160     matrix_linear_transform(m, outer_p);
00161 }
00162 
00164 // 2D scale along axis
00166 
00168 template < typename E, class A, class B, class L, class VecT >
00169 void matrix_scale_along_axis_2D(matrix<E,A,B,L>&  m, const VecT& axis,
00170     E scale)
00171 {
00172     typedef matrix<E,A,B,L> matrix_type;
00173     typedef typename matrix_type::value_type value_type;
00174 
00175     /* Checking */
00176     detail::CheckVec2(axis);
00177 
00178     matrix<E,fixed<2,2>,B,L> outer_p = outer(axis,axis)*(scale-value_type(1));
00179     outer_p(0,0) += value_type(1);
00180     outer_p(1,1) += value_type(1);
00181 
00182     matrix_linear_transform_2D(m, outer_p);
00183 }
00184 
00186 // 3D shear
00188 
00190 template < typename E, class A, class B, class L > void
00191 matrix_shear(matrix<E,A,B,L>& m, size_t axis, E shear_s, E shear_t)
00192 {
00193     /* Checking */
00194     detail::CheckMatLinear3D(m);
00195     detail::CheckIndex3(axis);
00196 
00197     identity_transform(m);
00198     
00199     size_t i, j, k;
00200     cyclic_permutation(axis, i, j, k);
00201     
00202     m.set_basis_element(i,j,shear_s);
00203     m.set_basis_element(i,k,shear_t);
00204 }
00205 
00207 template < typename E, class A, class B, class L > void
00208 matrix_shear_x(matrix<E,A,B,L>& m, E shear_s, E shear_t) {
00209     matrix_shear(m,0,shear_s,shear_t);
00210 }
00211 
00213 template < typename E, class A, class B, class L > void
00214 matrix_shear_y(matrix<E,A,B,L>& m, E shear_s, E shear_t) {
00215     matrix_shear(m,1,shear_s,shear_t);
00216 }
00217 
00219 template < typename E, class A, class B, class L > void
00220 matrix_shear_z(matrix<E,A,B,L>& m, E shear_s, E shear_t) {
00221     matrix_shear(m,2,shear_s,shear_t);
00222 }
00223 
00225 // 2D shear
00227 
00229 template < typename E, class A, class B, class L > void
00230 matrix_shear_2D(matrix<E,A,B,L>& m, size_t axis, E shear)
00231 {
00232     /* Checking */
00233     detail::CheckMatLinear2D(m);
00234     detail::CheckIndex2(axis);
00235 
00236     identity_transform(m);
00237     
00238     size_t i, j;
00239     cyclic_permutation(axis, i, j);
00240     
00241     m.set_basis_element(i,j,shear);
00242 }
00243 
00245 template < typename E, class A, class B, class L > void
00246 matrix_shear_x_2D(matrix<E,A,B,L>& m, E shear) {
00247     matrix_shear_2D(m,0,shear);
00248 }
00249 
00251 template < typename E, class A, class B, class L > void
00252 matrix_shear_y_2D(matrix<E,A,B,L>& m, E shear) {
00253     matrix_shear_2D(m,1,shear);
00254 }
00255 
00257 // 3D reflection
00259 
00261 template < typename E, class A, class B, class L > void
00262 matrix_reflect(matrix<E,A,B,L>& m, size_t axis)
00263 {
00264     typedef matrix<E,A,B,L> matrix_type;
00265     typedef typename matrix_type::value_type value_type;
00266 
00267     /* Checking */
00268     detail::CheckMatLinear3D(m);
00269     detail::CheckIndex3(axis);
00270 
00271     identity_transform(m);
00272     
00273     m(axis,axis) = value_type(-1);
00274 }
00275 
00277 template < typename E, class A, class B, class L > void
00278 matrix_reflect_x(matrix<E,A,B,L>& m) {
00279     matrix_reflect(m,0);
00280 }
00281 
00283 template < typename E, class A, class B, class L > void
00284 matrix_reflect_y(matrix<E,A,B,L>& m) {
00285     matrix_reflect(m,1);
00286 }
00287 
00289 template < typename E, class A, class B, class L > void
00290 matrix_reflect_z(matrix<E,A,B,L>& m) {
00291     matrix_reflect(m,2);
00292 }
00293 
00295 // 2D reflection
00297 
00299 template < typename E, class A, class B, class L > void
00300 matrix_reflect_2D(matrix<E,A,B,L>& m, size_t axis)
00301 {
00302     typedef matrix<E,A,B,L> matrix_type;
00303     typedef typename matrix_type::value_type value_type;
00304 
00305     /* Checking */
00306     detail::CheckMatLinear2D(m);
00307     detail::CheckIndex2(axis);
00308 
00309     identity_transform(m);
00310     
00311     m(axis,axis) = value_type(-1);
00312 }
00313 
00315 template < typename E, class A, class B, class L > void
00316 matrix_reflect_x_2D(matrix<E,A,B,L>& m) {
00317     matrix_reflect_2D(m,0);
00318 }
00319 
00321 template < typename E, class A, class B, class L > void
00322 matrix_reflect_y_2D(matrix<E,A,B,L>& m) {
00323     matrix_reflect_2D(m,1);
00324 }
00325 
00327 // 3D reflection about hyperplane
00329 
00331 template < typename E, class A, class B, class L, class VecT > void
00332 matrix_reflect_about_hplane(matrix<E,A,B,L>& m, const VecT& normal)
00333 {
00334     typedef matrix<E,A,B,L> matrix_type;
00335     typedef typename matrix_type::value_type value_type;
00336 
00337     matrix_scale_along_axis(m, normal, value_type(-1));
00338 }
00339 
00341 // 2D reflection about hyperplane
00343 
00345 template < typename E, class A, class B, class L, class VecT > void
00346 matrix_reflect_about_hplane_2D(matrix<E,A,B,L>&m, const VecT& normal)
00347 {
00348     typedef matrix<E,A,B,L> matrix_type;
00349     typedef typename matrix_type::value_type value_type;
00350 
00351     matrix_scale_along_axis_2D(m, normal, value_type(-1));
00352 }
00353 
00355 // 3D orthographic projection to cardinal hyperplane
00357 
00359 template < typename E, class A, class B, class L > void
00360 matrix_ortho_project(matrix<E,A,B,L>& m, size_t axis)
00361 {
00362     typedef matrix<E,A,B,L> matrix_type;
00363     typedef typename matrix_type::value_type value_type;
00364 
00365     /* Checking */
00366     detail::CheckMatLinear3D(m);
00367     detail::CheckIndex3(axis);
00368 
00369     identity_transform(m);
00370     
00371     m(axis,axis) = value_type(0);
00372 }
00373 
00375 template < typename E, class A, class B, class L > void
00376 matrix_ortho_project_yz(matrix<E,A,B,L>& m) {
00377     matrix_ortho_project(m,0);
00378 }
00379 
00381 template < typename E, class A, class B, class L > void
00382 matrix_ortho_project_zx(matrix<E,A,B,L>& m) {
00383     matrix_ortho_project(m,1);
00384 }
00385 
00387 template < typename E, class A, class B, class L > void
00388 matrix_ortho_project_xy(matrix<E,A,B,L>& m) {
00389     matrix_ortho_project(m,2);
00390 }
00391 
00393 // 2D orthographic projection to cardinal hyperplane
00395 
00397 template < typename E, class A, class B, class L > void
00398 matrix_ortho_project_2D(matrix<E,A,B,L>& m, size_t axis)
00399 {
00400     typedef matrix<E,A,B,L> matrix_type;
00401     typedef typename matrix_type::value_type value_type;
00402 
00403     /* Checking */
00404     detail::CheckMatLinear2D(m);
00405     detail::CheckIndex2(axis);
00406 
00407     identity_transform(m);
00408     
00409     m(axis,axis) = value_type(0);
00410 }
00411 
00413 template < typename E, class A, class B, class L > void
00414 matrix_ortho_project_y_2D(matrix<E,A,B,L>& m) {
00415     matrix_ortho_project_2D(m,0);
00416 }
00417 
00419 template < typename E, class A, class B, class L > void
00420 matrix_ortho_project_x_2D(matrix<E,A,B,L>& m) {
00421     matrix_ortho_project_2D(m,1);
00422 }
00423 
00425 // 3D orthographic projection to hyperplane
00427 
00431 template < typename E, class A, class B, class L, class VecT > void
00432 matrix_ortho_project_to_hplane(matrix<E,A,B,L>& m, const VecT& normal)
00433 {
00434     typedef matrix<E,A,B,L> matrix_type;
00435     typedef typename matrix_type::value_type value_type;
00436 
00437     matrix_scale_along_axis(m, normal, value_type(0));
00438 }
00439 
00441 // 2D orthographic projection to hyperplane
00443 
00447 template < typename E, class A, class B, class L, class VecT > void
00448 matrix_ortho_project_to_hplane_2D(matrix<E,A,B,L>& m, const VecT& normal)
00449 {
00450     typedef matrix<E,A,B,L> matrix_type;
00451     typedef typename matrix_type::value_type value_type;
00452 
00453     matrix_scale_along_axis_2D(m, normal, value_type(0));
00454 }
00455 
00457 // 3D 'aim at'
00459 
00461 template < typename E, class A, class B, class L,
00462     class VecT_1, class VecT_2, class VecT_3 > void
00463 matrix_aim_at(matrix<E,A,B,L>& m, const VecT_1& pos, const VecT_2& target,
00464     const VecT_3& reference,
00465     AxisOrder order = axis_order_zyx)
00466 {
00467     matrix_rotation_aim_at(m, pos, target, reference, order);
00468     matrix_set_translation(m, pos);
00469 }
00470 
00472 template < typename E, class A, class B, class L,
00473     class VecT_1, class VecT_2 > void
00474 matrix_aim_at(matrix<E,A,B,L>& m, const VecT_1& pos, const VecT_2& target,
00475     AxisOrder order = axis_order_zyx)
00476 {
00477     matrix_rotation_aim_at(m, pos, target, order);
00478     matrix_set_translation(m, pos);
00479 }
00480 
00482 template < typename E, class A, class B, class L,
00483     class VecT_1, class VecT_2, class VecT_3 > void
00484 matrix_aim_at_axial(
00485     matrix<E,A,B,L>& m,
00486     const VecT_1& pos,
00487     const VecT_2& target,
00488     const VecT_3& axis,
00489     AxisOrder order = axis_order_zyx)
00490 {
00491     matrix_rotation_aim_at_axial(m, pos, target, axis, order);
00492     matrix_set_translation(m, pos);
00493 }
00494 
00496 template < typename E,class A,class B,class L,class VecT,class MatT > void
00497 matrix_aim_at_viewplane(
00498     matrix<E,A,B,L>& m,
00499     const VecT& pos,
00500     const MatT& view_matrix,
00501     Handedness handedness,
00502     AxisOrder order = axis_order_zyx)
00503 {
00504     matrix_rotation_align_viewplane(m, view_matrix, handedness, order);
00505     matrix_set_translation(m, pos);
00506 }
00507 
00509 // 2D 'aim at'
00511 
00513 template < typename E,class A,class B,class L,class VecT_1,class VecT_2 > void
00514 matrix_aim_at_2D(
00515     matrix<E,A,B,L>& m,
00516     const VecT_1& pos,
00517     const VecT_2& target,
00518     AxisOrder2D order = axis_order_xy)
00519 {
00520     matrix_rotation_align_2D(m, target - pos, true, order);
00521     matrix_set_translation_2D(m, pos);
00522 }
00523 
00525 // 3D 'look at' view matrix
00527 
00529 template < typename E, class A, class B, class L,
00530     class VecT_1, class VecT_2, class VecT_3 > void
00531 matrix_look_at(
00532     matrix<E,A,B,L>& m,
00533     const VecT_1& eye,
00534     const VecT_2& target,
00535     const VecT_3& up,
00536     Handedness handedness)
00537 {
00538     typedef matrix<E,A,B,L> matrix_type;
00539     typedef vector< E,fixed<3> > vector_type;
00540     typedef typename matrix_type::value_type value_type;
00541 
00542     /* Checking */
00543     detail::CheckMatAffine3D(m);
00544 
00545     identity_transform(m);
00546 
00547     value_type s = handedness == left_handed ? 1 : -1;
00548     vector_type z = s * normalize(target - eye);
00549     vector_type x = unit_cross(up,z);
00550     vector_type y = cross(z,x);
00551 
00552     matrix_set_transposed_basis_vectors(m,x,y,z);
00553     matrix_set_translation(m,-dot(eye,x),-dot(eye,y),-dot(eye,z));
00554 }
00555 
00557 template < typename E, class A, class B, class L,
00558     class VecT_1, class VecT_2, class VecT_3 > void
00559 matrix_look_at_LH(matrix<E,A,B,L>& m, const VecT_1& eye,
00560     const VecT_2& target, const VecT_3& up)
00561 {
00562     matrix_look_at(m, eye, target, up, left_handed);
00563 }
00564 
00566 template < typename E, class A, class B, class L,
00567     class VecT_1, class VecT_2, class VecT_3 > void
00568 matrix_look_at_RH(matrix<E,A,B,L>& m, const VecT_1& eye,
00569     const VecT_2& target, const VecT_3& up)
00570 {
00571     matrix_look_at(m, eye, target, up, right_handed);
00572 }
00573 
00575 template < typename E, class A, class B, class L > void
00576 matrix_look_at(matrix<E,A,B,L>& m, E eye_x, E eye_y, E eye_z, E target_x,
00577     E target_y, E target_z, E up_x, E up_y, E up_z,
00578     Handedness handedness)
00579 {
00580     typedef vector< E, fixed<3> > vector_type;
00581     
00582     matrix_look_at(m,
00583         vector_type(eye_x,eye_y,eye_z),
00584         vector_type(target_x,target_y,target_z),
00585         vector_type(up_x,up_y,up_z),
00586         handedness
00587     );
00588 }
00589 
00591 template < typename E, class A, class B, class L > void
00592 matrix_look_at_LH(matrix<E,A,B,L>& m, E eye_x, E eye_y, E eye_z,
00593     E target_x, E target_y, E target_z, E up_x, E up_y, E up_z)
00594 {
00595     matrix_look_at(m,eye_x,eye_y,eye_z,target_x,target_y,target_z,up_x,up_y,
00596         up_z,left_handed);
00597 }
00598 
00600 template < typename E, class A, class B, class L > void
00601 matrix_look_at_RH(matrix<E,A,B,L>& m, E eye_x, E eye_y, E eye_z,
00602     E target_x, E target_y, E target_z, E up_x, E up_y, E up_z)
00603 {
00604     matrix_look_at(m,eye_x,eye_y,eye_z,target_x,target_y,target_z,up_x,up_y,
00605         up_z,right_handed);
00606 }
00607 
00609 // 3D linear transform
00611 
00613 template < typename E, class A, class B, class L, class MatT > void
00614 matrix_linear_transform(matrix<E,A,B,L>& m, const MatT& linear)
00615 {
00616     /* Checking */
00617     detail::CheckMatLinear3D(m);
00618     detail::CheckMatLinear3D(linear);
00619     
00620     identity_transform(m);
00621     
00622     for(size_t i = 0; i < 3; ++i) {
00623         for(size_t j = 0; j < 3; ++j) {
00624             m.set_basis_element(i,j,linear.basis_element(i,j));
00625         }
00626     }
00627 }
00628 
00630 // 2D linear transform
00632 
00634 template < typename E, class A, class B, class L, class MatT > void
00635 matrix_linear_transform_2D(matrix<E,A,B,L>& m, const MatT& linear)
00636 {
00637     /* Checking */
00638     detail::CheckMatLinear2D(m);
00639     detail::CheckMatLinear2D(linear);
00640     
00641     identity_transform(m);
00642     
00643     for(size_t i = 0; i < 2; ++i) {
00644         for(size_t j = 0; j < 2; ++j) {
00645             m.set_basis_element(i,j,linear.basis_element(i,j));
00646         }
00647     }
00648 }
00649 
00651 // 3D affine transform
00653 
00655 template <typename E, class A, class B, class L,
00656     class VecT_1, class VecT_2, class VecT_3, class VecT_4 > void
00657 matrix_affine_transform(matrix<E,A,B,L>& m, const VecT_1& x, const VecT_2& y,
00658     const VecT_3& z, const VecT_4& translation)
00659 {
00660     identity_transform(m);
00661     matrix_set_basis_vectors(m,x,y,z);
00662     matrix_set_translation(m,translation);
00663 }
00664 
00666 template <
00667     typename E, class A, class B, class L,
00668     typename QE, class QA, class O, class C, class VecT > void
00669 matrix_affine_transform(
00670     matrix<E,A,B,L>& m, const quaternion<QE,QA,O,C>& q,
00671     const VecT& translation)
00672 {
00673     matrix_rotation_quaternion(m,q);
00674     matrix_set_translation(m,translation);
00675 }
00676 
00678 template < typename E,class A,class B,class L,class XprT,class VecT > void
00679 matrix_affine_transform(
00680     matrix<E,A,B,L>& m, const et::QuaternionXpr<XprT>& q,
00681     const VecT& translation)
00682 {
00683     matrix_rotation_quaternion(m,q);
00684     matrix_set_translation(m,translation);
00685 }
00686 
00688 template <
00689     typename E, class A, class B, class L, class VecT_1, class VecT_2 > void
00690 matrix_affine_transform(
00691     matrix<E,A,B,L>& m,const VecT_1& axis,E angle,const VecT_2& translation)
00692 {
00693     matrix_rotation_axis_angle(m,axis,angle);
00694     matrix_set_translation(m,translation);
00695 }
00696 
00698 template < typename E, class A, class B, class L, class VecT > void
00699 matrix_affine_transform(matrix<E,A,B,L>& m, E angle_0, E angle_1,
00700     E angle_2, EulerOrder order, const VecT& translation)
00701 {
00702     matrix_rotation_euler(m,angle_0,angle_1,angle_2,order);
00703     matrix_set_translation(m,translation);
00704 }
00705 
00707 template <
00708     typename E, class A, class B, class L,
00709     typename ME, class MA, class MB, class ML, class VecT > void
00710 matrix_affine_transform(matrix<E,A,B,L>& m,
00711     const matrix<ME,MA,MB,ML>& linear, const VecT& translation)
00712 {
00713     matrix_linear_transform(m,linear);
00714     matrix_set_translation(m,translation);
00715 }
00716 
00718 template < typename E,class A,class B,class L,class XprT,class VecT > void
00719 matrix_affine_transform(
00720     matrix<E,A,B,L>& m, const et::MatrixXpr<XprT>& linear,
00721     const VecT& translation)
00722 {
00723     matrix_linear_transform(m,linear);
00724     matrix_set_translation(m,translation);
00725 }
00726 
00728 // 2D affine transform
00730 
00732 template <typename E, class A, class B, class L,
00733     class VecT_1, class VecT_2, class VecT_3 > void
00734 matrix_affine_transform_2D(matrix<E,A,B,L>& m, const VecT_1& x,
00735     const VecT_2& y, const VecT_3& translation)
00736 {
00737     identity_transform(m);
00738     matrix_set_basis_vectors_2D(m,x,y);
00739     matrix_set_translation_2D(m,translation);
00740 }
00741 
00743 template <typename E, class A, class B, class L, class VecT >
00744 void matrix_affine_transform_2D(matrix<E,A,B,L>& m, E angle,
00745     const VecT& translation)
00746 {
00747     matrix_rotation_2D(m,angle);
00748     matrix_set_translation_2D(m,translation);
00749 }
00750 
00752 template < typename E,class A,class B,class L,class MatT,class VecT > void
00753 matrix_affine_transform_2D(
00754     matrix<E,A,B,L>& m, const MatT& linear, const VecT& translation)
00755 {
00756     matrix_linear_transform_2D(m, linear);
00757     matrix_set_translation_2D(m,translation);
00758 }
00759 
00761 // 3D affine from 2D affine
00763 
00765 template < typename E, class A, class B, class L, class MatT > void
00766 matrix_3D_affine_from_2D_affine(matrix<E,A,B,L>& m, const MatT& affine_2D)
00767 {
00768     typedef vector< E, fixed<2> > vector_type;
00769 
00770     vector_type x = matrix_get_x_basis_vector_2D(affine_2D);
00771     vector_type y = matrix_get_y_basis_vector_2D(affine_2D);
00772     vector_type p = matrix_get_translation_2D(affine_2D);
00773     
00774     identity_transform(m);
00775     
00776     matrix_set_basis_vectors_2D(m,x,y);
00777     matrix_set_translation(m,p);
00778 }
00779 
00781 // 3D affine from 3D affine
00783 
00785 template < typename E, class A, class B, class L, class MatT > void
00786 matrix_3D_affine_from_3D_affine(matrix<E,A,B,L>& m, const MatT& affine_3D)
00787 {
00788     typedef vector< E, fixed<3> > vector_type;
00789 
00790     vector_type x = matrix_get_x_basis_vector(affine_3D);
00791     vector_type y = matrix_get_y_basis_vector(affine_3D);
00792     vector_type z = matrix_get_z_basis_vector(affine_3D);
00793     vector_type p = matrix_get_translation(affine_3D);
00794     
00795     identity_transform(m);
00796     
00797     matrix_set_basis_vectors(m,x,y,z);
00798     matrix_set_translation(m,p);
00799 }
00800 
00802 // Matrix decomposition (scale->rotate->translate)
00804 
00805 /* 3x3 matrix version */
00806 template <
00807     class MatT,
00808     typename Real,
00809     typename ME,
00810     class MA,
00811     class B,
00812     class L,
00813     typename VE,
00814     class VA
00815 >
00816 void matrix_decompose_SRT(
00817     const MatT& m,
00818     Real& scale_x,
00819     Real& scale_y,
00820     Real& scale_z,
00821     matrix<ME,MA,B,L>& rotation,
00822     vector<VE,VA>& translation)
00823 {
00824     typedef MatT matrix_type;
00825     typedef typename matrix_type::value_type value_type;
00826     typedef vector<value_type, fixed<3> > vector_type;
00827 
00828     /* Checking */
00829     detail::CheckMatAffine3D(m);
00830     detail::CheckMatLinear3D(rotation);
00831     
00832     vector_type x, y, z;
00833     matrix_get_basis_vectors(m, x, y, z);
00834     
00835     scale_x = x.length();
00836     scale_y = y.length();
00837     scale_z = z.length();
00838     
00839     x /= scale_x;
00840     y /= scale_y;
00841     z /= scale_z;
00842     
00843     matrix_set_basis_vectors(rotation, x, y, z);
00844     translation = matrix_get_translation(m);
00845 }
00846 
00847 /* Quaternion version */
00848 template <
00849     class MatT,
00850     typename Real,
00851     typename QE,
00852     class QA,
00853     class O,
00854     class C,
00855     typename VE,
00856     class VA
00857 >
00858 void matrix_decompose_SRT(
00859     const MatT& m,
00860     Real& scale_x,
00861     Real& scale_y,
00862     Real& scale_z,
00863     quaternion<QE,QA,O,C>& rotation,
00864     vector<VE,VA>& translation)
00865 {
00866     typedef MatT matrix_type;
00867     typedef typename matrix_type::value_type value_type;
00868     typedef matrix< value_type, fixed<3,3> > rotation_type;
00869 
00870     rotation_type rotation_matrix;
00871     matrix_decompose_SRT(
00872         m, scale_x, scale_y, scale_z, rotation_matrix, translation);
00873     quaternion_rotation_matrix(rotation, rotation_matrix);
00874 }
00875 
00876 /* Euler angle version */
00877 template < class MatT, typename Real, typename E, class A >
00878 void matrix_decompose_SRT(
00879     const MatT& m,
00880     Real& scale_x,
00881     Real& scale_y,
00882     Real& scale_z,
00883     Real& angle_0,
00884     Real& angle_1,
00885     Real& angle_2,
00886     EulerOrder order,
00887     vector<E,A>& translation,
00888     Real tolerance = epsilon<Real>::placeholder())
00889 {
00890     typedef MatT matrix_type;
00891     typedef typename matrix_type::value_type value_type;
00892     typedef matrix< value_type, fixed<3,3> > rotation_type;
00893 
00894     rotation_type rotation_matrix;
00895     matrix_decompose_SRT(
00896         m, scale_x, scale_y, scale_z, rotation_matrix, translation);
00897     matrix_to_euler(
00898         rotation_matrix, angle_0, angle_1, angle_2, order, tolerance);
00899 }
00900 
00901 /* Axis-angle version */
00902 template < class MatT, typename Real, typename E, class A >
00903 void matrix_decompose_SRT(
00904     const MatT& m,
00905     Real& scale_x,
00906     Real& scale_y,
00907     Real& scale_z,
00908     vector<E,A>& axis,
00909     Real& angle,
00910     vector<E,A>& translation,
00911     Real tolerance = epsilon<Real>::placeholder())
00912 {
00913     typedef MatT matrix_type;
00914     typedef typename matrix_type::value_type value_type;
00915     typedef matrix< value_type, fixed<3,3> > rotation_type;
00916 
00917     rotation_type rotation_matrix;
00918     matrix_decompose_SRT(
00919         m, scale_x, scale_y, scale_z, rotation_matrix, translation);
00920     matrix_to_axis_angle(rotation_matrix, axis, angle, tolerance);
00921 }
00922 
00923 /* 2x2 matrix version, 2-d */
00924 template <
00925     class MatT,
00926     typename Real,
00927     typename ME,
00928     class MA,
00929     class B,
00930     class L,
00931     typename VE,
00932     class VA
00933 >
00934 void matrix_decompose_SRT_2D(
00935     const MatT& m,
00936     Real& scale_x,
00937     Real& scale_y,
00938     matrix<ME,MA,B,L>& rotation,
00939     vector<VE,VA>& translation)
00940 {
00941     typedef MatT matrix_type;
00942     typedef typename matrix_type::value_type value_type;
00943     typedef vector<value_type, fixed<2> > vector_type;
00944 
00945     /* Checking */
00946     detail::CheckMatAffine2D(m);
00947     detail::CheckMatLinear2D(rotation);
00948     
00949     vector_type x, y;
00950     matrix_get_basis_vectors_2D(m, x, y);
00951     
00952     scale_x = x.length();
00953     scale_y = y.length();
00954     
00955     x /= scale_x;
00956     y /= scale_y;
00957     
00958     matrix_set_basis_vectors_2D(rotation, x, y);
00959     translation = matrix_get_translation_2D(m);
00960 }
00961 
00962 /* Angle version, 2-d */
00963 template < class MatT, typename Real, typename E, class A >
00964 void matrix_decompose_SRT_2D(
00965     const MatT& m,
00966     Real& scale_x,
00967     Real& scale_y,
00968     Real& angle,
00969     vector<E,A>& translation)
00970 {
00971     typedef MatT matrix_type;
00972     typedef typename matrix_type::value_type value_type;
00973     typedef matrix< value_type, fixed<2,2> > rotation_type;
00974 
00975     rotation_type rotation_matrix;
00976     matrix_decompose_SRT_2D(
00977         m, scale_x, scale_y, rotation_matrix, translation);
00978     angle = matrix_to_rotation_2D(rotation_matrix);
00979 }
00980 
00981 } // namespace cml
00982 
00983 #endif

Generated on Sat Jul 18 19:35:22 2009 for CML 1.0 by  doxygen 1.5.9