【问题标题】:Finding the region in a Voronoi diagram that contains a point在包含点的 Voronoi 图中查找区域
【发布时间】:2017-11-28 16:50:59
【问题描述】:

我正在尝试使用this link 中的代码构建 Voronoi 图。但是,我有几点想知道它们属于哪个区域。该代码与 MATLAB 中的原始函数(即voronoin)一样,提供两个输出:[vornb,vorvx],一个用于顶点,另一个用于单元格。所以,我想看看(x, y, z) 点落在 Voronoi 图的哪个区域。

我实际上正在寻找类似this 3D 区域遮罩的东西。

【问题讨论】:

    标签: matlab voronoi


    【解决方案1】:

    无论您是使用内置的voronoin(将点X 的N-by-D 矩阵作为输入)还是polybnd_voronoi(链接的File Exchange submission for bounded Voronoi cells,它采用一个额外的 M-by-D 点矩阵 BX 定义一个边界凸多面体),您可以仅使用相同的输入参数来计算哪个单元格包含给定点 [x y z]

    对于有界 Voronoi 单元的情况,您首先需要确定您的点是否在有界凸包内。一种方法是创建边界点的Delaunay triangulation 并使用pointLocation 方法确定该点是否在凸包内:

    DT = delaunayTriangulation(BX);
    cellIndex = pointLocation(DT, [x y z]);
    

    如果cellIndexNaN,则该点不在边界凸包内。否则,它在 Voronoi 单元之一中。要确定哪个,首先考虑Voronoi 单元C{i} 表示比X 中的任何其他点更接近点X(i, :) 的所有点的集合。因此,要找出点[x y z] 落入哪个单元格中,您只需在X 中找到它最接近的点。您可以使用pdist2min 来执行此操作,如下所示:

    [~, cellIndex] = min(pdist2(X, [x y z]));
    

    如果您无权访问pdist2(位于Statistics Toolbox 中),您可以自己计算距离,如下所示:

    [~, cellIndex] = min(sqrt(sum(bsxfun(@minus, X, [x y z]).^2, 2)));
    

    现在,cellIndex 可以用作voronoinpolybnd_voronoi 的输出参数的索引,以获取边界 Voronoi 单元格。

    泛化到多个点:

    您可以将以上内容概括为不止一个点[x y z],这将允许您创建一个 3D 区域蒙版:

    [PX, PY, PZ] = meshgrid(...);  % Generate regular points in a 3D volume
    PXYZ = [PX(:) PY(:) PZ(:)];    % Combine them into one matrix
    
    DT = delaunayTriangulation(BX);      % Create triangulation for boundary
    cellMask = pointLocation(DT, PXYZ);  % Find points in boundary
    
    index = ~isnan(cellMask);  % Index of points in boundary
    [~, cellMask(index)] = min(pdist2(X, PXYZ(index, :)), [], 1);  % Find cell index
    cellMask = reshape(cellMask, size(PX));  % Reshape mask to 3D
    

    3D 蒙版cellMask 将包含 Voronoi 单元内的点的索引值,NaN 将包含边界凸包外的点的索引值。

    【讨论】:

    • 我在这个 [mathworks.com/matlabcentral/fileexchange/… 链接上使用代码,我不确定上面的代码是否有效,因为我收到一个错误,指出索引超出矩阵维度。
    • 我将 d = 3 用于 3D 图和 [x, y, z] = [0.5 0.5 0.5]
    • @Sam:我不明白。您在问题中说您使用的是voronoin,而不是文件交换提交。您应该编辑问题并更清楚地说明您在做什么,例如您正在运行的特定代码和示例数据。
    • 我花了几个小时才得到一个有意义的结果。我认为问题在于您使用的是 DT 而不是 Voronoi,因为 DT 连接点,而 Voronoi 没有,而是将点放在顶点的中间。如果我错了,请纠正我
    • @Sam:我只使用delaunayTriangulation 作为边界多面体来获得它的凸包(即,只是将点BX 传递给polybnd_voronoi)。接下来的计算是为点集 PXYZ 找到 Voronoi 单元(由 X 定义)的索引。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-09
    • 2021-06-25
    • 1970-01-01
    • 1970-01-01
    • 2014-01-14
    • 2014-01-22
    • 2016-09-11
    相关资源
    最近更新 更多