Path: news.mathworks.com!not-for-mail
From: <HIDDEN>
Newsgroups: comp.soft-sys.matlab
Subject: Re: How can I make these lines shorter?
Date: Thu, 9 Apr 2009 16:13:01 +0000 (UTC)
Organization: The MathWorks, Inc.
Lines: 113
Message-ID: <grl6qd$j3f$1@fred.mathworks.com>
References: <gp295g$dn1$1@fred.mathworks.com> <muyd4cqlk2d.fsf@G99-Boettcher.llan.ll.mit.edu>
Reply-To: <HIDDEN>
NNTP-Posting-Host: webapp-05-blr.mathworks.com
Content-Type: text/plain; charset="ISO-8859-1"
Content-Transfer-Encoding: 8bit
X-Trace: fred.mathworks.com 1239293581 19567 172.30.248.35 (9 Apr 2009 16:13:01 GMT)
X-Complaints-To: news@mathworks.com
NNTP-Posting-Date: Thu, 9 Apr 2009 16:13:01 +0000 (UTC)
X-Newsreader: MATLAB Central Newsreader 1477385
Xref: news.mathworks.com comp.soft-sys.matlab:531715


Peter Boettcher <boettcher@ll.mit.edu> wrote in message <muyd4cqlk2d.fsf@G99-Boettcher.llan.ll.mit.edu>...
> "Husam Aldahiyat" <numandina@gmail.com> writes:
> 
> > "Darren Rowland" <darrenjremovethisrowland@hotmail.com> wrote in message <gp2bq0$500$1@fred.mathworks.com>...
> >> My apologies for multiple posts. I'm getting load errors for every page.
> >> 
> >> Try the following
> >> ~abs(sign(round(diff([con(1),con(3)])))) the same as isequal(con(1),con(3))
> >> and
> >> ~(~(sum(ismember(diff(con),1)))) the same as any(diff(con)==1)
> >> Hth
> >> Darren
> >
> > Thanks! 
> > The first was really a test to see if they were equal but I missed the function isequal. 
> >
> > The second was a test if the diff was 1. Also present in the algorithm
> > is another test if diff was 2 so I'll use any(diff(con)==2).
> >
> > Thanks for the help.
> 
> Other general advice:
> 
> Since these are scalars, == is even better than isequal.  Your first
> expression is simply
> 
> con(1)==con(3)
> 
> And if you need to negate it, use con(1)~=con(3)
> 
> I think you'll find that the ~(~(con(3)-con(2)-2)) expressions are also
> better written using equalities: con(3)~=con(2)+2
> 
> round does nothing when all the inputs are integers.
> 
> After you've gone through and done all these simplifications, post back
> again.  Other stuff might be clearer at that point.
> 
> Depending on what all this means, you might actually think about
> specifying the whole thing as a look-up table.  Right now the code means
> nothing to me, so a look-up table makes just as much sense:
> 
> sign2(1,1,1) = 1;
> sign2(1,1,2) = -1;
> 
> Etc.
> 
> Then just look up your answer with sign2(con(1),con(2),con(3))
> 
> 
> -Peter

I can make it a lookup table (only 12 cases for con), but I want to show-off with a short code :S

Anyway here it is. It takes a rotation matrix R, and an Euler angle convention, then outputs the three angles. It doesn't take care of singularities.

function s=eul(T,str)
% EUL obtain Euler Angles from R Matrix
% 
% Example: 
% >>T = [-0.30619     -0.91856         0.25;
%        0.88388     -0.17678      0.43301;
%       -0.35355      0.35355      0.86603];
% 
% >>s=eul(T,'zyz') 
% s =  
%     g: 0.7854
%     a: 1.0472
%     b: 0.5236
% 
% Example:
% >>a = 0.5;
% >>b = 0.7;
% >>g = pi/3;
%
% >>T = rotx(a)*roty(b)*rotz(g);
%
% >>s=eul(T,'xyz')
% s =  
%     g: 1.0472
%     a: 0.5
%     b: 0.7
% 
% See also TRANS
% 

s=struct;

% convert from xyz to 123
con=double(str)-119;

% get gamma
sign2=round(((con(1)==con(3))*(-2*((~(~(con(3)-con(2)+1)))*...
	(~(~(con(3)-con(2)-2))))+1))+~(con(1)==con(3)));

sign1=round(~(isequal(con(1),con(3)))*-2*(any(diff(con)==1))+1);

s.g=atan2(sign1*T(con(1),con(2)),sign2*T(con(1),6-sum([con(3),con(2)])));

% get alpha
sign2=sign2-(~(con(3)-con(1)))*2*sign2;

s.a=atan2(sign1*T(con(2),con(3)),sign2*T(6-sum([con(1),con(2)]),con(3)));

% get beta
T1=eval(['T/rot',str(3),'(',num2str(s.g),')']);

sign1=~(con(2)-1)*2-1;

s.b=atan2(sign1*T1((~(con(2)-3)-1)*-2+1,1-(~(con(2)-2)-1)),...
	T1((~(con(2)-3)-1)*-2+1,(~(con(2)-3)-1)*-2+1));

end