Search code examples
javascriptprocessingp5.js

Changing color of intersecting area of squares


I am working on a project these days. My goal is to change the color of the intersecting areas of the two squares. I have written the code which detects whenever two squares intersect but I cant figure out how to change the color of the intersecting area. Kindly help me with this.

    var sketch = function (p) {
      with(p) {

        let squares = [];
        let dragObject = null; // variable to hold the object being dragged

        p.setup = function() {
          createCanvas(600, 520);
          button1 = createButton("Alpha");
          button2 = createButton("Bravo");
          button3 = createButton("Charlie");
          button4 = createButton("Delta");
          button5 = createButton("Echo");
          button6 = createButton("Foxtrot");
          button7 = createButton("Golf");
          button8 = createButton("Hotel");
          button9 = createButton("India");
          button10 = createButton("Juliet");

          button1.mousePressed(doSomething);
        };
    
        p.draw = function() {

          background(25, 240, 255);

          // if a square is being dragged, update its position
          if (this.dragObject != null) {
            this.dragObject.position.x = mouseX;
            this.dragObject.position.y = mouseY;
          }

          //draw all squares
          for (let i = 0; i < squares.length; i++) {
            let s = squares[i];
            s.show();
          }
          for (let i = 0; i < squares.length; i++) {
            for (let j = i + 1; j < squares.length; j++) {
              if (i != j && squares[i].collides(squares[j])) {
                squares[i].changecolor();

              }
            }
          }
        };

        p.mousePressed = function () {

          if (this.dragObject == null) {

            //ask every square if they are being "hit"
            for (let i = 0; i < squares.length; i++) {
              let s = squares[i];
              if (s.hitTest()) {
                //if so, set the drag object as this square and return
                this.dragObject = s;
                return;
              }
            }

            //no squares are hit, create a new square.
            let square = new Square(mouseX, mouseY);
            squares.push(square);
          }
        };

        //mouse is released, release the current dragged object if there is one
        p.mouseReleased = function () {
          this.dragObject = null;
        };

        class Square {
          constructor(InitialX, InitialY) {
            this.w = 60;
            this.h = 60;
            this.position = {
              x: InitialX,
              y: InitialY
            };
          }

          //basic test of mouse position against square position and if its inside the rectangle
          hitTest() {
            let x = mouseX - this.position.x;
            let y = mouseY - this.position.y;
            return (x > 0 && x < this.w) && (y > 0 && y < this.h);
          }

          show() {
            fill(50);
            rect(this.position.x, this.position.y, this.w, this.h);
          }

          collides(sqr) {
            if (this.position.x < sqr.position.x + sqr.w &&
              this.position.x + this.w > sqr.position.x &&
              this.position.y < sqr.position.y + sqr.h &&
              this.position.y + this.h > sqr.position.y) {

              return true;
            }
            return false;
          }

          changecolor() {
            fill(random(255), random(255), random(255));
            background(200, 255, 100);
            for (let i = 0; i < squares.length; i++) {
              let s = squares[i];
              s.show();
            }
          }
        }

        function doSomething() {
          // fill(230, 170, 90);
          // ellipse(random(600), random(410), 30, 30);
          squares.pop();
        }

     
      }
    };
    
    let node = document.createElement('div');
    window.document.getElementById('p5-container').appendChild(node);
    new p5(sketch, node);
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.1.9/p5.js"></script>
<div id="p5-container"></div>


Solution

  • Lets think a bit how we could represent the intersecting area between two squares. Surely, one of the ways to do is simply to represent it as another rectangle, whose color we simply change based on the intercepting area. To draw a rectangle, we need to know the coordinates of the upper left corner, the width and the height. Therefore the challenge is to calculate those as we drag our squares around. This should be done in the draw() function. You already have the intersection check implemented, whats left is to calculate the new rectangle upper left point (newX, newY), width (newW) and height (newH).

    enter image description here

    In order to calculate the upper left corner, the width and height, we can add this to the block where we check for collision:

      ...
      //block checking collision
      if (i != j && squares[i].collides(squares[j])) {
        squares[i].changecolor();
    
        //set intersection color
        fill(50);
    
        //calculate parameters
        newX = Math.max(squares[i].position.x, squares[j].position.x);
        newY = Math.max(squares[i].position.y, squares[j].position.y);
    
        newW = Math.min(squares[i].position.x + squares[i].w, squares[j].position.x + squares[j].w) - newX;
        newH = Math.min(squares[i].position.y + squares[i].h, squares[j].position.y + squares[j].h) - newY;
    
        //draw rectangle
        rect(newX, newY, newW, newH);
      }
    

    Result:

    enter image description here