「The Nature of Code」から回転運動について取り上げます。複数の物体に任意の角度で回転運動をさせる方法について学びます。Processingでプログラムを書いて、動作を確認します。動作を確認できるところがProcessingの楽しいところです。
本記事の参考書籍は以下です。
万有引力と回転運動を組み合わせる
以下は、万有引力と回転運動を組み合わせたプログラムです。Moverクラス、Attractorクラス、実行用クラスを作ります。Moverクラスに回転運動に関する記述を追加します。
回転角は、物体の速度(ランダムな値)と加速度、万有引力の影響を受けます。
class Mover{ PVector location; PVector velocity; PVector acceleration; float mass; //角度に関する変数 float angle = 0; float aVelocity = 0; float aAcceleration = 0; //コンストラクタ Mover(float mass, float x, float y){ this.mass = mass; location = new PVector(x, y); velocity = new PVector(random(-1, 1), random(-1, 1)); acceleration = new PVector(0, 0); } //力を適用する void applyForce(PVector force){ PVector f = PVector.div(force, mass); acceleration.add(f); } //値の更新 void update(){ //座標の更新 velocity.add(acceleration); location.add(velocity); //回転角の更新 aAcceleration = acceleration.x / 10.0; aVelocity += aAcceleration; aVelocity = constrain(aVelocity, -0.1, 0.1); angle += aVelocity; acceleration.mult(0); } //図形の描画 void display(){ stroke(0); fill(175, 200); rectMode(CENTER); pushMatrix(); translate(location.x, location.y); rotate(angle); rect(0, 0, mass*16, mass*16); popMatrix(); } }
class Attractor{ float mass; PVector location; float g; //引力定数 //コンストラクタ Attractor(){ location = new PVector(width/2, height/2); mass = 20; g = 0.4; } //引力を求める PVector attract(Mover m){ PVector force = PVector.sub(location, m.location); float distance = force.mag(); distance = constrain(distance, 5.0, 25.0); force.normalize(); float strength = (g * mass * m.mass) / (distance * distance); force.mult(strength); return force; } //アトラクタの描画 void display(){ stroke(0); strokeWeight(2); fill(127); ellipse(location.x, location.y, 48, 48); } }
//Angular motion using rotate() with Mover Mover[] movers = new Mover[20]; Attractor a; void setup() { size(400, 400); for(int i = 0; i < movers.length; i++){ movers[i] = new Mover(random(0.1, 2), random(width), random(height)); } a = new Attractor(); } void draw() { background(255); a.display(); for(int i = 0; i < movers.length; i++){ PVector force = a.attract(movers[i]); movers[i].applyForce(force); movers[i].update(); movers[i].display(); } }
プログラムを実行して確認することをおすすめします。
プログラムの解説
Moverクラスに角度に関する変数を用意します。
update()メソッド内で、回転する角度の値を計算します。
//値の更新 void update(){ //座標の更新 ... //回転角の更新 aAcceleration = acceleration.x / 10.0; aVelocity += aAcceleration; aVelocity = constrain(aVelocity, -0.1, 0.1); angle += aVelocity; acceleration.mult(0); }
メモ
- rectMode(CORNER, CORNERS, CENTER, or RADIUS);
- 矩形の描画モードを指定する
- pushMatrix();
- 現在の座標系をスタックに保存する
- pophMatrix();
- 前の座標系を復元する
まとめ
「The Nature of Code」から回転運動について取り上げました。複数の物体に任意の角度で回転運動をさせる方法について学びました。引き続き、「The Nature of Code」の内容を勉強します。
参考書籍
※Javaの勉強にもなるので一石二鳥です。