Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Color unbounded cells of voronoi diagram in MATLAB

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

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.

and this is the result: enter image description here

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

Any suggestion?

like image 959
pooria haddad Avatar asked Oct 18 '22 21:10

pooria haddad


2 Answers

it seems that in Matlab R2018a or later(R2014b is ok but I didn't test the R2015 ~ R2016), the voronoi doesn't return the same h as expected before, though the document of this function doesn't change. In R2018a it returns

 h(1)

ans = 

 handle to deleted Data

while in R2014b it returns

h(1)

ans = 

  Line with properties:

              Color: [0 0.4470 0.7410]
          LineStyle: 'none'
          LineWidth: 0.5000
             Marker: '.'
         MarkerSize: 6
    MarkerFaceColor: 'none'
              XData: [1x200 double]
              YData: [1x200 double]
              ZData: [1x0 double]

  Show all properties

I was just wondering if there are some methods to extract the lines and vertices of unbounded cells in new version.

like image 85
Fangzhou AI Avatar answered Oct 21 '22 02:10

Fangzhou AI


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.

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

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

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

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);
like image 34
Will Avatar answered Oct 21 '22 02:10

Will