見出し画像

魅惑の周期運動:Processing 2D アニメーション作例

きっかけは、繭凸さん(@mayutotsu)の Twitter 投稿との出会いでした。

かっこいいでしょう?
変化の仕方がとても面白くて、ずっと見てられるアニメーションです。
これ私もやってみたい!と思ったのです。

よーく観察してみると、ひとつひとつの点はそんなに複雑な動きをしているわけではなくとも、点毎に移動速度を変えることで、それらが集まった群としてはとても面白い動きになるというのが特徴のようです。

画像1

よし! 作ってみましょう!

この記事は全文無料でお読みいただけます。もしお気に召しましたら投げ銭お願いしますね。😉✨

画像2

んで、うまくいかない

それで、やってみたんですけど、これがうまくいかない。
こんなのや

こんなの。

挙句はこんなのまで。

なんだこれ? 全然できない…

最初は点の描画位置の計算式を複雑にして、点が動く軌道を複雑にすればいいんだろうなと思ってやってうまくいかず。
じゃあ、まずは単純な円軌道でやってみようとしてもうまくいかない。

私の悪いクセで、せっかくコンピュータ使ってるんだから沢山計算させちゃえと、点を沢山描画したらきっと面白くなるだろうと、
…それが失敗でした。

一つ一つの点毎に移動速度を変えて描画していくわけですが、点が移動する軌道は線状なんですね。
複雑な曲線の軌道だとしても、その軌道に沿って沢山の点が流れていくわけです。
ここに、アホみたいに大量の点を並べるとどうなるか?
はい、賢明なる読者諸氏はもうおわかりですね。

ただの曲線が描かれるだけなんです。

それでこんなことになってしまうわけです。

画像3

アホですね〜、私って。


画像4

できた! 点の数も含めてパラメータ値の設定が大切

そんな紆余曲折(?)の末にできた作品がこちらです。
移動時の残像が残るような装飾も施してみました。

繭凸さんの作品のようにハッとさせられるような動きを作るまでには至りませんでしたが、ひとまず形にはなったかなと思います。

画像5

// 魅惑の周期運動:Processing 2D アニメーション作例
// Processing 3.2.1
// @deconbatch
// 2018.05.27

int   spotCntMax;
float stepCnt;
float stepCntMax;

void setup() {

  size(480, 480);
  colorMode(HSB, 360, 100, 100, 100);
  blendMode(SCREEN);
  frameRate(20);
  smooth();
  noStroke();

  spotCntMax = 20;
  stepCntMax = 20.0;
  stepCnt    = 0.0;

}

void draw() {

  translate(width / 2, height / 2);
  background(0, 0, 0, 100);

  for (int spotCnt = 1; spotCnt <= spotCntMax; ++spotCnt) {

    float start  = map(spotCnt, 1, spotCntMax, 0.0, 1000.0);
    float speed  = map(spotCnt, 1, spotCntMax, 2.0, 0.1);
    float radius = map(spotCnt, 1, spotCntMax, 50, 180);
    float radian = PI * (start + speed * stepCnt);

    for (float radianDiv = 0; radianDiv < 1.0; radianDiv += 0.1) {

      float radianApply = radian + PI * (radianDiv / 10.0 + speed / 4.0);
      float radiusApply = radius + (cos(radianApply) * sin(PI * stepCnt * 0.1)) * 40;
 
      float x = radiusApply * cos(radianApply);
      float y = radiusApply * sin(radianApply);
      
      fill(0, 40, 60 * sin(PI * 0.5 * radianDiv), 100);
      drawEllipse(x, y, 10);
        
    }
  }

  stepCnt += 0.02;
  if (stepCnt > stepCntMax) {
    exit();
  }
  
}

void drawEllipse(float x, float y, float size) {

  ellipse( x,  y, size, size);
  ellipse(-x, -y, size, size);

}

/*
Copyright (C) 2018 deconbatch

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>
*/


今回、x, y 座標計算の計算式は単純な円軌道を描く式になっています。

      float x = radiusApply * cos(radianApply);
      float y = radiusApply * sin(radianApply);

ここの計算式を複雑にすることで複雑な軌道を描くことができると思います。
ですが、この周期運動の場合は移動速度や軌道半径の計算式、それとその計算式に出てくるパラメータ値を調整することが面白い動きを出す秘訣のようです。

(もっとも、サンプルソースの軌道半径の計算式は軌道を変えてるんですけど…)

      float radiusApply = radius + (cos(radianApply) * sin(PI * stepCnt * 0.1)) * 40;

パラメータ値の調整で個々の点の動きの変化は少ししかなくとも、全体の動きの見た目は大きく違ってくる、それがこの周期運動の難しさであり、面白さであると思います。

あ、でも、パラメータ値の調整ではくれぐれも点の個数はほどほどに。
私、今まで『なんでも沢山描画すれば面白くなるんでしょ!』という考えでしたが、今回のことで少し大人になった気がします♥


画像6

追記:基本的動作の確認

いきなり最終的な作例のソースを出されてもわからんですたい!というご意見いただいたので、紆余曲折の中で基本的動作を確認した際のソースをご参考までに載せておきます。

画像7

// 魅惑の周期運動:Processing 2D アニメーション作例
// 基本的な動作の確認
// Processing 3.2.1
// @deconbatch
// 2018.05.28

int   spotCntMax;
float stepCnt;
float stepCntMax;

void setup() {

  size(480, 480);
  colorMode(HSB, 360, 100, 100, 100);
  frameRate(20);
  noStroke();

  spotCntMax = 30;
  stepCntMax = 20.0;
  stepCnt    = 0.0;

}

void draw() {

  translate(width / 2, height / 2);
  background(0, 0, 0, 100);

  for (int spotCnt = 1; spotCnt <= spotCntMax; ++spotCnt) {

    float radius = map(spotCnt, 1, spotCntMax, 10, 200);
    float speed  = map(spotCnt, 1, spotCntMax, 4.0, 0.1);
    float radian = PI * speed * stepCnt;

    float x = radius * cos(radian);
    float y = radius * sin(radian);
    
    fill(spotCnt * 10, 40, 60, 100);
    ellipse(x, y, 10, 10);
        
  }

  stepCnt += 0.02;
  if (stepCnt > stepCntMax) {
    exit();
  }
  
}

/*
  Copyright (C) 2018 deconbatch

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>
*/

グローバル変数の stepCnt でフレームごとの点の全体の速度をコントロール、ローカル変数の radius は点の回転半径、speed は点個々の速度です。

このソースでは回転の中心に近い点ほど速く動くようにしています。点の判別が出来るようにそれぞれに違う色を付けました。

それぞれの点は一定速度で回転しているだけですが、あるタイミングで整列したり、回転がふっと遅くなるように見えたり、全体として意思を持っているかのように感じられます。

周期運動面白いですよね、ぜひお試しあれ。
読んでくださってありがとうございました。


ここでこの記事はおしまいです。もしこの記事がお気に召しましたら投げ銭お願いします。😉✨

ここから先は

0字

¥ 100

この記事が面白かったらサポートしていただけませんか? ぜんざい好きな私に、ぜんざいをお腹いっぱい食べさせてほしい。あなたのことを想いながら食べるから、ぜんざいサポートお願いね 💕