MATLAB中voronoi图的彩色无界单元格

poo*_*dad 5 matlab plot voronoi

我有两组点,plot它们分别是蓝星和红点。然后我plotvoronoi(X,Y)函数的两个集合的 Voronoi 图。我想指定每个单元格的颜色取决于它的站点属于哪个集合。我几乎通过patch这种方式使用函数来完成这个:

     [v,c]=voronoin(D);
     for p=1:TheNumberOfSets
       r=rand()/2+0.5;    % random gray color
       col=[r r r];
       for s=1:PointsInSet(p)
           l=l+1;
           patch(v(c{l},1),v(c{l},2),col);  % color
           axis([0 10 0 10]);
       end
     end
Run Code Online (Sandbox Code Playgroud)

D集合点的坐标在哪里,TheNumberOfSets显示我们有多少个集合(在这个特定的部分我们只有 2 个集合),col指定一个随机的灰色,PointsInSet指定我们在每个集合中有多少个点,l用于枚举Voronoi 图的单元格。

这是结果: 在此处输入图片说明

现在我的问题(如你所见!)是关于无界细胞。此代码只是更改有界单元格的颜色,我想在轴框范围内(即您可以在图像中看到的框)使用其指定集的颜色为无界单元格着色。

有什么建议吗?

Wil*_*ill 1

您的示例实际上确实patch为无界单元创建了对象,但由于它们包含具有Inf表示无界边的值的顶点,因此它们不会显示。您需要用有限顶点替换这些顶点才能完成补丁。

voronoi绘制无界单元边缘生成的顶点对于此目的很有用。您可以在绘制 voronoi 图时获得这些:

h = voronoi(D);
v1 = shiftdim(reshape([h(2).XData;h(2).YData],2,3,[]),2); % Arranged one edge per row, one vertex per slice in the third dimension
Run Code Online (Sandbox Code Playgroud)

最后绘制无界边,因此您可以通过计算 中的无界单元格来隔离这些边c

nUnbounded = sum(cellfun(@(ic)ismember(1,ic),c));
v1Unbounded = v1(end-(nUnbounded-1):end,:,:);
Run Code Online (Sandbox Code Playgroud)

这些边的第一个列出的顶点是单元的有限顶点。voronoin由于浮点误差,这些并不总是与返回的坐标完全匹配,因此通过查找 的最小成对距离来确定这些顶点对应的编号顶点pdist2

[~,iBounded] = min(pdist2(v,v1Unbounded(:,:,1))); % Index of the bounded vertex
vUnbounded = v1Unbounded(:,:,2); % Displayed coordinate of the unbounded end of the cell edge
Run Code Online (Sandbox Code Playgroud)

要替换这些坐标,您可以替换patch(v(c{l},1),v(c{l},2),col);为以下内容:

cPatch = c{l}; % List of vertex indices
vPatch = v(cPatch,:); % Vertex coordinates which may contain Inf
idx = find(cPatch==1); % Check if cell has unbounded edges
if idx
    cPatch = circshift(cPatch,-idx); % Move the 1 to the end of the list of vertex indices
    vPatch = [vPatch(1:idx-1,:)
              vUnbounded(iBounded == cPatch(end-1),:)
              vUnbounded(iBounded == cPatch(1),:)
              vPatch(idx+1:end,:)]; % Replace Inf values at idx with coordinates from the unbounded edges that meet the two adjacent finite vertices
end
patch(vPatch(:,1),vPatch(:,2),col);
Run Code Online (Sandbox Code Playgroud)