Algorithm 如何找到;“内部边界”&引用;“内部凸包”;查看三维点列表?

Algorithm 如何找到;“内部边界”&引用;“内部凸包”;查看三维点列表?,algorithm,matlab,mathematical-optimization,computational-geometry,Algorithm,Matlab,Mathematical Optimization,Computational Geometry,我需要一些人帮我写这封信 给定一组线在空间中,当原点(参考点)为0.5,0.5,0.5时,我尝试查找可访问的体积,我执行以下操作: 对于每条直线,计算距离和直线上距离原点最近的点(0.5,0.5,0.5),然后收集所有这些点 之后,我想计算内部(既不是边界也不是convhull),因为我想计算(0.5,0.5,0.5)处球的可接近体积。它不完全是凸包或边界多边形 例如,我想在这个简单的例子中得到绿色(内线): 配置: 从原点(0.5,0.5,0.5)到直线的最近点 只有我想要“内部边界

我需要一些人帮我写这封信

给定一组线在空间中,当原点(参考点)为
0.5,0.5,0.5
时,我尝试查找可访问的体积,我执行以下操作:

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

之后,我想计算内部(既不是
边界
也不是
convhull
),因为我想计算(
0.5,0.5,0.5
)处球的可接近体积。它不完全是凸包或边界多边形


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


配置:

从原点(
0.5,0.5,0.5
)到直线的最近点

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

这是我想要的代码,而不是
convhull

我会这样做:

  • 四面体化你的点云

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

  • 结构
  • 您需要点、三角形和四面体的列表。每个三角形都需要一个计数器,它会告诉你是否使用过一次或两次

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

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

    为了确保整个体积不会出现孔洞,您需要优先选择列表中已经有更多三角形的四面体,从而确定填充过程的优先级。所以首先搜索4个三角形,如果没有找到3个,等等

    对于每个找到的有效四面体,将其添加到列表中,并再次查看,直到无法形成有效四面体。。。整个过程都是围绕着O(n^2)进行的,所以要小心点云中的点太多。同时,存储三角形的法线可以大大加快测试速度

  • 外部边界

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

  • 内部边界

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

  • 如果点密度均匀,则可以调整:


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

    如果我很理解你的问题,你希望另一卷中的最大卷,两卷之间没有共同点

    外部体积是从点集的子集构建的。显而易见的解决方案是用其余的点构建内部体积

    一组点的体积可以通过几种方式制作。如果体积不是凸面,则您需要更多信息(例如面之间的最小角度),因为您将获得星形多边形、cuasi凸面或其他形状

    对于凸面体积,我建议使用四面体进行3D Delaunay构造。边界由不与其他“TET”共享的“TET”面定义

    从全套点中删除属于边界的点:每个tet in边界有一个不位于边界上的第四点


    内部体积是另一个Delaunay构造。也许您只需要前面边界TET中的第四个点。

    如何定义内部空间?作为一个球?作为最大的凸形,适合内部的点?还有别的吗?提示——以原点为中心的最大的球很小,另一个球很复杂,我相信这是一个O(N^7)问题。@CrisLuengo,我想要凸面形状。我猜这个球基本上就是用到所有线的最小距离来画一个球。为了找到内部凸包,我可以对数据进行一些移动或任何转换吗?这是一个类似于凸壳的问题,只是从内部。问题是,即使是最简单的算法,我也搞不懂。寻找“凸面头骨”。power-7的顺序是2D,不确定是否有3D变体。@CrisLuengo我想你的意思是“凸面外壳”。@AlexisOlson否凸面外壳给出了外部边界。我不想要,我想要边界内部的凸包。他是对的。如果我用实际的线而不是找到最近的点会更好吗?@0x90我不这么认为,因为在你的图中,线太大了,所以你可能会得到非四面体区域。我有点迷路了,我试着实现你的算法,但是我不知道如何编写点云四面体化的第一部分,因为我没有在Matlab中编写代码,所以不能
    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