収縮リング
円周上に配置された四角が収縮します。題名は普通に。
収縮リング
— string s="ごつちやん"; (@gotutiyan_kapi) 2018年4月13日
中央で重なるたびに個数が変わるなどします#openframeworks
コードとその解説は以下から。https://t.co/1kFsUch2L5 pic.twitter.com/nLiPZXD3T6
四角を三角関数を使って円周上に配置しています。この円の大きさは変数radiusで設定されていて、これも三角関数で変化させています。この時sinの値は-1~1ですが、都合上マイナスの値は要らないので、1を足すことで0~2に範囲をずらしています。
また、四角の個数は変数numが持っていて、円が中心で一瞬合わさった時に5~30の範囲でランダムに変化しています。そして変化する度に360度を個数で割ることで、全ての四角が円周上で均等に配置されるように並べ直しています。
座標系の移動は、最初にofTranslate(ofGetWidth()/2,ofGetHeight()/2)で画面中央に移動させた後、各四角を円周上に並べるための円周上の点x,y座標を算出して、そこに追加でofTranslate(x,y)します。
このようにして座標系を移動させれば、原点が四角を描く位置に来るので、ofDrawRectangle(-size/2,-size/2,size,size)で四角の中心が原点に来るように描きます。
ぱっと見 簡単な動きをしていますが、いざ実装すると案外やることが多いなあという印象でした。
#include "ofApp.h" #define rep(i,j,k) for(int i=j;i<k;i++) int num=12; //numは四角の個数を表す class PIC{ float deg,x,y; float size,rotate; public: float radius; //初期化関数 void init(float edeg){ deg=edeg; //sin(deg)^2+cos(deg)^2=1を利用して単位円を構成、それをradius倍して円周を作る float x=cos(deg*DEG_TO_RAD)*radius; float y=sin(deg*DEG_TO_RAD)*radius; rotate=0; radius=0; size=50; } void move(){ rotate++; //radiusはフレーム数をラジアンとする三角関数で変化 radius=(1+sin((ofGetFrameNum())*DEG_TO_RAD))*100; float x=cos(deg*DEG_TO_RAD)*radius; float y=sin(deg*DEG_TO_RAD)*radius; ofPushMatrix(); //四角単体で回転させるためのところ ofTranslate(x,y); ofRotate(rotate); ofDrawRectangle(-size/2,-size/2,size,size); ofPopMatrix(); } }; //この配列vに、描かれる四角が格納される vector<PIC> v(num); void ofApp::setup(){ ofSetFrameRate(60); ofSetBackgroundColor(0); ofSetColor(255); ofSetCircleResolution(32); ofNoFill(); rep(i,0,num){ v[i].init((360/num)*i); } } void ofApp::update(){ } void ofApp::draw(){ ofTranslate(ofGetWidth()/2,ofGetHeight()/2); //全ての四角が中心で合わさったという判定は、結局radiusが0になった時と同値 if(v[0].radius==0){ num=ofRandom(5,30); //配列の数をresizeで変更して、全て初期化 v.resize(num); rep(i,0,num){ v[i].init((360.0/num)*i); } } //実際に描きます rep(i,0,num){ v[i].move(); } }