gotutiyan’s blog

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

カラフル。

とりあえず見た目がカラフルで、描く図形は円だったので、円の要素を句読点で表現してこの題名に。
動的配列であるvectorを使ってやりたいなあと思ったので、クリックで円の個数が変わるものを作りました。画面の上半分をクリックで円の個数が減り、下半分をクリックで円の個数が増えます。
また、色が徐々に変わっていきます。


色情報を扱うofColor型の変数を使えばHSBで色を指定できることが分かったので、それを円の個数だけ確保して値を入れます。
この色情報の配列は2次元にしたくなかったので、1次元で確保した上で、2重ループを回す中で

v[i+j*num]

という形で利用することで実質2次元配列のように扱います。この配列を

v[i*num+j]

とすると、グラデーションは縦に向くようになるので面白いですね。今回は前者の実装をして横方向にグラデーションしています。

vectorには何でも突っ込める印象があり、試しにofColorを突っ込んでみたら動いたので嬉しかったですね。

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

#include "ofApp.h"
#define rep(i,j,k) for(int i=j;i<k;i++)
int num=10;
vector<ofColor> v(num*num); //円の数はnum*num個
void ofApp::setup(){
    ofSetFrameRate(5);
    ofNoFill();
    ofSetBackgroundColor(0);
    ofSetColor(255);
    
    rep(i,0,num*num){
        v[i].setHsb(i*((255)/(num*num)),255,255);
    }
}

//要素を1個ずつずらします。
void ofApp::update(){
    ofColor temp=v[0];
    rep(i,0,num*num)v[i]=v[i+1];
    v[v.size()-1]=temp;
}

void ofApp::draw(){
    rep(i,0,num){
        rep(j,0,num){
            //半径は、画面幅/個数/2になります。
            float r=ofGetWidth()/num/2;
            ofSetColor(v[i+j*num]);
            ofDrawCircle(i*ofGetWidth()/num+r,j*ofGetHeight()/num+r,r);
        }
    }
}

void ofApp::mousePressed(int x, int y, int button){
    if(y<ofGetHeight()/2) {if(num>1)num--;}
    else num++;
    //vectorは vector::resize(要素数);を用いて動的に変化させることができます。
    v.resize(num*num);
    rep(i,0,num*num){
        v[i].setHsb(i*((255.0)/(num*num)),255,255);
    }
}

この円の数をとにかく増やしまくると、以下のようになります。まあ、結局点を打っていくことに等しくなっていくということですね。
f:id:gotutiyan:20180322112642p:plain