2012-02-17 2 views
27

У меня есть два прямоугольника a и b с их сторонами, параллельными осям системы координат. У меня есть их координаты как x1, y1, x2, y2.Как много перекрываются два прямоугольника?

Я пытаюсь определить, они не только перекрываются, но и как они перекрывают друг друга? Я пытаюсь выяснить, действительно ли они представляют собой один и тот же прямоугольник, или взять немного комнаты для маневра. Так же их площадь равна 95%?

Любая помощь при вычислении% перекрытия?

+1

Что вы придумали до сих пор? – Gumbo

+0

Вы хотите сказать, что 2 прямоугольника находятся в ящике с заданными координатами? – sgowd

+0

@ sans481 Да, я исправил вопрос спасибо. –

ответ

19

формула для пересечения будет

SI= Max(0, Min(XA2, XB2) - Max(XA1, XB1)) * Max(0, Min(YA2, YB2) - Max(YA1, YB1)) 

то объединение будет S=SA+SB-SI

И, наконец, коэффициент ш ill be SI/S.

+0

Отношение должно быть 'SI/S' – warmspringwinds

+0

@warmspringwinds: Я согласен – Joko

+14

Хммм. Этот ответ выглядит более или менее идентичным наивысшему рейтингу, который предшествует этому почти на два года. , , – imallett

50

Compute область пересечения, которая представляет собой прямоугольник тоже:

SI = Max(0, Max(XA2, XB2) - Min(XA1, XB1)) * Max(0, Max(YA2, YB2) - Min(YA1, YB1)) 

Оттуда вычислить площадь штуцера:

SU = SA + SB - SI 

И вы можете рассмотреть соотношение

SI/SU 

(100% при идеальном перекрытии, до 0%).

+0

ничего себе. Именно это я и поблагодарил! Я не думал об этом правильно. Введение концепции профсоюза - это то, чего я не хватало. Благодаря!. –

+0

Спасибо, человек! Работает как шарм. – skrat

+0

Является ли SA и SB областью A и B? И для SI, чем больше я перемещаю свой прямоугольник в правое нижнее, тем выше значения. – clankill3r

5

Я недавно столкнулся с этой проблемой и применил ответ Ив, но почему-то это привело к неправильному размеру области, поэтому я переписал ее.

Предполагая два прямоугольника А и В, выяснить, насколько они перекрывают друг друга, и если да, то возвращает размер области:

IF A.right < B.left OR A.left > B.right 
    OR A.bottom < B.top OR A.top > B.bottom THEN RETURN 0 

width := IF A.right > B.right THEN B.right - A.left ELSE A.right - B.left 
height := IF A.bottom > B.bottom THEN B.bottom - A.top ELSE A.bottom - B.top 

RETURN width * height 
4

Если предположить, что прямоугольник должен быть параллелен x и y оси, что, как представляется, ситуация из предыдущих комментариев и ответов.

Я еще не могу написать комментарий, но я хотел бы указать, что оба предыдущих ответа, похоже, игнорируют случай, когда один боковой прямоугольник полностью находится в стороне от другого прямоугольника. Пожалуйста, поправьте меня, если я ошибаюсь.

Рассмотрим случай

a: (1,1), (4,4) 
b: (2,2), (5,3) 

В этом случае мы видим, что для пересечения, высота должна быть bTop - bBottom, так как вертикальная часть b целиком содержится в a.

Нам просто нужно добавить еще несколько случаев: (код может быть закорочен, если вы обрабатываете верх и низ как то же самое, что и правое и левое, так что вам не нужно дублировать условный фрагмент дважды, но это должен делать.)

if aRight <= bLeft or bRight <= aLeft or aTop <= bBottom or bTop <= aBottom: 
    # There is no intersection in these cases 
    return 0 
else: 
    # There is some intersection 

    if aRight >= bRight and aLeft <= bLeft: 
     # From x axis point of view, b is wholly contained in a 
     width = bRight - bLeft 
    elif bRight >= aRight and bLeft <= aLeft: 
     # From x axis point of view, a is wholly contained in b 
     width = aRight - aLeft 
    elif aRight >= bRight: 
     width = bRight - aLeft 
    else: 
     width = aRight - bLeft 

    if aTop >= bTop and aBottom <= bBottom: 
     # From y axis point of view, b is wholly contained in a 
     height = bTop - bBottom 
    elif bTop >= aTop and bBottom <= aBottom: 
     # From y axis point of view, a is wholly contained in b 
     height = aTop - aBottom 
    elif aTop >= bTop: 
     height = bTop - aBottom 
    else: 
     height = aTop - bBottom 

return width * height 
3

Просто фиксации предыдущих ответов, так что отношение находится между 0 и 1 (с использованием Python):

# (x1,y1) top-left coord, (x2,y2) bottom-right coord, (w,h) size 
    A = {'x1': 0, 'y1': 0, 'x2': 99, 'y2': 99, 'w': 100, 'h': 100} 
    B = {'x1': 0, 'y1': 0, 'x2': 49, 'y2': 49, 'w': 50, 'h': 50} 

    # overlap between A and B 
    SA = A['w']*A['h'] 
    SB = B['w']*B['h'] 
    SI = np.max([ 0, 1 + np.min([A['x2'],B['x2']]) - np.max([A['x1'],B['x1']]) ]) * np.max([ 0, 1 + np.min([A['y2'],B['y2']]) - np.max([A['y1'],B['y1']]) ]) 
    SU = SA + SB - SI 
    overlap_AB = float(SI)/float(SU) 
    print 'overlap between A and B: %f' % overlap_AB 

    # overlap between A and A 
    B = A 
    SB = B['w']*B['h'] 
    SI = np.max([ 0, 1 + np.min([A['x2'],B['x2']]) - np.max([A['x1'],B['x1']]) ]) * np.max([ 0, 1 + np.min([A['y2'],B['y2']]) - np.max([A['y1'],B['y1']]) ]) 
    SU = SA + SB - SI 
    overlap_AA = float(SI)/float(SU) 
    print 'overlap between A and A: %f' % overlap_AA 

Выходной сигнал будет:

overlap between A and B: 0.250000 
    overlap between A and A: 1.000000 
+0

Примечание. В этом ответе используется NumPy. – rayryeng

2

@ User3025064 является правильным и является самым простым решением , однако, исключительность должна быть проверена сначала для прямоугольников, которые не пересекаются, например, для прямоугольников A & B (на Visual Basic):

If A.Top =< B.Bottom or A.Bottom => B.Top or A.Right =< B.Left or A.Left => B.Right then 
    Exit sub 'No intersection 
else 
    width = ABS(Min(XA2, XB2) - Max(XA1, XB1)) 
    height = ABS(Min(YA2, YB2) - Max(YA1, YB1)) 
    Area = width * height  'Total intersection area. 
End if 
2
[ymin_a, xmin_a, ymax_a, xmax_a] = list(bbox_a) 
[ymin_b, xmin_b, ymax_b, xmax_b] = list(bbox_b) 

x_intersection = min(xmax_a, xmax_b) - max(xmin_a, xmin_b) + 1 
y_intersection = min(ymax_a, ymax_b) - max(ymin_a, ymin_b) + 1 

if x_intersection <= 0 or y_intersection <= 0: 
    return 0 
else: 
    return x_intersection * y_intersection 
1

Ответ на вопрос @ user3025064 - правильный ответ. Принятый ответ непреднамеренно переворачивает внутренние MAX и MIN звонки. Нам также не нужно сначала проверять, пересекаются они или нет, если мы используем представленную формулу MAX (0, x) в отличие от ABS (x). Если они не пересекаются, MAX (0, x) возвращает ноль, что делает область пересечения 0 (т.е. дизъюнктной).

Я предлагаю, чтобы @Yves Daoust исправил свой ответ, потому что он принят, который появляется всем, кто ищет эту проблему. Еще раз, здесь правильную формулу для пересечения:

SI = Max(0, Min(XA2, XB2) - Max(XA1, XB1)) * Max(0, Min(YA2, YB2) - Max(YA1, YB1))

Остальное как обычно. Союз:

SU = SA + SB - SI

и соотношение:

SI/SU

+1

вы уверены? Я обновил правильный ответ, основываясь на ваших советах, но 30 человек предложили, чтобы Ив был правильным ответом, поэтому я надеюсь, что вы можете дважды проверить свое предположение для меня. Благодарю. –

+0

Попробуйте этот пример счетчика: два прямоугольника, которые не перекрываются, поэтому 'XA1 Hazem