Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays MATLAB中无相交线连接任意点_Arrays_Matlab_Geometry_Computational Geometry - Fatal编程技术网

Arrays MATLAB中无相交线连接任意点

Arrays MATLAB中无相交线连接任意点,arrays,matlab,geometry,computational-geometry,Arrays,Matlab,Geometry,Computational Geometry,我需要帮助解决这个问题。我随机生成了点(例如图片1),我想用线将它们连接起来(例如图片2)。线不能相交,连接后,连接点应看起来像不规则区域 %Generating random points xn = randi([3 7],1,10); yn = randi([3 6],1,10); %Generated points xn = [6,3,7,7,6,6,6,4,6,3]; yn = [5,3,4,3,3,6,5,4,6,3]; 图#1: 结果应该是这样的: 图2: 你知道怎么解决这个

我需要帮助解决这个问题。我随机生成了点(例如图片1),我想用线将它们连接起来(例如图片2)。线不能相交,连接后,连接点应看起来像不规则区域

%Generating random points
xn = randi([3 7],1,10);
yn = randi([3 6],1,10);

%Generated points
xn = [6,3,7,7,6,6,6,4,6,3];
yn = [5,3,4,3,3,6,5,4,6,3];
图#1:

结果应该是这样的: 图2:


你知道怎么解决这个问题吗

我想在一般情况下,很难找到解决方案。但是,假设您的点“很好地”分散,有一个非常简单的解决方案

如果根据连接点和点云中心的向量x轴上方的角度对点进行排序,则:

P = [xn;yn]; %// group the points as columns in a matrix
c = mean(P,2); %// center point relative to which you compute the angles
d = bsxfun(@minus, P, c ); %// vectors connecting the central point and the dots
th = atan2(d(2,:),d(1,:)); %// angle above x axis
[st si] = sort(th); 
sP = P(:,si); %// sorting the points
就这样。要绘制结果,请执行以下操作:

sP = [sP sP(:,1)]; %// add the first point again to close the polygon
figure;plot( sP(1,:), sP(2,:), 'x-');axis([0 10 0 10]);
如果多个点与点云中心的角度相同,则该算法将失败

具有20个随机点的示例:

P = rand(2,50);

您可以修改中的代码,以生成任意边数的随机简单多边形。这里的区别是您已经选择了一组点,因此隐含了您想要的边数(即与唯一点数相同)。下面是代码的样子:

xn = [6,3,7,7,6,6,6,4,6,3];  % Sample x points
yn = [5,3,4,3,3,6,5,4,6,3];  % Sample y points
[~, index] = unique([xn.' yn.'], 'rows', 'stable');  % Get the unique pairs of points
x = xn(index).';
y = yn(index).';
numSides = numel(index);
dt = DelaunayTri(x, y);
boundaryEdges = freeBoundary(dt);
numEdges = size(boundaryEdges, 1);

while numEdges ~= numSides
    if numEdges > numSides
        triIndex = vertexAttachments(dt, boundaryEdges(:,1));
        triIndex = triIndex(randperm(numel(triIndex)));
        keep = (cellfun('size', triIndex, 2) ~= 1);
    end
    if (numEdges < numSides) || all(keep)
        triIndex = edgeAttachments(dt, boundaryEdges);
        triIndex = triIndex(randperm(numel(triIndex)));
        triPoints = dt([triIndex{:}], :);
        keep = all(ismember(triPoints, boundaryEdges(:,1)), 2);
    end
    if all(keep)
        warning('Couldn''t achieve desired number of sides!');
        break
    end
    triPoints = dt.Triangulation;
    triPoints(triIndex{find(~keep, 1)}, :) = [];
    dt = TriRep(triPoints, x, y);
    boundaryEdges = freeBoundary(dt);
    numEdges = size(boundaryEdges, 1);
end

boundaryEdges = [boundaryEdges(:,1); boundaryEdges(1,1)];
x = dt.X(boundaryEdges, 1);
y = dt.X(boundaryEdges, 2);

有两点需要注意:

  • 某些点集(如您在此处选择的点集)将没有唯一的解决方案。请注意,我的代码是如何以与您稍有不同的方式连接前4个点的
  • 我使用了和类,这两个类在未来的MATLAB版本中可能会被删除,以支持该类

对于随机点,不存在解决方案的保证。@AnderBiguri我不同意。即使我们不能解决一般情况,仍然可以提出一些实用的方法,并证明它们是有用的。@Shai I刚才提出了一个观点,以便澄清如何处理不存在完美解的情况。因此,这基本上可以在delaunay三角剖分的边上找到一个哈密顿循环?@knedlsepp Yep。它通过从delaunay三角剖分(这是一个凸包)中修剪三角形,直到得到所需的边数,这意味着它最终连接了所有的点。很好。我只是试着用提交和
d=delaunayTriangulation(P)来做;g=图(d.边);C=哈密顿循环(g),但问题是,对于超过20个节点,它比您的方法花费的时间要长得多。(以秒为单位,而不是以毫秒为单位。)
patch(x,y,'w');
hold on;
plot(x,y,'r*');
axis([0 10 0 10]);