xxxxxxxxxx
113
let gridSize = 20;
let cols, rows;
let noiseScale = 0.02; // ノイズのスケールを小さくして安定させる
let timeOffset = 0; // 時間オフセットでノイズの動きを作る
let stateGrid = []; // 各セルの状態(マルコフモデル用)
function setup() {
createCanvas(600, 600);
cols = width / gridSize;
rows = height / gridSize;
colorMode(RGB, 255, 255, 255);
// 初期化: 各セルの状態をランダムに設定
for (let i = 0; i < cols; i++) {
stateGrid[i] = [];
for (let j = 0; j < rows; j++) {
stateGrid[i][j] = floor(random(5)); // 5つの状態を持つ
}
}
frameRate(10); // 描画更新の頻度を抑える
}
function draw() {
background(255);
// 時間オフセットを少しだけ増やし、ゆっくりした変化を作る
timeOffset += 0.001;
for (let i = 0; i < cols; i++) {
for (let j = 0; j < rows; j++) {
// 各セルの状態に基づいて色を決定
let state = stateGrid[i][j];
let noiseValue = noise(i * noiseScale, j * noiseScale, timeOffset);
let col = colorPattern(state); // 状態を用いた色生成
fill(col);
noStroke();
rect(i * gridSize, j * gridSize, gridSize, gridSize);
}
}
// マルコフ連鎖による状態更新(更新頻度を下げる)
if (frameCount % 1 === 0) {
updateStates();
}
}
// 状態に基づいて色を決定する関数
function colorPattern(state) {
// 状態ごとに色を設定
if (state === 0) {
return color(255, 0, 0); // 赤
} else if (state === 1) {
return color(255, 255, 0); // 黄
} else if (state === 2) {
return color(0, 0, 255); // 青
} else if (state === 3) {
return color(0, 0, 0); // 黒
} else {
return color(255, 255, 255); // 白
}
}
// マルコフ連鎖を用いて各セルの状態を更新
function updateStates() {
for (let i = 0; i < cols; i++) {
for (let j = 0; j < rows; j++) {
// 隣接セルの状態に基づく遷移確率
let neighbors = getNeighborStates(i, j);
let currentState = stateGrid[i][j];
stateGrid[i][j] = nextState(currentState, neighbors);
}
}
}
// 隣接セルの状態を取得する関数
function getNeighborStates(x, y) {
let states = [];
if (x > 0) states.push(stateGrid[x - 1][y]);
if (x < cols - 1) states.push(stateGrid[x + 1][y]);
if (y > 0) states.push(stateGrid[x][y - 1]);
if (y < rows - 1) states.push(stateGrid[x][y + 1]);
return states;
}
// 現在の状態と隣接状態に基づいて次の状態を決定する
function nextState(currentState, neighbors) {
let transitionMatrix = [
[0.9996, 0.0001, 0.0001, 0.0001, 0.0001], // 状態0からの遷移確率
[0.0001, 0.9996, 0.0001, 0.0001, 0.0001], // 状態1からの遷移確率
[0.0001, 0.0001, 0.9996, 0.0001, 0.0001], // 状態2からの遷移確率
[0.0001, 0.0001, 0.0001, 0.9996, 0.0001], // 状態3からの遷移確率
[0.0001, 0.0001, 0.0001, 0.0001, 0.9996] // 状態4からの遷移確率
];
// 隣接セルの状態に基づいて遷移確率を調整
let nextStateProbabilities = transitionMatrix[currentState];
let weightedProbability = [nextStateProbabilities];
neighbors.forEach(state => {
weightedProbability[state] += 0.1; // 隣接セルと同じ状態になる確率を上げる
});
// 正規化して次の状態を決定
let total = weightedProbability.reduce((acc, val) => acc + val, 0);
let randomValue = random(total);
let cumulative = 0;
for (let i = 0; i < weightedProbability.length; i++) {
cumulative += weightedProbability[i];
if (randomValue < cumulative) return i;
}
return currentState; // 何も該当しない場合は現在の状態を保持
}