本文介绍了在MATLAB中为voronoi图的无界单元格上色的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两组点,plot分别是蓝色的星星和红色的点.然后我用voronoi(X,Y)函数的两个集合的plot Voronoi图.我想指定每个单元格的颜色取决于它的站点属于哪个集合.通过使用patch函数,我几乎可以做到这一点:

I have two sets of points and plot them in blue stars and red dots. Then I plot Voronoi diagram of both sets with voronoi(X,Y) function. I want to specify color of each cell depends on which set it's site is belong. I've almost done this one by the use of patch function this way:

     [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

其中D是集合点的坐标,TheNumberOfSets显示我们有多少个集合(在此特定部分,我们只有2个集合),col指定随机的灰色,PointsInSet指定每个集合中有多少个点,并使用l枚举Voronoi图的单元格.

WhereD is the coordinates of the points of sets, TheNumberOfSets show how many sets do we have (in this particular part we have just 2 sets), col specify a random gray color, PointsInSet specify how many points do we have in each set and l is used to enumerate cells of Voronoi diagram.

,这是结果:

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

now my problem (as you can see!) is about unbounded cells. This code just change the color of the bounded cells and I want to color unbounded cells with their specified set's color in the range of axis box (i.e. the box that you can see in the image).

有什么建议吗?

推荐答案

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

Your example does in fact create patch objects for the unbounded cells, but because they contain vertices that have Inf values representing the unbounded edges, they aren't displayed. You need to replace these vertices with finite ones to complete the patches.

voronoi生成的绘制无界单元格边缘的顶点可用于此目的.您可以在绘制voronoi图时获得这些信息:

The vertices generated by voronoi to draw the unbounded cell edges are useful for this purpose. You can obtain these when drawing the voronoi diagram:

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

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

The unbounded edges are plotted last, so you can isolate these by counting unbounded cells in c:

nUnbounded = sum(cellfun(@(ic)ismember(1,ic),c));
v1Unbounded = v1(end-(nUnbounded-1):end,:,:);

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

The first listed vertex of these edges is the finite vertex of the cell. These don't always exactly match the coordinates returned by voronoin due to floating-point error, so identify which numbered vertices these correspond to by finding the minimum pairwise distance from 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

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

To substitute in these coordinates you can then replace patch(v(c{l},1),v(c{l},2),col); with the following:

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);

这篇关于在MATLAB中为voronoi图的无界单元格上色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 00:22