简体   繁体   English

如何有效地找到离散点集的顺序?

[英]How to find the order of discrete point-set efficiently?

I have a series of discrete point on a plane, However, their order is scattered.我在平面上有一系列离散点,但是,它们的顺序是分散的。 Here is an instance:这是一个例子:

在此处输入图片说明

To connect them with a smooth curve, I wrote a findSmoothBoundary() to achieve the smooth boundary.为了用平滑的曲线将它们连接起来,我写了一个findSmoothBoundary()来实现平滑的边界。

Code代码

    function findSmoothBoundary(boundaryPointSet)
        %initialize the current point
        currentP = boundaryPointSet(1,:);
        
        %Create a space smoothPointsSet  to store the point
        smoothPointsSet = NaN*ones(length(boundaryPointSet),2);
        %delete the current point from the boundaryPointSet
        boundaryPointSet(1,:) = [];
        ptsNum = 1; %record the number of smoothPointsSet
        
        smoothPointsSet(ptsNum,:) = currentP;

        while ~isempty(boundaryPointSet)
            %ultilize the built-in knnsearch() to 
            %achieve the nearest point of current point
            nearestPidx = knnsearch(boundaryPointSet,currentP);
            currentP = boundaryPointSet(nearestPidx,:);
            ptsNum = ptsNum + 1;
            smoothPointsSet(ptsNum,:) = currentP;
            %delete the nearest point from boundaryPointSet
            boundaryPointSet(nearestPidx,:) = [];
        end
        %visualize the smooth boundary
        plot(smoothPointsSet(:,1),smoothPointsSet(:,2))
        axis equal
    end

Although findSmoothBoundary() can find the smooth boundary rightly, but its efficiency is much lower ( About the data , please see here )虽然findSmoothBoundary()可以正确地找到平滑边界,但它的效率要低得多(关于数据,请看这里

在此处输入图片说明


So I would like to know:所以我想知道:

  • How to find the discrete point order effieciently?如何有效地找到离散点序?

Data数据

theta = linspace(0,2*pi,1000)';
boundaryPointSet= [2*sin(theta),cos(theta)];

tic;
findSmoothBoundary(boundaryPointSet)
toc;

%Elapsed time is 4.570719 seconds.

在此处输入图片说明

This answer is not perfect because I'll have to make a few hypothesis in order for it to work.这个答案并不完美,因为我必须做出一些假设才能使其发挥作用。 However, for a vast majority of cases, it should works as intended.但是,对于绝大多数情况,它应该按预期工作。 Moreover, from the link you gave in the comments, I think these hypothesis are at least weak, if not verified by definition :此外,从你在评论中给出的链接来看,我认为这些假设至少是弱的,如果没有通过定义验证:

1. The point form a single connected region 1.点形成单个连通区域

2. The center of mass of your points lies in the convex hull of those points 2.你的点的质心位于这些点的凸包中


If these hypothesis are respected, you can do the following (Full code available at the end):如果这些假设得到尊重,您可以执行以下操作(完整代码在最后):

Step 1 : Calculate the center of mass of your points第 1 步:计算点的质心

Means=mean(boundaryPointSet);

Step 2 : Change variables to set the origin to the center of mass第 2 步:更改变量以将原点设置为质心

boundaryPointSet(:,1)=boundaryPointSet(:,1)-Means(1);
boundaryPointSet(:,2)=boundaryPointSet(:,2)-Means(2);

Step3 : Convert coordinates to polar Step3:将坐标转换为极坐标

[Angles,Radius]=cart2pol(boundaryPointSet(:,1),boundaryPointSet(:,2));

Step4 : Sort the Angle and use this sorting to sort the Radius Step4:Angle进行排序并使用这种排序对Radius进行排序

[newAngles,ids]=sort(Angles);
newRadius=Radius(ids);

Step5 : Go back to cartesian coordinates and re-add the coordinates of the center of mass: Step5:回到笛卡尔坐标,重新添加质心坐标:

[X,Y]=pol2cart(newAngles,newRadius);
X=X+Means(1);
Y=Y+means(2);

Full Code完整代码

%%% Find smooth boundary
fid=fopen('SmoothBoundary.txt');
A=textscan(fid,'%f %f','delimiter',',');

boundaryPointSet=cell2mat(A);

boundaryPointSet(any(isnan(boundaryPointSet),2),:)=[];

idx=randperm(size(boundaryPointSet,1));

boundaryPointSet=boundaryPointSet(idx,:);

tic

plot(boundaryPointSet(:,1),boundaryPointSet(:,2))

%% Find mean value of all parameters

Means=mean(boundaryPointSet);

%% Center values around Mean point

boundaryPointSet(:,1)=boundaryPointSet(:,1)-Means(1);
boundaryPointSet(:,2)=boundaryPointSet(:,2)-Means(2);

%% Get polar coordinates of your points

[Angles,Radius]=cart2pol(boundaryPointSet(:,1),boundaryPointSet(:,2));

[newAngles,ids]=sort(Angles);
newRadius=Radius(ids);

[X,Y]=pol2cart(newAngles,newRadius);
X=X+Means(1);
Y=Y+means(2);    
toc

figure

plot(X,Y);

Note : As your values are already sorted in your input file, I had to mess it up a bit by permutating them注意:由于您的值已经在您的输入文件中排序,我不得不通过排列它们来弄乱它

Outputs :输出:

Boundary边界

Elapsed time is 0.131808 seconds.经过的时间是 0.131808 秒。

Messed Input :混乱的输入:

在此处输入图片说明

Output :输出:

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 从大集合中以离散分布有效地抽取小样本 - Draw small sample from large set with discrete distribution efficiently 如何有效地找到相似的文件 - How to efficiently find similar documents 如何有效地找到特定尺寸的开放矩形? - How to find open rectangle with specific size efficiently? 如何有效地查找网格中某个范围内的元素总数? - How to find sum of elements in a range in a grid efficiently? JavaScript-有效地查找包含大量字符串之一的所有元素 - JavaScript - Efficiently find all elements containing one of a large set of strings 如何在Java中有效存储一组元组/对 - How to efficiently store a set of tuples/pairs in Java 给定一个点和大量的四面体,如何高效判断该点在哪个四面体中 - Given a point and a large number of tetrahedrons, how to efficiently determine in which tetrahedron the point is 如何有效地移动数字中的小数点直到达到某个阈值 - How to efficiently move the decimal point in a number until reaching some threshold 如何有效地将订单变量添加到大数据框中 - How to efficiently add an order variable to a big data frame 如何在PostgreSQL中有效地设置减去连接表? - How to efficiently set subtract a join table in PostgreSQL?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM