Давайте сначала упростим вашу проблему до одного измерения:
У вас есть интервал A = [a0, a1]
, и вы хотите узнать, насколько другой интервал B = [b0, b1]
пересекает его. Я буду представлять A
знаком =
и B
-
.
Есть 6 возможных сценариев:
A
содержит B
, intersection = b1 - b0
a0 b0 b1 a1
==============
------
B
содержит A
, intersection = a1 - a0
b0 a0 a1 b1
======
--------------
B
пересекает A
слева, intersection = b1 - a0
b0 a0 b1 a1
==========
----------
B
пересекает A
справа, intersection = a1 - b0
a0 b0 a1 b1
==========
----------
B
находится слева от A
, intersection = 0
b0 b1 a0 a1
======
------
B
находится справа от A
, intersection = 0
a0 a1 b0 b1
======
------
Исходя из этого, мы можем определить функцию, которая, учитывая два интервала A = [a0, a1]
и B = [b0, b1]
, возвращает, насколько они пересекаются:
def calculateIntersection(a0, a1, b0, b1):
if a0 >= b0 and a1 <= b1: # Contained
intersection = a1 - a0
elif a0 < b0 and a1 > b1: # Contains
intersection = b1 - b0
elif a0 < b0 and a1 > b0: # Intersects right
intersection = a1 - b0
elif a1 > b1 and a0 < b1: # Intersects left
intersection = b1 - a0
else: # No intersection (either side)
intersection = 0
return intersection
Это почти все, что вам нужно. Чтобы узнать, насколько пересекаются два прямоугольника, вам просто нужно выполнить эту функцию как по оси X
, так и по оси Y
и умножить эти суммы, чтобы получить площадь пересечения:
# The rectangle against which you are going to test the rest and its area:
X0, Y0, X1, Y1, = [0, 0, 10, 10]
AREA = float((X1 - X0) * (Y1 - Y0))
# Rectangles to check
rectangles = [[15, 0, 20, 10], [0, 15, 10, 20], [0, 0, 5, 5], [0, 0, 5, 10], [0, 5, 10, 100], [0, 0, 100, 100]]
# Intersecting rectangles:
intersecting = []
for x0, y0, x1, y1 in rectangles:
width = calculateIntersection(x0, x1, X0, X1)
height = calculateIntersection(y0, y1, Y0, Y1)
area = width * height
percent = area / AREA
if (percent >= 0.5):
intersecting.append([x0, y0, x1, y1])
В результате получится:
[15, 0, 20, 10]
не пересекается по оси X, поэтому width = 0
.
[0, 15, 10, 20]
не пересекается по оси Y, поэтому height = 0
.
[0, 0, 5, 5]
пересекает только 25%
.
[0, 0, 5, 10]
пересекает 50%
и будет добавлен к intersecting
.
[0, 5, 10, 100]
пересекает 50%
и будет добавлен к intersecting
.
[0, 0, 100, 100]
пересекает 100%
и будет добавлен к intersecting
.
person
Danziger
schedule
31.01.2018