3

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>
Dominique Fortin
  • 2,212
  • 15
  • 20
Osama Younus
  • 115
  • 1
  • 8
  • Add the code into your question, not as an external link that could be dead/broken in the future. – Cleptus Jul 05 '19 at 12:15
  • Welcome to StackOverflow. Please take the [tour](http://stackoverflow.com/tour) have a look around, and read through the [HELP center](http://stackoverflow.com/help), then read [How to Ask Question](http://stackoverflow.com/help/how-to-ask), [What types of questions should I avoid asking?](http://stackoverflow.com/help/dont-ask) and provide a [MCVE: Minimal, Complete, and Verifiable Example](http://stackoverflow.com/help/mcve). If people around can easily read and understand what you mean, or what the problem is, they'll be more likely willing to help:) – Dwhitz Jul 05 '19 at 12:17
  • We have created you a snippet. Please fix it so it is a [mcve] by adding createCanvas and call setup – mplungjan Jul 05 '19 at 12:21
  • A bunch of code makes others hard to contribute/help. Consider, emphasis on *minimal*, creating a [mcve] – Cleptus Jul 05 '19 at 12:27
  • Hey. I am new here so I am not sure what you mean by minimal code and what should I do. – Osama Younus Jul 05 '19 at 12:27

1 Answers1

6

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

vs97
  • 5,765
  • 3
  • 28
  • 41
  • Is it possible to assign different colors to the new rectangle at different times. My idea was that the buttons down bellow represent colors and the fill color is set to that particular color when the rectangle is made? – Osama Younus Jul 08 '19 at 08:12
  • Also whenever new squares intersect the old rectangle goes away. I want it to stay. – Osama Younus Jul 08 '19 at 08:38
  • 1
    About the colors: you could have something like a global color defined on top of your code, which you change with a button click and feed it into the fill() function before the calculating parameters code. If you're struggling, would be a good idea to open a new question, as its a different problem. – vs97 Jul 08 '19 at 08:41
  • 1
    About the new intersecting squares: the idea would be the same as just two squares intercepting - instead of drawing one "interception" triangle, you would have to draw 2, 3, 4, for example. Again, you have everything in the code above to achieve this - if you need help, please ask a separate question and we can go from there. – vs97 Jul 08 '19 at 08:43