'shortest distance between a point and a rectangle based on numpy implementation
Goal:
For a point a and a rectangle B, I would like to calculate the shortest distance between these two objects.
Motivation
Because this calculation is part of the innermost loop of multiple loops, I would like to optimize this calculation as much as possible. With my current python knowledge, making use of dedicated NumPy functions should be the way to goal(?).
Some more details:
- The situation is 2D;
x,ycoordinates - rectangle
Bis defined by a certain center-of-gravity/mid-point, and width and length (And thus not by a vector of points) - the distance is thus from
ato the edges of the rectangleB
My current implementation makes use of the following idea: link. Here the rectangle is divided into multiple subareas. First, it is determined inside which sub-area of B a is located. Hereafter, the calculating the shortest distance between a and B is then straightforward. However, a lot of logic checking is required to determine inside which sub-area a is located. It looks something as following,
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
Ideally,
- I would like to have an alternative/faster logic checking (Python improvement) or
- a faster mathematical algorithm
Maybe...?
One possible alternative I came up with while writing this question, is to calculate a discrete amount of n points based on Bs chaterestics. From this vector of n points I think it is quite easy use NumPy to:
- calculate the shortest distance between
aand each point of thenpoints - find the smallest value of this new vector
For a larger n, this solution would become more precise with a higher performance cost. Do you think this could be a better solution? Or do you have any suggestions for a mathematical (and no approximation) algorithm?
EDIT: added extra clarification, that the distance is towards the edges of the rectangle B
Solution 1:[1]
I think, this is a nice implementation of the distance function:
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)
I don't know, how well the Python interpreter translates this code. It is possible, to implement this approach completely branchless, which is a nice property for optimized code.
If you want to compare one point to many rectangles (1:n), you could store all rectangles in a numpy array and compare your point to all rectangles at once using numpy array functions. The same would be possible for n:1 comparison. This could greatly speed up the process!
Without knowing more about your loops I can't provide such a solution, though.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Florian Metzger-Noel |
