Divide Rectangle Into Smaller Rectangles
const rand = num => ~~(Math.random() * num)
let rectNum = 2 + rand(10)
let rectCount = 0
document.body.appendChild(document.createElement('div')).innerText =
'click anywhere to regenerate'
function reset() {
;[...document.querySelectorAll('.rect')].forEach(rect => rect.remove())
rectNum = 2 + rand(10)
rectCount = 0
newRect(300, 300, 50, 50)
}
reset()
onpointerup = reset
function newRect(w, h, xp, yp) {
const rect = document.body.appendChild(document.createElement('div'))
rect.classList.add('rect')
rectCount++
Object.assign(rect.style, {
position: 'absolute',
left: `${xp}px`,
top: `${yp}px`,
width: `${w}px`,
height: `${h}px`,
outline: `1px solid black`,
})
const props = {
x: xp,
y: yp,
height: h,
width: w,
seed: rand(3),
divide() {
const div = 2 + rand(5 * Math.random() * Math.random())
if (rand(2) == rand(2)) {
const newHeight = this.height / div
newRect(this.width, this.height - newHeight, this.x, this.y)
newRect(this.width, newHeight, this.x, this.y + this.height - newHeight)
} else {
const newWidth = w / div
newRect(this.width - newWidth, this.height, this.x, this.y)
newRect(newWidth, this.height, this.x + this.width - newWidth, this.y)
}
rect.remove()
},
}
window.requestAnimationFrame(() => {
if (rectCount < rectNum) {
props.divide()
} else {
console.log('DONE!')
}
})
}
This snippet comes to mind from time to time – one easy way to divide a rectangle into smaller rectangles- I actually went back and looked it up as it was an answer to a student question from 2006. The original one was written in ActionScript 2. Have a look:
var wormNum:Number = 123;
var wormCount:Number = 0;
newWorm(400, 400, 0, 0);
this.onEnterFrame = function() {
if (wormCount < wormNum) {
for (var props:String in this) {
if (this[props]._x != undefined) {
this[props].divide();
}
}
}
};
function newWorm(w, h, xp, yp) {
var currWorm:MovieClip = this.createEmptyMovieClip("box"+wormCount, this.getNextHighestDepth());
wormCount++;
box(w, h, currWorm, random(0xFFFFFF));
currWorm._x = xp;
currWorm._y = yp;
currWorm.seed = random(3);
currWorm.divide = function() {
var div = random(4)+(1+Math.random()*1);
if (random(2) == random(2)) {
// divide vertically
var nh:Number = this._height/div;
newWorm(this._width, this._height-nh, this._x, this._y);
newWorm(this._width, nh, this._x, this._y+this._height-nh);
} else {
// divide horizonatlly
var nw:Number = this._width/div;
newWorm(this._width-nw, this._height, this._x, this._y);
newWorm(nw, this._height, this._x+this._width-nw, this._y);
}
this.removeMovieClip();
};
}
function box(w:Number, h:Number, mc:MovieClip, col:Number):Void {
with (mc) {
lineStyle(0, 0, 20);
beginFill(col, 10);
moveTo(0, 0);
lineTo(w, 0);
lineTo(w, h);
lineTo(0, h);
endFill();
}
}
Don’t remember why I called them worms instead of rectangles, some AS2 types floating around…