我正在尝试使用此链接中的代码构建Voronoi图。但是,我有几点,想知道它们属于哪个地区。这段代码,就像 MATLAB 中的原始函数一样(即voronoin
)给出了两个输出:[vornb,vorvx]
,一个用于顶点,另一个用于单元格。所以,我想看看(x, y, z)
落在沃罗诺伊图的哪个区域。
我实际上正在寻找类似 3D 区域遮罩的东西。
无论您是使用内置voronoin
(将X
点的 N×D 矩阵作为输入)还是polybnd_voronoi
(有界 Voronoi 单元的链接文件交换提交,在定义边界凸多面体BX
采用额外的 M-by-D 点矩阵)生成 Voronoi 单元格,您都可以仅使用这些相同的输入参数来计算哪个单元格包含给定的点[x y z]
。
对于有界 Voronoi 像元情况,首先需要确定点是否在有界凸包内。一种方法是创建边界点的 Delaunay 三角测量,并使用pointLocation
方法确定该点是否在凸包内:
DT = delaunayTriangulation(BX);
cellIndex = pointLocation(DT, [x y z]);
如果cellIndex
NaN
,则点不在边界凸包内。否则,它位于沃罗诺伊牢房之一中。要确定哪个,首先考虑 Voronoi 像元C{i}
表示比X
中任何其他点更接近点X(i, :)
的所有点的集合。因此,要找出[x y z]
点落入哪个单元格,您只需找到X
中最接近的点。您可以使用pdist2
和min
来执行此操作,如下所示:
[~, cellIndex] = min(pdist2(X, [x y z]));
如果您无权访问pdist2
(位于统计工具箱中),则可以像这样自行计算距离:
[~, 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
。