surolog

AI・機械学習・データ分析 と 本 など

ベクトルの導入

NATUREofCODE

processingを用いたプログラミングの書籍として、「NATUREofCODE」というとてもおもしろいものがあります。ざっくりいうとprocessingを使って物理シミュレーションを行う内容なのですが、高校の物理の教科書に出てくるような簡単な物理法則の式を実装・適用するだけで、驚くほど生き生きと物体をシミュレートすることができます。
勉強をかねて、コードを実装していきます。

Nature of Code -Processingではじめる自然現象のシミュレーション-

Nature of Code -Processingではじめる自然現象のシミュレーション-

ベクトル

今後、コードで物理シミュレーションを実現するにあたって、重要な要素である「ベクトル」を導入していきます。
ベクトルという言葉は、いろいろなシーンでいろいろな意味で使われています。プログラムでも配列データ構造をベクトルと呼んだりしますが、ここで使う場合のベクトルはユークリッドベクトルを指します。意味するところは、「大きさと方向の両方を持つ実体」であるということです。

ベクトルなしで運動を表現

ベクトルは今後、物理シミュレーションとして「運動」を表現するにあたり必要になってきます。
ですが、ひとまずベクトルなしで運動をコードで表現してみます。シンプルなバウンドし続けるボールを描いてみます。

Fig1.バウンドするボール
f:id:sator926:20160225212129g:plain

コードはこちらになります。

float x=100;
float y=100;
float xspeed=1;
float yspeed=3;

void setup(){
  size(500,300);
  background(255);
}

void draw(){
  fill(255,100);
  rect(0,0,width,height);

  //update x,y  
  x=x+xspeed;
  y=y+yspeed;
  
  //collision detection 
  if((x>width) || (x<0)){
    xspeed=xspeed*-1;
  }
  if((y>height) || (y<0)){
    yspeed=yspeed*-1;
  }
  noStroke();
  fill(125);
  ellipse(x,y,25,25);
}

上記のコードの中で、ボールの運動は直前の位置(x,y)に速度(xspeed,yspeed)を加えたものになります。
つまり速度は、現在の位置と直前の位置の差になります。そこには、「方向」があり、移動距離という「大きさ」があるので、ベクトルとして表現することができそうです。一方位置は、空間上の1点を指しているように見えます。しかし、どこかに原点があると考えると(実際、processingの平面上ではデフォルトで左上隅が座標(0,0)の原点です)、位置も原点からその位置までのベクトルと考えることができます。そこで、位置と速度をベクトルとして再定義してみます。

class PVector{
 float x;
 float y;

 PVector(float x_, float y_){
  x=x_;
  y=y_;
 }

 //ベクトル加算の表現
 void add(PVector v){
  x=x+v.x;
  y=y+v.y;
 }
}

PVector location = new PVector(100,100);
PVector velocity = new PVector(1,3);

それでは、このベクトル表現を使ってバウンドするボールのコードを書き直します。

PVector location;
PVector velocity;

void setup(){
  size(500,300);
  background(255);
  
  location = new PVector(100,100);
  velocity = new PVector(1,3);
}

void draw(){
  fill(255,100);
  rect(0,0,width,height);

  //update location
  location.add(velocity);
  
  //collision detection
  if((location.x>width) || (location.x<0)){
    velocity.x=velocity.x*-1;
  }
  if((location.y>height) || (location.y<0)){
    velocity.y=velocity.y*-1;
  }
  noStroke();
  fill(125);
  ellipse(location.x,location.y,25,25);
}

一見するとスッキリしたわけではないですが、これから先、相互作用しあう複数の物体を表現するときに、ベクトル表現が大きな力を発揮します。