我正在尝试创建一个由几何形状组成的原始体积数据的数据集。重点是使用体积射线投射将它们投影为 2D,但首先我想手动创建体积。
几何结构由一个位于体积中间的圆柱体、沿 Z 轴和 2 个围绕第一个圆柱体的较小圆柱体组成,这些圆柱体源自围绕轴的旋转。
到目前为止,这是我的功能:
function cyl= createCylinders(a, b, c, rad1, h1, rad2, h2)
% a : data width
% b : data height
% c : data depth
% rad1: radius of the big center cylinder
% rad2: radius of the smaller cylinders
% h1: height of the big center cylinder
% h2: height of the smaller cylinders
[Y X Z] =meshgrid(1:a,1:b,1:c); %matlab saves in a different order so X must be Y
centerX = a/2;
centerY = b/2;
centerZ = c/2;
theta = 0; %around y
fi = pi/4; %around x
% First cylinder
cyl = zeros(a,b,c);
% create for infinite height
R = sqrt((X-centerX).^2 + (Y-centerY).^2);
startZ = ceil(c/2) - floor(h1/2);
endZ = startZ + h1 - 1;
% then trim it to height = h1
temp = zeros(a,b,h1);
temp( R(:,:,startZ:endZ)<rad1 ) = 255;
cyl(:,:,startZ:endZ) = temp;
% Second cylinder
cyl2 = zeros(a,b,c);
A = (X-centerX)*cos(theta) + (Y-centerY)*sin(theta)*sin(fi) + (Z-centerZ)*cos(fi)*sin(theta);
B = (Y-centerY)*cos(fi) - (Z-centerZ)*sin(fi);
% create again for infinite height
R2 = sqrt(A.^2+B.^2);
cyl2(R2<rad2) = 255;
%then use 2 planes to trim outside of the limits
N = [ cos(fi)*sin(theta) -sin(fi) cos(fi)*cos(theta) ];
P = (rad2).*N + [ centerX centerY centerZ];
T = (X-P(1))*N(1) + (Y-P(2))*N(2) + (Z-P(3))*N(3);
cyl2(T<0) = 0;
P = (rad2+h2).*N + [ centerX centerY centerZ];
T = (X-P(1))*N(1) + (Y-P(2))*N(2) + (Z-P(3))*N(3);
cyl2(T>0) = 0;
% Third cylinder
% ...
cyl = cyl + cyl2;
cyl = uint8(round(cyl));
% ...
其概念是创建第一个圆柱体,然后根据 z 轴值“切割”,以定义其高度。另一个圆柱体是使用关系 A 2 + B 2 = R 2创建的,其中 A 和 B 使用仅围绕 x 和 y 轴的旋转矩阵进行相应旋转,使用 R y (θ)R x (φ),如此处所述。
到目前为止,一切似乎都在工作,因为我已经实现了代码(测试它运行良好)来显示投影,并且当圆柱体没有从无限高度“修剪”时,它们似乎有正确的旋转。
我计算出N
哪个是向量,[0 0 1]
也就是 z 轴,其旋转方式与圆柱体相同。然后我找到两个P
我希望圆柱体边缘具有相同距离的T
点,并根据该点和法向量计算平面方程。最后,我根据该等式进行修剪。或者至少这就是我认为我正在做的事情,因为在修剪后我通常什么也得不到(每个值都是零)。或者,我在试验时能得到的最好的东西是修剪了圆柱体,但是顶部和底部的平面没有很好地定向。
如果我的代码有任何帮助或更正,我将不胜感激,因为我一直在查看几何方程,但找不到错误所在。
编辑:这是我正在尝试创建的对象的快速屏幕截图。请注意,圆柱体在体积数据中是不透明的,所有内部都被视为均质材料。