「The Nature of Code」から回転角について取り上げます。物体がマウスに向かって移動するとき、移動方向を向いて進みます。つまり、速度ベクトルに従って角度を変えつつ進みます。Processingでプログラムを書いて、動作を確認します。動作を確認できるところがProcessingの楽しいところです。
速度ベクトルの傾き:tangent
速度ベクトルの傾きとアークタンジェントから角度を求めます。タンジェントとアークタンジェントの関係は以下だそうです。
- tangent(angle) = velocity.y / velocity.x = 傾き(x座標分のy座標)
- angle = arctangent(velocity.y / velocity.x)
これより、速度ベクトルの角度(θ=回転角)が計算できます。
回転角を利用したプログラム
以前の記事(PVectorと加速度(マウスに向かう加速))では、マウスに向かう物体の形は円でした。今回は、長方形の物体をマウスに向かわせます。以下は、その参考例です。
class Mover{ PVector location; PVector velocity; PVector acceleration; float topspeed; //コンストラクタ Mover(){ location = new PVector(width/2, height/2); velocity = new PVector(0, 0); acceleration = new PVector(0, 0); topspeed = 4; } //座標の更新 void update(){ PVector mouse = new PVector(mouseX, mouseY); PVector dir = PVector.sub(mouse, location); dir.normalize(); dir.mult(0.5); acceleration = dir; velocity.add(acceleration); velocity.limit(topspeed); location.add(velocity); } //ウィンドウから外れたときの処理 void checkEdges(){ //幅に対して if(location.x > width){ location.x = 0; }else if(location.x < 0){ location.x = width; } //高さに対して if(location.y > height){ location.y = 0; }else if(location.y < 0){ location.y = height; } } //図形の表示 void display(){ //float theta = atan2(velocity.y, velocity.x); float theta = velocity.heading(); background(255); stroke(0); fill(127); pushMatrix(); rectMode(CENTER); translate(location.x, location.y); rotate(theta); rect(0, 0, 30, 10); popMatrix(); } }
//Pointing in the direction of motion Mover mover; void setup(){ size(200, 200); mover = new Mover(); } void draw(){ background(255); mover.update(); mover.checkEdges(); mover.display(); }
プログラムの解説
display()メソッド内で、物体の速度ベクトルの角度(θ=回転角)を取得します。速度ベクトルはマウスの方向を指します。その値をrotate()メソッドに渡して、物体を回転させます。物体は常にマウスの方向を向いて進みます。
//図形の表示 void display(){ //float theta = atan2(velocity.y, velocity.x); //速度ベクトルの角度の取得 float theta = velocity.heading(); //上記の書き換え background(255); stroke(0); fill(127); pushMatrix(); rectMode(CENTER); translate(location.x, location.y); rotate(theta); rect(0, 0, 30, 10); popMatrix(); }
メモ
//atan()の実行例 float a1 = atan(1/1); float a2 = atan(-1/-1); println(degrees(a1) + " : " + degrees(a2)); //45.0 : 45.0と表示
//atan2()の実行例 float a1 = atan2(1, 1); //(1, 1) float a2 = atan2(-1, -1); //(-1, -1) println(degrees(a1) + " : " + degrees(a2)); //45.0 : -135.0と表示
//atan2()とheading()の実行例 PVector velocity = new PVector(1, -1); float angle1 = atan2(velocity.y, velocity.x); float angle2 = velocity.heading(); println(degrees(angle1)); //-45.0と表示 println(degrees(angle2)); //-45.0と表示
まとめ
「The Nature of Code」から回転角について取り上げました。回転角を考えるときは、三角比が理解の助けになります。引き続き、「The Nature of Code」の内容を勉強します。
参考書籍
※Javaの勉強にもなるので一石二鳥です。