How do I see if two rectangles intersect in JavaScript or pseudocode?

后端 未结 5 2179
孤城傲影
孤城傲影 2021-02-19 04:53

I have two rectangles which I must return in a function whether they intersect or not.

They are represented by [ x0, y0, x1, y1 ] pairs that represent the t

相关标签:
5条回答
  • 2021-02-19 05:31

    Two rectangles are overlapping if both the x and the y areas Overlap. If any of the x co-ordinates overlap the other rectangles, then there will be an over lap.

    Along the x axis, either the first point is within the other two rectangles, the second point is within the other two, or two points are on opposite sides of the other points.

    function checkRectOverlap(rect1, rect2) {
        /*
         * Each array in parameter is one rectangle
         * in each array, there is an array showing the co-ordinates of two opposite corners of the rectangle
         * Example:
         * [[x1, y1], [x2, y2]], [[x3, y3], [x4, y4]]
         */
    
        //Check whether there is an x overlap
        if ((rect1[0][0] < rect2[0][0] && rect2[0][0] < rect1[1][0]) //Event that x3 is inbetween x1 and x2
            || (rect1[0][0] < rect2[1][0] && rect2[1][0] < rect1[1][0]) //Event that x4 is inbetween x1 and x2
            || (rect2[0][0] < rect1[0][0] && rect1[1][0] < rect2[1][0])) {  //Event that x1 and x2 are inbetween x3 and x4
            //Check whether there is a y overlap using the same procedure
            if ((rect1[0][1] < rect2[0][1] && rect2[0][1] < rect1[1][1]) //Event that y3 is between y1 and y2
                || (rect1[0][1] < rect2[1][1] && rect2[1][1] < rect1[1][1]) //Event that y4 is between y1 and y2
                || (rect2[0][1] < rect1[0][1] && rect1[1][1] < rect2[1][1])) { //Event that y1 and y2 are between y3 and y4
                return true;
            }
        }
        return false;
    }
    
    0 讨论(0)
  • 2021-02-19 05:32

    A look at the matter from a different site.

    The case turns out to be quite simple if we look at the problem (algorithm) from the other side.

    It means that instead of answering the question: "Are the rectangles overlap?", we will answer the question: "Are the rectangles do not overlap?".

    In the end, both questions resolve the same problem but the answer to the second question is simpler to implement because rectangles do not overlap only when one is under the other or when one is more to the left of the other (it is enough for one of these cases to take place, but of course it may happen that both will happen simultaneously - here a good understanding of the logical condition "or" is important). This reduces many cases that need to be considered on the first question.

    The whole matter is also simplified by the use of appropriate variable names:

    const areRectanglesOverlap = (rect1, rect2) => {
      let [left1, top1, right1, bottom1] = [rect1[0], rect1[1], rect1[2], rect1[3]],
          [left2, top2, right2, bottom2] = [rect2[0], rect2[1], rect2[2], rect2[3]];
      // The first rectangle is under the second or vice versa
      if (top1 < bottom2 || top2 < bottom1) {
        return false;
      }
      // The first rectangle is to the left of the second or vice versa
      if (right1 < left2 || right2 < left1) {
        return false;
      }
      // Rectangles overlap
      return true;
    }
    

    Even if we have a different representation of a rectangle, it is easy to adapt the above function to it by modifying only the section where the variables changes are defined. The further part of the function remains unchanged (of course, the comments are not really needed here, but I added them so that everyone could quickly understand this simple algorithm).

    An equivalent but maybe a little less readable form of the above function may look like this:

    const areRectanglesOverlap = (rect1, rect2) => {
    
      let [left1, top1, right1, bottom1] = [...rect1],
          [left2, top2, right2, bottom2] = [...rect2];
      
      return !(top1 < bottom2 || top2 < bottom1 || right1 < left2 || right2 < left1);
    }
    
    0 讨论(0)
  • 2021-02-19 05:38

    Give rectangle 1 with points UL1 and LR1 and rectangle 2 with points UR2 and LR2 -

    Check if UL1 is in r2 or LR1 is in r2 (case 1 and case 2 in diagram). Finally check if one of UR2 / LR2 is in r1 (case 3 in diagram).

    You check if a point is in a rectangle by checking that x and y are between min and max of a rectangles' x and y range.

    Clear?

    enter image description here

    Blue is R1, Purple is R2

    0 讨论(0)
  • 2021-02-19 05:41

    Update

    After a time I decided to redo a complete answer about detecting collision between 2 rotated rectangles: How to detect when rotated rectangles are colliding each other


    Original Answer

    If you want to check if 2 rotated rectangles collide you have to make projection of one rectangle corner on the axes of the other. If all projections of rectA hit the rectB, and rectB projections hit rectA then the two rectangles collide.

    Some projection don't collide here, the 2 rectangles are not collide. enter image description here

    The 4 projections hit the other rectangle, the 2 rectangles are collide. enter image description here

    I have made a presentation on this JSFiddle for more comprehension.

    You can check the function is_collide for more example

    0 讨论(0)
  • 2021-02-19 05:43

    Check for the cases where the rectangles are definitely not intersecting. If none of these cases are true then the rectangles must intersect. i.e.:

    public boolean rectanglesIntersect( 
        float minAx, float minAy, float maxAx, float maxAy,
        float minBx, float minBy, float maxBx, float maxBy ) {
        boolean aLeftOfB = maxAx < minBx;
        boolean aRightOfB = minAx > maxBx;
        boolean aAboveB = minAy > maxBy;
        boolean aBelowB = maxAy < minBy;
    
        return !( aLeftOfB || aRightOfB || aAboveB || aBelowB );
    }
    

    This illustrates the concept but could be made slightly faster by inlining the booleans so as to take advantage of the short-circuiting behavior of ||

    0 讨论(0)
提交回复
热议问题