【问题标题】:Splitting a set of points into subsets based on line segments根据线段将一组点拆分为子集
【发布时间】:2016-08-21 22:06:43
【问题描述】:

我有一组点和一组线段。我想根据这些线段将点集拆分为子集或集群。最终,我正在寻找每个子集的凸包(右图中显示的橙色多边形)。尽管下例中的线段相互连接,但并非总是如此。我猜该方法应该从所有点(左侧显示的橙色多边形)构造一个凸包,然后在与线段的交点处分割凸包,并以某种方式将“内部”点包含在新的凸包中船体(即下面示例中的点 1、2、3 和 4)。

points = [-0.1325 -2.2267; -0.1525 -2.2267; -0.5319  1.0698; -1.3628 -0.1296;  1.7438  1.3784;  1.5770  0.9458;  0.5147 -2.6114;  0.8169 -2.2797; -1.0244  2.7143; -0.4422  2.8257; -1.7421 -2.4453; -2.4492 -0.4012]
linesegments = [-1.1258 -4.2270 -0.7196 -3.9662; -0.7196 -3.9662  0.4347 -0.4873; -2.3293  1.4275 -3.3717  2.2654; -2.3293  1.4275  0.4347 -0.4873;  1.3579  3.1700  3.3566  0.5079;  3.3566  0.5079  0.4347 -0.4873] % Each row is line with format [x1 y1 x2 y2];

在这个例子中,有 12 个点和 6 个线段。点 1 和 2 的位置相当接近,但点 2 稍微偏左,点 1 稍微偏右。每个子集的凸包为:

ch1 = [9 10 5 6 3 9];
ch2 = [12 4 2 11 12];
ch3 = [1 8 7 1];

【问题讨论】:

  • 你可以看看WhatIf包和相关论文不确定它们是否直接适用,但它是一个镜头。

标签: r matlab cluster-analysis subset


【解决方案1】:

从任何一点开始。标签为 A。遍历所有邻居。如果您可以到达邻居,也将其标记为 A。继续下一个标记为 A 的点(除非它正好在一条线上)。处理完所有 A 点后,该部分就完成了。从一个未标记的点开始 B。

之后计算凸包。

【讨论】:

    【解决方案2】:

    在每对点之间构造线。找到这些线和线段之间的交点(下面我使用了lineSegmentIntersect)。忽略与任何线段相交的点对。从剩余的点对构造一个无向图。在无向图中找到connected components(下面我使用了基于Dulmage-Mendelsohn 分解conncomp)。最后根据每个连通分量中的点计算凸包。

    这个 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
    

    【讨论】:

      猜你喜欢
      • 2011-06-15
      • 1970-01-01
      • 1970-01-01
      • 2019-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-15
      • 1970-01-01
      相关资源
      最近更新 更多