好的,我有一个使用 map 系统绘制线条的应用程序。每行 A、B 都以纬度/经度格式定义。当用户单击 map 时,给我的只是一个点 C,用户在其中以经/纬度格式单击。我想让用户能够通过单击来选择 map 上的线。问题是,由于缩放级别不同,用户很难准确地沿着直线单击。我最多希望它们在我定义的某个阈值距离内点击。仅给出此信息,我如何才能确定用户已点击或合理地接近某条线?
我对算法有一个粗略的想法,但我还没有充实它,而且我不确定这是否是最有效的方法。由于屏幕上随时可能有很多行,因此算法需要相当快。
到目前为止我想到的是首先检查 AC 和 BC 的距离。如果任一距离大于 AB,则用户没有点击该行。如果它通过了这个检查,那么我会计算角度 CAB 和 CBA。如果 C 正好在线上,那么两个角度都应该为 0,我想,我的三角有点生疏了。否则,为了确定 C 是否“足够接近”,我将选择两个计算出的角度中最小的一个,看看它是否低于某个预定义的阈值。
我走在正确的轨道上还是偏离了轨道?有更好的想法吗?
最佳答案
您也可以直接计算您的点到任何直线的距离。 wikipedia article为您提供详细信息和一些(伪)代码。
在您的情况下,您还必须分别考虑端点。 IE。您首先必须计算参数 t
(参见上面的文章)并检查它是否在 0 到 AB
的长度范围内。然后,如果距离低于预定量,则用户确实点击了该线,否则没有。
您案例中的公式如下所示:
(C - (A + t * (B-A))) * (B-A) = 0
=> t = (C.x - A.x) * (B.x - A.x) + (C.y - A.y) * (B.y - A.y) / ((B.x - A.X) * (B.x - A.x) + (B.y - A.y) * (B.y - A.y))
如果 t
小于 0 或大于 1,则用户没有点击该行。否则(即 t
介于 0 和 1 之间)您可以使用此值 t
计算距离 d
:
d = dist(C, A+t*(B-A)) = sqrt( (C.x - A.x - t * (B.x - A.x))^2 + (C.y - A.y - t * (B.y - A.y))^2)
如果 d
低于某个预定义的阈值,您可以假设用户点击了您的行。
关于c# - 确定一个点是沿着一条线还是非常接近的算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8463611/