[work 64] Ribbon – stripe –
Movie
Source code
about
- ストライプ柄のリボンを描く
file
- 上部にあるファイル名が表示されているボタンを押すと、表示されるファイルが切り替わります
- 別ウィンドウ表示したい時や行番号などが無いRawMode表示したい時は、コード内右上のボタンを押してください(ボタンはマウスオーバーすると表示されます)
#include "ofMain.h" #include "ofApp.h" //================================ int main( ){ // 4K:4096x2160 // 2K:2048x1080 // FullHD:1920x1080 // HD:1440x1080 // HD720p:1280x720 // DVD:720x480 // setup the GL context ofSetupOpenGL(1280, 720, OF_WINDOW); // this kicks off the running of my app // can be OF_WINDOW or OF_FULLSCREEN // pass in width and height too: ofRunApp( new ofApp()); }
#pragma once #include "ofMain.h" #include "Ribbon.hpp" class ofApp : public ofBaseApp{ public: ofApp(); ~ofApp(); void setup(); void update(); void draw(); void keyPressed(int key); void keyReleased(int key); void mouseMoved(int x, int y); void mouseDragged(int x, int y, int button); void mousePressed(int x, int y, int button); void mouseReleased(int x, int y, int button); void mouseEntered(int x, int y); void mouseExited(int x, int y); void windowResized(int w, int h); void dragEvent(ofDragInfo dragInfo); void gotMessage(ofMessage msg); private: std::vector<std::shared_ptr<Ribbon>> ribbons; };
#include "ofApp.h" ofApp::ofApp(){ } ofApp::~ofApp(){ } //-------------------------------------------------------------- void ofApp::setup(){ double fps = 30; ofSetFrameRate(fps); ofBackground(0); ofSetBackgroundAuto(true); ofSetVerticalSync(true); ofRectangle drawArea = ofRectangle(290, 10, 700, 700); int maxRow = 2; int maxCol = 2; for (int i = 0; i < maxCol; i++) { float w = (drawArea.getWidth() / maxCol); float x = drawArea.getLeft() + (w * i) + (w / 2); for (int j = 0; j < maxRow; j++) { float h = (drawArea.getHeight() / maxRow); float y = drawArea.getTop() + (h * j) + (h / 2); ribbons.push_back(make_shared<Ribbon>(ofVec2f(x, y))); } } for (shared_ptr<Ribbon> r : ribbons) { r->setup(); } } //-------------------------------------------------------------- void ofApp::update(){ for (shared_ptr<Ribbon> r : ribbons) { r->update(); } } //-------------------------------------------------------------- void ofApp::draw(){ for (shared_ptr<Ribbon> r : ribbons) { r->display(); } } //-------------------------------------------------------------- void ofApp::keyPressed(int key){ if (key == 's') { ofImage img; img.grabScreen(0, 0, ofGetWidth(), ofGetHeight()); img.save("screenshot.png"); } else if (key == 'r') { for (shared_ptr<Ribbon> r : ribbons) { r->reset(); } } }
#ifndef Ribbon_hpp #define Ribbon_hpp #include <stdio.h> #include "ofMain.h" #include "Trochoid.hpp" #define MAX_LINE (10) class Ribbon { public: Ribbon(ofVec2f c); ~Ribbon(); void setup(); void update(); void display(); void reset(); private: std::shared_ptr<Trochoid> trochoid; std::vector<ofVec2f> locations; std::array<std::vector<ofVec2f>, MAX_LINE> points; std::array<ofColor, MAX_LINE> colors; ofColor color; ofVec2f center; std::shared_ptr<ofFbo> fbo; }; #endif /* Ribbon_hpp */
#include "Ribbon.hpp" Ribbon::Ribbon(ofVec2f c) { center = c; } Ribbon::~Ribbon() { } void Ribbon::setup() { trochoid = make_shared<Trochoid>(center, 4, false); trochoid->setup(); fbo = make_shared<ofFbo>(); fbo->allocate(ofGetWidth(), ofGetHeight(), GL_RGBA, 4); fbo->begin(); ofClear(0); fbo->end(); for (int i = 0; i < colors.size(); i++) { colors.at(i) = ofColor(ofRandom(255), ofRandom(255), ofRandom(255), 255); } } void Ribbon::update() { locations.clear(); trochoid->update(); trochoid->getLocations(locations); auto itr = locations.rbegin(); ofVec2f tail = *itr; ofVec2f head = *(itr + 1); ofVec2f arm = tail - head; float len = arm.length(); ofVec2f unit = arm.normalize(); for (int i = 0; i < points.size(); i++) { float d = (len / points.size()) * i; points.at(i).push_back(head + unit * d); } ofEnableBlendMode(OF_BLENDMODE_SCREEN); fbo->begin(); ofNoFill(); ofSetLineWidth(1); for (int i = 0; i < points.size(); i++) { if (points.at(i).size() > 1) { ofSetColor(colors.at(i)); auto itr = points.at(i).rbegin(); ofVec2f pre = *(itr + 1); ofVec2f current = *(itr); ofDrawLine(pre, current); } } fbo->end(); } void Ribbon::display() { fbo->draw(0, 0); } void Ribbon::reset() { fbo = nullptr; trochoid = nullptr; setup(); }
#ifndef Trochoid_hpp #define Trochoid_hpp #include <stdio.h> #include "ofMain.h" class Trochoid { public: Trochoid(ofVec2f org, int dim, bool dec); ~Trochoid(); void setup(); void update(); void display(); void getLocations(std::vector<ofVec2f> &loc); ofVec2f getPoint(); private: Trochoid(); ofVec2f origin; ofVec2f point; ofMesh locus; std::vector<float> angle; // radian std::vector<float> angleVelocity; std::vector<int> direction; std::vector<float> decay; std::vector<float> amplitude; std::vector<ofVec2f> location; bool isDecay; int dimension; }; #endif /* Trochoid_hpp */
#include "Trochoid.hpp" Trochoid::Trochoid(ofVec2f org, int dim, bool dec) { origin = org; dimension = (int)ofClamp(dim, 1, 10); isDecay = dec; } Trochoid::~Trochoid() { } void Trochoid::setup() { int k = 0; std::cout << "Create Trochoid" << std::endl; for (int i = 0; i < dimension; i++) { k = (int)ofRandom(4); angle.push_back(PI / 2 * k); std::cout << "[angle]" << angle[i] << std::endl; k = (int)ofRandom(1, 16); angleVelocity.push_back((PI / (180 * 10)) * k); std::cout << "[angleV]" << angleVelocity[i] << std::endl; k = ((ofRandom(-1,1) < 0) ? -1 : 1); direction.push_back(k); std::cout << "[direction]" << direction[i] << std::endl; if (isDecay) { decay.push_back(ofRandom(0.998, 1)); } else { decay.push_back(1); } std::cout << "[decay]" << decay[i] << std::endl; amplitude.push_back(ofRandom(20, 60)); std::cout << "[amplitude]" << amplitude[i] << std::endl; } location.push_back(origin); for (int i = 1; i < dimension + 1; i++) { location.push_back(ofVec2f(0,0)); } } void Trochoid::update() { for (int i = 0; i < location.size() - 1; i++) { location.at(i + 1).x = location.at(i).x + std::cos(angle.at(i)) * amplitude.at(i); location.at(i + 1).y = location.at(i).y + std::sin(angle.at(i)) * amplitude.at(i); angle.at(i) += angleVelocity.at(i) * direction.at(i); if (amplitude.at(i) > 1) { amplitude.at(i) *= decay.at(i); } } point = location.back(); } void Trochoid::display() { for (int i = 0; i < location.size() - 1; i++) { ofNoFill(); ofSetLineWidth(1); ofDrawLine(location.at(i), location.at(i + 1)); } for (int i = 0; i < location.size(); i++) { ofFill(); ofDrawCircle(location.at(i), 5); } locus.addVertex(ofVec3f(point.x, point.y, 0)); locus.addColor(ofColor(255)); locus.drawVertices(); } void Trochoid::getLocations(std::vector<ofVec2f> &loc) { loc = location; } ofVec2f Trochoid::getPoint() { return point; }
Link to the reference page
ソースコードで使用したAPIの中から要点になりそうなものをいくつか選んでリストアップしました。
category | API/Lib |
openframeworks | ofVec2f |
c++ | std::vector |
Development environment
- openframeworks 0.10.1
- c++
- macOS
- Xcode