gotutiyan’s blog

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

フレア

今までで一番好きな見た目の作品です!見た目がフレアっぽいのでね。


仕組みは以下のようになっています。(説明には最後に載せたコードで使われる変数名を含みます)
まず、点をdiv個等間隔に打った円を作ります。(画像はdiv=60)
f:id:gotutiyan:20180524152003p:plain
次にこれの大小を変えてnum個配置します。
f:id:gotutiyan:20180524152215p:plain

あとは同じ放射状にある点を繋いで、かつ全ての点をノイズでずらせば完成ですね!

コードは以下の通りです。

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

int num=30; //並べる円の個数
class Pic{
public:
    float div=60,r; //divは何個点を打つか
    vector<pair<float,float>> v; //点の情報(x,y)をペア(first,second)で格納
    vector<float> noiseSeed;
    //初期化関数
    void init(float r0){
        rep(i,0,div)noiseSeed.push_back(ofRandom(0,1000));
        r=r0;
        rep(i,0,div)v.push_back(pair<float,float>(0,0));
    }
    
    void move(){
        rep(i,0,div){
            noiseSeed[i]+=0.01;
            //ラジアンをノイズでずらすことで、打った点をずらす
            v[i].first=r*cos(DEG_TO_RAD*(i*(360/div)+ofMap(ofNoise(noiseSeed[i]),0,1,0,30)));
            v[i].second=r*sin(DEG_TO_RAD*(i*(360/div)+ofMap(ofNoise(noiseSeed[i]),0,1,0,30)));
        }
    }
};
vector<Pic> pic(num);

void ofApp::setup(){
    ofSetRectMode(OF_RECTMODE_CENTER);
    ofSetFrameRate(60);
    ofSetBackgroundColor(0);
    ofSetColor(255);
    ofSetCircleResolution(64);
    ofNoFill();
    
    rep(i,0,num)pic[i].init(i*(250.0/num));
}

void ofApp::update(){
    
}

void ofApp::draw(){
    ofTranslate(ofGetWidth()/2,ofGetHeight()/2);
    rep(i,0,num){
        pic[i].move();
        ofColor c;
        c.setHsb(i*(255.0/num),255,255);
        ofSetColor(c);
        if(i){
            rep(j,0,pic[i].v.size()){
                //隣同士の円の各点について線を引く
                ofDrawLine(pic[i-1].v[j].first,pic[i-1].v[j].second,pic[i].v[j].first,pic[i].v[j].second);
            }
        }
    }
}