memorandums

日々の生活で問題解決したこと、知ってよかったことなどを自分が思い出すために記録しています。

マネって楽しい(p5.js)

いきさつ

ツイッターのTLでたまたま見つけた対談動画,著名な先生の対談で楽しく視聴させていただきました.

建築情報学会という学会があるということを初めて知り,情報を色々と追ってみました.自分の建築というイメージとはちょっと違っていて,コンピュータにも近い感じがします.さらに以下の動画を拝見しました.

そこで,池田亮司さんを初めて知りました.作品を拝見するとこれがまたカッコいい...こういう分野は関心があったつもりですが...知らなかったのが恥ずかしいくらい有名な方のようです.その作品の1つがこれ.

もうカッコいいのなんのって...LEDビジョンなんでしょうね.暗闇で高輝度な大型ビジョンに映し出された幾何学的であり情報学的であり不思議な映像でした.

ちょっと自分にも作れそうなシーンをマネしてみることにしました.せっかくなのでForkを使ってバージョン管理しながら進めたいと思います.

ちょっと長くなりますが,もしご興味がありましたらお付き合いください.

実装環境はp5.jsです.p5jseditorなんかを使うとブラウザ上で試せますので遊んでみてください.

少しずつ本物に近づける過程,これが楽しい

まず,こちらをクリックして実装する映像を見てください.上記と同じコンテンツですが開始位置を指定しています.開始2:45のところから5秒くらい流れるシーンです.

1.最初のトライ

まず,ドットを右から左に流してみます.コードはこんな感じです.

let dt = [];



function setup() {

  createCanvas(600, 400);

  for (let i=0; i<100; i++) {

    let s = random(5);

    dt.push({x:width, y:random(height), dx:s});

  }

  stroke(255);

}



function draw() {

  background(0);

  for (let a of dt) {

    line(a.x, a.y, a.x+a.dx, a.y);

    a.x -= a.dx;

  }

}

2.つづいて連続してドットを流すように

let dt = [];



function setup() {

  createCanvas(600, 400);

  for (let i=0; i<100; i++) {

    let s = random(5);

    dt.push({x:width, y:random(height), dx:s});

  }

  stroke(255);

}



function draw() {

  background(0);

  for (let a of dt) {

    line(a.x, a.y, a.x+a.dx, a.y);

    a.x -= a.dx;

  }

  if (random() < 0.1) add_dt(10);

}



function add_dt(n) {

  for (let i=0; i<n; i++) {

    let s = random(5);

    dt.push({x:width, y:random(height), dx:s});

  }

}

3.流すドットをちょっと多めに変更してみました

let dt = [];



function setup() {

  createCanvas(600, 400);

  for (let i=0; i<100; i++) {

    let s = random(5);

    dt.push({x:width, y:random(height), dx:s});

  }

  stroke(255);

}



function draw() {

  background(0);

  for (let a of dt) {

    line(a.x, a.y, a.x+a.dx, a.y);

    a.x -= a.dx;

  }

  if (random() < 0.1) add_dt(100);

}



function add_dt(n) {

  for (let i=0; i<n; i++) {

    let s = random(5);

    dt.push({x:width, y:random(height), dx:s});

  }

}

4.なんか違う...

もとの動画をここで改めて見てみるとどうもランダムな位置からランダムでドットが出ている感じではないように見えました.左から右に向かってビット列を伝送路にのせて流しているイメージです.ということで,ドットストリームを生成するようなクラスを作りました.かなりいい感じになりました.

class Generator {

  constructor(x, y, sp) {

    this.x = x;

    this.y = y;

    this.sp = sp;

    this.dt = [];

  }

  update() {

    for (let i=this.dt.length-1; i>=0; i--) {

      this.dt[i].x -= this.sp;

      if (this.dt[i].x < 0) this.dt.splice(i, 1);

    }

    if (random() < 0.2) {

      this.dt.push({x: this.x, y: this.y, l: random(5)}); 

    }

  }

  draw() {

    for (let d of this.dt) {

      line(d.x, d.y, d.x+d.l, d.y);

    }

  }

}





let gt = [];



function setup() {

  createCanvas(600, 400);

  for (let i=0; i<100; i++) {

    gt.push(new Generator(width, random(height), random(1,5)));

  }

  stroke(255);

}



function draw() {

  background(0);

  for (let g of gt) {

    g.update();

    g.draw();

  }

}

5.2次元ではなく3次元かぁ〜い

再度,本物をみると2次元ではなく3次元空間のように見えました.3Dにしてもいいのですが面倒だったので疑似3Dっぽくすることにしました.要は遠近法的なやつですね.とりあえずY座標方向にも少し移動するようにしただけです.ただの斜め移動ですね...

class Generator {

  constructor(x, y, sp) {

    this.x = x;

    this.y = y;

    this.sp = sp;

    this.dt = [];

  }

  update() {

    for (let i=this.dt.length-1; i>=0; i--) {

      this.dt[i].x -= this.sp;

      this.dt[i].y -= this.sp/10.0;

      if (this.dt[i].x < 0) this.dt.splice(i, 1);

    }

    if (random() < 0.2) {

      this.dt.push({x: this.x, y: this.y, l: random(5)}); 

    }

  }

  draw() {

    for (let d of this.dt) {

      line(d.x, d.y, d.x+d.l, d.y);

    }

  }

}





let gt = [];



function setup() {

  createCanvas(600, 400);

  for (let i=0; i<100; i++) {

    gt.push(new Generator(width, random(height), random(1,5)));

  }

  stroke(255);

}



function draw() {

  background(0);

  for (let g of gt) {

    g.update();

    g.draw();

  }

}

6.遠近法的な感じにしたかったけど...あれ?

斜めだけでは遠近法ではないので...とちょっと考えてやってみたら偶然できたのが以下です.これはこれで...面白い.

class Generator {

  constructor(x, y, sp) {

    this.x = x;

    this.y = y;

    this.sp = sp;

    this.dt = [];

  }

  update() {

    for (let i=this.dt.length-1; i>=0; i--) {

      this.dt[i].x -= this.sp;

      this.dt[i].y -= this.sp/((width+1-this.dt[i].x)*0.05);

      if (this.dt[i].x < 0) this.dt.splice(i, 1);

    }

    if (random() < 0.2) {

      this.dt.push({x: this.x, y: this.y, l: random(5)}); 

    }

  }

  draw() {

    for (let d of this.dt) {

      line(d.x, d.y, d.x+d.l, d.y);

    }

  }

}





let gt = [];



function setup() {

  createCanvas(600, 400);

  for (let i=0; i<100; i++) {

    gt.push(new Generator(width, random(height), random(1,5)));

  }

  stroke(255);

}



function draw() {

  background(0);

  for (let g of gt) {

    g.update();

    g.draw();

  }

}

7.今度こそ遠近法的にした

もう少し頑張って変えてみました.おおっと思いましたが...なんかちがう...ドットの移動速度をそれぞれで変えているのですが,横方向の移動速度と縦方向の増分のバランスがとれていないのでこうなっちゃうんですね...

class Generator {

  constructor(x, y, sp) {

    this.x = x;

    this.y = y;

    this.dy = (300 - y) * 0.005;

    this.sp = sp;

    this.dt = [];

  }

  update() {

    for (let i=this.dt.length-1; i>=0; i--) {

      this.dt[i].x -= this.sp;

      this.dt[i].y -= this.dy;

      if (this.dt[i].x < 0) this.dt.splice(i, 1);

    }

    if (random() < 0.2) {

      this.dt.push({x: this.x, y: this.y, l: random(5)}); 

    }

  }

  draw() {

    for (let d of this.dt) {

      line(d.x, d.y, d.x+d.l, d.y);

    }

  }

}





let gt = [];



function setup() {

  createCanvas(600, 400);

  for (let i=0; i<100; i++) {

    gt.push(new Generator(width, random(height), random(1,5)));

  }

  stroke(255);

}



function draw() {

  background(0);

  for (let g of gt) {

    g.update();

    g.draw();

  }

}

8.やっとできた👍

角度とスピードを定義して作ればいいんでしょうけど面倒だったのであれこれやったらできた感じです.まぁ,同じようなものができた気がします.

class Generator {

  constructor(x, y, sp) {

    this.x = x;

    this.y = y;

    this.dy = (300 - y) * 0.002;

    this.sp = sp;

    this.dt = [];

  }

  update() {

    for (let i=this.dt.length-1; i>=0; i--) {

      this.dt[i].x -= this.sp;

      this.dt[i].y -= (this.dy*this.sp);

      if (this.dt[i].x < 0) this.dt.splice(i, 1);

    }

    if (random() < 0.2) {

      this.dt.push({x: this.x, y: this.y, l: random(5)}); 

    }

  }

  draw() {

    for (let d of this.dt) {

      line(d.x, d.y, d.x+d.l, d.y);

    }

  }

}





let gt = [];



function setup() {

  createCanvas(600, 400);

  for (let i=0; i<100; i++) {

    gt.push(new Generator(width, random(height), random(1,5)));

  }

  stroke(255);

}



function draw() {

  background(0);

  for (let g of gt) {

    g.update();

    g.draw();

  }

}

Gifだと汚いので,YouTubeの動画も貼っておきます.せっかく作ったので.

 

はい,以上になります.ここまで3時間くらいでしょうか.楽しめました.コードはこちらにもおいています.よろしければどうぞ.あ〜楽しかった😁

https://openprocessing.org/sketch/1497717

inspired_lines - OpenProcessing I created it because I was inspired by this work. https://www openprocessing.org