Why does my code splice to many rectangles from the array?

I am trying to make the piet mondrian in p5js, kinda following this site
https://generativeartistry.com/tutorials/piet-mondrian/

I keep on running into same problem over and over again and have tried different ways to solve it last few days. If I diving the step with 4 or bigger it starts to splice extra rectangles from the upper left corner. I am at a loss why that is happening :thinking: Is there somebody that can help me out here?

This is the code I have so far:
https://openprocessing.org/sketch/1953246

let rectangles = ;

function setup() {
createCanvas(1080, 1080);
background(100);
colorMode(HSB);

let x = 115;
let y = 115;
let w = 850;
let h = 850;
let step = 850/4;
let rectStart = new Rectangle(x, y, w, h);
rectangles.push(rectStart);

for (var i = 0; i < 850; i += step) {
splitSquaresWith(115 + i)
}

for (let i = rectangles.length - 1; i >= 0; i--) {
rectangles[i].show();

}

}

function splitSquaresWith(splitAt) {

 for (let i = rectangles.length - 1; i >= 0; i--) {
	 let square = rectangles[i];
	 
	 if(splitAt && splitAt > square.x && splitAt < (square.x + square.w)){ 
		// remove square
  	rectangles.splice(i, 1);
		// 2 new squares based on the x coordinates given
		splitOnX(square, splitAt); 
	}
	 
	 	if(splitAt && splitAt > square.y && splitAt < (square.y + square.h)){ 
		// remove square
  	rectangles.splice(i, 1);
		// 2 new squares based on the x coordinates given
		splitOnY(square, splitAt); 
	} 	 
 }

}

function splitOnX(square, splitAt) {

let newX = square.x;
let newY = square.y;
let newW = square.w - (square.w - splitAt + square.x);
let newH = square.h;
let squareA = new Rectangle(newX, newY, newW, newH);

let newX2 = splitAt;
let newY2 = square.y;
let newW2 = square.w - splitAt + square.x;
let newH2 = square.h;
let squareB = new Rectangle(newX2, newY2, newW2, newH2);

rectangles.push(squareA);
rectangles.push(squareB);
}

function splitOnY(square, splitAt) {
let newX = square.x;
let newY = square.y;
let newW = square.w;
let newH = square.h - (square.h - splitAt + square.y)
let squareA = new Rectangle(newX, newY, newW, newH);

let newX2 = square.x;
let newY2 = splitAt;
let newW2 = square.w;
let newH2 = square.h - splitAt + square.y;
let squareB = new Rectangle(newX2, newY2, newW2, newH2);

rectangles.push(squareA);
rectangles.push(squareB);
}

function keyPressed() {
if (key === “s”) {
save(“mondrian.png”);
}
}

I’ve compared your splitSquaresWith() function w/ the 1 from the tutorial site; and they don’t seem to match very well.

This is my own attempt which tries to combine both yours & tutorial’s implementations:

function splitSquaresWith({ x: cx, y: cy }, { length: i } = rectangles) {
  while (i--) {
    const { x, y, w, h } = rectangles[i];

    if (cx && cx > x && cx < x + w) {
      rectangles.splice(i, 1);
      splitOnX(rectangles, cx);
    }

    if (cy && cy > y && cy < y + h) {
      rectangles.splice(i, 1);
      splitOnY(square, cy); 
    } 	 
  }
}

In order to invoke splitSquaresWith() you need to pass an object containing numeric properties { x } or { y } or both { x, y }.

1 Like

Thank you for putting me on the right track @GoToLoop.

I also had to change
for (var i = 0; i < 850; i += step) {
splitSquaresWith(115 + i)
}

to

for (var i = 0; i < 850; i += step) {
splitSquaresWith({x : 115 + i})
splitSquaresWith({y : 115 + i})
}

The bug was caused by my trying to do x and y step in on go and not splitting the up.