1次元セルオートマトン
提供:kuhalaboWiki
(版間での差分)
(→256のルールを記述) |
(→256のルールを記述) |
||
| 333行: | 333行: | ||
// ルール番号の表示 | // ルール番号の表示 | ||
ofSetColor(ofColor::white); | ofSetColor(ofColor::white); | ||
| − | ofDrawBitmapString("rule: " + ofToString(r), 10, | + | ofDrawBitmapString("rule: " + ofToString(r), 10, 20); |
r = ( r + 1 ) % 256; | r = ( r + 1 ) % 256; | ||
} | } | ||
2017年11月6日 (月) 14:29時点における版
Wolframのセルオートマトンの描画プログラム
目次 |
シェルピンスキーのガスケット
シンプルに配列だけで記述
#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 );
}
}
}
クラスを使って記述
- Cellクラスを設計
- ルール30(01011010)の規則を記述
- Cell.h
#pragma once
#include "ofMain.h"
class Cell {
public:
ofPoint pos; //位置
float width; //幅
ofColor bcolor; //描画色
int state; //内部状態
int sXXX; //次の状態 000-111の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, 100);
}
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(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;
}