gotutiyan’s blog

競技プログラミングをやったりopenframeworksでお絵かきをしたりしています。

硯を求めて

ofNoiseを使ってノイズを使おうとして、以下のサイトを見ていたところ良さげな模様を作ってらっしゃったので手元で再現することにしました。
naoyashiga.hatenablog.com

動いてるところは以下のツイートで。

黒い点が書道してるときに飛んだ墨汁に見えて、それが動いて硯に戻ろうとしてるみたいな印象を受けたのでこの題名に。

とりあえず円をたくさん作るので、クラスを作って100個くらい複製する方針で。久しぶりに真面目にクラスを書いたので、コンストラクタの作り方を思い出しながらでした。

また、Update()とDraw()の2種類あるので(違いがまだよくわかってないが)、クラスを設計するときにも関数を2つ作って用途を分けるということに少し苦労しました。

横に進むスピードが円の半径にもなっているので、小さい円は遅く、大きい円は速いです。遠近感が出ますね。肝心のノイズはy軸方向に揺らすために使っています。

コードは以下の通りです。ofApp.hはデフォルト(emptyExample)のままです。

#include "ofApp.h"
#define rep(i,j,k) for(int i=j;i<k;i++)

class EN{
    float speed;
    float x,y;
    float noiseCenter=0; //ノイズのシード値
    
public:
    EN();
    void print();
    void move();
    
};
//コンストラクタ
EN::EN(){
    speed=ofRandom(3);
    x=ofRandom(1280);
    y=ofRandom(720);
    noiseCenter=ofRandom(500);
}

//描画部分
void EN::print(){
    ofDrawCircle(x,y,speed*5,speed*5);
}

//計算部分。x座標増やして行き過ぎたら戻る。ノイズのシード値を増やして、画面のy座標を掛け算。
void EN::move(){
    x+=speed;
    if(x+speed>ofGetWidth())x=0;
    y=ofNoise(noiseCenter)*ofGetWidth();
    noiseCenter+=0.01;
}

EN en[100];
void ofApp::setup(){
    ofSetFrameRate(60);
    ofSetBackgroundColor(255);
    ofSetColor(0);
}

void ofApp::update(){
    rep(i,0,100)en[i].move();
}

void ofApp::draw(){
    rep(i,0,100)en[i].print();
}

・感想
画面幅はofGetWidth()とofGetHeight()で取れることを知った。
ぱっと見は 三角関数っぽい動きをするけど、ノイズ使ってるので多分ちょっと複雑で違うんだろうな。