2016-12-02 71 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雙]' ... 我會嘗試弄清楚它並將其用於我的代碼,我知道你的答案是正確的。問候。 –