如何从多边形的离散化细胞表示产生有序多边形顶点序列 [英] How to produce an ordered sequence of vertices of polygon from a discretized cellular representation of polygon

查看:224
本文介绍了如何从多边形的离散化细胞表示产生有序多边形顶点序列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下是多边形的细胞表示: -





这是显示的提取多边形。





我们将输入作为矩阵 polM ,为粉红色单元格存储1,为黄色单元格存储2。从黄色单元格我们想要创建一个多边形。这也是使用以下来自


Here is the cellular representation of polygon shown:-

Here is the extracted polygon shown.

We are given the input as a matrix polM that stores 1 for pink cells and 2 for yellow cells. From the yellow colored cells we want to create a polygon. This is also done using below code derived from here.

clear;
close all;
A=ones(25,25);
indices=[64,65,88,89,90,91,111,112,113,114,115,116,117,135,136,137,138,139,140,141,142,143,158,159,160,161,162,163,164,165,166,167,168,169,182,183,184,185,186,187,188,189,190,191,192,193,194,195,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,282,283,284,285,286,287,288,289,290,291,292,293,294,295,307,308,309,310,311,314,315,316,317,318,319,320,341,342,343,344,345,367,368,369,393,394];
A(indices)=2;

figure
hold on
axis equal
axis ij
xx=10:20:500;
yy=10:20:500;
imagesc(xx,yy,A);
colormap([1.0000         0    0.7931;
    1.0000    0.8276         0]);
rt=[0,500];
gcs=0:20:500;
gds=ones(size(rt,2),size(gcs,2));
gds = bsxfun(@times,gds,gcs);
plot(rt,gds,'Color','k','LineStyle','-');
plot(gds,rt,'Color','k','LineStyle','-');
axis([0 350 100 450])

A=A-1;
% we identify patterns with edges over 2x2 patches, describing with
% the first 4 binary values what pixels are set, and with the next 2
% the edge with 2 indices over the 2x2 patch
patterns = [
    0,1,0,1,  3,4 % vertical edge at rhe right
    1,0,1,0,  1,2 % vertical edge at the left
    0,0,1,1,  2,4 % horizontal edge at the bottom
    1,1,0,0,  1,3 % horizontal edge at the top
    1,0,0,1,  1,4 % diagonal edge
    0,1,1,0,  2,3 % diagonal edge
    1,0,1,1,  1,4 % diagonal edge, extra pixel set
    1,1,0,1,  1,4 % diagonal edge, extra pixel set
    1,1,1,0,  2,3 % diagonal edge, extra pixel set
    0,1,1,1,  2,3 % diagonal edge, extra pixel set
    ];

% 2x2 patches (matrix form)
P00 = A(1:end-1,1:end-1);
P10 = A(2:end,1:end-1);
P01 = A(1:end-1,2:end);
P11 = A(2:end,2:end);

% edge unique identifier using powers of 2
id = @(p00,p01,p10,p11) 1*p00 + 2*p10 + 4*p01 + 8*p11;
P = id(P00,P01,P10,P11); % vectorized pattern identification

% edges
e0 = []; % from (i,j)
e1 = []; % to (i,j)
for i = 1:size(patterns, 1) % small loop over the 10 patterns
    p = patterns(i, :);
    E = (P == id(p(1),p(2),p(3),p(4))); % pattern search, vectorized
    [c,r] = ind2sub(size(E), find(E));
    [c0,r0] = ind2sub([2,2], p(5));
    [c1,r1] = ind2sub([2,2], p(6));
    e0 = [e0; c+c0, r+r0];
    e1 = [e1; c+c1, r+r1];
end

X = [e0(:,2) e1(:,2)]';
Y = size(A,1) - [e0(:,1) e1(:,1)]';

figure
hold on
axis equal
axis ij
X=X*20;
Y=Y*20; Y=500-Y;
plot(X, Y, '.-')
axis([0 350 100 450])

But the output of this code which represents the polygon is given by arrays X and Y. I want to express the output in nx2 matrix form where all rows represent a vertex if the final polygon and the vertices are in a clockwise or counter clockwise order starting from the first vertex. There are methods here that can post-process a jumbled sequence of vertices to an ordered sequence but i want an algorithm to determine the polygonal vertices from input matrix polM in an ordered sequence only. SO input is polM and output is a nx2 matrix of polygon vertices in either cw or ccw order only.

Can someone suggest an efficient change to the algorithm?

EDIT:

If you add this piece of code assuming ordered result is already coming you get error:-

newp=[X(1,:)',Y(1,:)'];
figure
hold on
axis([0 350 100 450])
axis equal
axis ij
line(newp(:,1), newp(:,2));

Basically i want to resolve this error.

解决方案

X and Y are both 2xn matrices specifying n unordered vertexes, i.e. a line should be drawn between [X(1, i) Y(1, i)] and [X(2, i) Y(2, i)] for every i=1:n. Because all the vertexes are connected, every point should occur twice in these X and Y matrices. Therefore, one can start at an arbitrary point on the polygon and search the next point iteratively. This can be done as follows:

% XY_from: a `nx2` matrix containing all starting points 
% with a third column indicating if this vertex is already used
XY_from = [X(1, :)' Y(1, :)' zeros(size(X, 2), 1)]; 
XY_to = [X(2, :)' Y(2, :)' zeros(size(X, 2), 1)]; % similar matrix for destination points
new_poly = zeros(size(X, 2)+1, 2); % allocate output space
new_poly(1, :) = XY_from(1, 1:2); % select an arbitrary starting point
for i=2:size(new_poly, 1)
  index = find(all([new_poly(i-1, :) 0] == XY_from, 2), 1); % search the previous (unused) point in the starting points
  if isempty(index) 
    index = find(all([new_poly(i-1, :) 0] == XY_to, 2), 1); % if no point was found, search it in the destination points
    new_poly(i, :) = XY_from(index, 1:2); % add the new point (corresponding with the found destination point)
  else
    new_poly(i, :) = XY_to(index, 1:2); % add the new point (corresponding with the found start point)
  end
  XY_from(index, 3) = 1; % indicate that this start point is used
  XY_to(index, 3) = 1; % indicate that this destination point is used
end

hold on
plot(new_poly(:, 1), new_poly(:, 2), '--k', 'LineWidth', 2); % plot on top of the polygon

这篇关于如何从多边形的离散化细胞表示产生有序多边形顶点序列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆