LoginSignup
0
0

More than 1 year has passed since last update.

Processingでアニメーションを作成する

Last updated at Posted at 2021-12-23

■基本編

$ cat sketch_211223a.pde
int degree = 0;
int r = 100;

void setup(){
  size(300,300);
  frameRate(24);
  smooth();
}

void draw(){
  background(0);
  degree += 2;
  float x = width/2 + r * cos(degree*PI/180.0);
  float y = height/2 + r * sin(degree*PI/180.0);
  translate(x,y);
  rotate(-degree * PI/15.0);

  // These below are relative coorinates from the translated origin
  // In this case, (0,0) is the center for rotation
  rect(-10,-10,20,20);

  /*** Save into PNG ***/
  saveFrame("frames/######.png");
}

上記を実行すると以下のPNGが連番フレームで作成される。

$ ls *.png | (head; echo; tail)
000001.png
000002.png
000003.png
000004.png
000005.png
000006.png
000007.png
000008.png
000009.png
000010.png

000316.png
000317.png
000318.png
000319.png
000320.png
000321.png
000322.png
000323.png
000324.png
000325.png

この連番PNGファイルをffmpegで動画作成する。

$ ffmpeg -r 30 -i %06d.png -vcodec libx264 -pix_fmt yuv420p -r 60 out.mp4

動画は添付できないのでイメージのみwww
000325.png

■応用編その1

これはProcessingのご本家サイトからサンプルソースをベースに遊んでみたもの:

$ cat Tree.pde
float theta;
float a;
int direction;
int bCount = 120;

void setup() {
    size(640, 480);
    smooth();
    a = 0;
    direction = 1;
}

void draw() {
    background(0);
    frameRate(24);
    stroke(255);
    theta = radians(a);
    translate(width/2,height);
    line(0,0,0,-240);
    translate(0,-240);
    branch(bCount);
    a += direction;

    if( a < 0 || a > 1280 ) {
        direction = -1 * direction;
    }

    /*** Save into PNG ***/
    saveFrame("frames/######.png");

}

void branch(float h) {
    // Each branch will be 2/3rds the size of the previous one
    h *= 2.0/3;

    // All recursive functions must have an exit condition!!!!
    // Here, ours is when the length of the branch is 2 pixels or less

    if (h > 2) {
        pushMatrix();    // Save the current state of transformation (i.e. where are we now)
        rotate(theta);   // Rotate by theta
        line(0, 0, 0, -h);  // Draw the branch
        translate(0, -h); // Move to the end of the branch
        branch(h);       // Ok, now call myself to draw two new branches!!
        popMatrix();     // Whenever we get back here, we "pop" in order to restore the previous matrix state
        // Repeat the same thing, only branch off to the "left" this time!
        pushMatrix();
        rotate(-theta);
        line(0, 0, 0, -h);
        translate(0, -h);
        branch(h);
        popMatrix();
    }

}

これまた、動画は添付できないのでイメージのみwww

000061.png

■応用編その2

これは鎖をイメージしたこれ私の勝手オリジナルw

ElementManager em;

void setup(){
  em = new ElementManager();
  size(640,640);
  stroke(255);
  smooth();
  background(0);
}

void draw(){
  background(0);
  translate(width/2, height/2);
  scale(1,-1);
  em.move();
  em.renderAll();

  /*** Save into PNG ***/
  saveFrame("frames/######.png");
}

class Element{
  float x;
  float y; 
  Element follower = null;

  public Element( float x, float y ){
    this.x = x;
    this.y = y; 
  }
}

class ElementManager{
  final int NUM_OF_ELEMENTS = 128;
  ArrayList al;
  float len = 25;
  int angle = 0;

  ElementManager(){
    al = new ArrayList();
    for(int i=0;i<NUM_OF_ELEMENTS;i++){
      al.add(new Element(-len*i,0));
    }
    // println(al.size());
  }

  public int getSize(){
    return al.size(); 
  }

  public void move(){
    angle += 1;
    // The 1st one moves freewheelingly
    Element e1st = (Element)al.get(0);
    e1st.x += -10*cos(angle*PI/90.0);
    e1st.y += 5*cos(angle*PI/180.0);

    // println( e1st.y );

    for(int i=1;i<al.size();i++){
      Element e1 = (Element)al.get(i-1);
      Element e2 = (Element)al.get(i);

      // get unit vertor
      float vx = e1.x - e2.x;
      float vy = e1.y - e2.y;
      float distance = sqrt(vx*vx + vy*vy);
      vx /= distance;
      vy /= distance;

      // set new location
      e2.x = e1.x - vx * len;
      e2.y = e1.y - vy * len;   
    }
  }

  public void renderAll(){
    for(int i=0;i<al.size()-1;i++ ){
      Element e1 = (Element)al.get(i);
      Element e2 = (Element)al.get(i+1);
      rectMode(CENTER);
      rect(e1.x, e1.y, 3, 3);
      rect(e2.x, e2.y, 3, 3);
      line(e1.x, e1.y, e2.x, e2.y);
    }
  }

}

000057.png
000184.png
000232.png

■応用編その3

// $ astyle --delete-empty-lines --mode=java --indent=spaces=2 Chain.pde


// $ cat Chain.pde
ElementManager em;

void setup() {
  em = new ElementManager();
  size ( 1500, 640 );
  stroke ( 255 );
  smooth();
  background ( 0 );
}

void draw() {
  background ( 0 );
  translate ( width/2, height/2 );
  scale ( 1,-1 );
  em.move();
  em.renderAll();
  /*** Save into PNG ***/
  // saveFrame ( "frames/######.png" );
}

class Element {

  float x;
  float y;

  // Element follower = null;
  public Element ( float x, float y ) {
    this.x = x;
    this.y = y;
  }

}

class ElementManager {

  final int NUM_OF_ELEMENTS = 256;
  ArrayList al;
  float len = 25;
  int angle = 0;

  ElementManager() {
    al = new ArrayList();
    for ( int i=0; i<NUM_OF_ELEMENTS; i++ ) {
      al.add ( new Element ( -len*i,0 ) );
    }
    // println(al.size());
  }

  public int getSize() {
    return al.size();
  }

  public void move() {
    angle += 1;
    // The 1st one moves freewheelingly
    Element e1st = ( Element ) al.get ( 0 );
    e1st.x += 3*sin ( angle*PI/320.0 );
    e1st.y += 5*cos ( angle*PI/180.0 );
    // println( e1st.y );
    for ( int i=1; i<al.size(); i++ ) {
      Element e1 = ( Element ) al.get ( i-1 );
      Element e2 = ( Element ) al.get ( i );
      // get unit vertor
      float vx = e1.x - e2.x;
      float vy = e1.y - e2.y;
      float distance = sqrt ( vx*vx + vy*vy );
      vx /= distance;
      vy /= distance;
      // set new location
      e2.x = e1.x - vx * len;
      e2.y = e1.y - vy * len;
    }
  }

  public void renderAll() {
    for ( int i=0; i<al.size()-1; i++ ) {
      Element e1 = ( Element ) al.get ( i );
      Element e2 = ( Element ) al.get ( i+1 );
      rectMode ( CENTER );
      rect ( e1.x, e1.y, 3, 3 );
      rect ( e2.x, e2.y, 3, 3 );
      line ( e1.x, e1.y, e2.x, e2.y );
    }
  }

}

キャプチャ.PNG

■備忘録

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0