MATLAB 中 voronoi 图的彩色无界单元
Color unbounded cells of voronoi diagram in MATLAB
我有两组点,plot
它们分别是蓝星和红点。然后我plot
Voronoi diagram of both sets with voronoi(X,Y)
function。我想指定每个单元格的颜色取决于它的站点属于哪个集合。通过使用 patch
函数,我几乎完成了这个:
[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 图的单元格。
这是结果:
现在我的问题(如您所见!)是关于无限单元格的。此代码仅更改有界单元格的颜色,我想在轴框(即您可以在图像中看到的框)范围内使用指定集的颜色为无界单元格着色。
有什么建议吗?
您的示例实际上确实为无限单元格创建了 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);
似乎在 Matlab R2018a 或更高版本中(R2014b 可以,但我没有测试 R2015 ~ R2016),voronoi 没有 return 与之前预期的相同 h,尽管文档这个功能没有改变。
在 R2018a 中 returns
h(1)
ans =
handle to deleted Data
而在 R2014b 中 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
我想知道新版本有没有提取无界单元格的线和顶点的方法
我有两组点,plot
它们分别是蓝星和红点。然后我plot
Voronoi diagram of both sets with voronoi(X,Y)
function。我想指定每个单元格的颜色取决于它的站点属于哪个集合。通过使用 patch
函数,我几乎完成了这个:
[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 图的单元格。
这是结果:
现在我的问题(如您所见!)是关于无限单元格的。此代码仅更改有界单元格的颜色,我想在轴框(即您可以在图像中看到的框)范围内使用指定集的颜色为无界单元格着色。
有什么建议吗?
您的示例实际上确实为无限单元格创建了 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);
似乎在 Matlab R2018a 或更高版本中(R2014b 可以,但我没有测试 R2015 ~ R2016),voronoi 没有 return 与之前预期的相同 h,尽管文档这个功能没有改变。 在 R2018a 中 returns
h(1)
ans =
handle to deleted Data
而在 R2014b 中 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
我想知道新版本有没有提取无界单元格的线和顶点的方法