在问到previous question之后,我想创建一个3d体积,即e f(x,y,z)
,从2D矩阵I(x,y)
开始而不仅仅是曲线。
例如,假设I=peaks(10)
,我如何围绕其中一个轴(比如y轴)旋转它以获得3D矩阵?如果我改为I(r,theta)
,会更容易吗?
我可以在3D中旋转平面,但这不是3D矩阵的一部分,只是新的x,y,z坐标。
答案 0 :(得分:4)
我认为检查预期的3d数组的索引非常简单,几何上找到它们对应的I(x,y)
值(是的,基本上是笛卡尔到圆柱变换),然后根据需要填充每个值。
这是我的意思的最小版本。假设大小为[N,N]
的输入数组对应于x
中的坐标y
,0:N-1
。假设输入数组沿xz
平面定向,并围绕z
轴旋转,以生成输出数组V
。因此,V
的维度对应于-(N-1):N-1
和x
上的y
以及0:N-1
上的z
。因此V
的维度为[2*N-1, 2*N-1, N]
。
演示两种方法(分别使用griddata
和interp2
),完成绘制重现性:
% size of the problem
N = 10;
% input data
I = peaks(N);
% two sets of output V for two methods
V1 = zeros(2*N-1,2*N-1,N);
V2 = zeros(2*N-1,2*N-1,N);
[i1,i2,i3] = ndgrid(1:2*N-1,1:2*N-1,1:N);
% [i1(:), i2(:), i3(:)] are the contiguous indices of V
% z dimension is the same as of I: rotate around z axis
% it will be assumed that input 1:N span elements from 0 to N-1
% output V spans -(N-1):N-1 along x and y
x = i1-N; % -(N-1):N-1
y = i2-N; % -(N-1):N-1
z = i3-1; % 0:N-1
% input array I is in xz plane, rotated along z axis, geometrically speaking
% identify the cylindrical coordinates of each voxel [i1,i2,i3]
[~,r_out,z_out] = cart2pol(x,y,z); % theta is redundant; z_out===z
% identify the coordinates of each input pixel with the above
[j1,j2] = meshgrid(1:N,1:N);
r_in = j1-1; % Cartesian input x <-> cylindrical output r
z_in = j2-1; % Cartesian input y <-> cylindrical output z
% note that j1 and j2 are swapped with respect to x and y
% but this is what interp2 will expect later
% interpolate each voxel based on r and z
method = 'nearest'; %probably the least biased
%method = 'cubic'; %probably the prettiest
V1(:) = griddata(r_in,z_in,I,...
r_out(:),z_out(:),method);
V2(:) = interp2(r_in,z_in,I,...
r_out(:),z_out(:),method,...
0); % extrapolation value, otherwise NaNs appear outside
% plot two slices: xz plane and general rotated one
figure;
% generate rotated versions of the xz plane by rotating with phi around z
for phi=[0, -25, -90]/180*pi
[xp0,zp] = meshgrid(-(N-1):0.1:N-1,0:0.1:N-1);
xp = xp0*cos(phi);
yp = xp0*sin(phi);
subplot(121);
slice(y,x,z,V1,xp,yp,zp);
title('griddata nearest');
shading flat;
axis equal vis3d;
hold on;
subplot(122);
slice(y,x,z,V2,xp,yp,zp);
title('interp2 nearest, extrap 0');
shading flat;
axis equal vis3d;
hold on;
end
如您所见,slice
直接在V
中绘制数据,因此这是生成的3d数组的准确表示。
作为参考,这里是输入I = peaks(10)
的单个样本: