Geometry 如何快速找到距离三维或三维平面最近的k点

Geometry 如何快速找到距离三维或三维平面最近的k点,geometry,point,nearest-neighbor,euclidean-distance,kdtree,Geometry,Point,Nearest Neighbor,Euclidean Distance,Kdtree,我需要在3维(或更多维)中快速找到离平面(或超平面)最近的k点。使用某种巧妙的数据结构(类似于kd树对k个最近邻的工作方式),有没有一种快速的方法来执行此搜索 我知道我可以旋转平面和所有点,使平面与其中一个轴正交,然后简单地使用该轴上的坐标测量每个点到平面的距离。然而,这种蛮力方法的时间复杂度是O(N),其中(N)是点数。因为我必须找到大量平面和大量点的k个最近邻,所以如果可能的话,我需要找到一个更快的算法。使用点积和超平面法线测量距离。。。因此,让我们: n-是超平面法向单位向量 p0-是超平

我需要在3维(或更多维)中快速找到离平面(或超平面)最近的k点。使用某种巧妙的数据结构(类似于kd树对k个最近邻的工作方式),有没有一种快速的方法来执行此搜索


我知道我可以旋转平面和所有点,使平面与其中一个轴正交,然后简单地使用该轴上的坐标测量每个点到平面的距离。然而,这种蛮力方法的时间复杂度是O(N),其中(N)是点数。因为我必须找到大量平面和大量点的k个最近邻,所以如果可能的话,我需要找到一个更快的算法。

使用点积和超平面法线测量距离。。。因此,让我们:


n
-是超平面法向单位向量
p0
-是超平面上的任意点
p[i]
-成为点云的第i个点
i={0,1,2…n-1}

那么到超平面的距离是:

d = |dot( p[i] - p0 , n )|
正如您所见,无需进行任何昂贵的操作,就无需变换/对齐任何东西及其
O(1)
。我预计在大多数情况下,任何点的预排序或使用智能结构都会比这慢

现在您有两个选项,或者计算每个点的
d
,然后快速排序,这将导致
O(n.log(n))
时间和
O(n)
空间复杂度

或者记住
k
运行中最近的点,导致
O(k*n)
时间和
O(k)
空间


因此,如果
k
很小
(k
或者您没有足够的内存来使用第二种方法,否则使用第一种方法…

使用点积和超平面法线测量距离。。。因此,让我们:


n
-是超平面法向单位向量
p0
-是超平面上的任意点
p[i]
-成为点云的第i个点
i={0,1,2…n-1}

那么到超平面的距离是:

d = |dot( p[i] - p0 , n )|
正如您所见,无需进行任何昂贵的操作,就无需变换/对齐任何东西及其
O(1)
。我预计在大多数情况下,任何点的预排序或使用智能结构都会比这慢

现在您有两个选项,或者计算每个点的
d
,然后快速排序,这将导致
O(n.log(n))
时间和
O(n)
空间复杂度

或者记住
k
运行中最近的点,导致
O(k*n)
时间和
O(k)
空间


因此,如果
k
很小
(k
或者您没有足够的内存来使用第二种方法,否则使用第一种方法…

我认为您可以简单地使用支持自定义距离函数的任何空间数据结构(kd树、R树…)。您应该能够定义一个距离函数,该函数仅使用到平面的距离,而不是到中心点的距离

如何计算此距离由@Spektre描述

我不知道它是如何扩展的,因为它可能取决于实现所使用的kNN搜索算法。 然而,我相信标准算法(Hjaltason和Samet:“空间数据库中的距离浏览”)至少应该比O(n)好


如果您使用Java,我的库中的R树、四叉树和PH树索引都使用此算法。

我认为您可以简单地使用支持自定义距离函数的任何空间数据结构(kd树、R树……)。您应该能够定义一个距离函数,该函数仅使用到平面的距离,而不是到中心点的距离

如何计算此距离由@Spektre描述

我不知道它是如何扩展的,因为它可能取决于实现所使用的kNN搜索算法。 然而,我相信标准算法(Hjaltason和Samet:“空间数据库中的距离浏览”)至少应该比O(n)好


如果您使用的是Java,则我的库中的R树、四叉树和PH树索引都使用此算法。

其中的“或更多”部分相当重要。你看了多少个维度,有多少个点?KD树是实现这一点的常用工具,但除非
N/log(N)<2^D
,否则KD树不会太有用,其中
N
是点数,
D
是维度数,否则KD树不是真正的树。三维是主要目标,但我正在考虑将曲面法线和/或点的反射率添加到距离函数中,因此可能是4、6或7维。即使是一个3维的实现也会很棒。我已经在其他地方使用了k-d树,是的,即使是6维,性能也会下降到几乎线性(或者当查询点到最近邻居的距离远大于k-d树中点之间的距离时,即使是3维)。我不知道如何调整k-d树来使用平面而不是点进行搜索。你有很多选择:如果你还没有完全阅读维基百科,我也会完整地阅读:其中的“或更多”部分相当重要。你看了多少个维度,有多少个点?KD树是实现这一点的常用工具,但除非
N/log(N)<2^D
,否则KD树不会太有用,其中
N
是点数,
D
是维度数,否则KD树不是真正的树。三维是主要目标,但我正在考虑将曲面法线和/或点的反射率添加到距离函数中,因此可能是4、6或7维。即使是一个3维的实现也会很棒。我已经在其他地方使用了k-d树,是的,性能下降到接近l