0001 function ba = bodyang(R1,R2,R3)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 tol = 4*eps;
0014 null_value = nan;
0015
0016
0017
0018 if nargin==0, help bodyang, return, end
0019 if nargin==1
0020 sz = size(R1);
0021 if all(sz==[2 2]), R1 = [0 0; R1];
0022 elseif all(sz==[2 3]), R1 = R1'; end
0023 if all(size(R1)==[3 2])
0024 [R1,R2,R3] = sph2cart(R1(:,1)',R1(:,2)',1);
0025 end
0026 if all(sz==[3 3]),
0027 R2=R1(2,:)'; R3=R1(3,:)'; R1=R1(1,:)';
0028 elseif any(sz>3)|any(sz<2)
0029 error(' Input matrix must be 3 by 3 or 3 by 2')
0030 end
0031 end
0032 if nargin==2
0033 error(' Must be 1 or 3 input arguments.')
0034 end
0035 if nargin==3
0036 sz = [size(R1); size(R2); size(R3)];
0037 if any(diff(prod(sz')))
0038 error(' Arguments R1,R2,R3 must have the same size')
0039 end
0040 is3 = all(any(sz'==3));
0041 is2 = all(any(sz'==2));
0042 if is3
0043 nn = find(sz(:,1)==3);
0044 for jj = 1:3
0045 nn = find(sz(jj,:)==3);
0046 if nn(1)>1
0047 eval(['R' num2str(jj) '=R' num2str(jj) ''';']);
0048 end
0049 end
0050 elseif is2
0051 else, error(' Input matrices must be N by 3')
0052 end
0053 end
0054
0055
0056
0057 o3 = ones(3,1);
0058
0059
0060 normal12 = [sqrt(sum(R1.^2)); sqrt(sum(R2.^2)); sqrt(sum(R3.^2))];
0061 numnull = find(~(any(normal12)));
0062 normal12(:,numnull) = ones(3,length(numnull));
0063
0064
0065 a23 = normal12(1,:);
0066 R1 = R1./a23(o3,:);
0067 R2 = R2./normal12(2*o3,:);
0068 R3 = R3./normal12(3*o3,:);
0069
0070
0071 normal12 = cross(R1,R2);
0072 ln12 = sqrt(sum(normal12.^2));
0073 normal12 = normal12./ln12(o3,:);
0074 normal13 = cross(R1,R3);
0075 ln13 = sqrt(sum(normal13.^2));
0076 normal13 = normal13./ln13(o3,:);
0077 normal23 = cross(R2,R3);
0078 ln23 = sqrt(sum(normal23.^2));
0079 normal23 = normal23./ln23(o3,:);
0080
0081
0082
0083 ang1 = acos(abs(sum(normal12.*normal13)));
0084 ang2 = acos(abs(sum(normal12.*normal23)));
0085 numnorm = find(ang1+ang2>=pi-tol);
0086
0087
0088 prjn = sum(R3.*normal12);
0089 R3prj = R3-normal12.*prjn(o3,:);
0090 a12 = sqrt(sum(R3prj.^2));
0091 a12(numnorm) = ones(size(numnorm));
0092 R3prj = R3prj./a12(o3,:);
0093
0094
0095 a12 = acos(sum(R1.*R2));
0096 a13 = acos(sum(R1.*R3prj));
0097 a23 = acos(sum(R2.*R3prj));
0098
0099
0100 ba = a13>pi/2;
0101 ba1 = abs(2*ang1.*ba-asin(sin(ang1).*sin(a13)));
0102 ba = a23>pi/2;
0103 ba2 = abs(2*ang1.*ba-asin(sin(ang2).*sin(a23)));
0104
0105
0106
0107
0108 ln13 = (a12+a13+a23)>=(2*pi-tol);
0109 ln12 = ~ln13&(a13>a12|a23>a12);
0110 ln12 = ln12*2-1;
0111
0112
0113 ba = abs(ba1-ba2.*ln12);
0114 ba(ln13) = 2*pi-ba(ln13);
0115
0116
0117 ba(numnorm) = a12(numnorm);
0118 ba(numnull) = ba(numnull)*null_value;