Subdivide rectangles either horizontal or vertical until it has reached a minimal size.
- balance1: how much to be splitted from center
- balance2: how much the size should be taken in account for choosing horizontal or vertical split
- balance3: how much chance to stop continuing splitting up
#kdtree
Log in to post a comment.
const turtle = new Turtle();
const balance1 = 0.50; // min=0.0, max=1.0, step=0.01
const balance2 = 0.85; // min=0, max=1, step=0.01
const balance3 = 0.15; // min=0, max=1, step=0.01
const sizeX = 185; // min=50, max=200, step=5
const sizeY = 185; // min=50, max=200, step=5
const minSize = 6; // min=1, max=50, step=0.1
const spacing = 1.5; // min=0, max=10, step=0.1
const shape = 0; // min=0, max=1, step=1 (Square, Square with triangle)
const startPos = [-sizeX/2, -sizeY/2];
const areas = [
[0, 0, sizeX, sizeY],
];
function walk(i) {
if (i === 0) {
for (const area of areas.slice()) {
subdivide(area);
}
}
let area = areas.shift();
const a = [area[0], area[1]];
const b = [(area[0] + area[2]), (area[1] + area[3])];
let s = spacing*.5;
add2(a, startPos);
add2(b, startPos);
add2(a, [s,s]);
add2(b, [-s,-s]);
s = spacing * 2/3;
if (shape == 0) {
turtle.jump(a[0], a[1]);
turtle.goto(b[0], a[1]);
turtle.goto(b[0], b[1]);
turtle.goto(a[0], b[1]);
turtle.goto(a[0], a[1]);
} else if (shape == 1) {
if (Math.random() > balance1 * balance2 * balance3) {
turtle.jump(a[0], a[1]);
turtle.goto(b[0] - s, a[1]);
turtle.goto(a[0], b[1] - s);
turtle.goto(a[0], a[1]);
turtle.jump(b[0], a[1] + s);
turtle.goto(b[0] , b[1]);
turtle.goto(a[0] + s, b[1]);
turtle.goto(b[0], a[1]+ s);
} else {
turtle.jump(a[0], a[1]+s);
turtle.goto(b[0]-s, b[1]);
turtle.goto(a[0], b[1]);
turtle.goto(a[0], a[1]+s);
turtle.jump(b[0], b[1]-s);
turtle.goto(a[0]+s, a[1]);
turtle.goto(b[0], a[1]);
turtle.goto(b[0], b[1]-s);
}
}
return areas.length;
}
Array.prototype.remove = function(item) {
var idx;
while ((idx = this.indexOf(item)) !== -1) {
this.splice(idx, 1);
}
return this;
}
function subdivide(area) {
const b1 = 1 - balance1;
let r = 0.5 - (b1 / 2) + Math.random() * b1 / 2;
let verticalSplit = Math.random() > 0.5;
if (Math.random() < balance2) verticalSplit = area[2] < area[3]
const area1 = verticalSplit ?
[area[0], area[1], area[2], area[3]*r]
:
[area[0], area[1], area[2]*r, area[3]];
const area2 = !verticalSplit ?
[area[0] + area[2]*r, area[1], area[2]*(1-r), area[3]]
:
[area[0], area[1] + area[3]*r, area[2], area[3]*(1-r)];
areas.remove(area);
areas.push(area1);
areas.push(area2);
const minWidth = Math.max(minSize + spacing, spacing);
const minHeight = Math.max(minSize + spacing, spacing)
if ((area1[2] > minWidth) && (area1[3] > minHeight)) {
if (Math.random() > Math.pow(balance3, 3)) subdivide(area1);
}
if ((area2[2] > minWidth) && (area2[3] > minHeight)) {
if (Math.random() > Math.pow(balance3, 3)) subdivide(area2);
}
}
function add2(p, v) { p[0] += v[0]; p[1] += v[1]; return p }