我有一组点和一组线段。我想基于这些线段将这组点分成子集或簇。最后,我正在寻找每个子集的凸包(右图中显示的橙色多边形)。尽管下面示例中的线段彼此连接,但情况并非总是如此。我猜这个方法应该从所有点(左边显示的橙色多边形)构造一个凸包,然后在与线段的交叉点处将凸包分开,并以某种方式包括"内部"新凸壳中的点(即下面示例中的点1,2,3和4)。
ch1 = [9 10 5 6 3 9];
ch2 = [12 4 2 11 12];
ch3 = [1 8 7 1];
在此示例中,有12个点和6个线段。点1和2位置相当接近,但点2略微向左,点1略微向右。每个子集的凸包是:
{{1}}
答案 0 :(得分:1)
从任何一点开始。标记为A.迭代所有邻居。如果您可以联系到邻居,也将其标记为A.继续标记为A的下一个点(除非它正好在一条线上)。处理完所有A点后,该部分就完成了。在未标记的点上启动B.
之后计算凸包。
答案 1 :(得分:0)
在每对点之间构造线条。找到这些线和线段之间的交集(下面我使用lineSegmentIntersect)。忽略与任何线段相交的点对。从剩余的点对构造无向图。在无向图中找到connected components(下面我使用conncomp,它基于 Dulmage-Mendelsohn分解)。最后从每个连通分量中的点计算凸包。
这个Matlab函数convhullc(points, linesegments)
将找到每个凸包的坐标。
function C = convhullc(pp, ll)
np = size(pp,1); % Number of points
% Create line between all pairs of points
combi = nchoosek(1:np, 2);
ppxy = [pp(combi(:,1),:) pp(combi(:,2),:)];
% Intersection between all lines and all line segments
intersectpl = lineSegmentIntersect( ppxy, ll )
% Pairs of points that do not intersect a line segment
nointersect = (sum(intersectpl.intAdjacencyMatrix,2) == 0);
% Creating adjacency matrix of points with no intersect
adj = sparse(combi(nointersect,1), combi(nointersect,2), 1, np, np);
% Create undirected graph
adj = adj + adj.'; %'
% Find the connected components
[nch, bin] = conncomp(adj);
% Find the convex hulls
ch = cell(nch,1);
for i=1:nch
if( sum((bin==i)) > 2 )
ppx = pp((bin==i),1);
ppy = pp((bin==i),2);
K = convhull(ppx, ppy);
ch{i} = [ppx(K) ppy(K)];
end
end
ch = ch(~cellfun('isempty',ch));
C = ch;
end