Square with resizeable rectangles inside

Hi Guys,
i’m pretty new with processing and have a problem:

I need a square with different squares in it. These should be changeable in size, but not smaller than a certain minimum size. I have tried different approaches, but always fail because of the minimum size.
Do you have any idea how I can solve this problem? Unfortunately I lack the experience to abstract the problem in Java.

If u will i can share my current state, but i think my code is to static to use a lot of it.

Sorry about my english, greets from germany.

Best regards, BooWseR

1 Like

Hello,

https://processing.org/reference/rect_.html
https://processing.org/reference/random_.html
https://processing.org/examples/constrain.html
https://processing.org/reference/constrain_.html

Post what you have so far.

Hint:

    rectMode(CENTER);
    rect(x, y, w, h);

:slight_smile:

1 Like

can these little rect inside the big rect overlap each other?
if not it might be tricky, like
random_rect_in_rect_no_overlap

Hey guys, thanks for your reply.

Thanks for that hint, but im not as new as i dont know that. :smiley:

Not really. There is also a dependency between the squares, which causes me some difficulties. I tried to work with a kind of snapshot and in case of an error I dropped back to the previous coordinate. Unfortunately, I also have problems to create a connection between the squares, because they are basically own objects.

My code is a bit WIP because I tried many things:

ClassRect
class ClassRect {
 
  float x1, y1, rectWidth, rectHeight;
  int col;
  
  float xOld, yOld;
  float wOld, hOld;
 
  ClassRect (float x1_, float y1_, float rectWidth_, float rectHeight_, int col_) 
  {
    //Pos
    x1=x1_;
    y1=y1_;
   
    //Size
    rectWidth=rectWidth_;
    rectHeight=rectHeight_;
    
    //Color
    col = col_;
  }
  
  //Fallback
  void snapshot() {
    this.xOld = this.x1;
    this.yOld = this.y1;
    this.wOld = this.rectWidth;
    this.hOld = this.rectHeight;
  }
  
  void reset() {
    this.x1         = this.xOld;
    this.y1         = this.yOld;
    this.rectWidth  = max(this.wOld, 10);
    this.rectHeight = max(this.hOld, 10);
  }
  
  void moveTo(int x, int y)
  {
    this.snapshot();
    this.x1 = x;
    this.y1 = y;
  }
  
  boolean intersects(ClassRect other)
  {
    return (
      this.x1 - this.rectWidth/2 < other.x1 + other.rectWidth/2 &&
      this.x1 + this.rectWidth/2 > other.x1 - other.rectWidth/2 &&
      this.y1 - this.rectHeight/2 < other.y1 + other.rectHeight/2 &&
      this.y1 + this.rectHeight/2 > other.y1 - other.rectHeight/2
    );
  }

  boolean intersects(int x, int y)
  {
    return (this.x1 - this.rectWidth/2 < x && x < this.x1 + this.rectWidth/2) && (this.y1 - this.rectHeight/2 < y && y < this.y1 + this.rectHeight/2);
  }

 
  void draw() {
    fill(colors[col]);
    if (rectWidth <= 10) {rectWidth = 11;}
    if (rectHeight <= 10) {rectHeight = 11;}
    rect(x1, y1, rectWidth, rectHeight);
  }
}
MainClass
ClassRect lines [] = new ClassRect [7];  //Initiale Anzahl der Rechtecke
ClassRect old_lines[] = new ClassRect [7];
color[] colors     = new color[10];      //Initiale Anzahl der Farben
int range          = 25;                 //Definiert Toleranz zum Klicken auf Linie in Pixeln
int outer_border   = 800;                //Variable um die auessere Grenze zu definieren. Notloesung

boolean line1_h, line2_h, line3_h, line1_v, line2_v;

void setup()
{
  //Initialisierung
  //Fenstergroesse
  size(1000, 1000);
  
  //Farben
  colors[0] = #000000; //black
  colors[1] = #0000CD; //MediumBlue
  colors[2] = #8B4513; //SaddleBrown
  colors[3] = #BEBEBE; //gray
  colors[4] = #006400; //DarkGreen
  colors[5] = #FF8C00; //DarkOrange
  colors[6] = #FF0000; //red
  colors[7] = #FF1493; //DeepPink
  colors[8] = #8B008B; //DarkMagenta
  colors[9] = #FFFFFF; //White
  
  //Rechtecke
  lines [0] = new ClassRect  ( 700, 700, 100, 100, 0 ); //black
  lines [1] = new ClassRect  ( 400, 600, 300, 200, 1 ); //MediumBlue
  lines [2] = new ClassRect  ( 400, 200, 400, 400, 2 ); //SaddleBrown
  lines [3] = new ClassRect  ( 200, 200, 200, 200, 3 ); //gray
  lines [4] = new ClassRect  ( 200, 400, 200, 200, 4 ); //DarkGreen
  lines [5] = new ClassRect  ( 200, 600, 200, 200, 5 ); //DarkOrange
  lines [6] = new ClassRect  ( 700, 600, 100, 100, 6 ); //red
}
 
void draw()
{ 
  //Hintergrundfarbe grau
  background(111);
  
  //Rahmenfarbe + Staerke
  stroke(0);
  strokeWeight(4);
  
 
  //Initiales Zeichen der Rechtecke
  for (int i = 0; i < lines.length; i++) {
    lines[i].draw();
  }
 
  //Verändern der Groesse der Rechtecke 
   // ----- Horizontale Linien -----
   checkCollision(lines);
   if (line1_h) {
     lines[2].snapshot();
     lines[2].rectHeight = mouseY - lines[2].y1;
     if (collidesWithAnyOther(lines[2])) {text("collision!!!", 50, 30);lines[2].reset();}
     
     lines[1].y1         = lines[2].y1 + lines[2].rectHeight;
     lines[1].rectHeight = outer_border - lines[1].y1;
     
     lines[6].y1         = lines[1].y1;
     lines[6].rectHeight = lines[0].y1 - lines[6].y1;
     
     lines[5].y1         = lines[1].y1;
     lines[5].rectHeight = outer_border - lines[1].y1;
     
     lines[4].y1         = lines[3].y1 + lines[3].rectHeight;
     lines[4].rectHeight = lines[5].y1 - lines[4].y1;     
  }
  
   if (line2_h) {
     lines[3].rectHeight = mouseY - lines[3].y1;
    
     lines[4].y1         = lines[3].y1 + lines[3].rectHeight;
     lines[4].rectHeight = lines[5].y1 - (lines[3].y1 + lines[3].rectHeight);
  }
  
   if (line3_h) {
     lines[6].rectHeight = mouseY - lines[6].y1;
    
     lines[0].y1         = lines[6].y1 + lines[6].rectHeight;
     lines[0].rectHeight = outer_border - lines[0].y1;
  }
  // ----- Vertikale Linien -----
   if (line1_v) {
     lines[3].rectWidth  = mouseX - lines[3].x1;     
     lines[4].rectWidth  = lines[3].rectWidth;    
     lines[5].rectWidth  = lines[3].rectWidth;
      
     lines[2].x1         = lines[3].x1 + lines[3].rectWidth;
     lines[2].rectWidth  = outer_border - lines[2].x1;
      
     lines[1].x1         = lines[5].x1 + lines[5].rectWidth;
     lines[1].rectWidth  = lines[0].x1 - (lines[5].x1 + lines[5].rectWidth);
  }
  
   if (line2_v) {
     lines[1].rectWidth  = mouseX - lines[1].x1;
      
     lines[0].x1         = lines[1].x1 + lines[1].rectWidth;
     lines[0].rectWidth  = outer_border - lines[0].x1;
      
     lines[6].x1         = lines[1].x1 + lines[1].rectWidth;
     lines[6].rectWidth  = outer_border - lines[6].x1;
  }
}
 
void mousePressed() {
  //Linke Maustaste zum Aendern der Groesse
  if (mouseButton == LEFT) {
    // ----- Horizontale Linien -----
    if (checkUpperEdge(lines[0])) { line3_h = true; }
    if (checkUpperEdge(lines[1])) { line1_h = true; }
    if (checkUpperEdge(lines[4])) { line2_h = true; }
    if (checkUpperEdge(lines[5])) { line1_h = true; }
    if (checkUpperEdge(lines[6])) { line1_h = true; }
  
    // ----- Vertikale Linien -----
    if (checkRightEdge(lines[1])) { line2_v = true; }
    if (checkRightEdge(lines[3])) { line1_v = true; }
    if (checkRightEdge(lines[4])) { line1_v = true; }
    if (checkRightEdge(lines[5])) { line1_v = true; }
  
  }
  
  //Rechte Maustaste zum Aendern der Farbe
  if (mouseButton == RIGHT) {
    //Iterieren durch alle Rechtecke, pruefe ob die Maus innerhalb des Rechtecks ist.
    for (int i = 0; i < lines.length; i++) {
      //Falls true, uebergib das Objekt in die Funktion changeColor()
      if (mouseX >= lines[i].x1 & mouseX <= lines[i].x1 + lines[i].rectWidth & mouseY > lines[i].y1 & mouseY <= lines[i].y1 + lines[i].rectHeight) {
      changeColor(lines[i]);
      }
    }
  }
}


void mouseReleased() {
  line1_h=false;
  line2_h=false;
  line3_h=false;
  line1_v=false;
  line2_v=false;
}

void changeColor(ClassRect rectangle_) {
  
  ClassRect rectangle = rectangle_;
  
  //if Bedingung verhindert OutOfBoundsException
  if (rectangle.col < colors.length - 1) {
    rectangle.col = rectangle.col + 1;
  }
  else rectangle.col = 0;

}


// ==== Funktionen zur Kolisionspruefung ====
boolean checkUpperEdge(ClassRect rectangle_) {
  
  ClassRect rectangle = rectangle_;
    
  if (dist(mouseX, mouseY, mouseX, rectangle.y1) <= range && dist(mouseX, mouseY, rectangle.x1 + abs(rectangle.rectWidth/2), mouseY) <= abs(rectangle.rectWidth)/2) {
    return true;
  }
  
  return false;
}

boolean checkRightEdge(ClassRect rectangle_) {
  
  ClassRect rectangle = rectangle_;
    
  if (dist(mouseX, mouseY, rectangle.x1+abs(rectangle.rectWidth), mouseY) <= range && dist(mouseX, mouseY, mouseX, rectangle.y1 + abs(rectangle.rectHeight)/2) <= abs(rectangle.rectHeight)/2) {
    return true;
  }
  
  return false;
}

boolean collidesWithAnyOther(ClassRect rect)
{
  for (ClassRect other : lines)
  {
    if (rect == other)
      continue;
    if (rect.intersects(other))
      text("collision!", 30, 30);
      return true;
  }
  return false;
}

boolean checkCollision(ClassRect[] rectangle_) {
  
  ClassRect[] rectangle = rectangle_;
  
  //for (ClassRect other : rectangle) { text("Koordinate: " + other.x1, other.x1, other.y1);}
  
  for (int i = 0; i < rectangle.length; i++) {
    for (int j = 0; j < rectangle.length; j++) {
      if (rectangle[i].x1 < rectangle[j].x1 + rectangle[j].rectWidth 
      && rectangle[i].x1 + rectangle[i].rectWidth > rectangle[j].x1
      && rectangle[i].y1 < rectangle[j].y1 + rectangle[j].rectHeight
      && rectangle[i].y1 + rectangle[i].rectHeight > rectangle[j].y1
      && rectangle[i].x1 != rectangle[j].x1){
      text("Collision detected...", 30, 30);
      return true;
      }
    }
  }
  return false;
}

If you run this program and start to vary the size of the rectangles you will see quite quickly where my problems are.
I’m grateful for any kind of help.

Greetz, BooWseR

1 Like

yes, you should limit the mouseX Y used by the size of the outer_border = 800
https://processing.org/reference/constrain_.html
there that outer_border AND a wMin should be used.
Then use that new value ( instead of mouse X Y )

Thank you for your answer, but I have already implemented a similar limitation.

if (rectWidth <= 10) {rectWidth = 11;}
if (rectHeight <= 10) {rectHeight = 11;}

The problem is that the squares are technically not on the same level. I can limit their size on < 10 px, but that doesn’t prevent them from overlapping and disappearing visually.
I need a way to prevent the squares from overlapping and at the same time prevent their size from falling below a certain value. At best, the squares should be able to displace each other, which would make my function much more flexible. At the moment I have leading lines which affect the size of the squares.

-a- but this


that the rect go outside the box
should be possible?

-b- also the
boolean function checkCollision()
is called and print text, but not used in any logic?

No, it shouldn’t be possible to go outside.

Yeah, as i said the code is heavily wip, so i tried many ways and use this message as part of a debug, so i can see if i trigger the “collision” correctly.