在MATLAB多维数组中旋转元素?

时间:2014-09-28 18:13:14

标签: arrays matlab multidimensional-array 3d rotation

我有一些圆柱形线源,我用它来表示3D内核;我首先通过生成一个简单的二维核心来做到这一点,如下所示:

A = 625;
B =  25;

%2D kernal 
grid2d = zeros(101,101);
c = 51; %centre

for m = 1:101
    for n = 1:101

   r(m,n) = sqrt((m - c).^2 + (n - c).^2); %distance of point on grid to centre

   %Populating the grid as a kernal 

   if r(m,n) <= 5

       grid2d(m,n) = 100;

  elseif r(m,n) >= 25

      grid2d(m,n) = 0;

   else

      grid2d(m,n) = A./r(m,n) - B;

   end
    end
end

这给了我一个2D核心。现在,如果我将3D版本定义为沿更大网格内的z轴长9个元素,我可以通过以下方式创建3D内核;

gz = 147:155; %9 elements in the z axis
H = length(gz);
kernel3D = zeros(301,301,301); %

for n = 1:H

    kernel3D(151-50:1:151+50,151-50:1:151+50,gz(n)) = grid2d;
end

如果我使用垂直线源,这很有效,但我很好奇是否可以在任何所需方向上旋转此数组的元素,因此我可能会为倾斜源生成内核;例如,我想说我想将这个数组相对于XY平面旋转45度,并通过线源中心(151,151,151)旋转60度到XZ平面?

是否有一种优雅的方法可以使用旋转矩阵?

1 个答案:

答案 0 :(得分:0)

我认为我发现了一个有效但不优雅的解决方案 - 在这个版本中,我生成了2D内核,并将其嵌套在3D数组中。然后我使用旋转操作符将位置上的适当值映射到旋转变换。这很难看,但看起来很有效。

  %generate a test 2d kernel as before...  

A = 625; B =  25; c = 51;  cen = 151; grid2d = zeros(101,101); 

for m = 1:101
for n = 1:101


        r(m,n) = sqrt((m - c).^2 + (n - c).^2 ); %distance of point on grid to centre

%Populating the grid as a kernal 

 if r(m,n) <= 5

    grid2d(m,n) = 100;

elseif r(m,n) >= 25

   grid2d(m,n) = 0;

 else

   grid2d(m,n) = A./r(m,n) - B;

  end
   end
  end

%make a bigger array for this to nest in
flat3d = zeros(301,301,301);
range = 101:201; %centre range of new grid

flat3d(range,range,cen) = grid2d;  % inserts grid2d at centre of new flat3d grid!  

%now the incline angles
theta = input('Enter incline in XZ (vertical) plane in degrees : ' );
phi = input('Enter incline in XY (horizontal) plane in degrees : ' );

%Now a loop which inclines each point relative to theta around (x,y,z) = (cen,cen,cen);

g = range(1); 

inc3d = zeros(301,301,301); %new inclined grid initialised 

for m = 1:101
for n = 1:101


   %the g - cen value is added to the index to map arrays sync up correctly and 
   %keep loop reasonable / avoid overlap outside index ! 

  xpart(m,n) = cen + cosd(theta).*(g + m -cen) - sind(theta).*(g + n - cen);  
  xn(m,n) = cen + cosd(phi).*(xpart(m,n) - cen) - sind(phi).*(g + n - cen); %this maps a value of x to new position theta and phi
  yn(m,n) = cen + sind(phi).*(xn(m,n) - cen) + cosd(phi).*(g + n - cen); %maps a value of y to new position relative to phi
  zn(m,n) = cen + sind(theta).*(g + m - cen) + cosd(theta).*(g + n - cen); %maps z to new position relative to theta (doesnt change relative to phi)

    xn = round(xn);
    yn = round(yn);  %round to avoid integer problems with indexing 
    zn = round(zn);


   inc3d(xn(m,n),yn(m,n),zn(m,n)) = flat3d(g + m,g + n,cen);

 end
end

这似乎有效;如果我生成theta = 30和phi = 15的plot3图片,例如,我得到这样的东西;

enter image description here

从这个2D平面图像,用线的等式,我认为可以简单地总结并生成需要任何区域的内核。这很麻烦,但似乎有效。如果有人知道更清洁的方式,请务必添加它:)