Processing|神経の中を光が通る

Processing

ニューロンとか神経系の中を光が走るイメージです。

Visual

Code

ArrayList<Neuron> neurons = new ArrayList<Neuron>();
ArrayList<Signal> signals = new ArrayList<Signal>();

void setup() {
  size(800, 600, P3D);
  
  // ニューロンを3D空間に配置
  for (int i = 0; i < 40; i++) {
    neurons.add(new Neuron(random(-300, 300), random(-300, 300), random(-300, 300)));
  }
  
  for (Neuron n : neurons) {
    n.addNeighbors(neurons);
  }
}

void draw() {
  background(0); // 一旦真っ黒にする(これで「何も見えない」を回避)
  
  // カメラの設定:中心へ移動し、少し引いた視点にする
  translate(width/2, height/2, -200);
  rotateY(frameCount * 0.005);
  rotateX(frameCount * 0.003);

  // 光り輝かせる設定
  blendMode(ADD);
  
  // 1. 神経の「管」を描画
  noFill();
  for (Neuron n : neurons) {
    n.displayConnections();
  }
  
  // 2. 信号(走る光)を更新・描画
  for (int i = signals.size()-1; i >= 0; i--) {
    Signal s = signals.get(i);
    s.update();
    s.display();
    if (s.isDead) {
      s.target.trigger();
      signals.remove(i);
    }
  }

  // 3. 定期的にどこかのニューロンを光らせる
  if (frameCount % 30 == 0) {
    neurons.get((int)random(neurons.size())).trigger();
  }
  
  blendMode(BLEND);
}

// --- 以下、計算用クラス ---

class Neuron {
  PVector pos;
  ArrayList<Neuron> neighbors = new ArrayList<Neuron>();
  
  Neuron(float x, float y, float z) {
    pos = new PVector(x, y, z);
  }
  
  void addNeighbors(ArrayList<Neuron> others) {
    for (Neuron o : others) {
      float d = PVector.dist(pos, o.pos);
      if (d > 50 && d < 300) neighbors.add(o);
    }
  }
  
  void displayConnections() {
    strokeWeight(1);
    for (Neuron n : neighbors) {
      if (neurons.indexOf(n) > neurons.indexOf(this)) {
        // 管の表現:2色の線で「光る筒」を模写
        stroke(0, 50, 200, 50); // 外側の青
        strokeWeight(4);
        line(pos.x, pos.y, pos.z, n.pos.x, n.pos.y, n.pos.z);
        
        stroke(100, 200, 255, 150); // 内側の光る芯
        strokeWeight(1);
        line(pos.x, pos.y, pos.z, n.pos.x, n.pos.y, n.pos.z);
      }
    }
  }
  
  void trigger() {
    if (neighbors.size() > 0) {
      signals.add(new Signal(this, neighbors.get((int)random(neighbors.size()))));
    }
  }
}

class Signal {
  PVector start, targetPos;
  Neuron target;
  float pct = 0;
  
  Signal(Neuron s, Neuron t) {
    start = s.pos;
    target = t;
    targetPos = t.pos;
  }
  
  void update() {
    pct += 0.03;
  }
  
  boolean isDead = (pct >= 1.0);
  
  void display() {
    if (pct >= 1.0) { isDead = true; return; }
    
    float x = lerp(start.x, targetPos.x, pct);
    float y = lerp(start.y, targetPos.y, pct);
    float z = lerp(start.z, targetPos.z, pct);
    
    pushMatrix();
    translate(x, y, z);
    noStroke();
    // 強い光の粒
    fill(255, 255, 255);
    sphere(3); 
    // 周囲のオーラ
    fill(0, 150, 255, 100);
    sphere(8);
    popMatrix();
  }
}

オススメのProcessing参考書

Processing クリエイティブ・コーディング入門
―コードが生み出す創造表現

コメント

タイトルとURLをコピーしました