gotutiyan’s blog

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

集中レーザー

レーザーが集中しているので。(最近良い題名が思いつきませんね)

今回からコードの解説はできるだけ以下のコードの中にコメントとして書くことにしました。その方がわかりやすい気がします(たぶん)。

初めてofMapを使いました。
ofMap(値、元範囲の最小値、元範囲の最大値、目的範囲の最小値、目的範囲の最大値)として使います。

例えば、sin関数は-1~1しか取りませんが、これを0~100の間に範囲を移したいとします。このとき、例えば0なら中間なので50になったり、-0.5なら小さい方から1/4地点ということで25になったりします。

float value = ofMap(sin(ラジアン), -1, 1, 0 ,100);

このように「ある一定の範囲しか取らない値を、別の範囲に対応させる」ときによく使います。今回は0~1しか取らないofNoise()を、-25~25に対応させています。これは便利ですね。

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

int deg=0;
void ofApp::setup(){
    ofSetFrameRate(60);
    ofSetBackgroundColor(0);
    ofSetColor(255);
    ofSetCircleResolution(64);
    ofNoFill();
    
}

void ofApp::update(){
}

void ofApp::draw(){
    deg++;
    ofTranslate(ofGetWidth()/2,ofGetHeight()/2); //原点中心に
    vector<float> xx,yy; //各点の座標を保管します
    float radiusx=200*cos(deg*DEG_TO_RAD); //radiusx,yは、色とりどりの線が集中する一点の座標を示します
    float radiusy=200*sin(deg*DEG_TO_RAD);
    rep(i,0,12){  //30度ずつずらして12個の点を線で繋ぐことを考えます
        int radius,noiseValue=1;
        if(i%2==0)radius=200; //iの偶奇で、出っ張るか凹ますかをradiusの値を変えることで決めます。
        else {
            radius=150;
            noiseValue=ofMap(ofNoise(i*0.05,ofGetFrameNum()*0.01),0.0,1.0,-25.0,25.0);  //凹む点についてはノイズで適当にずらします
        }
        float x=radius*cos(((i*30)+noiseValue)*DEG_TO_RAD);
        float y=radius*sin(((i*30)+noiseValue)*DEG_TO_RAD);
        xx.push_back(x); //各点の座標を配列に格納します
        yy.push_back(y);
        
        ofDrawLine(x,y,0,0); //各点と、画面中心をまず結びます
        if(i)ofDrawLine(x,y,xx[i-1],yy[i-1]); //次に各点同士を結びます。外周の線が完成します
        
        ofColor c; //色とりどりの線の色を決めるためのofColor型変数です
        c.setHsb(255*((20.0*i)/255),255,255);  //iの値によってHSBのHを変えます。
        ofSetColor(c);
        ofDrawLine(x,y,radiusx,radiusy); //色とりどりの線を引きます
        ofSetColor(255);
        
    }
    ofDrawLine(xx[0],yy[0],xx[xx.size()-1],yy[yy.size()-1]); //1番目の点と12番目の点はこれまででは結んでくれないので、別で書きます
}