v_roteucode

PURPOSE ^

V_ROTEUCODE decodes a string specifying a rotation axis sequence

SYNOPSIS ^

function mv=v_roteucode(m)

DESCRIPTION ^

V_ROTEUCODE decodes a string specifying a rotation axis sequence
     M(n)     a string of n characters from the set determining the order of rotation axes
              as listed below. Note that the control characters 'rdoOaA' may occur anywhere in the string:
                'x','y','z'    rotate around the given axis by the corresponding angle
                               given in e()
                '1','2','3'    90 degree rotation around x,y or z axis; doesn't use a value from e()
                '4','5','6'    180 degree rotation around x,y or z axis; doesn't use a value from e()
                '7','8','9'    270 degree rotation around x,y or z axis; doesn't use a value from e()
                'r','d'        all angles are given in radians or degrees  [radians]
             'o','O','a','A'   selects whether to rotate the object or the coordinate axes and
                               whether the rotation axes remain fixed in space for consecutive
                               rotations (extrinsic) or else move with each rotation (intrinsic).
                                  'o' = object-extrinsic [default]
                                  'O' = object-intrinsic
                                  'a' = axes-extrinsic
                                  'A' = axes-intrinsic
 Outputs:

     mv(7,k)    where k-1 is the number of non-control characters in the input string m
                    mv(1,j) = Code for the j'th rotation: 1,2,3 for x,y,z rotation and 4 to 12 for the fixed rotations listed above.
                              All entries are in the range [1,12] except for mv(1,k)=0.
                    mv(2,j) = index into euler angle array for x,y,z rotations. mv(2,k) gives total number of euler angles needed
                    mv(3,j) = rotation class before rotation j. mv(3,k) is the final rotation class and equals 52 for arbitrary rotations.
                    mv(4,j) = index into a vectorized matrix of the entry that becomes non-zero after rotation j
                    mv(5,j) = index into a vectorized matrix of the other changing element in the same column
                    mv(6,j) = +-1 = sign of the sine term affecting entry mv(4,j). For mv(1,j) in [1,3], mv(6,j)=0 if the rotation is unnecessary
                    mv(7,j) = +-1 = sign of entry mv(5,j) before rotation j if known
                Special entries:
                    mv(7,k) = -1 to invert the rotation (i.e. transpose the matrix) or +1 otherwise
                    mv(4,k) = scale factor for euler angles: +-1 or +-pi/180
      

 The string M specifies the seqeunce of axes about which the rotations are performed. There are 12
 possible 3-character sequences that avoid consecutive repetitions. These are 'Euler angles' if
 there is a repeated axis or 'Tait-Bryan angles' if not. Common choices are:
 (1) 'zxz' the most common Euler angle set
 (2) 'xyz' corresponds to 'roll, pitch, yaw' for an aeroplane heading in the x direction with y to
     the right and z down. The intrinsic equivalent is 'Ozyx' corresponding to 'yaw, pitch, roll'.
 (3) 'z1z1z' involves 5 rotations, in which all the non-fixed rotations are around the z axis.

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function mv=v_roteucode(m)
0002 %V_ROTEUCODE decodes a string specifying a rotation axis sequence
0003 %     M(n)     a string of n characters from the set determining the order of rotation axes
0004 %              as listed below. Note that the control characters 'rdoOaA' may occur anywhere in the string:
0005 %                'x','y','z'    rotate around the given axis by the corresponding angle
0006 %                               given in e()
0007 %                '1','2','3'    90 degree rotation around x,y or z axis; doesn't use a value from e()
0008 %                '4','5','6'    180 degree rotation around x,y or z axis; doesn't use a value from e()
0009 %                '7','8','9'    270 degree rotation around x,y or z axis; doesn't use a value from e()
0010 %                'r','d'        all angles are given in radians or degrees  [radians]
0011 %             'o','O','a','A'   selects whether to rotate the object or the coordinate axes and
0012 %                               whether the rotation axes remain fixed in space for consecutive
0013 %                               rotations (extrinsic) or else move with each rotation (intrinsic).
0014 %                                  'o' = object-extrinsic [default]
0015 %                                  'O' = object-intrinsic
0016 %                                  'a' = axes-extrinsic
0017 %                                  'A' = axes-intrinsic
0018 % Outputs:
0019 %
0020 %     mv(7,k)    where k-1 is the number of non-control characters in the input string m
0021 %                    mv(1,j) = Code for the j'th rotation: 1,2,3 for x,y,z rotation and 4 to 12 for the fixed rotations listed above.
0022 %                              All entries are in the range [1,12] except for mv(1,k)=0.
0023 %                    mv(2,j) = index into euler angle array for x,y,z rotations. mv(2,k) gives total number of euler angles needed
0024 %                    mv(3,j) = rotation class before rotation j. mv(3,k) is the final rotation class and equals 52 for arbitrary rotations.
0025 %                    mv(4,j) = index into a vectorized matrix of the entry that becomes non-zero after rotation j
0026 %                    mv(5,j) = index into a vectorized matrix of the other changing element in the same column
0027 %                    mv(6,j) = +-1 = sign of the sine term affecting entry mv(4,j). For mv(1,j) in [1,3], mv(6,j)=0 if the rotation is unnecessary
0028 %                    mv(7,j) = +-1 = sign of entry mv(5,j) before rotation j if known
0029 %                Special entries:
0030 %                    mv(7,k) = -1 to invert the rotation (i.e. transpose the matrix) or +1 otherwise
0031 %                    mv(4,k) = scale factor for euler angles: +-1 or +-pi/180
0032 %
0033 %
0034 % The string M specifies the seqeunce of axes about which the rotations are performed. There are 12
0035 % possible 3-character sequences that avoid consecutive repetitions. These are 'Euler angles' if
0036 % there is a repeated axis or 'Tait-Bryan angles' if not. Common choices are:
0037 % (1) 'zxz' the most common Euler angle set
0038 % (2) 'xyz' corresponds to 'roll, pitch, yaw' for an aeroplane heading in the x direction with y to
0039 %     the right and z down. The intrinsic equivalent is 'Ozyx' corresponding to 'yaw, pitch, roll'.
0040 % (3) 'z1z1z' involves 5 rotations, in which all the non-fixed rotations are around the z axis.
0041 %
0042 
0043 %      Copyright (C) Mike Brookes 2007-2020
0044 %      Version: $Id: v_roteucode.m 11260 2020-07-18 20:07:58Z dmb $
0045 %
0046 %   VOICEBOX is a MATLAB toolbox for speech processing.
0047 %   Home page: http://www.ee.ic.ac.uk/hp/staff/dmb/voicebox/voicebox.html
0048 %
0049 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
0050 %   This program is free software; you can redistribute it and/or modify
0051 %   it under the terms of the GNU General Public License as published by
0052 %   the Free Software Foundation; either version 2 of the License, or
0053 %   (at your option) any later version.
0054 %
0055 %   This program is distributed in the hope that it will be useful,
0056 %   but WITHOUT ANY WARRANTY; without even the implied warranty of
0057 %   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0058 %   GNU General Public License for more details.
0059 %
0060 %   You can obtain a copy of the GNU General Public License from
0061 %   http://www.gnu.org/copyleft/gpl.html or by writing to
0062 %   Free Software Foundation, Inc.,675 Mass Ave, Cambridge, MA 02139, USA.
0063 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
0064 
0065 persistent mes trmap zel mch mvch  jch nch
0066 if isempty(mes)     % setup fixed arrays and initialize cache of mode strings
0067     nch=5;          % size of cache
0068     mch=cell(nch,1); % cache of input character strings
0069     mvch=cell(nch,1);  % cache of output mv codes
0070     flefch=zeros(nch,2);  % cache of output flef codes
0071     jch=(1:nch); % cache usage order jch(1) is the most recent, jch(nch) the oldest
0072     for i=1:nch
0073         mch{i}='';
0074         mvch{i}=[0;0;1;1;0;0;1];
0075     end
0076     mes=[1:3 10:12 7:9 4:6]; % sign reversal look-up table
0077     %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
0078     % The trmap and zel arrays contain information about each of 52 different  %
0079     % patterns of -1,0,+1 that may exist in a rotation matrix as follows:      %
0080     %                                                                          %
0081     %   1-3 : identity matrix rows in order: 123, 231, 312                     %
0082     %   4-6 : negated identity matrix rows in order: 132, 213, 321             %
0083     %   7-12: As 1-6 but with rows 2,3 negated                                 %
0084     %  13-18: As 1-6 but with rows 1,3 negated                                 %
0085     %  19-24: As 1-6 but with rows 1,2 negated                                 %
0086     %  25-33: +1 in position (i-24) and 0's in remainder of this row and col   %
0087     %  34-42: -1 in position (i-24) and 0's in remainder of this row and col   %
0088     %  43-51: 0 in position (i-42)                                             %
0089     %  52: no special symmetry                                                 %
0090     %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
0091     % trmap(i,j) gives the pattern that i is transformed into by rotation j    %
0092     % where j=1:3 corresponds to x,y,z and j=4:12 corresponds to the 9         %
0093     % multiples of 90 degree rotations listed in the main comments.            %
0094     %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
0095     trmap=[ 25 29 33 16 24 11  7 13 19 22 12 17;
0096         28 32 27 17 22 12  8 14 20 23 10 18;
0097         31 26 30 18 23 10  9 15 21 24 11 16;
0098         34 41 39 13 20  9 10 16 22 19  8 15;
0099         37 35 42 14 21  7 11 17 23 20  9 13;
0100         40 38 36 15 19  8 12 18 24 21  7 14;
0101         25 38 42 22  6 23  1 19 13 16 18  5;
0102         28 41 36 23  4 24  2 20 14 17 16  6;
0103         31 35 39 24  5 22  3 21 15 18 17  4;
0104         34 32 30 19  2 21  4 22 16 13 14  3;
0105         37 26 33 20  3 19  5 23 17 14 15  1;
0106         40 29 27 21  1 20  6 24 18 15 13  2;
0107         34 29 42 10 12  5 19  1  7  4 24 23;
0108         37 32 36 11 10  6 20  2  8  5 22 24;
0109         40 26 39 12 11  4 21  3  9  6 23 22;
0110         25 41 30  7  8  3 22  4 10  1 20 21;
0111         28 35 33  8  9  1 23  5 11  2 21 19;
0112         31 38 27  9  7  2 24  6 12  3 19 20;
0113         34 38 33  4 18 17 13  7  1 10  6 11;
0114         37 41 27  5 16 18 14  8  2 11  4 12;
0115         40 35 30  6 17 16 15  9  3 12  5 10;
0116         25 32 39  1 14 15 16 10  4  7  2  9;
0117         28 26 42  2 15 13 17 11  5  8  3  7;
0118         31 29 36  3 13 14 18 12  6  9  1  8;
0119         25 44 45 25 36 26 25 34 34 25 27 35;
0120         43 26 45 27 26 34 35 26 35 36 26 25;
0121         43 44 27 35 25 27 36 36 27 26 34 27;
0122         28 47 48 28 39 29 28 37 37 28 30 38;
0123         46 29 48 30 29 37 38 29 38 39 29 28;
0124         46 47 30 38 28 30 39 39 30 29 37 30;
0125         31 50 51 31 42 32 31 40 40 31 33 41;
0126         49 32 51 33 32 40 41 32 41 42 32 31;
0127         49 50 33 41 31 33 42 42 33 32 40 33;
0128         34 44 45 34 27 35 34 25 25 34 36 26;
0129         43 35 45 36 35 25 26 35 26 27 35 34;
0130         43 44 36 26 34 36 27 27 36 35 25 36;
0131         37 47 48 37 30 38 37 28 28 37 39 29;
0132         46 38 48 39 38 28 29 38 29 30 38 37;
0133         46 47 39 29 37 39 30 30 39 38 28 39;
0134         40 50 51 40 33 41 40 31 31 40 42 32;
0135         49 41 51 42 41 31 32 41 32 33 41 40;
0136         49 50 42 32 40 42 33 33 42 41 31 42;
0137         43 52 52 43 45 44 43 43 43 43 45 44;
0138         52 44 52 45 44 43 44 44 44 45 44 43;
0139         52 52 45 44 43 45 45 45 45 44 43 45;
0140         46 52 52 46 48 47 46 46 46 46 48 47;
0141         52 47 52 48 47 46 47 47 47 48 47 46;
0142         52 52 48 47 46 48 48 48 48 47 46 48;
0143         49 52 52 49 51 50 49 49 49 49 51 50;
0144         52 50 52 51 50 49 50 50 50 51 50 49;
0145         52 52 51 50 49 51 51 51 51 50 49 51;
0146         52 52 52 52 52 52 52 52 52 52 52 52];
0147     %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
0148     % Each Euler angle is chosen so that the inverse rotation forces a specific element  %
0149     % of the rotation matrix to zero. zel(k,j,i) gives information about which element   %
0150     % ceases to be zero when a rotation around axis j is applied to pattern i.           %
0151     %    k=1 gives the index into a vectorized matrix of the entry that becomes non-zero %
0152     %    k=2 gives the index of the other element in the same column that changes        %
0153     %    k=3 gives the sign of the sine term affecting the first of these entries        %
0154     %    k=4 gives the sign of the initial value of the second of these entries if known %
0155     %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
0156     zel=reshape([  6  5  1  1  3  1 -1  1  2  1  1  1;
0157         2  3 -1  1  1  3  1  1  5  4  1  1;
0158         3  2  1  1  4  6  1  1  1  2 -1  1;
0159         5  6 -1 -1  3  1 -1 -1  2  1  1 -1;
0160         3  2  1 -1  6  4 -1 -1  1  2 -1 -1;
0161         2  3 -1 -1  1  3  1 -1  4  5 -1 -1;
0162         6  5  1 -1  3  1 -1  1  2  1  1  1;
0163         2  3 -1 -1  1  3  1 -1  5  4  1  1;
0164         3  2  1 -1  4  6  1 -1  1  2 -1 -1;
0165         5  6 -1  1  3  1 -1 -1  2  1  1 -1;
0166         3  2  1  1  6  4 -1 -1  1  2 -1  1;
0167         2  3 -1  1  1  3  1  1  4  5 -1  1;
0168         6  5  1  1  3  1 -1 -1  2  1  1 -1;
0169         2  3 -1 -1  1  3  1 -1  5  4  1 -1;
0170         3  2  1  1  4  6  1 -1  1  2 -1  1;
0171         5  6 -1  1  3  1 -1  1  2  1  1  1;
0172         3  2  1 -1  6  4 -1  1  1  2 -1 -1;
0173         2  3 -1  1  1  3  1  1  4  5 -1 -1;
0174         6  5  1 -1  3  1 -1 -1  2  1  1 -1;
0175         2  3 -1  1  1  3  1  1  5  4  1 -1;
0176         3  2  1 -1  4  6  1  1  1  2 -1 -1;
0177         5  6 -1 -1  3  1 -1  1  2  1  1  1;
0178         3  2  1  1  6  4 -1  1  1  2 -1  1;
0179         2  3 -1 -1  1  3  1 -1  4  5 -1  1;
0180         0  0  0  0  3  1 -1  1  2  1  1  1;
0181         3  2  1  1  0  0  0  0  1  2 -1  1;
0182         2  3 -1  1  1  3  1  1  0  0  0  0;
0183         0  0  0  0  6  4 -1  1  5  4  1  1;
0184         6  5  1  1  0  0  0  0  4  5 -1  1;
0185         5  6 -1  1  4  6  1  1  0  0  0  0;
0186         0  0  0  0  9  7 -1  1  8  7  1  1;
0187         9  8  1  1  0  0  0  0  7  8 -1  1;
0188         8  9 -1  1  7  9  1  1  0  0  0  0;
0189         0  0  0  0  3  1 -1 -1  2  1  1 -1;
0190         3  2  1 -1  0  0  0  0  1  2 -1 -1;
0191         2  3 -1 -1  1  3  1 -1  0  0  0  0;
0192         0  0  0  0  6  4 -1 -1  5  4  1 -1;
0193         6  5  1 -1  0  0  0  0  4  5 -1 -1;
0194         5  6 -1 -1  4  6  1 -1  0  0  0  0;
0195         0  0  0  0  9  7 -1 -1  8  7  1 -1;
0196         9  8  1 -1  0  0  0  0  7  8 -1 -1;
0197         8  9 -1 -1  7  9  1 -1  0  0  0  0;
0198         0  0  0  0  1  3  1  1  1  2 -1  1;
0199         2  3 -1  1  0  0  0  0  2  1  1  1;
0200         3  2  1  1  3  1 -1  1  0  0  0  0;
0201         0  0  0  0  4  6  1  1  4  5 -1  1;
0202         5  6 -1  1  0  0  0  0  5  4  1  1;
0203         6  5  1  1  6  4 -1  1  0  0  0  0;
0204         0  0  0  0  7  9  1  1  7  8 -1  1;
0205         8  9 -1  1  0  0  0  0  8  7  1  1;
0206         9  8  1  1  9  7 -1  1  0  0  0  0;
0207         0  0  0  0  0  0  0  0  0  0  0  0]',4,3,52);
0208 end
0209 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
0210 % Convert the m string
0211 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
0212 if ~ischar(m) % lecacy call with integer m argument
0213     m=char(m+'w'); % convert to characters
0214 end
0215 ich=find(strcmp(m,mch),1);      % check if already in the cache
0216 if isempty(ich)                 % not yet in the cache
0217     mm=m-'w';                   % convert to integers with x -> 1
0218     mi=mm>=-31 & mm<=-29;       % find characters XYZ
0219     mm(mi)=mm(mi)+32;           % convert XYZ to xyz (for compatibility)
0220     mi=mm>=-70 & mm<=-62;       % find digits 1:9
0221     mm(mi)=mm(mi)+74;           % convert to 4:12
0222     mi=mm<=0;                   % select control characters
0223     mc=mm(mi);                  % controls
0224     mm=mm(~mi);                 % rotations
0225     ef=1;                       % angle scale factor
0226     es=1;                       % angle sign
0227     fl=1;                       % default to no rotation matrix tranposing
0228     for i=1:length(mc)
0229         switch mc(i)
0230             case -5             % 'r' = radians
0231             case -19            % 'd' = degrees
0232                 ef=pi/180;      % scale factor to convert to radians
0233             case -37            % 'R' = negated radians
0234                 ef=-1;
0235             case -51            % 'D' = negated degrees
0236                 ef=-pi/180;      % scale factor to convert to radians
0237             case -8             % 'o' = object-extrinsic
0238             case -40            % 'O' = object-intrinsic
0239                 fl=-1;
0240                 es=-1;
0241             case -22            % 'a' = axes-extrinsic
0242                 fl=-1;
0243             case -54            % 'A' = axes-intrinsic
0244                 es=-1;
0245             otherwise
0246                 error('Invalid character: %s',mc(i)+'w')
0247         end
0248     end
0249     ef=ef*es;               % change sign of scale factor if necessary
0250     if es<0
0251         mm=mes(mm);         % sign-reverse: interchage 4,5,6 with 10,11,12
0252     end
0253     nm=length(mm);
0254     mv=zeros(7,nm+1);
0255     mv(1,:)=[mm 0];
0256     mv(2,:)=cumsum([mm<=3 0]);      % index into euler angle array
0257     mv(3,1)=1; % initial pattern is the identity matrix
0258     for i=1:nm                % loop for each rotation
0259         mmi=mm(i); % rotation code
0260         mv(3,i+1)=trmap(mv(3,i),mmi); % pattern ID after rotation
0261         if mmi<4
0262             mv(4:7,i)=zel(:,mmi,mv(3,i)); % information about which matrix elements change from zero
0263         end
0264     end
0265     mv(end)=fl;
0266     mv(end-3)=ef;
0267     % now save in the cache
0268     ich=jch(nch);       % find oldest cache entry
0269     mch{ich}=m;                 % save input string
0270     mvch{ich}=mv;               % save parameters
0271     jch=[ich jch(1:nch-1)];     % age all the other cache entries
0272 else                            % already in the cache
0273     kch=find(jch==ich,1);       % find existing ich entry
0274     jch(1:kch)=[ich jch(1:kch-1)];
0275     mv=mvch{ich};               % retrieve from cache
0276 end

Generated by m2html © 2003