基于numpy实现的点和矩形之间的最短距离
shortest distance between a point and a rectangle based on numpy implementation
目标:
对于一个点a
和一个矩形B
,我想计算这两个对象之间的最短距离。
动机
因为这个计算是多次循环的最内层循环的一部分,所以我想尽可能优化这个计算。以我目前的 python 知识,使用专用的 NumPy 函数应该是实现目标的途径(?)。
更多细节:
- 情况是二维的;
x,y
坐标
- 矩形
B
由某个 center-of-gravity/mid-point 以及宽度和长度定义(因此不是由点向量定义)
- 因此距离是从
a
到矩形的 edges B
我当前的实现使用了以下想法:link。这里矩形被划分为多个子区域。首先判断B
a
位于哪个子区域内。此后,计算a
和B
之间的最短距离就很简单了。但是,需要进行大量逻辑检查才能确定 a
位于哪个子区域。它看起来如下所示,
def distance_a_to_B(a:Point):
if a in sub_area_1:
return easy_calculation_1(a)
if a in sub_area_2:
return easy_calculation_2(a)
if a in sub_area_3:
return easy_calculation_3(a)
etc
理想情况下,
- 我想要alternative/faster逻辑检查(Python改进)
或
- 更快的数学算法
也许……?
我在写这个问题时想到的一个可能的替代方法是根据 B
的特征计算离散数量的 n
点。从这个 n
点的矢量,我认为使用 NumPy 很容易:
- 计算
a
到n
个点中每个点的最短距离
- 找到这个新向量的最小值
对于更大的 n
,此解决方案将变得更加精确,但性能成本更高。您认为这可能是更好的解决方案吗?或者您对数学(非近似)算法有什么建议吗?
编辑:添加了额外说明,距离朝向矩形的边缘 B
我认为,这是距离函数的一个很好的实现:
from math import sqrt
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
class Rectangle:
def __init__(self, center: Point, width: float, height: float):
self.center = center
self.width = width
self.height = height
def distance_to_point(self, point: Point) -> float:
""" assuming that the distance to a point inside of this rect is zero """
dx = abs(self.center.x - point.x) - (self.width * 0.5)
dy = abs(self.center.y - point.y) - (self.height * 0.5)
return sqrt((dx * (dx > 0)) ** 2 + (dy * (dy > 0)) ** 2)
我不知道,Python 解释器翻译这段代码的效果如何。完全无分支地实现这种方法是可能的,这对于优化代码来说是一个很好的 属性。
如果您想将一个点与多个矩形 (1:n) 进行比较,您可以将所有矩形存储在一个 numpy 数组中,然后使用 numpy 数组函数一次将您的点与所有矩形进行比较。 n:1 比较也是如此。这可以大大加快这个过程!
不过,在不了解您的循环的更多信息的情况下,我无法提供这样的解决方案。
目标:
对于一个点a
和一个矩形B
,我想计算这两个对象之间的最短距离。
动机
因为这个计算是多次循环的最内层循环的一部分,所以我想尽可能优化这个计算。以我目前的 python 知识,使用专用的 NumPy 函数应该是实现目标的途径(?)。
更多细节:
- 情况是二维的;
x,y
坐标 - 矩形
B
由某个 center-of-gravity/mid-point 以及宽度和长度定义(因此不是由点向量定义) - 因此距离是从
a
到矩形的 edgesB
我当前的实现使用了以下想法:link。这里矩形被划分为多个子区域。首先判断B
a
位于哪个子区域内。此后,计算a
和B
之间的最短距离就很简单了。但是,需要进行大量逻辑检查才能确定 a
位于哪个子区域。它看起来如下所示,
def distance_a_to_B(a:Point):
if a in sub_area_1:
return easy_calculation_1(a)
if a in sub_area_2:
return easy_calculation_2(a)
if a in sub_area_3:
return easy_calculation_3(a)
etc
理想情况下,
- 我想要alternative/faster逻辑检查(Python改进) 或
- 更快的数学算法
也许……?
我在写这个问题时想到的一个可能的替代方法是根据 B
的特征计算离散数量的 n
点。从这个 n
点的矢量,我认为使用 NumPy 很容易:
- 计算
a
到n
个点中每个点的最短距离 - 找到这个新向量的最小值
对于更大的 n
,此解决方案将变得更加精确,但性能成本更高。您认为这可能是更好的解决方案吗?或者您对数学(非近似)算法有什么建议吗?
编辑:添加了额外说明,距离朝向矩形的边缘 B
我认为,这是距离函数的一个很好的实现:
from math import sqrt
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
class Rectangle:
def __init__(self, center: Point, width: float, height: float):
self.center = center
self.width = width
self.height = height
def distance_to_point(self, point: Point) -> float:
""" assuming that the distance to a point inside of this rect is zero """
dx = abs(self.center.x - point.x) - (self.width * 0.5)
dy = abs(self.center.y - point.y) - (self.height * 0.5)
return sqrt((dx * (dx > 0)) ** 2 + (dy * (dy > 0)) ** 2)
我不知道,Python 解释器翻译这段代码的效果如何。完全无分支地实现这种方法是可能的,这对于优化代码来说是一个很好的 属性。
如果您想将一个点与多个矩形 (1:n) 进行比较,您可以将所有矩形存储在一个 numpy 数组中,然后使用 numpy 数组函数一次将您的点与所有矩形进行比较。 n:1 比较也是如此。这可以大大加快这个过程!
不过,在不了解您的循环的更多信息的情况下,我无法提供这样的解决方案。