「がんばれない」けど「がんばりたい」

ITエンジニアの仕事のこと。AI、機械学習、ディープラーニング。地頭力。車のこと。

Waves|Nature of Code

角速度を用いて位置を変化させる事について前回の記事で行ってみた。今回は波をプロットしてみる事を行ってみる。といっても、前回までの角速度を用いたオブジェクト移動のロジックと同じ。

■Static wave
まずシンプルに考えて動かないStatic波を表示してみる。初期値としては今まで通り以下を用意。

float angle = 0.0;
float aVelocity = 0.02;
float amplitude = 100.0;

次に考える事は、

  1. y値をangleおよびamplitudeを使って計算する
  2. x, yの位置に円を描画する
  3. angleの値をaVelocityで更新していく

aVelocity値によって波形は以下のように違う。角速度aVelocityが大きいほどperiod(周期)は小さくなっているのが分かる。

●aVelocity = 0.02

●aVelocity = 0.2

●aVelocity = 0.4 wave0.4

code is following.

float amplitude = 200;
float ang = 0.0;
float aVelocity = 0.4;

//--------------------------------------------------------------
void testApp::setup(){
    
    ofSetFrameRate(60);
    ofEnableSmoothing();
    ofSetVerticalSync(true);
    ofBackground(100);

    glPointSize(2.0);
    ofNoFill();
}

//--------------------------------------------------------------
void testApp::update(){
    ang = 0.0;
}

//--------------------------------------------------------------
void testApp::draw(){
    
    glBegin(GL_LINE_STRIP);
    for (int x = 0; x < ofGetWidth(); x+=5)
    {
        float y = amplitude * sin(ang);
        glVertex3f(x, y + ofGetHeight() * .5, 0);
        ang += aVelocity;
    }
    glEnd();
}

■dynamic wave

静止状態の波を描画出来たので、今度は波を動かしてみる。これは以下のコードのように毎フレーム毎にdraw内で開始する最初のθを変更していく事で可能。この考え方って、結構重要。draw内で使用しているグローバル変数angleに対して直接update()内でincrementすればいいと思いがちだったり、draw()内でなんとかしてやろうとか考えると、うまくいかない(※いろんな変数を用意して、複雑なロジックにすればいけるかもだけど…)。

float amplitude = 200;
float ang = 0.0;
float aVelocity = 0.02;


/*-----------------------------------------
 [変更点]
//毎フレーム毎に描画開始するθを変更する事によって、
//波が動いているように見える
 -----------------------------------------*/
float startAngle = 0.0;


//--------------------------------------------------------------
void testApp::setup(){
    
    ofSetFrameRate(60);
    ofEnableSmoothing();
    ofSetVerticalSync(true);
    ofBackground(100);

    glPointSize(1.0);
}

//--------------------------------------------------------------
void testApp::update(){
    
    //毎フレーム毎にstartAngleを更新
    startAngle += 0.08;
}

//--------------------------------------------------------------
void testApp::draw(){
    
    glBegin(GL_LINE_STRIP);
    
    ang = startAngle;
    
    for (int x = 0; x < ofGetWidth(); x+=5)
    {
        float y = amplitude * sin(ang);
        glVertex3f(x, y + ofGetHeight() * .5, 0);
        ang += aVelocity;
    }
    glEnd();
}