1次元セルオートマトン

提供:kuhalaboWiki
(版間での差分)
移動: 案内, 検索
(シェルピンスキーのギャスケット その1)
(シェルピンスキーのギャスケット その1)
3行: 3行:
 
== シンプルに配列だけで記述 ==
 
== シンプルに配列だけで記述 ==
 
=== シェルピンスキーのギャスケット その1 ===
 
=== シェルピンスキーのギャスケット その1 ===
* 2次元配列cell[256][256]を作り、一度に計算する。
+
* 2次元配列cell[256][256]を作り、まとめて状態を更新し、描画する。
 
<pre>
 
<pre>
 
#include "ofApp.h"
 
#include "ofApp.h"

2017年11月6日 (月) 23:54時点における版

Wolframのセルオートマトンの描画プログラム

目次

シンプルに配列だけで記述

シェルピンスキーのギャスケット その1

  • 2次元配列cell[256][256]を作り、まとめて状態を更新し、描画する。
#include "ofApp.h"

static const int NUM = 256; //セルの個数
int cell[NUM][NUM];

//--------------------------------------------------------------
void ofApp::setup(){
	ofBackground(0, 0, 0); //背景色の設定
//初期状態は真ん中だけが 1 で残りはすべて 0
	for(int i = 0; i < NUM; i++){
		cell[i][0] = 0;
	}
	cell[NUM/2][0] = 1;
}

//--------------------------------------------------------------
void ofApp::update(){
//状態遷移則 1つ前と1つ後の値を足した値の1桁目(2進法の足し算 XOR)
	for(int j = 1; j < NUM; j++){
		for(int i = 1; i < NUM-1; i++){
			cell[i][j] = ( cell[i-1][j-1] + cell[i+1][j-1] ) % 2;
		}
	}
}

//--------------------------------------------------------------
void ofApp::draw(){
	int w = 4; //セルの描画幅
	for(int i = 0; i < NUM; i++){
		for(int j = 0; j < NUM; j++){
			if( cell[i][j] > 0 ) ofSetColor(255,0,0); //セルが 1 の時の描画色
			else ofSetColor(0,0,0); //セルが 0 の時の描画色
			ofRect(i * w, j * w , w , w ); 
		}
	}
}

クラスを使って記述

シェルピンスキーのギャスケット その2

  • Cellクラスを設計
  • ルール90(01011010)の規則を記述
Cell.h
#pragma once
#include "ofMain.h"

class Cell {
public:
	ofPoint pos; //位置
	float width; //幅
	ofColor bcolor; //描画色
	int state; //内部状態
	int sXXX; //自分と両隣りの状態 000-111(0-7)の8通り

public:
	Cell();
	void draw();
	void update();
};
Cell.cpp
#include "Cell.h"

Cell::Cell(){
	pos = ofPoint(0, 0);
	width = 4;
	state = 0;
	bcolor = ofColor(255, 0, 0);//セルの描画色
}

void Cell::update(){
//自分と両隣りの状態に応じて次の自分の状態を決める
		switch(sXXX){
		case 0: //000
			state = 0;
			break;
		case 1: //001
			state = 1;
			break;
		case 2: //010
			state = 0;
			break;
		case 3: //011
			state = 1;
			break;
		case 4: //100
			state = 1;
			break;
		case 5: //101
			state = 0;
			break;
		case 6: //110
			state = 1;
			break;
		case 7: //111
			state = 0;
			break;
		}
}

void Cell::draw(){
	if( state ){
		ofSetColor(bcolor);
		ofRect(pos, width,width);
	}
}
ofApp.h
#pragma once

#include "ofMain.h"
#include "Cell.h"

class ofApp : public ofBaseApp{

	public:
		void setup();
		void update();
		void draw();

		void keyPressed(int key);
		void keyReleased(int key);
		void mouseMoved(int x, int y );
		void mouseDragged(int x, int y, int button);
		void mousePressed(int x, int y, int button);
		void mouseReleased(int x, int y, int button);
		void windowResized(int w, int h);
		void dragEvent(ofDragInfo dragInfo);
		void gotMessage(ofMessage msg);

		static const int NUM = 256; //セルの個数
		Cell cell[NUM][NUM];
		
};
ofApp.cpp
//--------------------------------------------------------------
void ofApp::setup(){
	ofBackground(0, 0, 0); //背景色の設定
	//初期状態は真ん中だけが 1 で残りはすべて 0
	for(int i = 0; i < NUM; i++){
		cell[i][0].state = 0;
		cell[i][0].pos = ofPoint(i * cell[i][0].width, 0);
	}
	cell[NUM/2][0].state = 1;
}

//--------------------------------------------------------------
void ofApp::update(){
	for(int j = 1; j < NUM; j++){
		for(int i = 0; i < NUM; i++){
			int iP = (i - 1 + NUM ) % NUM;
			int iN = (i + 1 + NUM ) % NUM;
			cell[i][j].sXXX = cell[iP][j-1].state * 4 + cell[i][j-1].state * 2 + cell[iN][j-1].state;
			cell[i][j].update();
			cell[i][j].pos = ofPoint(i * cell[i][j].width, j * cell[i][j].width);
		}
	}
}

//--------------------------------------------------------------
void ofApp::draw(){

	for(int i = 0; i < NUM; i++){
		for(int j = 0; j < NUM; j++){
			cell[i][j].draw();
		}
	}
}

256種のルールのセルオートマトン

  • 256種類のルール全てのセルオートマトンを順番に表示する。
Cell.h
#pragma once
#include "ofMain.h"

class Cell {
public:
	ofPoint pos; //位置
	float width; //幅
	ofColor bcolor; //描画色
	int state; //内部状態
	int sXXX; //次の状態 000-111の8通り
	int rX8; //ルール 8bit 256通り

public:
	Cell();
	void draw();
	void update();
};
Cell.cpp
#include "Cell.h"

Cell::Cell(){
	pos = ofPoint(0, 0);
	width = 4;
	state = 0;
	bcolor = ofColor(255, 0, 0);
}

void Cell::update(){
		switch(sXXX){
		case 0: //000
			state =  rX8 % 2;
			break;
		case 1: //001
			state = ( rX8 % 4) / 2;
			break;
		case 2: //010
			state = ( rX8 % 8) / 4;
			break;
		case 3: //011
			state = ( rX8 % 16) / 8;
			break;
		case 4: //100
			state = ( rX8 % 32) / 16;
			break;
		case 5: //101
			state = ( rX8 % 64 ) / 32;
			break;
		case 6: //110
			state = ( rX8 % 128 ) / 64;
			break;
		case 7: //111
			state = rX8 / 128;
			break;
		}
}

void Cell::draw(){
	if( state ){
		ofSetColor(bcolor);
		ofRect(pos, width,width);
	}
	else
	{
		ofSetColor(ofColor(0, 0, 0));
		ofRect(pos, width,width);
	}
}
ofApp.h
#pragma once

#include "ofMain.h"
#include "Cell.h"

class ofApp : public ofBaseApp{

	public:
		void setup();
		void update();
		void draw();

		void keyPressed(int key);
		void keyReleased(int key);
		void mouseMoved(int x, int y );
		void mouseDragged(int x, int y, int button);
		void mousePressed(int x, int y, int button);
		void mouseReleased(int x, int y, int button);
		void windowResized(int w, int h);
		void dragEvent(ofDragInfo dragInfo);
		void gotMessage(ofMessage msg);
		
		static const int NUM = 256; //セルの個数
		Cell cell[NUM][NUM];
		int r; //ルール番号
};
ofApp.cpp
#include "ofApp.h"

//--------------------------------------------------------------
void ofApp::setup(){
	ofBackground(0, 0, 0); //背景色の設定
	ofSetFrameRate(2); //フレームレイト設定
	r = 0;

	//初期状態は真ん中だけが 1 で残りはすべて 0
	for(int i = 0; i < NUM; i++){
		cell[i][0].state = 0;
		cell[i][0].rX8 = 0;
		cell[i][0].pos = ofPoint(i * cell[i][0].width, 0);
	}
	cell[NUM/2][0].state = 1;

}

//--------------------------------------------------------------
void ofApp::update(){
	for(int j = 1; j < NUM; j++){
		for(int i = 0; i < NUM; i++){
			cell[i][j].rX8 = r;
			int iP = (i - 1 + NUM ) % NUM;
			int iN = (i + 1 + NUM ) % NUM;
			cell[i][j].sXXX = cell[iP][j-1].state * 4 + cell[i][j-1].state * 2 + cell[iN][j-1].state;
			cell[i][j].update();
			cell[i][j].pos = ofPoint(i * cell[i][j].width, j * cell[i][j].width);
			cell[i][j].bcolor = ofColor(255-r, i, j); //模様にグラデーションをつける
		}
	}
}

//--------------------------------------------------------------
void ofApp::draw(){
	for(int i = 0; i < NUM; i++){
		for(int j = 0; j < NUM; j++){
			cell[i][j].draw();
		}
	}
	// ルール番号の表示
	ofSetColor(ofColor::white);
	ofDrawBitmapString("rule: " + ofToString(r), 10, 20);
	r = ( r + 1 ) % 256;
}

参考

ジェネラティブアート論

個人用ツール
名前空間

変種
操作
案内
ツールボックス