Part.4に続いて、Processingによる回転・振動に関する解説です。今回は「ばね」の実装がテーマです。
目次
「ばね」の実装
「ばね」は静止長(力が加わっていない時に静止する長さ)から伸びたり縮められたりした際にその方向とは逆向きの力が、長さの変化に比例する大きさで力が働きます。これはフックの法則として知られており、以下のように定式化できます。
フックの法則(Hooke’s Law)
フックの法則は、弾性力学において、理想的なバネに働く復元力が、バネの変位に比例するという法則です。フックの法則は以下の式で表されます:
F=−kx
ここで、
- F はバネによる力(N)
- k はバネ定数(N/m)
- x はバネの変位(m)
符号「-」は、力が変位の方向とは逆であることを示しています。つまり、バネは自然な長さに戻ろうとする力を持っています。
Processingにおけるフックの法則の実装
以下は、Processingでフックの法則を利用してバネの動きをシミュレートする基本的なサンプルコードです。
class Bob {//おもり部分のクラス
PVector location;
PVector velocity;
PVector acceleration;
Bob(float x, float y) {
location = new PVector(x, y);
velocity = new PVector(0, 0);
acceleration = new PVector(0, 0);
}
void display() {
fill(127);
ellipse(location.x, location.y, 16, 16);
}
void update() {
velocity.add(acceleration);
location.add(velocity);
acceleration.mult(0); // 重力加速度をリセット
}
void applyForce(PVector force) {
PVector f = force.get();
acceleration.add(f);
}
}
class Spring {//ばねの部分のクラス
PVector anchor; ////ばねの片方の端(おもりではなく、屋根などに固定する側の端の位置)
float len; //ばねの静止長
float k = 0.1;//ばね定数
Spring(float x, float y, int l) {
anchor = new PVector(x, y);
len = l;
}
void connect(Bob b) {//おもりとの結合
PVector force = PVector.sub(b.location, anchor);
float d = force.mag(); //ばねの現在の長さ
float stretch = d - len; //静止長より伸びていればプラス、縮められていればマイナスの値になる
force.normalize();
force.mult(-1 * k * stretch); // F=-kx (xは静止長からの伸び具合、伸びていればプラス、縮んでいればマイナスをとる値)
b.applyForce(force); //繋がっているおもりにばねから力を加える
}
void display() {//ばねの根本を描画
fill(175);
rectMode(CENTER);
rect(anchor.x, anchor.y, 10, 10);
}
void displayLine(Bob b) {//おもりとばねの間の線を描画
stroke(0);
line(b.location.x, b.location.y, anchor.x, anchor.y);
}
}
// メインプログラム
Bob bob;
Spring spring;
void setup() {
size(400, 300);
bob = new Bob(width/2, 100);
spring = new Spring(width/2, 10, 90);
}
void draw() {
background(255);
PVector gravity = new PVector(0, 2); //重力を画面下方向に2と固定
bob.applyForce(gravity);
spring.connect(bob);
spring.displayLine(bob);
bob.update();
bob.display();
spring.display();
}
「Nature of Code Processingではじめる自然現象のシミュレーション」ダニエル・シフマン著 尼岡 利祟監修 p.116 Example 3.11 ばねの結合を参考に作成
上記コードはこれまでに登場したコードに比べると量が多いですが、これまでに実装してきたものの組み合わせによって成り立っています。以下にコードの解説を行います。
Bob クラス
Bob
クラスは、バネの下端に取り付けられた重り(ボブ)を表現しています。このクラスには以下の主要なメソッドとプロパティがあります。
location
、velocity
、acceleration
:それぞれ重りの位置、速度、加速度を表現するPVector
オブジェクトです。display()
:重りを描写するためのメソッドです。このメソッドでは、重りの位置に灰色の円を描写します。update()
:重りの動きを更新するためのメソッドです。このメソッドでは、加速度から速度を、速度から位置を更新します。最後に、加速度をリセットします。applyForce(PVector force)
:外部から力を加えるためのメソッドです。引数として力ベクトルを受け取り、それを加速度に加えます。
Spring クラス
Spring
クラスは、バネを表現しています。このクラスには以下の主要なメソッドとプロパティがあります。
anchor
:バネの固定点の位置を表現するPVector
オブジェクトです。len
:バネの自然長です。k
:バネ定数です。バネの硬さを表現します。connect(Bob b)
:バネと重りを接続し、重りに作用するバネ力を計算し適用するメソッドです。display()
:バネの固定点を描写するためのメソッドです。displayLine(Bob b)
:バネの固定点と重りを結ぶ線を描写するためのメソッドです。
演習
- 自分でも「ばね」の実装を作成してみてください(実装方法は一通りではないので、自分でクラスの設計から考えてみても良いです)。
- マウスでおもりを引っ張れるように修正を加えてください。