xxxxxxxxxx
155
const WIDTH = 7;
const HEIGHT = 7;
const SIZE = WIDTH * HEIGHT;
let tile_size;
function setup() {
let fit_size = min(windowWidth, windowHeight);
createCanvas(fit_size, fit_size);
tile_size = min(width / WIDTH, height / HEIGHT);
colorMode(RGB, 1);
noLoop()
strokeWeight(15);
stroke(1);
init();
}
let state, groups;
function init() {
do {
state = floor(random(2 ** SIZE));
groups = generateGroups(state);
} while(!groups);
console.log(state.toString(2));
console.log(groups);
draw();
}
function isFlipped(x, y) {
// return (state & posMask(x, y)) === 0
return Number(BigInt(state) & BigInt(posMask(x, y))) === 0
}
function posMask(x, y) {
const index = getIndex(x, y);
const mask = 2 ** index; //1 << index;
return mask;
}
function getIndex(x, y) {
return x + y * WIDTH;
}
function getGroupIndex(x, y) {
return x + y * (WIDTH + 1);
}
function generateGroups(state) {
let groups = [];
const getGroup = (index) => {
for (const group of groups)
if (group.has(index))
return group;
const new_group = new Set([index]);
groups.push(new_group);
return new_group;
}
for (let x=0; x<WIDTH; x++) {
for (let y=0; y<HEIGHT; y++) {
const flipped = isFlipped(x, y);
let index1, index2;
if (!flipped) {
index1 = getGroupIndex(x, y);
index2 = getGroupIndex(x + 1, y + 1);
}else{
index1 = getGroupIndex(x + 1, y);
index2 = getGroupIndex(x, y + 1);
}
let group1 = getGroup(index1);
let group2 = getGroup(index2);
if (group1 !== group2) {
group2.forEach(g => group1.add(g));
groups = groups.filter(g => g !== group2);
}else{
console.log("loop!");
return null;
}
}
}
return groups;
}
function draw() {
background(0);
resetMatrix();
translate(width / 8, height / 8);
scale(0.75, 0.75);
const getGroupNumber = (x, y) => {
const index = getGroupIndex(x, y);
const group = groups.find(g => g.has(index));
return groups.indexOf(group);
}
for (let x=0; x<WIDTH; x++) {
for (let y=0; y<HEIGHT; y++) {
const flipped = isFlipped(x, y);
let begin, end, groupNumber;
if (!flipped) {
begin = getWorldPos(x, y);
end = getWorldPos(x + 1, y + 1);
groupNumber = getGroupNumber(x, y);
}else{
begin = getWorldPos(x + 1, y);
end = getWorldPos(x, y + 1);
groupNumber = getGroupNumber(x + 1, y);
}
stroke(gradient(groupNumber / groups.length));
line(begin.x, begin.y, end.x, end.y);
}
}
// for (let x=0; x<WIDTH + 1; x++) {
// for (let y=0; y<HEIGHT + 1; y++) {
// const pos = getWorldPos(x, y);
// fill(1);
// noStroke();
// textSize(tile_size * 0.4);
// text(getGroupNumber(x, y), pos.x, pos.y + textSize() / 2);
// }
// }
}
function gradient(n) {
return [
map(cos((n + 0/6) * TAU), -1, 1, 0, 1),
map(cos((n + 1/6) * TAU), -1, 1, 0, 1),
map(cos((n + 2/6) * TAU), -1, 1, 0, 1),
]
}
function getWorldPos(x, y) {
return { x: x * tile_size, y: y * tile_size }
}
function keyPressed() {
init();
}