C# 平面上距离给定点最近的x点快速算法

C# 平面上距离给定点最近的x点快速算法,c#,algorithm,map,point,plane,C#,Algorithm,Map,Point,Plane,我想找到一个快速算法,以便找到平面上离给定点最近的x点 我们实际上处理的点不太多(在1000到100000之间),但我需要每个点的x最近点。(其中x通常在5到20之间。) 我需要用C写 关于用例的更多上下文:这些点是地图上的坐标。(我知道,这意味着我们并不是在谈论平面,但我希望避免处理投影问题。)在端点中,有许多其他点靠近它们的点应显示为红色,没有太多点靠近它们的点应显示为绿色。在这两个极值之间,点位于颜色渐变上。对于给定点(并非所有点),由于点的数量不是极值,您可以计算到每个点的距离: var

我想找到一个快速算法,以便找到平面上离给定点最近的x点

我们实际上处理的点不太多(在1000到100000之间),但我需要每个点的x最近点。(其中x通常在5到20之间。)

我需要用C写

关于用例的更多上下文:这些点是地图上的坐标。(我知道,这意味着我们并不是在谈论平面,但我希望避免处理投影问题。)在端点中,有许多其他点靠近它们的点应显示为红色,没有太多点靠近它们的点应显示为绿色。在这两个极值之间,点位于颜色渐变上。

对于给定点(并非所有点),由于点的数量不是极值,您可以计算到每个点的距离:

var points = new List<Point>();
Point source = ...
....
var closestPoints = points.Where(point => point != source).
                           OrderBy(point => NotReallyDistanceButShouldDo(source, point)).
                           Take(20);

private double NotReallyDistanceButShouldDo(Point source, Point target)
{
   return Math.Pow(target.X - source.X, 2) + Math.Pow(target.Y - source.Y, 2);
}
var points=新列表();
点源=。。。
....
var closestPoints=points.Where(point=>point!=source)。
OrderBy(point=>notreallydestance但shoullddo(source,point))。
采取(20);
私有双精度非真实距离,但应执行(点源、点目标)
{
返回Math.Pow(target.X-source.X,2)+Math.Pow(target.Y-source.Y,2);
}
(我使用了x=20)

计算是基于双倍的,所以fpu应该能够在这里做得很好。
请注意,如果Point是一个类而不是一个结构,您可能会获得更好的性能。

您需要创建一个距离函数,然后计算每个点的距离并对结果进行排序,然后取第一个x

如果结果必须100%准确,则可以使用标准距离函数:


d=SQRT((x2-x1)^2+(y2-y1)^2)

以提高效率。假设距离是k。取x坐标在x-k和x+k之间的所有点。类似地,取y-k和y+k。所以你已经移除了所有多余的坐标。现在通过(x-x1)^2+(y-y1)^2来确定距离。在它们上面创建一个由k个元素组成的最小堆,如果newpoint您需要的是一个适合于在平面中组织点的数据结构。K-D树通常用于这种情况。见维基百科

在这里,我找到了对


更新
我将KD树的Java实现移植到C#。请看RoboWiki。你可以在那里下载代码,也可以直接从我的网站下载(只下载,不需要文档)。

不需要使用sqr root。你可以根据dx2+dy2进行排序事实上,你也可以根据abs(dx)+abs(dy)@DarenThomas:Wow,这可能是最快的。我不确定你要求的算法是否最适合你的用例。也许您可以循环遍历所有点并计算一个粗略的密度函数(二维直方图)。然后,你可以根据计算出的每个点所在单元的密度来给每个点上色,也许还可以考虑相邻单元。更快:省去Math.Sqrt,似乎你不需要知道确切的距离:)@vanhelgen true,让我们更快一点为什么在这里调用Math.pow()<代码>双dx=target.x-source.x;double dy=target.y-source.y;返回dx+dydy