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?
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.
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With