如何找到“内部边界”/“内部凸包”的3D点列表?

时间:2018-02-07 21:50:44

标签: algorithm matlab mathematical-optimization computational-geometry

我需要一些帮助来撰写algorithm

给定一组行在空间中,并且我试图在原点(参考点)为0.5,0.5,0.5时找到可访问的卷,并且我执行以下操作:

对于每一行,计算最接近原点的线上的距离和点(0.5,0.5,0.5),然后收集所有这些点。

之后我想计算内部(boundaryconvhull),因为我想在(0.5,0.5,0.5)评估球的可访问量。它不是凸包或边界多边形。

例如,我想在这个简单的例子中得到绿色(内部线): enter image description here

配置:

enter image description here

从原点(0.5,0.5,0.5)到线条的最近点 enter image description here

只有我想要“内部边界”的点,这意味着在内部或边界之外界定所有点的形状。

enter image description here

以下是我想要的其他代码,而不是convhull

close all
N=30;

S1 = cell(1, N);
for k = 1:N, S1{k} = rand(1, 3); end
S2 = cell(1, N);
for k = 1:N, S2{k} = rand(1, 3); end

M1 = cat(3, S1{:});
M2 = cat(3, S2{:});
M  = permute(cat(1, M1, M2), [1, 3, 2]);
figure
plot3(M(:, :, 1), M(:, :, 2), M(:, :, 3))
hold on
[x,y,z] = sphere;
x=x/100;y=y/100;z=z/100;
plot3(x+0.5,y+0.5,z+0.5)


figure 
hold on

NearestIntersectionPoints = cell(1,N); 
for k = 1:N 
    tmp1 = M(1,k,:); tmp2 = M(2,k,:);
    v1=tmp1(1,:); v2=tmp2(1,:);
    [d, intersection] = point_to_line([0.5,0.5,0.5], v1, v2);

    [x,y,z] = sphere;
    x=x/500;y=y/500;z=z/500;
    plot3(x+intersection(1),y+intersection(2),z+intersection(3))
    NearestIntersectionPoints{k} = intersection;

end


MHull = cat(3,NearestIntersectionPoints{:});
X=MHull(:,1,:); Y=MHull(:,2,:); Z=MHull(:,3,:);
X=X(:); Y=Y(:); Z=Z(:);
k = boundary(X,Y,Z);
hold on

plot3(X(k),Y(k),Z(k), 'r-*')


function [d,intersection] = point_to_line(pt, v1, v2)
      a = v1 - v2;
      b = pt - v2;
      d = norm(cross(a,b)) / norm(a);
      theta = asin(norm(cross(a,b))/(norm(a)*norm(b)));
      intersection = v2 + a * cos(theta);

end

2 个答案:

答案 0 :(得分:2)

我会这样做:

  1. 将您的pointcloud四面化

    所以创建一个由四面体组成的网格,其中没有四面体与任何其他四面体相交或包含任何点。我是这样做的:

    1. 结构
    2. 你需要点,三角形和四面体的列表。每个三角形都需要一个计数器,它会告诉你它是使用过一次还是两次。

      1. 创建第一个四面体
      2. 通过所有点的4个嵌套循环,检查形成的四面体是否包含任何内部点。如果没有停止,因为你发现了你的第一个四面体。这是O(n^5),但由于有很多有效的四面体,它永远不会达到如此高的运行时间......现在只需将这个四面体添加到三角形和四面体列表中。

        1. 找到下一个四面体
        2. 现在遍历已使用过的所有三角形。对于每种形式的四面体,使用它所使用的3个点,并以与#2 相同的方式找到第4个点。有效四面体不得包含任何点,也不得与列表中任何现有的四面体相交。

          为了确保在没有孔的情况下填充整个体积,您需要优先选择具有更多三角形的四面体列表中的优先顺序。所以首先搜索4个三角形,如果没有找到3个等等...

          对于每个找到的有效四面体,将其添加到列表中并再次查看,直到无法形成有效的四面体...整个过程大约为O(n^2),因此请注意pointcloud中的点太多。同时存储三角形的法线可以加快测试速度......

        3. 外部边界

          外边界由列表中的三角形组成,仅使用一次

        4. 内部边界

          内部间隙四面体应大于其他所有四面体。因此,检查它们的大小与平均大小,如果更大,它们很可能是一个差距。所以将它们组合在一起列表。每个间隙只有大的四面体,并且它们都必须共用至少一个面(三角形)。现在只计算每个组的三角形用法,只使用一次的所有三角形将形成间隙/孔/内部边界/网格。

        5. 如果你的点密度是均匀的,你可以调整它:

          创建点密度的体素图...没有密度的体素是间隙或外层空间。这可以用于更快和更好地选择内部四面体。

答案 1 :(得分:0)

如果我理解你的问题,你想要另一卷中的最大音量,两卷之间没有共同点。

外部卷是从一组点的子集构建的。显而易见的解决方案是用剩余的点构建内部卷。

可以通过多种方式制作一组点中的音量。如果体积不是凸的,那么你需要一些更多的信息(例如,面之间的最小角度),因为你得到加星标的多面体或者是凸面的,或者其他形状。

对于凸体积,我推荐使用四面体的3D Delaunay结构。边界由“tets”的面定义,这些面不与其他“tets”共享。

从属于边界的那些点中移除:边界中的每个tet都有第四个不在边界上的点。

内部卷是另一个Delaunay结构。也许你只需要前面边界的第四点。