【发布时间】:2017-11-28 16:50:59
【问题描述】:
我正在尝试使用this link 中的代码构建 Voronoi 图。但是,我有几点想知道它们属于哪个区域。该代码与 MATLAB 中的原始函数(即voronoin)一样,提供两个输出:[vornb,vorvx],一个用于顶点,另一个用于单元格。所以,我想看看(x, y, z) 点落在 Voronoi 图的哪个区域。
我实际上正在寻找类似this 3D 区域遮罩的东西。
【问题讨论】:
我正在尝试使用this link 中的代码构建 Voronoi 图。但是,我有几点想知道它们属于哪个区域。该代码与 MATLAB 中的原始函数(即voronoin)一样,提供两个输出:[vornb,vorvx],一个用于顶点,另一个用于单元格。所以,我想看看(x, y, z) 点落在 Voronoi 图的哪个区域。
我实际上正在寻找类似this 3D 区域遮罩的东西。
【问题讨论】:
无论您是使用内置的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]);
如果cellIndex 是NaN,则该点不在边界凸包内。否则,它在 Voronoi 单元之一中。要确定哪个,首先考虑Voronoi 单元C{i} 表示比X 中的任何其他点更接近点X(i, :) 的所有点的集合。因此,要找出点[x y z] 落入哪个单元格中,您只需在X 中找到它最接近的点。您可以使用pdist2 和min 来执行此操作,如下所示:
[~, cellIndex] = min(pdist2(X, [x y z]));
如果您无权访问pdist2(位于Statistics Toolbox 中),您可以自己计算距离,如下所示:
[~, cellIndex] = min(sqrt(sum(bsxfun(@minus, X, [x y z]).^2, 2)));
现在,cellIndex 可以用作voronoin 或polybnd_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 将包含边界凸包外的点的索引值。
【讨论】:
voronoin,而不是文件交换提交。您应该编辑问题并更清楚地说明您在做什么,例如您正在运行的特定代码和示例数据。
delaunayTriangulation 作为边界多面体来获得它的凸包(即,只是将点BX 传递给polybnd_voronoi)。接下来的计算是为点集 PXYZ 找到 Voronoi 单元(由 X 定义)的索引。