计算一个点和一个矩形框之间的距离(最近点)

Dan*_*iel 27 3d geometry distance

有一个简单的公式来计算这个?我一直在研究一些数学但是我只能找到一种方法来计算指向盒子中心的距离,而不是指向最近的点..这个问题有一些资源吗?

Mul*_*ero 54

这是一个避免所有案例逻辑的公式.(我现在正好在JS工作,所以这是一个JS实现).让我们rect = {max:{x:_, y:_}, min:{x:_, y:_}}p={x:_, y:_}

function distance(rect, p) {
  var dx = Math.max(rect.min.x - p.x, 0, p.x - rect.max.x);
  var dy = Math.max(rect.min.y - p.y, 0, p.y - rect.max.y);
  return Math.sqrt(dx*dx + dy*dy);
}
Run Code Online (Sandbox Code Playgroud)

说明:这将问题分解为计算x距离dx和y距离dy.然后使用距离公式.

为了计算dx,这是如何工作的.(dy是类似的)

查看提供给max函数的元组:(min-p, 0, p-max).让我们指定这个元组(a,b,c).

如果p保留为min,那么我们有p <min <max,这意味着元组将评估为(+,0,-),因此max函数将正确返回a = min - p.

如果p在min和max之间,那么我们有min <p <max,这意味着元组将评估为(-,0,-).再次,max函数将正确返回b = 0.

最后,如果p在max的右边,那么我们有,min <max <p,并且元组的计算结果为(-,0,+).再次,Math.max正确返回c = p - max.

因此,结果表明所有的情况逻辑都由Math.max处理,这导致了一个漂亮的3行,无控制流功能.

  • +1 这是一个非常好的具体解决方案。如果盒子没有用坐标轴定向,它仍然可以通过旋转问题来使用。它并没有真正避免“所有案例逻辑”;它通过对“Math.max”的一次调用来捕获它(在每个轴上)。我相信它甚至可以通过简单地添加一个类似的 `dz` 组件来推广到 3D。 (2认同)

Ted*_*opp 8

我认为你需要分析案例; 没有单一的公式.从两个方面说明更容易:

1          2          3
    +-------------+
    |             |
4   |      0      |   5
    |             |
    +-------------+
6          7          8
Run Code Online (Sandbox Code Playgroud)

盒子的边缘(延伸)将外部分成9个区域.区域0(框内)通过计算到每条边的距离并取最小值来求解.区域1中的每个点最接近左上顶点,对于区域3,6和8也类似.对于区域2,4,5和7,您需要找到从该点到最近边缘的距离,是一个相当简单的问题.您可以通过对每个边缘进行分类来确定点所在的区域.(通过指示边缘,比如逆时针方向,更容易看到如何做到这一点.)这也会告诉您该点是否在框内.

在3D中,逻辑完全相同,只是您根据六个面进行分类,并且您有更多的情况.

如果盒子的边缘与坐标轴平行,问题就更简单了.


AnT*_*AnT 5

让我们说这个点被命名P并且ABCD是我们的矩形.然后问题可以分解为以下子问题集:

(1)开发一个dist(P, AB)计算点P和任意 之间距离的函数AB.

(2)计算你的点P和矩形每边之间的四个距离(每边是一个部分)并取四个中最短的一个

  distance = min(dist(P, AB), dist(P,BC), dist(P, CD), dist(P, DA))
Run Code Online (Sandbox Code Playgroud)

那是你的答案.

现在,我们需要知道如何计算点P和任意段之间的距离AB,即如何计算dist(P, AB).这样做如下

(1)执行点P到线的垂直投影AB.你得到新的点P'AB.

(2)如果P'之间谎言AB,然后dist(P, AB)是之间的距离PP'.

(3)否则,dist(P, AB)是之间的距离P和任一AB,以较短者为准.

而已.有一些明显的方法来优化程序,但即使按字面意思实现,它也会很好地工作.

PS当然,人们可以询问如何执行点到线的投影.我会把它作为练习留给读者:)


Rob*_*gar -1

这是一个 3D 盒子还是 2D 矩形?无论哪种方式,您可能最好获取每条边的点线(对于 2D)或点平面(3D)距离,然后选择最小值。

编辑:这里描述了一种更好的方法(最后一篇文章)。它涉及将点坐标转换为框空间,然后用框大小“饱和”坐标以找到框上最接近该点的点。我还没有尝试过,但它看起来对我来说很合适。

  • 答案中的链接和上面评论中更正的链接都已损坏。 (3认同)