function out = Rot3d(in,n,dim) % out = Rot3d(in,n,dim) % rotates input matrix around x-, y- of z-axis % IN is a vector, a 2D or a 3D matrix (all three can be rotated three % dimensionally) % % rotation can only be performed by multiples of 90 degrees, N is the % number of 90 degree steps by which the matrix will be rotated (clockwise, % same as rot90()) % DIM indicates the axis to rotate about: % 1=y; 2=x; 3=z % % Rot3d([1 2 3 4; 3 5 6 7],1,1) % ans(:,:,1) = % 4 % 7 % ans(:,:,2) = % 3 % 6 % ans(:,:,3) = % 2 % 5 % ans(:,:,4) = % 1 % 3 % DN 2008 psychassert(nargin==3,'function requires three inputs'); psychassert(ndims(in)<=3,'input cannot have more than three dimensions'); psychassert(dim>0 && dim<=3,'invalid rotation axis specified (%d)\nuse 1=y; 2=x; 3=z',dim); ss = AltSize(in,[1 2 3]); [y,x,z] = meshgrid(1:ss(1),1:ss(2),1:ss(3)); yi = y(:); xi = x(:); zi = z(:); incoords = [xi.'; yi.'; zi.']; % change to a 3xN matrix with [x; y; z] rot = n*90; switch dim case 1 oc = Roty(incoords,rot); case 2 oc = Rotx(incoords,rot); case 3 oc = Rotz(incoords,rot); end % make all coordinates positive rijplus = (max(abs(oc),[],2)+1) .* max(oc<=0,[],2); yo = oc(2,:)+rijplus(2); xo = oc(1,:)+rijplus(1); zo = oc(3,:)+rijplus(3); % use original and rotated indices to create output out = zeros(max(yo),max(xo),max(zo)); ii = sub2ind(ss,yi,xi,zi); oi = sub2ind(size(out),yo,xo,zo); out(oi) = in(ii); % subfunctions (multiplication with rotation matrices) function [XYZ] = Rotx(XYZ,a) Rx = [1 0 0; 0 cosd(a) -sind(a); 0 sind(a) cosd(a)]; XYZ = Rx * XYZ; function [XYZ] = Roty(XYZ,b) Ry = [cosd(b) 0 sind(b); 0 1 0; -sind(b) 0 cosd(b)]; XYZ = Ry * XYZ; function [XYZ] = Rotz(XYZ,g) Rz = [cosd(g) -sind(g) 0; sind(g) cosd(g) 0; 0 0 1]; XYZ = Rz * XYZ;