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