元Webデザイナー兼コーダーの備忘録

ウェブデザインやプログラミング、ブログのカスタマイズなどについてアウトプットしています。

 メニュー

» HTML入門のまとめはこちらです。

Processing:摩擦

The Nature of Code(PDF版)から摩擦について取り上げます。今回は、摩擦のプログラムについて学びます。Processingでプログラムを書いて、動作を確認します。動作を確認できるところがProcessingの楽しいところです。

PVectorと摩擦

F(friction) = -1 * μ * N * \hat{v}

この式を摩擦の向きと大きさに分解して考えます。

  • 向き
    • -\hat{v}:速度の単位ベクトルの-1倍
    • 摩擦は速度(移動方向)と逆方向
  • 大きさ
    • μ*N(動摩擦係数×垂直抗力)
    • μ(動摩擦係数):任意の値
    • N(垂直抗力):1とする

摩擦なし

比較のため摩擦なしのプログラムを用意します。

class Mover {
  PVector location;
  PVector velocity;
  PVector acceleration;
  float mass;  //質量

  //コンストラクタ
  Mover() {
    location = new PVector(30,30);
    velocity = new PVector(0,0);
    acceleration = new PVector(0,0);
    mass = 1;
  }
  Mover(float m, float x, float y) {
    location = new PVector(x,y);
    velocity = new PVector(0,0);
    acceleration = new PVector(0,0);
    mass = m;
  }

  //力を足し合わせる(力の蓄積)
  void applyForce(PVector force) {
    PVector f = PVector.div(force,mass);
    acceleration.add(f);
  }

  //ボールの位置の更新
  void update() {
    velocity.add(acceleration);
    location.add(velocity);
    acceleration.mult(0);  //力の蓄積をリセットする
  }

  //ボールの描画
  void display() {
    stroke(0);
    strokeWeight(2);
    fill(0, 127);
    ellipse(location.x,location.y,mass*16,mass*16);
  }

  //ボールがウィンドウから外れたときの処理
  void checkEdges() {
    if (location.x > width) {
      location.x = width;
      velocity.x *= -1;
    } else if (location.x < 0) {
      velocity.x *= -1;
      location.x = 0;
    }

    if (location.y > height) {
      velocity.y *= -1;
      location.y = height;
    }
  }
}
//nofriction
Mover[] movers = new Mover[5];

void setup() {
  size(400,200);
  randomSeed(1);
  smooth();

  for(int i = 0 ; i < movers.length; i++){
    movers[i] = new Mover(random(0.1,4), random(width),0);
  }
}

void draw() {
  background(255);

  for(int i = 0; i < movers.length; i++){
    PVector wind = new PVector(0.01,0);  //風
    float m = movers[i].mass;
    PVector gravity = new PVector(0,0.1*m);  //重力

    movers[i].applyForce(wind);
    movers[i].applyForce(gravity);

    movers[i].update();
    movers[i].display();
    movers[i].checkEdges();
  }
}

摩擦あり

以下は、摩擦のプログラムの参考例です。Moverクラスは、摩擦なしと同じものを使います。draw()メソッド内で摩擦を計算して、ボールに摩擦の力を適用します。

//Including friction
Mover[] movers = new Mover[5];

void setup() {
  size(400,200);
  randomSeed(1);
  smooth();

  for(int i = 0 ; i < movers.length; i++){
    movers[i] = new Mover(random(0.1,4), random(width),0);
  }
}

void draw() {
  background(255);

  for(int i = 0; i < movers.length; i++){
    PVector wind = new PVector(0.01,0);  //風
    float m = movers[i].mass;
    PVector gravity = new PVector(0,0.1*m);  //重力

    //摩擦の計算
    float c = 0.05; //動摩擦係数
    PVector friction = movers[i].velocity.copy();
    friction.mult(-1);
    friction.normalize();
    friction.mult(c);

    movers[i].applyForce(friction); //ボールに摩擦を適用する
    movers[i].applyForce(wind);
    movers[i].applyForce(gravity);

    movers[i].update();
    movers[i].display();
    movers[i].checkEdges();
  }
}

静止画だと分かりにくいので、プログラムを実行して確認することをおすすめします。

プログラムの解説

以下のように摩擦の力を計算します。ボールの速度ベクトルを取得し、マイナス1をかけて、正規化、動摩擦係数をかけます。

//摩擦の計算
float c = 0.05;
PVector friction = movers[i].velocity.copy();
friction.mult(-1);
friction.normalize();
friction.mult(c);

摩擦を計算したら、ボールに摩擦の力を適用します。

movers[i].applyForce(friction);

メモ

  • randomSeed(int):パラメータを定数に設定すると同じ擬似乱数が設定される
  • copy():新たなPVectorにベクトルをコピーして返す

まとめ

The Nature of Code(PDF版)から摩擦について取り上げました。今回は、摩擦のプログラムについて学びました。引き続き、The Nature of Code(PDF版)の内容を勉強します。

参考サイト

» HTML入門のまとめはこちらです。