查询凸包内的人工块体积

时间:2016-09-20 13:53:31

标签: matlab convex-hull

问题:

我有一个三维点云,每个块的质心代表一个块。为简单起见,这个例子只是二维的。 如图所示,我想根据参数包含感兴趣的块。在这种情况下块1,6,5,4。为了进一步处理它们,我需要通过使用alpha形状或凸包来找到它们周围最小的船体。我有每个质心的坐标,我知道块扩展,所以我可以很容易地找到块的边缘点:

    xdimension=5;
ydimension=5;
block1=[5 15 1];
block2=[5 10 0];
block3=[5 5 0];
block4=[10 5 1];
block5=[10 10 1];
block6=[10 15 1];
block7=[15 5 0];
block8=[15 10 0];
block9=[15 15 0];
blocks=[block1;block2;block3;block4;block5;block6;block7;block8;block9]

dimension=[xdimension/2 ydimension/2];
point1=[1 1].*dimension;
point2=[1 -1].*dimension;
point3=[-1 1].*dimension;
point4=[-1 -1].*dimension;
i=size(blocks,1);
point1=repmat(point1,i,1);
point2=repmat(point2,i,1);
point3=repmat(point3,i,1);
point4=repmat(point4,i,1);
edges1=[blocks(:,1:2)+point1, blocks(:,3)] ;
edges2=[blocks(:,1:2)+point2, blocks(:,3)];
edges3=[blocks(:,1:2)+point3, blocks(:,3)];
edges4=[blocks(:,1:2)+point4, blocks(:,3)];
edges=[edges1;edges2;edges3;edges4];
x=edges(edges(:,3)==1,1);
y=edges(edges(:,3)==1,2);
K=convhull(x,y)
scatter(edges(:,1), edges(:,2))
hold on
plot(x(K),y(K),'r-')
hold off

这会生成类似于此处的图片。

问题

如何查询第2和第3块凸包所包含的曲面(或我的实际问题中的体积)?我需要包含每个单个块的确切表面/体积,而不是我指定的块(这里带有二进制指示符)。 请注意,这是一个示例,我正在寻找如何独立于示例的想法。我真的很感激一些帮助,因为我主要陷入困境,我不知道如何解决它。

enter image description here

3 个答案:

答案 0 :(得分:1)

在2D中,我会使用inpolygon函数来测试一个点是否位于凸包和正方形2和3的交叉点内。

对于3D,我没有在MATLAB中找到等价物,但以下matlab exchange file应该是解决方案。

如何使用inhull函数查找内部区域的点的示例:

% Create a 3D cube
cubePoints = randi(5,[500,3]);

% Bounding volume
boundingVolume = zeros(8,3);
boundingVolume(1,:) = [1,3,1];
boundingVolume(2,:) = [1,3,3];
boundingVolume(3,:) = [3,3,1];
boundingVolume(4,:) = [3,3,3];
boundingVolume(5,:) = [3,1,3];
boundingVolume(6,:) = [3,1,1];
boundingVolume(7,:) = [2,1,1];
boundingVolume(8,:) = [2,1,3];

% Find points inside area
inVol = inhull(cubePoints,boundingVolume);

% Plot the point in the bounding volume in blue and the points outsode the
% bounding volume in red
scatter3(cubePoints(:,1).*inVol,cubePoints(:,2).*inVol,cubePoints(:,3).*inVol,36,'blue');
hold on
scatter3(cubePoints(:,1).*~inVol,cubePoints(:,2).*~inVol,cubePoints(:,3).*~inVol,36,'red');

答案 1 :(得分:0)

如果你成功找到了你的covex船体(使用convhull功能),它的第二个输出变量将为你提供所需的东西(?)。

[IDs,V] = convhull(X,Y,Z)

此处V是包含在点(X,Y,Z)的凸包中的体积。保佑Matlab!

答案 2 :(得分:0)

我相信这种方法有效,但如果系统很大,就内存消耗而言,它没有什么可以炫耀的:

首先以3d二进制数组的形式构造总凸包。此外,每个块应在整个空间上形成一个3d二进制数组,在块的扩展上有true个元素,在其他地方有false个元素。 (要完成此操作,请查看link中的Amitay's answer。)

现在您可以从中计算每个块的份额。如果您按照说明形成了所有内容,则其余内容很简单:您可以直接计算conv与每个block的重叠,如下所示:

num = numel(block);
shareofblock = zeros(num, 1);
for jj = 1:num
    overlap = block(jj) & conv;
    shareofblock(jj) = sum(overlap(:));
end