点到框边界的距离

时间:2021-05-30 18:05:18

标签: python numpy distance euclidean-distance

在我用 Pygame 编写的游戏中,我有一个 2D 点 (x,y) 在一个从 (0,0)(1,1)(带边的完美正方形)的框中长度 1)。 我想计算从点到框边界在 alpha 方向上的欧几里德距离,其中 alpha 是一个以逆时针弧度为单位的方位角方向,从 alpha=0 开始作为 x -轴方向。

我写了一个 python 代码来计算这个距离,但我不确定这是最有效/最干净的方法:

import numpy as np


def get_distance_to_boundary(x, y, angle):
    cos_angle, sin_angle = np.cos(angle), np.sin(angle)
    if cos_angle == 0:
        return y if sin_angle < 0 else 1 - y
    if sin_angle == 0:
        return x if cos_angle < 0 else 1 - x
    x_target = 1 if cos_angle > 0 else 0
    y_target = y + (x_target - x) * np.tan(angle)
    if y_target > 1:
        return np.fabs((1 - y) / sin_angle)
    if y_target < 0:
        return np.fabs(y / sin_angle)
    return np.sqrt((x_target - x) ** 2 + (y_target - y) ** 2)

有更好的方法吗?

插图:

enter image description here

1 个答案:

答案 0 :(得分:1)

这种方法更高效/更简洁,因为您不需要 tanfabssqrt**2

def distance(x,y,angle):
    cos_angle, sin_angle = np.cos(angle), np.sin(angle)
    if cos_angle == 0:
        return y if sin_angle < 0 else 1 - y
    if sin_angle == 0:
        return x if cos_angle < 0 else 1 - x
    distance_EW = (1-x)/cos_angle if cos_angle>0 else -x/cos_angle
    distance_NS = (1-y)/sin_angle if sin_angle>0 else -y/sin_angle
    return min(distance_EW, distance_NS)

我将 distance_EW 定义为目标在东墙(如果 cos_angle>0)或在西墙(如果 cos_angle<0)的情况下的距离。同样,为北墙或南墙定义 distance_NS

...

警告:由于舍入误差,我的距离函数有时会产生与您的函数不同的结果!!当您的起点位于框的边界并且 angle 接近 π/2 的倍数时,这尤其成问题。 我建议您设置某种容差,例如 if abs(sin_angle) < 1e-12:,而不是 if sin_angle == 0:。这样,sin_angle = np.sin(np.pi) 将在 if 条件中被接受,即使它不完全等于 0(因为 np.sin(np.pi)1.2e-16 与 python)。