The Nature of Code(PDF版)から摩擦について取り上げます。今回は、摩擦のプログラムについて学びます。Processingでプログラムを書いて、動作を確認します。動作を確認できるところがProcessingの楽しいところです。
PVectorと摩擦
この式を摩擦の向きと大きさに分解して考えます。
- 向き
- :速度の単位ベクトルの-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版)の内容を勉強します。