有機的な動きを表現するのはprocessingに限らず難しいものです。
なるべく短くしたスクリプトで微生物、深海生物を表現しました。
ArrayList<Branch> branches;
int len=100;
void setup() {
background(0);
size(1000, 800);
stroke(255, 30);
branches=new ArrayList<Branch>();
for (int i = 0; i < len; i++) {
branches.add(new Branch());
}
}
void draw() {
background(0);
for (int i = 0; i < branches.size (); i++) {
Branch b = (Branch) branches.get(i);
pushMatrix();
translate(width/2, height/2);
rotate(radians(b.startAngle));
b.branch(b.segments);
popMatrix();
strokeWeight(random(20));
ellipse(width/2, height/2, 5, 5);
}
}
void mousePressed() {
setup();
}
void keyPressed() {
if ( key == ' ' ) {
save( "hoge.png" );
}
}
setup()内の主なスクリプトです。
#ArrayList
配列の長さが決まっていない場合に使うクラスで可変長配列とよばれています。setup()内でnew演算子を使ってオブジェクトを作成します。
ArrayList 変数名 = new ArrayList();
もしくは下記のように作成します。
ArrayList<型> 変数名 = new ArrayList<型>();
そのあとfor文に以下を記述します。
変数名.add(new 型());
そしてdraw()内でオブジェクトbを宣言し、branchesから触手を表示させます。
クラス名.オブジェクト=(クラス名) 変数名.get();
こちらは触手を発生させるclassです。
class Branch {
float segments, startAngle, angle, theta, num;
Branch(){
segments = random(80);
startAngle = random(-360, 360);
angle = map(startAngle, -360, 360, -10, 10);
}
void branch(float len){
len *= 0.85;
float t = random(5);
theta = angle + sin(len+num) * 10;
strokeWeight(t*2);
noFill();
line(0, 0, 0, -len);
fill(255);
ellipse(0, 0, t, t);
translate(0, -len);
if(len > 5){
pushMatrix();
rotate(radians(-theta));
branch(len);
popMatrix();
}
num += 0.005;
}
}
#map
map(a, b, c, d, e)
aを範囲b-cから別の範囲d-eへ変換します。今回は360度のランダム値をstartAngleを格納し、-10〜10へ変換しています。
#branch()関数
void branch(float len){}内にさらにbranch(len)を呼ぶことにより、触手を伸ばすようにしています。