掻き分けて、円
マウスカーソルから円が逃げます。
「掻き分けて、円」
— ごつちやん (@gotutiyan_kapi) 2018年5月25日
マウスカーソルから円が逃げます#openframeworks
コードと解説は以下からhttps://t.co/yYp6YpQ2Lz pic.twitter.com/qYkEfF0DcE
たまにはマウス座標を使おうと思って作りましたが、案外実装が楽で終わってしまったので、移動具合によって色も変えました。numの個数を変えれば敷き詰める円の個数も変わります。
変数を闇雲に作ったのと、三項演算子バリバリのコーディングをしたので少し見にくいかもしれません。
def_x,def_yが、各円の座標の初期値です。ここからどれくらい離れたかで色を変えます。
point_diffは、マウスから逃げる円の、逃げる距離の最大値です。つまり、円はマウス位置からpoint_diffを半径とした円周上まで逃げます。
diff_x,diff_yは、マウス位置と円の中心を比べた時の、x,y座標の差です。この値を使って、point_diffと比べます。
2点間の距離を調べるときには三平方の定理を使うわけですが、一応競技プログラミング界隈の人間なので、別に気にしなくても良い誤差を気にしてsqrt()は使わず、距離の2乗で比較しています。
#include "ofApp.h" #include <vector> #include <utility> #include <algorithm> #include <cmath> #define rep(i,j,k) for(int i=j;i<k;i++) int num=10; //縦横の個数num class Pic{ public: float x,y,r; float def_x,def_y; float diffx,diffy,point_diff; ofColor c; void init(float x0,float y0,float r0,float point_diff0){ x=x0; y=y0; r=r0; point_diff=point_diff0; def_x=x; def_y=y; } void move(){ //元の位置からの距離を測って、その距離をそのままHSBのH要素に c.setHsb(ofMap((x-def_x)*(x-def_x)+(y-def_y)*(y-def_y),0,5000,0,255),255,255); ofSetColor(c); ofDrawCircle(x,y,r); float distx=ofGetMouseX()-x, disty=ofGetMouseY()-y; //円の中心とマウスの距離がpoint_diffより小さい時(逃げるところ) if(distx*distx+disty*disty<point_diff*point_diff){ x+=(distx<0)?0.5:-0.5; y+=(disty<0)?0.5:-0.5; //逃げた円が元に戻るところ }else { distx=x-def_x; disty=y-def_y; if(distx) x+=(distx<0)?0.2:-0.2; if(disty) y+=(disty<0)?0.2:-0.2; } } }; vector<vector<Pic>> pic(num,vector<Pic>(num)); void ofApp::setup(){ ofSetRectMode(OF_RECTMODE_CENTER); ofSetFrameRate(60); ofSetBackgroundColor(0); ofSetColor(255); ofSetCircleResolution(64); ofNoFill(); //初期化。numの値によって自動で変わるようになっている。 float pos=ofGetHeight()/num; rep(i,0,num)rep(j,0,num)pic[i][j].init(pos/2+pos*i, pos/2+pos*j, pos/2,70); } void ofApp::update(){ } void ofApp::draw(){ rep(i,0,num)rep(j,0,num)pic[i][j].move(); }