Search code examples
phpintersectionrectangles

Php - check if rectangles overlap


I am using the below mentioned code to find out if the rectangles on image map intersect or overlap but I am getting wrong results. Y coordinates increase from top towards bottom. The dimensions of rectangles vary.

$r1 = array('MapX1' => 10, 'MapX2' => 10, 'MapY1' => 30, 'MapY2' => 30);
$r2 = array( 'MapX1' => 20, 'MapX2' => 20, 'MapY1' => 50, 'MapY2' => 50);

function intersectRect($r1, $r2) {
        /*
        left: x1,
        right: x1 + x2,
        top: y1,
        bottom: y1 + y2,
      */

$r1['MapX2'] = $r1['MapX2'] - $r1['MapX1'];
$r2['MapX2'] = $r2['MapX2'] - $r2['MapX1'];

$r1['MapY1'] = $r1['MapY2'] - $r1['MapY1'];
$r2['MapY2'] = $r1['MapY2'] - $r1['MapY1'];

        $a = array('left' => $r1['MapX1'], 'right' => $r1['MapX1'] + $r1['MapX2'], 'top' => $r1['MapY1'], 
            'bottom' => $r1['MapY1'] + $r1['MapY2']);
        $b = array('left' => $r2['MapX1'], 'right' => $r2['MapX1'] + $r2['MapX2'], 'top' => $r2['MapY1'], 
            'bottom' => $r2['MapY1'] + $r2['MapY2']);
        if(
            $a['right'] < $b['left'] || 
            $a['left'] > $b['right'] || 
            $a['bottom'] < $b['top'] || 
            $a['top'] > $b['bottom']
          ){ 
            return 0;
    }
    else{
        return 1;
    }
}

echo intersectRect($r1, $r2);

Please help me figure out what am i doing wrong here?

The above code does not work correct for the below rectangles: Gives 1 but should return 0.

$r1 = array(
    [MapX1] => 536
    [MapX2] => 567
    [MapY1] => 199
    [MapY2] => 237
)
$r2 = array
(
    [MapX1] => 430
    [MapX2] => 453
    [MapY1] => 141
    [MapY2] => 153
)

Solution

  • After your comments and discussion on chat, it appears that you're expecting the X2 and Y2 values to be co-ordinates, but your code is treating them as widths and heights respectively.

    If you want the code to treat them as co-ordinates instead, your code would be changed to the following:

    $r1 = array('MapX1' => 536, 'MapX2' => 567, 'MapY1' => 199, 'MapY2' => 237);
    $r2 = array( 'MapX1' => 430, 'MapX2' => 453, 'MapY1' => 141, 'MapY2' => 153);
    
    function intersectRect($r1, $r2) {
        /*
        left: x1,
        right: x2,
        top: y1,
        bottom: y2,
      */
    
        $a = array('left' => $r1['MapX1'], 'right' => $r1['MapX2'], 'top' => $r1['MapY1'], 
            'bottom' => $r1['MapY2']);
        $b = array('left' => $r2['MapX1'], 'right' => $r2['MapX2'], 'top' => $r2['MapY1'], 
            'bottom' => $r2['MapY2']);
        if(
            $a['right'] < $b['left'] || 
            $a['left'] > $b['right'] || 
            $a['bottom'] < $b['top'] || 
            $a['top'] > $b['bottom']
          ){ 
            return 0;
        } else {
            return 1;
        }
    }
    
    echo intersectRect($r1, $r2);
    

    Note that I have changed the code where you are declaring $a and $b so that it takes the X2 and Y2 values directly, instead of adding them to the X1 and Y1 values. I've also used the rectangles that you added in the edit to your question, rather than the original rectangles you defined.