2016-12-02 64 views
4

我有两组点和plot他们在蓝色的星星和红点。然后我plot沃罗诺伊图与voronoi(X,Y)功能。我想指定每个单元格的颜色取决于它的网站所属的集合。我几乎被使用patch函数来完成这一个是这样的:在MATLAB中voronoi图的颜色无限细胞

 [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图的单元。

,这是结果: enter image description here

现在我的问题(你可以看到!)大约是无限的细胞。这段代码只是改变了有界单元格的颜色,我想用它们在axis box范围内的指定集合的​​颜色(即可以在图像中看到的框)对无界单元格着色。

有什么建议吗?

+1

能否请您添加TheNumberOfSets','PointsInSet','l','v','C','col'的'样本信息,以及任何我可能已经错过了?请参阅[mcve]上的帮助文件(http://stackoverflow.com/help/mcve)以获取有关如何针对问题制作正确示例的更多信息。 –

+0

我已经添加了更多信息。 @FranzHahn –

+0

'l'呢? –

回答

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 

的无界边缘最后绘制,因此您可以通过在c计数无限细胞中分离出这些:

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

这些边缘的第一家上市的顶点是细胞的有限顶点。这些并不总是完全匹配由于浮点错误由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 

要替换这些坐标,你可以然后更换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); 
+0

非常感谢你这个伟大的答案(一个月后,你是第一个)。我只有一个问题来运行你的代码。在'h = voronoi(D);'后,''h只有一列而不是两个图表行,所以我收到错误:**对于h(2).XData',索引矩阵引用**不正确。当然我使用MATLAB R2014a并且看到了**注意:h = voronoi(..)的行为已经改变。新行为返回两个图表线条手柄的向量;一个表示点,另一个表示[mathworks](https://www.mathworks.com/help/matlab/ref/voronoi.html)中的Voronoi边**。你有什么想法吗?再次感谢 –

+0

哦,亲爱的!它看起来像在R2014a中,行坐标仍然可以通过仍然以'h'返回的句柄访问,但句柄的顺序和行数据的结构可能不像上面描述的那样,并且不能像' .XData'来访问它。它没有明确记录,所以需要一点探索,以确定在哪里找到正确的值,以替代上面的'patch'输入。如果我记得正确的话,你应该可以使用'get(h,{'XData','YData'})'来访问所有的行数据。 – Will

+0

再次感谢你@威尔。我尝试过'获得(h,{'XData','YData'})'并获得了一个14x2的单元格类,获得7分;这是这样的: 第一行:'[1X7双] [1X7双]' 第二行:'[1×2双] [1×2双]' 第三行:'[1×2双] [1×2双]' ... 我会尝试弄清楚它并将其用于我的代码,我知道你的答案是正确的。问候。 –