アニメーションでsin波を描画してみる、というものを作ります。
#sinについて
sinはみなさん高校で勉強してきたと思います。
sinはそのまま使うとすると-1から1の範囲を行き来します。
値 | 0 | 1 | 0 | -1 | 0 |
---|---|---|---|---|---|
度数法 | 0° | 90° | 180° | 270° | 360° |
弧度法 | 0πrad | 0.5πrad | πrad | 1.5πrad | 2πrad |
数値 | 0 | 1.5707 | 3.1415 | 4.7123 | 6.2831 |
なのでメディアアートで繰り返す処理や曲線的な動きをつくりたい時、sinを使うとかなり便利になります。
#アニメーション基礎
もしopenframeworksのアニメーションの基礎がわかっていない人はyoppaさんのスライドみてください。
http://yoppa.org/tau_media16/6840.html
これを読んだらまず中心の横一直線を動く円を作ってみましょう。
##[問題]横一直線を動く円を作る
[解答]
float x = 0;
float y = ofGetHeight()/2;
#include "ofApp.h"
using namespace std;
//--------------------------------------------------------------
void ofApp::setup(){
//フレームレートを60に設定
//(1秒間に60枚画面を変える)
ofSetFrameRate(60);
//背景黒
ofBackground(0, 0, 0);
//塗りをリセットしないようにする(軌跡が描画されるようにする)
ofSetBackgroundAuto(false);
}
//--------------------------------------------------------------
void ofApp::update(){
x = x + 1;
}
//--------------------------------------------------------------
void ofApp::draw(){
//白色に
ofSetColor(255, 255, 255);
ofDrawCircle(x, y, 3);
}
動きましたか?
横の動きができたので縦の動きも付け足してみましょう。
ただ、横の動きに関しては横一直線の等速直線運動ではxに足すのは1でいいですが、y座標はそうはいきません。上下させたいので定数ではなく、変わる数を足さなくてはなりません。
そしてその”変わる数”こそがsinをつかってだした数値なのです。
それではそのsinをつかっていい具合に上下させる数値を作って行きましょう。
#openframeworksのsinとは
openframeworksのsin関数には引数として、入るのは度数でもなく、πとかでもなく数値(3.141592...とか)です。
sin(0) = 0 (0 = 0π)
sin(3.14) = 1(3.14 = π)
sin(6.28) = 0 (6.28 = 2π)
て感じです。
なので引数にはできたら小数点第2位くらいで常に変化し続ける(動かしたいから)値が必要です。それではまず常に変化し続ける値からです。
#sinを使う
常に変化し続ける値変数をつくってupdateの中で値を増やしていってを”作る”のもいいですがofGetFrameNum()というその時のフレームの値を常に取得し返してくれる関数があるので使用して行きましょう。
ofGetFrameNum()で取得した値をsinで変換してそれをofGetHeight()/2にまず足します。こういう感じですね。
void ofApp::update(){
x = x + 1;
y = ofGetHeight()/2 + sin(ofGetFrameNum());
}
でもこれじゃ、なにがおこっているかまったくわからないですよね?
理由は、sinの振動はsinの()の中の値が0~6.28で完結します。それが問題で、ofGetFrameNum()はフレーム数を取得します。
ちなみにこのプログラムではフレームレートは60/sと設定されているので1s間に10回くらい上下します。意味わかんないですね。なのでofGetFrameNum()に0.05くらいをかけてsinの中の値を小さくしましょう。
void ofApp::update(){
x = x + 1;
y = ofGetHeight()/2 + sin(ofGetFrameNum() * 0.05);
}
これでも全然わからないですよね。なんでかっていうとsinは-1~1までしか振動しないので、それくらいの動きされてもわからないんですよね。なので50でもかけましょう。それで完成です。
void ofApp::update(){
x = x + 1;
y = ofGetHeight()/2 + (sin(ofGetFrameNum() * 0.05) * 50);
}
以上です。
どうでしょう?openframeworksのsinの扱いについて少しわかったのではないでしょうか?一応githubであげておいたので共有しておきます。動くものがあるのとないのでは本当に違うと思います。僕もoF勉強中ですけど、githubにこんなのじゃなくてちゃんとすげー作品卍あげている人は神様だと思ってます。
[github]
https://github.com/hazamayuji/171021_sin
なにか不明点、違うところがあったらなんでもいうてくださいね!
ではでは。