Calculate distance to rectange border

Use negative numbers to denote distance to the border from inside the
rectangle.
This commit is contained in:
Arjan Molenaar 2022-03-17 20:53:16 +01:00
parent c05f47db4a
commit 509dbb948c
2 changed files with 26 additions and 5 deletions

View File

@ -291,26 +291,38 @@ def distance_point_point_fast(point1: Point, point2: Point = (0.0, 0.0)) -> floa
return abs(dx) + abs(dy)
def distance_rectangle_point(rect: Rect | Rectangle, point: Point) -> float:
def distance_rectangle_border_point(rect: Rect | Rectangle, point: Point) -> float:
"""Return the distance (fast) from a rectangle ``(x, y, width,height)`` to
a ``point``."""
dx = dy = 0.0
px, py = point
rx, ry, rw, rh = rect # typing: ignore[misc]
rx1 = rx + rw
ry1 = ry + rh
if rx < px < rx1 and ry < py < ry1:
return -min(px - rx, rx1 - px, py - ry, ry1 - py)
if px < rx:
dx = rx - px
elif px > rx + rw:
dx = px - (rx + rw)
elif px > rx1:
dx = px - rx1
if py < ry:
dy = ry - py
elif py > ry + rh:
dy = py - (ry + rh)
elif py > ry1:
dy = py - ry1
return abs(dx) + abs(dy)
def distance_rectangle_point(rect: Rect | Rectangle, point: Point) -> float:
"""Return the distance (fast) from a rectangle ``(x, y, width,height)`` to
a ``point``."""
d = distance_rectangle_border_point(rect, point)
return 0 if d < 0 else d
def point_on_rectangle(
rect: Rect | Rectangle, point: Point, border: bool = False
) -> Point:

View File

@ -5,6 +5,7 @@ import pytest
from gaphas.geometry import (
Rectangle,
distance_line_point,
distance_rectangle_border_point,
distance_rectangle_point,
intersect_line_line,
point_on_rectangle,
@ -72,6 +73,14 @@ def test_distance_with_negative_numbers_in_rectangle():
assert distance_rectangle_point((-50, -100, 100, 100), (-17, -65)) == 0
def test_distance_rectangle_border_point():
assert distance_rectangle_border_point((2, 0, 2, 2), (0, 0)) == 2
assert distance_rectangle_border_point(Rectangle(0, 0, 10, 10), (11, -1)) == 2
assert distance_rectangle_border_point((0, 0, 10, 10), (11, -1)) == 2
assert distance_rectangle_border_point((0, 0, 10, 10), (3, 4)) == -3
assert distance_rectangle_border_point((0, 0, 2, 2), (1, 1)) == -1
def test_point_on_rectangle():
assert point_on_rectangle((2, 2, 2, 2), (0, 0)) == (2, 2)
assert point_on_rectangle((2, 2, 2, 2), (3, 0)) == (3, 2)