在3D体数据中创建圆柱。

3

我正在尝试创建一个由几何形状组成的原始体积数据集。目标是使用体积光线投影将它们投影到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轴的值“切割”它以定义其高度。另一个圆柱是使用关系A2 + B 2 = R2创建的,其中A和B分别使用旋转矩阵仅绕x和y轴旋转,并使用Ry(θ)Rx(φ)进行旋转,如此处所述。
到目前为止,一切似乎都正常,因为我已经实现了代码(测试了它的良好运行),以显示投影,当它们没有被从无限高度“修剪”时,圆柱的旋转似乎是正确的。
我计算向量N,即以与圆柱相同的方式旋转的向量[0 0 1],即z轴。然后我找到两个距离相同的点P,这些点是我想要圆柱边缘的距离,并根据那些点和法向量计算平面方程T。最后,我根据该等式进行修剪。或者至少我认为我是这样做的,因为在修剪之后,我通常什么也得不到(每个值都是零)。或者,在我进行实验时,最好的结果是修剪过的圆柱,但是顶部和底部的平面没有正确定位。
我会感激任何帮助或更正我的代码,因为我一直在查看几何方程式,但找不到错误所在。
编辑: 这是我试图创建的对象的快速截图。请注意,圆柱在体积数据中是不透明的,所有内部都被视为均匀材料。 set of cylinders

也许画个草图会有帮助。 - John Alexiou
我添加了一个屏幕截图,展示我正在尝试创建的内容。 - George Aprilis
气缸是否合并,还是它们之间有间隙。 - John Alexiou
一开始我创建了无限长的圆柱体,然后我想用起始点 P 来修剪它们,其中 P = rad2*N + [ centerX centerY centerZ];。因此,当小圆柱的轴是水平的时候,实际上是圆柱底部的平面与第一个圆柱相切。 - George Aprilis
1个回答

1

我认为应该使用:

T = (X-P(1))*N(1) + (Y-P(2))*N(2) + (Z-P(3))*N(3);

你应该在两个地方都尝试以下操作:
T = (X-P(1)) + (Y-P(2)) + (Z-P(3));

乘以N是为了考虑第二个圆柱的轴向,你已经在上一步中完成了这一步骤。

我尝试了你的建议,但似乎不起作用。它产生了难以理解的结果。我也不确定像 cyl2(T<0) = 0; 这样的语句是否正确。也许方程是正确的,但修剪可能有误?无论如何,感谢您的帮助。 - George Aprilis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接