built_with_processing

キモい生物をつくる

有機的な動きを表現するのはprocessingに限らず難しいものです。
なるべく短くしたスクリプトで微生物、深海生物を表現しました。

creatures.pde

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です。
Branch.pde

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)を呼ぶことにより、触手を伸ばすようにしています。

参考:http://www.openprocessing.org/sketch/158344

built_with_processing

punktiertを使ったアニメーション

punktiertは、2D/3D空間上に有機的なアニメーションを搭載できるライブラリです。

http://www.lab-eds.org/punktiert

比較的短いスクリプトで様々な物理エンジンが利用できます。
exampleを見るとパーティクル系が多いです。
また、ドラッグでカメラ視点を変えられるpeasycamも今回使用しました。
こちらも3D作品の際には役に立つライブラリです。

http://mrfeinberg.com/peasycam/#about

p5.pde

import peasy.PeasyCam;
import punktiert.math.Vec;
import punktiert.physics.*;

VPhysics physics;

PeasyCam cam;

public void setup() {
  size(800, 600, P3D);
  smooth();

  cam = new PeasyCam(this, 800);

  physics = new VPhysics();

  for (int i = 0; i < 1000; i++) {

    Vec pos = new Vec(0, 0, 0).jitter(1);
    Vec vel = new Vec(random(-1, 1), random(-1, 1), random(-1, 1));
    VBoid p = new VBoid(pos, vel);
    p.setRadius(20);

    p.swarm.setCohesionRadius(80);
    p.trail.setInPast(3);
    p.trail.setreductionFactor(2);
    physics.addParticle(p);

    p.addBehavior(new BCollision());

    physics.addSpring(new VSpringRange(p, new VParticle(), 300, 400, 0.0005f));
  }
}

public void draw() {
  background(240);

  physics.update();
  for (int i = 0; i < physics.particles.size(); i++) {
    VBoid boid = (VBoid) physics.particles.get(i);

    strokeWeight(5);
    stroke(0);
    point(boid.x, boid.y, boid.z);

    if (frameCount > 400) {
      boid.trail.setInPast(100);
    }
    strokeWeight(1);
    stroke(200, 0, 0);
    noFill();
    beginShape();
    for (int j = 0; j < boid.trail.particles.size(); j++) {
      VParticle t = boid.trail.particles.get(j);
      vertex(t.x, t.y, t.z);
    }
    endShape();
  }
}
built_with_processing

光の絨毯

noise()を使ってパーティクルの波をランダムに発生させ、宇宙空間ぽくしました。
今回は3次元なので、x軸、y軸、z軸にパーリンノイズを生成するためにnoise(x,y,z)として、各パラメータを取得しました。

コンピュータグラフィクスで自然物を表現するときのテクスチャや地形描写などで使われるパーリンノイズの生成に使います。
【構文】
noise(x)
noise(x, y)
noise(x, y, z)
【パラメータ】
x ノイズ空間におけるx座標(float)
y ノイズ空間におけるy座標(float)
z ノイズ空間におけるz座標(float)
【戻り値】
0.0から1.0の間の値(float)
またlerp関数を使用して、-speedとspeedの間の値を取得しました。
lerp(a, b, c)・・・aとbの間の、比cで指定される値を求める

p5.pde

int nPoints=30000;
float complexity =3;
float maxMass=0.05;
float timeSpeed=0.002;
float phase=PI;

float windSpeed=70;
int step=10;

float[] pollenMass;
float[][] points;

void setup(){
  //size(500,400,P3D);
  size(displayWidth, displayHeight,P3D);
  background(0);
  frameRate(30);
  points=new float[nPoints][2];
  pollenMass=new float[nPoints];

  for(int i=0;i<nPoints;i++){
    points[i]=new float[]{
     random(0,width),random(0,height) 
    };
    pollenMass[i]=noise(0,maxMass);
  }
}

void draw(){
  background(0);
  stroke(255);
  smooth();

  //camera(mouseX, mouseY, 220.0, width/2, height/2, height/2, 1, 1, 1);

  for(int i=0; i<nPoints; i++){
  pushMatrix();
    float x = points[i][0];
    float y = points[i][1];
    float z = points[i][1];

    float normx = norm(x, 0, width);
    float normy = norm(y, 0, height);
    float normz = norm(z, 0, -1000);
    float u = noise(phase, normx * complexity, normy * complexity);
    float v = noise(phase, normy * complexity, normz * complexity);
    float w = noise(phase, normz * complexity, normx * complexity);
    float speed = (1 + noise(u, v, w)) / pollenMass[i];
    x += lerp(-speed, speed, u);
    y += lerp(-speed, speed, v);
    z += lerp(-speed, speed, w);

    strokeWeight(z/random(100, 500));
    point(x, y, z);
    //image(particleImg, x, y, 30, 30);

    points[i][0] = x;
    points[i][1] = y;
    points[i][1] = z;
    popMatrix();

  }
}

void mousePressed(){
  setup();
}

void keyPressed() {
  if ( key == ' ' ) {
    save( "hoge.png" );
  }
}

またパーティクルの数(nPoints)は30000としていますが、
これ以上増やすと自分のマシンが遅くなるので、とりあえずこの数にしています。
もっと増やすと綺麗になりますが、処理落ちしてしまうので、この辺りは数を増やしたり減らしたりして、さじ加減が必要になるかと思います。

参考:noise() ノイズの生成
http://www.openprocessing.org/sketch/2785

258250ed-5d95-82c5-4fb4-21b66bebe27b

random()とnoise()の違い

Processingで乱数を取得する関数にrandom()とnoise()がありますが、両者には違いがあります。

random()

乱数を呼び出すたびに取得し、返り値はfloat型になります。
引数に何も記述しないと0.0〜1.0の範囲の乱数を取得します。
random(max);
引数が1つのときは0〜maxの範囲の乱数を取得します。
random(min, max);
引数が2つのときはmin〜maxの範囲の乱数を取得します。

539f17e3-c1da-73b0-278c-eaa30a9c83b1

random.pde

size(500,100);
background(255);
strokeWeight(5);
smooth();
stroke(0, 30);
line(20,50,480,50);

int step = 10;
float lastx = -999;
float lasty = -999;
float y = 50;
int borderx=20;
int bordery=10;

stroke(0);
for (int x=borderx; x<=width-borderx; x+=step) { y = bordery + random(height - 2*bordery); //from 10 to 90 if (lastx > -999) {
    line(x, y, lastx, lasty);
  }
  lastx = x;
  lasty = y;
}

yの値は10から90の範囲を取得します。

noise()

こちらも乱数を取得しますが、正確にはパーリンノイズという主に自然物を描写する際に使用するノイズ値を取得します。
0.0から1.0の間のfloat型を取得します。

258250ed-5d95-82c5-4fb4-21b66bebe27b
noise.pde

size(500, 100);
background(255);
strokeWeight(5);
smooth();
stroke(0, 30);
line(20, 50, 480, 50);
stroke(0);
int step = 10;
float lastx = -999;
float lasty = -999;
float ynoise = random(10);
float y;
for (int x=20; x<=480; x+=step) { y = 10 + noise(ynoise) * 80; //from 10 to 90 if (lastx > -999) {
    line(x, y, lastx, lasty);
  }
  lastx = x;
  lasty = y;
  ynoise += 0.1;
}

この例では変数ynoiseをrandom(10)からはじめ、
その値を0.1ずつ増やしてnoise()の引数にしています。パーリンノイズはゲーム開発において炎、雲、水などに使用されているので、random()より自然な動きを作り出すことができます。
パーリンノイズについては奥が深く、今回は触り程度の内容なので、機会があれば続きを投稿したいと思います。

参考:ジェネラティブ・アート―Processingによる実践ガイド

180px-Processing_Logo_Clipped.svg

参考にしている本、サイト

ここでは僕が参考にしている本やサイトを紹介します。
Processingはデジタルアートやビジュアルデザインの表現のためのプログラミング言語です。
実行すればすぐに結果が見られ、他の言語でも使用される変数宣言やif文、for文、オブジェクト指向などの勉強も一通りできるので、初心者向きの言語です。
しかし奥も深いので、美しいグラフィックを制作するには、それなりの学習が必要になります。
個人的にはProcessingが一番使いやすく、馴染んでいるのでよく使います。
しかしオブジェクトが多くなると徐々に処理速度が低下しやすいのが難点です。

https://processing.org/

■本

オフィシャルにリファレンスがありますが、最初は本の方がいいと思います。
順序だって学習でき、サンプルや索引があるものが良いです。

・初級編

Processing:ビジュアルデザイナーとアーティストのためのプログラミング入門
Processing開発者のベン・フライ、 ケイシー・リースによって書かれた入門書なので、間違いはないです。
問題は値段。僕も以前英語版を購入しようか迷いましたが、値段がアレなので我慢しました。


Built with Processing[Ver. 1.x対応版] -デザイン/アートのためのプログラミング入門
僕が最初に手に取ったのはこれより改訂前の本でしたが、良き入門書です。
今読み返してもわかりやすいのですが、さすがに内容が古いかも。

・初〜中級編

[普及版]ジェネラティブ・アート―Processingによる実践ガイド
僕が一番オススメしたいのがこの本。
後半は難しくなるので初心者〜中級者向けといったところでしょうか。
ただのリファレンス本ではなく、デザインやアートの視点から順序だてて教えてくれます。
著者マット・ピアソンのジェネラティブアートに関する哲学も書かれていて、読み物としても最高です。

・上級編

ビジュアライジング・データ ―Processingによる情報視覚化手法
2008年出版と古いですが、データの視覚化については今でも参考になります。
途中から難しくなりますと前書きにありますが、最初から難しく、途中から難易度MAXに到達します(笑)

上記の他にも僕が読んでいない日本語の入門書があるので、自分にあった本をます一冊読みこむと良いと思います。

■Web

次はいよいよ自分がイメージしたグラフィックをwebで参考にして実現する番です。
僕が参考にしているサイトをいくつか紹介します。
世の中には本当にすごい、そしてやさしい人が多いです。

Processing学習ノート
Processingの基本から教えてくれます。
説明も丁寧で、今もよく参考にさせてもらっています。

OpenProcessing
Processingの猛者達が自身の作品をアップしています。
嬉しいのはソースコードが見られること。
コードを見たり、写経したりして、どのように組んでいるのかが参考になります。
ただ、高度なプログラミングを駆使している人が多く、レベル高いです。全体的に。

AbandonedArt.org
マット・ピアソンのサイト。こちらのソースコードも参考になります。
レベルも基本が身についていれば理解できるし、勉強にもなります。
憧れの人です。実際に会ったら目をキラキラさせてサインください!!と言っちゃうレベル。

Tutoprocessing
こちらはフランス語(!)ですが初級、中級、上級と分けたチュートリアルがあるので、コードだけ読めればなんとか参考になります。

{Software} Structures by Casey Reas et al.
全体的に難しいですが、Processingで著名な面々のサンプルがあります。
もう更新はされていないようです。