# Detect rectangle intersection in 3D

**URL:** <https://discourse.processing.org/t/detect-rectangle-intersection-in-3d/35201>\
**Category:** Coding Questions\
**Created:** [February 16, 2022, 9:53am UTC](https://discourse.processing.org/t/detect-rectangle-intersection-in-3d/35201 "2022-02-16T09:53:47Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![bruno.pace](https://avatars.discourse-cdn.com/v4/letter/b/b5a626/32.png) [@bruno.pace](https://discourse.processing.org/u/bruno.pace)\
**Post date:** [February 16, 2022, 9:53am UTC](https://discourse.processing.org/t/detect-rectangle-intersection-in-3d/35201/1 "2022-02-16T09:53:47Z")

</div>

Hi there,

I am writing a program to draw some white squares in 3D space and I would like that, where they intersect, a black line is shown. I can’t find an easy way to do that.

However, if I use different colors for the squares, the lines I want to draw appear between the colors like in the image below.

Can anyone help me find an easy solution?

Thank you very much!

 ![squares](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/8/80c164df7af4b7541792010ff2eabc31de7214d1.png)

```auto
float x,y,z,a,b ;
int num = 50 ; 
int side = 500;
int imax = 0; 
float y0 = 2./3;
int radius;

int previousDisplayTime; // Keep track of the last time a frame of the animation was displayed
int deltaTime; 

boolean sense = true;
boolean pause = false;

void setup() {
  size(1000,1000,P3D);
  lights();
  //ortho();
  y0 = height;///2+side/2;
  println(y0);
  x = width/2;
  y = y0;
  z = 0;
  a = 0;
  b = 0;
  
  directionalLight(255, 255, 255, 0, -1, -1);
  
  deltaTime = 100;
  previousDisplayTime = 0;  
  
  //float fov = PI/2;
  //float cameraZ = (4000) / tan(fov/2.0);
  //perspective(fov, float(width)/float(height), 
  // cameraZ/10.0, cameraZ*10.0);
}

void draw() {
  radius = side + mouseX;
  //lights();
  //stroke(220);
  stroke(255*1/4);
  //noStroke();
  background(220, 220, 220);  
  //background(255);
  //fill(255, 0, 0, 10);
  camera(//width, 0, width/3, // eyeX, eyeY, eyeZ
         width/2-10*width/4, height/2-10*width/4, radius-10*width/4,
         0, 0, 0,
         //3*width/4, width/4, width/8, // centerX, centerY, centerZ
         0.0, 1.0, 0.0);

  perspective(PI/3.0, float(width)/float(height), mouseX, 10*radius-100*width/4);//1, 25*radius);
  
  
  if ((millis() > previousDisplayTime + deltaTime) & sense & !pause) {
    imax++;
    if (imax > num) { 
      sense = false;
    }
    previousDisplayTime = millis();
  }

  if ((millis() > previousDisplayTime + deltaTime) & !sense & !pause) {
    imax--;
    if (imax < 0) { 
      sense = true;
    }
    previousDisplayTime = millis();
  }

  for (int i=0; i < imax; i++) {
      x = radius * cos(i*2*PI/num);
      y = radius * sin(i*2*PI/num); 
      drawSheet(i);
      //y-=side/(num-1); // The rectangle moves forward as z increments.
      a+=0.02*mouseX/width*20;
      b+=0.02*mouseY/width*20;
  }
  
  a = 0;
  b = 0;
  y = y0;
  x=width/2;

}

void mousePressed() {
 pause = !pause; 
}

void drawSheet(int i) {
  pushMatrix();
  translate(x,y,0);
  rectMode(CENTER);
  fill(255, random(255), random(255));
  //rotateX(-PI/6);
  //rotateY(PI/3);
  rotateX(PI/2);
  rotateY(2*PI/num*i);
  rotateZ(a);
  rotateY(b);
  rect(0,0,side,side);
  popMatrix();
}

```

---

<div class="post-metadata">

**Author:** ![scudly](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/scudly/32/5597_2.png) [@scudly](https://discourse.processing.org/u/scudly)\
**Post date:** [February 16, 2022, 5:02pm UTC](https://discourse.processing.org/t/detect-rectangle-intersection-in-3d/35201/2 "2022-02-16T17:02:13Z")

</div>

There isn’t a great easy solution, but this kinda works. At the bottom of your draw() add:

```auto
  loadPixels();
  for( int jj=0; jj<height-1; jj++ ) {
    for( int ii=0; ii<width-1; ii++ ) {
      int idx = jj*width+ii;
      if( pixels[idx] == 0 || pixels[idx+1] == 0 || pixels[idx+width] == 0 )
        continue;
      if( pixels[idx] != pixels[idx+1] || pixels[idx] != pixels[idx+width] )
        pixels[idx] = 0;
    }
  }
  updatePixels();

```

It does a crude edge detection that checks if each pixel is a different color from its neighbor to the right or below, then set to black. It can’t handle anti-aliasing, though, so your edges lose any smoothness. And if two squares are the same color, it won’t put an edge between them.

---

<div class="post-metadata">

**Author:** ![bruno.pace](https://avatars.discourse-cdn.com/v4/letter/b/b5a626/32.png) [@bruno.pace](https://discourse.processing.org/u/bruno.pace)\
**Post date:** [February 18, 2022, 6:45pm UTC](https://discourse.processing.org/t/detect-rectangle-intersection-in-3d/35201/3 "2022-02-18T18:45:00Z")

</div>

Thanks a lot for your reply. It would work indeed if I wanted to have the sheets in color. Since I need them all in white, it doesn’t work. Could you think of another solution for this problem, considering the color constraint? Also, the thickness of the lines change, it doesn’t really render well with this solution. Ideas?

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [February 18, 2022, 6:55pm UTC](https://discourse.processing.org/t/detect-rectangle-intersection-in-3d/35201/4 "2022-02-18T18:55:17Z")

</div>

> [@bruno.pace](#):
>
> Could you think of another solution for this problem, considering the color constraint?

when speed is not an issue you can modify the approach:

- Make a PGraphics pg, same size as your window.

- Draw the same rects on pg but with color.

- no anti-aliasing for the pg (because the approach can’t handle anti-aliasing) and no change of thickness of the lines (or use noStroke in the pg)

- (Don’t display the pg)

NOW use [scudly](https://discourse.processing.org/u/scudly)’s code on the pg instead.

---

<div class="post-metadata">

**Author:** ![scudly](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/scudly/32/5597_2.png) [@scudly](https://discourse.processing.org/u/scudly)\
**Post date:** [February 18, 2022, 8:24pm UTC](https://discourse.processing.org/t/detect-rectangle-intersection-in-3d/35201/6 "2022-02-18T20:24:14Z")

</div>

From your original code, draw the squares with noStroke() and let my code create the boundaries which will then be a more consistent, though not perfect, thickness.

Do a second pass that turns everything that is NOT black to white.

---

<div class="post-metadata">

**Author:** ![bruno.pace](https://avatars.discourse-cdn.com/v4/letter/b/b5a626/32.png) [@bruno.pace](https://discourse.processing.org/u/bruno.pace)\
**Post date:** [February 19, 2022, 3:50pm UTC](https://discourse.processing.org/t/detect-rectangle-intersection-in-3d/35201/7 "2022-02-19T15:50:12Z")

</div>

Hey @Chrisir @scudly, thanks for your help. It works! Here is the integrated code, the rendering is almost perfect.

```auto
PGraphics pg;

float x,y,z,a,b ;
int num = 500 ; 
int side = 500;
int imax = 0; 
float y0 = 2./3;
int radius;

int previousDisplayTime; // Keep track of the last time a frame of the animation was displayed
int deltaTime; 

boolean sense = true;
boolean pause = false;

void setup() {
  size(1000,1000,P3D);
  pg = createGraphics(1000, 1000, P3D);
  pg.noSmooth();
  pg.noStroke();
  lights();
  y0 = height;
  println(y0);
  x = width/2;
  y = y0;
  z = 0;
  a = 0;
  b = 0;
  
  directionalLight(255, 255, 255, 0, -1, -1);
  
  deltaTime = 100;
  previousDisplayTime = 0;  

}

void draw() {
  radius = side + mouseX;
  stroke(255*1/4);
  background(220, 220, 220);  
  

  pg.loadPixels();
  for (int i = 0; i < (width*height); i++) {
    pg.pixels[i] = color(220,220,220);
  }
  pg.updatePixels();  
  
  camera(
         width/2-10*width/4, height/2-10*width/4, radius-10*width/4,
         0, 0, 0,
         0.0, 1.0, 0.0);
  pg.camera(
         width/2-10*width/4, height/2-10*width/4, radius-10*width/4,
         0, 0, 0,
         0.0, 1.0, 0.0);

  perspective(PI/3.0, float(width)/float(height), mouseX, 10*radius-100*width/4);//1, 25*radius);
  pg.perspective(PI/3.0, float(width)/float(height), mouseX, 10*radius-100*width/4);//1, 25*radius);
  
  if ((millis() > previousDisplayTime + deltaTime) & sense & !pause) {
    imax++;
    if (imax > num) { 
      sense = false;
    }
    previousDisplayTime = millis();
  }

  if ((millis() > previousDisplayTime + deltaTime) & !sense & !pause) {
    imax--;
    if (imax < 0) { 
      sense = true;
    }
    previousDisplayTime = millis();
  }

  pg.beginDraw();
  for (int i=0; i < imax; i++) {
      x = radius * cos(i*2*PI/num);
      y = radius * sin(i*2*PI/num); 
      drawSheet(i);
      a+=0.02*mouseX/width*20;
      b+=0.02*mouseY/width*20;
  }
  pg.endDraw();
  
  a = 0;
  b = 0;
  y = y0;
  x=width/2;

  pg.loadPixels();
  loadPixels();
  for( int jj=0; jj<height-1; jj++ ) {
    for( int ii=0; ii<width-1; ii++ ) {
      int idx = jj*width+ii;
      if( pg.pixels[idx] == 0 || pg.pixels[idx+1] == 0 || pg.pixels[idx+width] == 0 )
        continue;
      if( pg.pixels[idx] != pg.pixels[idx+1] || pg.pixels[idx] != pg.pixels[idx+width] )
        pixels[idx] = color(100,100,100);
    }
  }
  updatePixels();

}

void mousePressed() {
 pause = !pause; 
}

void drawSheet(int i) {
  pushMatrix();
  translate(x,y,0);
  rectMode(CENTER);
  noStroke();
  fill(255);
  rotateX(PI/2);
  rotateY(2*PI/num*i);
  rotateZ(a);
  rotateY(b);
  rect(0,0,side,side);
  popMatrix();
  
  pg.pushMatrix();
  pg.translate(x,y,0);
  pg.rectMode(CENTER);
  pg.noStroke();
  pg.fill(255, random(255), random(255));//, random(255), random(255));
  pg.rotateX(PI/2);
  pg.rotateY(2*PI/num*i);
  pg.rotateZ(a);
  pg.rotateY(b);
  pg.rect(0,0,side,side);
  pg.popMatrix();
}

```

 ![Screenshot from 2022-02-19 16-41-00](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/9/9a2ef8a4aa21da7f8f78b7fc2506f07679668481.png)
