Go to the documentation of this file.00001 #ifndef OPENTISSUE_KINEMATICS_INVERSE_INVERSE_COMPUTE_JACOBIAN_H
00002 #define OPENTISSUE_KINEMATICS_INVERSE_INVERSE_COMPUTE_JACOBIAN_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <OpenTissue/core/math/big/big_types.h>
00013
00014 #include <vector>
00015
00016 namespace OpenTissue
00017 {
00018 namespace kinematics
00019 {
00020 namespace inverse
00021 {
00022
00041 template < typename chain_iterator, typename bone_iterator, typename matrix_type>
00042 inline void compute_jacobian(
00043 chain_iterator const & chain_begin
00044 , chain_iterator const & chain_end
00045 , bone_iterator const & bone_begin
00046 , bone_iterator const & bone_end
00047 , matrix_type & J
00048 )
00049 {
00050 typedef typename matrix_type::value_type real_type;
00051 typedef typename ublas::vector<real_type> vector_type;
00052 typedef typename ublas::matrix_range< matrix_type > matrix_range;
00053
00054 typedef typename chain_iterator::value_type chain_type;
00055 typedef typename chain_type::bone_traits bone_traits;
00056
00057
00058 size_t max_chains = std::distance( chain_begin, chain_end );
00059 size_t max_bones = std::distance( bone_begin, bone_end );
00060
00061
00062 std::vector<size_t> row_index(max_chains);
00063 std::vector<size_t> column_index(max_bones);
00064
00065 size_t rows = 0;
00066 size_t columns = 0;
00067
00068 std::vector<size_t> dof_array(max_bones);
00069 {
00070 size_t index = 0;
00071 for(chain_iterator chain = chain_begin;chain!=chain_end;++chain)
00072 {
00073 row_index[index++] = rows;
00074 rows += chain->get_goal_dimension();
00075 }
00076
00077 bone_iterator bone = bone_begin;
00078 for(;bone!=bone_end;++bone)
00079 {
00080 dof_array[ bone->get_number()] = bone->active_dofs();
00081 }
00082
00083 for (size_t i=0;i<max_bones;++i)
00084 {
00085 column_index[i] = columns;
00086 columns += dof_array[i];
00087 }
00088 }
00089
00090
00091 if(J.size1() != rows || J.size2() != columns)
00092 {
00093 J.resize( rows, columns, false);
00094 }
00095 J.clear();
00096
00097
00098 size_t chain_index = 0;
00099 for(chain_iterator chain = chain_begin;chain!=chain_end;++chain)
00100 {
00101 typename chain_type::bone_iterator bend = chain->bone_end();
00102 typename chain_type::bone_iterator bone = chain->bone_begin();
00103
00104 for(; bone != bend ; ++bone)
00105 {
00106 size_t bone_index = bone->get_number();
00107
00108 size_t begin_row = row_index[chain_index];
00109 size_t end_row = begin_row + chain->get_goal_dimension();
00110 size_t begin_column = column_index[bone_index];
00111 size_t end_column = begin_column + dof_array[bone_index];
00112
00113 matrix_range J_block = ublas::subrange(
00114 J
00115 , begin_row
00116 , end_row
00117 , begin_column
00118 , end_column
00119 );
00120
00121 bone_traits::compute_jacobian( (*bone) , (*chain), J_block);
00122 }
00123 ++chain_index;
00124 }
00125
00126 }
00127
00128 }
00129 }
00130 }
00131
00132
00133 #endif