让我们将线串视为点列表,我将其命名为Trail。我需要检测哪个点足够接近此路径。我还有另一个称为兴趣点的线串,我需要从轨迹线串返回最接近的索引点。我想提及的是,这些兴趣点未包含在路径线串中,因此我将通过给出该兴趣点以某种方式评估该路径中的索引点。所得的兴趣点将获得线索列表中现有的值。
[编辑]:
我将使用纯数字转换此问题。我发现这很容易。
输入列表[0.5、1、1.5、2、2.5、3、3.5、4、4.5、5]。
输入数字:3.30
我可以轻松地看到这种情况:list [n] 然后,我可以检查费用:
cost1 =数字-列表[n]
cost2 = list [n + 1]-数字。
然后如果(cost1
[重要]:
点对象无法与数字相提并论,这使我陷入了一个盲点。
最佳答案
如果您只需要执行一次,或者速度不是很重要,并且迹线不会趋向于自身循环,则检测最接近的两个点可能与检测它们之间的线段有所不同,因此非常简单。
首先,您需要一个点的距离平方公式(这代替了纯数字的差):
def dSq(x0: Double, y0: Double, x1: Double, y1: Double) =
(x1 - x0)*(x1 - x0) + (y1 - y0)*(y1 - y0)
请注意,使用普通距离而不是距离平方没有真正的优势,除了必须计算额外的平方根。 (但是请随意添加
def d(...) = sqrt(dSq(...))
并使用它。)现在,您可以找到从轨迹到目标点的距离:
val ds = trace.map(p => dSq(target.x, target.y, p.x, p.y))
您会发现两对点之间的距离:
val pairDs = ds.sliding(2).map(xx => xx(0) + xx(1))
您会发现其中最小的索引:
val smallest = pairDs.min
val index = pairDs.indexWhere(_ == smallest)
然后,在您的原始列表中,这两点是
index
和index+1
。或者,您可以找到最接近的单个点,然后通过比较距离来确定下一个还是上一个。 (同样,请注意,所有这些都是不精确的-要正确地做到这一点,您必须计算该点与两点之间的线段最接近的点,这是一个较长的公式。)
如果您必须执行很多操作,那么您将需要一种更快的方法来忽略无关紧要的长距离。一种常见的方法是在迹线上放置一个网格,然后在每个网格元素内创建子迹。然后,在给出兴趣点时,您首先查找其网格位置,然后在网格内部进行相同的搜索技巧。 (您可能还需要根据在网格内裁剪点的方式来搜索8个相邻的邻居。)
关于java - 从线串中提取最近的点索引到给定点?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30968496/