我有 3 个点(A、B 和 X)和一个距离(d)。我需要创建一个函数来测试点 X 到线段 AB 上的任何点是否比距离 d 更近。
问题首先是,我的解决方案是否正确,然后提出更好(更快)的解决方案。
我的第一关如下
AX = X-A
BX = X-B
AB = A-B
// closer than d to A (done squared to avoid needing to compute the sqrt in mag)
If d^2 > AX.mag^2 return true
// closer than d to B
If d^2 > BX.mag^2 return true
// "beyond" B
If (dot(BX,AB) < 0) return false
// "beyond" A
If (dot(AX,AB) > 0) return false
// find component of BX perpendicular to AB
Return (BX.mag)^2 - (dot(AB,BX)/AB.mag)^2 < d^2
这段代码最终将针对大量 P 和大量 A/B/d 三元组运行,目的是找到所有通过至少一个 A/B/d 的 P,所以我怀疑有一种方法在此基础上降低总体成本,但我还没有研究过。
(顺便说一句:我知道一些重新排序、一些临时值和一些代数恒等式可能会降低上述成本。为了清楚起见,我只是省略了它们。)
编辑:这是一个 2D 问题(但推广到 3D 的解决方案会很酷
编辑:进一步思考,我预计命中率在 50% 左右。X 点可以在嵌套层次结构中形成,因此我希望能够将大型子树修剪为全通过和全失败。限制三连音的 A/B/d 将更像是一个技巧。
编辑:d 与 AB 的数量级相同。
编辑:Artelius 发布了一个不错的解决方案。我不确定我是否完全理解他的意思,因为我在完全理解之前就走上了正轨。无论如何,结果想到了另一个想法:
- 首先 Artelius 的位,预先计算一个矩阵,该矩阵将 AB 居中并与 X 轴对齐。(2 次添加、4 毫升和 2 次添加)
- 将其全部折叠到第一象限(2个腹肌)
- 在 X&Y 中缩放以使区域的中心部分成为一个单位正方形 (2 mul)
- test if the point is in that square (2 test) is so quit
- test the end cap (go back to the unscaled values
- translate in x to place the end at the origin (1 add)
- square and add (2 mul, 1 add)
- compare to d^2 (1 cmp)
I'm fairly sure this beats my solution.
(if nothing better comes along sone Artelius gets the "prize" :)