1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
""" 
Porting Rect's intersects to pure Python to avoid::
 
  terminated by signal SIGSEGV (Address boundary error)

When calling::

  block.hitbox.intersects(visible_rectangle)
"""

def get_rect_intersection(r1, r2):
    """
    Accept two sfml.graphics.Rect objects.
    Return a new sfml.graphics.Rect of the overlap or None.
    """

    # We allow Rects with negative dimensions, so handle them correctly.

    # Compute the min and max of the first Rect (r1).
    r1_min_x = min(r1.left, r1.left + r1.width)
    r1_max_x = max(r1.left, r1.left + r1.width)
    r1_min_y = min(r1.top, r1.top + r1.height)
    r1_max_y = max(r1.top, r1.top + r1.height)

    # Compute the min and max of the second Rect (r2).
    r2_min_x = min(r2.left, r2.left + r2.width)
    r2_max_x = max(r2.left, r2.left + r2.width)
    r2_min_y = min(r2.top, r2.top + r2.height)
    r2_max_y = max(r2.top, r2.top + r2.height)

    # compute the intersection boundaries.
    i_left   = max(r1_min_x, r2_min_x)
    i_top    = max(r1_min_y, r2_min_y)
    i_right  = min(r1_max_x, r2_max_x)
    i_bottom = min(r1_max_y, r2_max_y)

    # if the intersection is valid (positive non zero area),
    # then there is an intersection.
    if i_left < i_right and i_top < i_bottom:
        return sfml.graphics.Rect((i_left, i_top), (i_right - i_left, i_bottom - i_top))


# https://github.com/SFML/SFML/blob/ff011dc51dc47373b0d49b087f8ac9d3d2bc8b06/include/SFML/Graphics/Rect.inl#L108-L142
"""
template <typename T>
bool Rect<T>::intersects(const Rect<T>& rectangle, Rect<T>& intersection) const
{
    // Rectangles with negative dimensions are allowed, so we must handle them correctly

    // Compute the min and max of the first rectangle on both axes
    T r1MinX = std::min(left, static_cast<T>(left + width));
    T r1MaxX = std::max(left, static_cast<T>(left + width));
    T r1MinY = std::min(top, static_cast<T>(top + height));
    T r1MaxY = std::max(top, static_cast<T>(top + height));

    // Compute the min and max of the second rectangle on both axes
    T r2MinX = std::min(rectangle.left, static_cast<T>(rectangle.left + rectangle.width));
    T r2MaxX = std::max(rectangle.left, static_cast<T>(rectangle.left + rectangle.width));
    T r2MinY = std::min(rectangle.top, static_cast<T>(rectangle.top + rectangle.height));
    T r2MaxY = std::max(rectangle.top, static_cast<T>(rectangle.top + rectangle.height));

    // Compute the intersection boundaries
    T interLeft   = std::max(r1MinX, r2MinX);
    T interTop    = std::max(r1MinY, r2MinY);
    T interRight  = std::min(r1MaxX, r2MaxX);
    T interBottom = std::min(r1MaxY, r2MaxY);

    // If the intersection is valid (positive non zero area), then there is an intersection
    if ((interLeft < interRight) && (interTop < interBottom))
    {
        intersection = Rect<T>(interLeft, interTop, interRight - interLeft, interBottom - interTop);
        return true;
    }
    else
    {
        intersection = Rect<T>(0, 0, 0, 0);
        return false;
    }
}
"""