BioErrorLog Tech Blog

試行錯誤の記録

Generative Art #14 - Processing作品

おはよう。@bioerrorlogです。

ProcessingによるGenerative Art作品
14作目を記録します。

自作品まとめはこちら: www.bioerrorlog.work

Output

f:id:BioErrorLog:20200419210659p:plain f:id:BioErrorLog:20200419210715p:plain f:id:BioErrorLog:20200419210741p:plain f:id:BioErrorLog:20200419210804p:plain

フル解像度/その他出力パターンはこちら:
Generative_14 - BioErrorLog - pixiv


Material

使用言語: Processing 3.5.3

Processingというプログラミング言語に聞き覚えがない、という方は是非こちらをご参考ください:
www.bioerrorlog.work


Source Code

GitHubはこちら

Cell[][] _cellArray;
int _cellSize = 1; // Cellの大きさ(pixel)
int _numX, _numY; // ディスプレイのCell格子


void setup() { 
  size(1920, 1080); // ディスプレイサイズ
  _numX = floor(width/_cellSize);
  _numY = floor(height/_cellSize);
  restart();
} 


void restart() {
  // _cellArrayに画面分のCellを入れる
  _cellArray = new Cell[_numX][_numY];    
  for (int x = 0; x<_numX; x++) {
    for (int y = 0; y<_numY; y++) {    
      Cell newCell = new Cell(x, y);  
      _cellArray[x][y] = newCell;      
    }               
  }                 
  
  for (int x = 0; x < _numX; x++) {
    for (int y = 0; y < _numY; y++) {  
      
      int above = y-1;        
      int below = y+1;        
      int left = x-1;         
      int right = x+1;            
      
      // 画面端の処理
      if (above < 0) { above = _numY-1; }    
      if (below == _numY) { below = 0; } 
      if (left < 0) { left = _numX-1; }  
      if (right == _numX) { right = 0; } 

     _cellArray[x][y].addNeighbour(_cellArray[left][above]);    
     _cellArray[x][y].addNeighbour(_cellArray[left][y]);        
     _cellArray[x][y].addNeighbour(_cellArray[left][below]);    
     _cellArray[x][y].addNeighbour(_cellArray[x][below]);   
     _cellArray[x][y].addNeighbour(_cellArray[right][below]);   
     _cellArray[x][y].addNeighbour(_cellArray[right][y]);   
     _cellArray[x][y].addNeighbour(_cellArray[right][above]);   
     _cellArray[x][y].addNeighbour(_cellArray[x][above]);       
    }
  }
}


void draw() {
  background(200);
                    
  for (int x = 0; x < _numX; x++) {
    for (int y = 0; y < _numY; y++) {
     _cellArray[x][y].calcNextState();
    }
  }
                        
  translate(_cellSize/2, _cellSize/2);     
                        
  for (int x = 0; x < _numX; x++) {
    for (int y = 0; y < _numY; y++) {
     _cellArray[x][y].drawMe();
    }
  }

  saveFrame("frames/generative_14_#####.png"); // 各フレームで画像を保存
}


void keyPressed(){
    /*
    BACKSPACEキー押下: setup()を呼ぶ
    */

    if (keyCode == BACKSPACE){
        setup();
    }
}


class Cell {
  float x, y;
  float state;         
  float nextState;  
  float lastState = 0; 
  Cell[] neighbours;
  
  Cell(float ex, float why) {
    x = ex * _cellSize;
    y = why * _cellSize;
    
    // Cellの初期状態を定義
    // 画面の真ん中のCellは確率で255, それ以外は0
    // 255になるのは4つまで
    int initCount = 0;
    if(width/4 < ex && ex < width*3/4 && height/4 < why && why < height*3/4 && initCount <= 4){
      if(random(100000) < 1){
        nextState = 255; 
        initCount += 1;
      }else{
        nextState = 0;
      }
    }else{
      nextState = 0;
    }

    state = nextState;
    neighbours = new Cell[0];
  }
  
  void addNeighbour(Cell cell) {
    neighbours = (Cell[])append(neighbours, cell); 
  }
  
  void calcNextState() {
    /*
    1. そうでなければ、新しい状態=現在の状態+隣接セルの状態の平均ー前の状態の値
    2. もし新しい状態が255を超えたら255にし、
    3. もし新しい状態が0以下ならそれを0にする
    */
                
    float total = 0;              
    for (int i=0; i < neighbours.length; i++) { 
       total += neighbours[i].state;        
    }                   
    float average = int(total/8);
                
    if (1 < average && average < 10) { // ※
      nextState = 255;
    }else{
    nextState = state + average;
      if (lastState > 0) { nextState -= lastState; } // 1.
      if (nextState > 255) { nextState = 255; } // 2.
      else if (nextState < 0) { nextState = 0; } // 3.
    }
    lastState = state;  
  }
  
  void drawMe() {
    state = nextState;
    noStroke();
    fill(state);    
    rect(x, y, _cellSize, _cellSize);
  }
}

Discussion

6作目7作目と同様、セルオートマトンの法則を利用して作成しました。

序盤の規則的な四角い造形から、斜め方向に走るパターンが現れ、徐々に雨降る道路の水たまりのような、複雑な状態になっていく過程が面白いところです。


See also

www.bioerrorlog.work

www.bioerrorlog.work

www.bioerrorlog.work