[work 89] Ribbon

[work 89] Ribbon

Movie

Source code

about

  • トロコイドの一番先端にあるアームの軌跡上にリボンを描く
  • work 88でトロコイドを3D対応させたのでトロコイドの仕組みを利用して作ったwork 64のリボンも3Dバージョンにした

file

  • 上部にあるファイル名が表示されているボタンを押すと、表示されるファイルが切り替わります
  • 別ウィンドウ表示したい時や行番号などが無いRawMode表示したい時は、コード内右上のボタンを押してください(ボタンはマウスオーバーすると表示されます)
main.cpp
ofApp.h
ofApp.cpp
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
#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());
}
#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::shared_ptr<Ribbon> ribbon;
ofEasyCam cam;
};
#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::shared_ptr<Ribbon> ribbon; ofEasyCam cam; };
#include "ofApp.h"
ofApp::ofApp(){
}
ofApp::~ofApp(){
}
//--------------------------------------------------------------
void ofApp::setup(){
double fps = 30;
ofSetFrameRate(fps);
ofBackground(0);
ofSetBackgroundAuto(true);
ofSetVerticalSync(true);
ribbon = make_shared<Ribbon>(ofVec3f(0, 0, 0));
ribbon->setup();
}
//--------------------------------------------------------------
void ofApp::update(){
ribbon->update();
}
//--------------------------------------------------------------
void ofApp::draw(){
cam.begin();
ofRotateYDeg(ofGetFrameNum());
ribbon->display();
cam.end();
}
//--------------------------------------------------------------
void ofApp::keyPressed(int key){
if (key == 's') {
ofImage img;
img.grabScreen(0, 0, ofGetWidth(), ofGetHeight());
img.save("screenshot.png");
}
}
#include "ofApp.h" ofApp::ofApp(){ } ofApp::~ofApp(){ } //-------------------------------------------------------------- void ofApp::setup(){ double fps = 30; ofSetFrameRate(fps); ofBackground(0); ofSetBackgroundAuto(true); ofSetVerticalSync(true); ribbon = make_shared<Ribbon>(ofVec3f(0, 0, 0)); ribbon->setup(); } //-------------------------------------------------------------- void ofApp::update(){ ribbon->update(); } //-------------------------------------------------------------- void ofApp::draw(){ cam.begin(); ofRotateYDeg(ofGetFrameNum()); ribbon->display(); cam.end(); } //-------------------------------------------------------------- void ofApp::keyPressed(int key){ if (key == 's') { ofImage img; img.grabScreen(0, 0, ofGetWidth(), ofGetHeight()); img.save("screenshot.png"); } }
#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::shared_ptr<Ribbon> ribbon;
    
    ofEasyCam cam;
};
#include "ofApp.h"


ofApp::ofApp(){
    
}

ofApp::~ofApp(){
    
}

//--------------------------------------------------------------
void ofApp::setup(){
    double fps = 30;
    
    
    ofSetFrameRate(fps);
    ofBackground(0);
    ofSetBackgroundAuto(true);
    ofSetVerticalSync(true);
    
    ribbon = make_shared<Ribbon>(ofVec3f(0, 0, 0));
    ribbon->setup();
}

//--------------------------------------------------------------
void ofApp::update(){
    ribbon->update();
}

//--------------------------------------------------------------
void ofApp::draw(){
    cam.begin();
    ofRotateYDeg(ofGetFrameNum());
    ribbon->display();
    cam.end();
}

//--------------------------------------------------------------
void ofApp::keyPressed(int key){
    if (key == 's') {
        ofImage img;
        img.grabScreen(0, 0, ofGetWidth(), ofGetHeight());
        img.save("screenshot.png");
    }
}
Trochoid.hpp
Trochoid.cpp
Ribbon.hpp
Ribbon.cpp
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
#ifndef Trochoid_hpp
#define Trochoid_hpp
#include <stdio.h>
#include "ofMain.h"
class Trochoid {
public:
Trochoid(ofVec3f org, int dim, bool dec);
~Trochoid();
void setup();
void update();
void display();
void getLocations(std::vector<ofVec3f> &loc);
ofVec3f getPoint();
private:
Trochoid();
ofVec3f origin;
ofVec3f point;
ofMesh locus;
std::vector<float> angleVelocity; // radian
std::vector<int> direction;
std::vector<float> decay;
std::vector<float> amplitude;
std::vector<ofVec3f> location;
std::vector<ofVec3f> rotAxis;
bool isDecay;
int dimension;
};
#endif /* Trochoid_hpp */
#ifndef Trochoid_hpp #define Trochoid_hpp #include <stdio.h> #include "ofMain.h" class Trochoid { public: Trochoid(ofVec3f org, int dim, bool dec); ~Trochoid(); void setup(); void update(); void display(); void getLocations(std::vector<ofVec3f> &loc); ofVec3f getPoint(); private: Trochoid(); ofVec3f origin; ofVec3f point; ofMesh locus; std::vector<float> angleVelocity; // radian std::vector<int> direction; std::vector<float> decay; std::vector<float> amplitude; std::vector<ofVec3f> location; std::vector<ofVec3f> rotAxis; bool isDecay; int dimension; }; #endif /* Trochoid_hpp */
#include "Trochoid.hpp"
Trochoid::Trochoid(ofVec3f 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(1, 16);
angleVelocity.push_back((PI / (180 * 2)) * 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(80, 200));
std::cout << "[amplitude]" << amplitude[i] << std::endl;
glm::vec3 loc = glm::vec3(amplitude.back(), 0, 0);
glm::vec3 axis = glm::vec3(0, 0, 1);
glm::mat4 rotX = glm::rotate(glm::mat4(), ofDegToRad(ofRandom(0, 360)), glm::vec3(1, 0, 0));
glm::mat4 rotY = glm::rotate(glm::mat4(), ofDegToRad(ofRandom(0, 360)), glm::vec3(0, 1, 0));
glm::mat4 rotZ = glm::rotate(glm::mat4(), ofDegToRad(ofRandom(0, 360)), glm::vec3(0, 0, 1));
loc = glm::vec4(loc, 0) * rotZ * rotY * rotX;
glm::mat4 rotEx = glm::rotate(glm::mat4(), ofDegToRad(ofRandom(0, 360)), glm::vec3(1, 0, 0));
axis = glm::vec4(axis, 0) * rotEx * rotZ * rotY * rotX;
location.push_back(loc);
rotAxis.push_back(axis);
}
}
void Trochoid::update()
{
for (int i = 0; i < location.size(); i++) {
glm::vec3 pre = location.at(i);
glm::vec3 axis = rotAxis.at(i);
glm::mat4 rotM = glm::rotate(glm::mat4(), angleVelocity.at(i) * direction.at(i), axis);
glm::vec3 s = glm::vec3(decay.at(i));
glm::mat4 sclM = glm::scale(glm::mat4(), s);
glm::vec3 loc = glm::vec4(pre, 0) * rotM * sclM;
location.at(i) = loc;
}
ofVec3f p = origin;
for (int i = 0; i < location.size(); i++) {
p += location.at(i);
}
point = p;
}
void Trochoid::display()
{
ofEnableBlendMode(OF_BLENDMODE_SCREEN);
ofSetColor(ofColor(102, 188, 216), 60);
ofVec3f org = origin;
for (int i = 0; i < location.size(); i++) {
ofNoFill();
ofSetLineWidth(1);
ofDrawLine(org, org + location.at(i));
org += location.at(i);
}
ofSetColor(ofColor(102, 188, 216), 60);
ofFill();
org = origin;
ofDrawSphere(org, 3);
for (int i = 0; i < location.size(); i++) {
ofDrawSphere(org + location.at(i), 3);
org += location.at(i);
}
locus.setMode(OF_PRIMITIVE_LINE_STRIP);
locus.addVertex(point);
locus.addColor(ofColor(255));
locus.draw();
}
void Trochoid::getLocations(std::vector<ofVec3f> &loc)
{
std::vector<ofVec3f> l;
l.push_back(origin);
for (int i = 0; i < location.size(); i++) {
l.push_back(l.back() + location.at(i));
}
loc = l;
}
ofVec3f Trochoid::getPoint()
{
return point;
}
#include "Trochoid.hpp" Trochoid::Trochoid(ofVec3f 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(1, 16); angleVelocity.push_back((PI / (180 * 2)) * 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(80, 200)); std::cout << "[amplitude]" << amplitude[i] << std::endl; glm::vec3 loc = glm::vec3(amplitude.back(), 0, 0); glm::vec3 axis = glm::vec3(0, 0, 1); glm::mat4 rotX = glm::rotate(glm::mat4(), ofDegToRad(ofRandom(0, 360)), glm::vec3(1, 0, 0)); glm::mat4 rotY = glm::rotate(glm::mat4(), ofDegToRad(ofRandom(0, 360)), glm::vec3(0, 1, 0)); glm::mat4 rotZ = glm::rotate(glm::mat4(), ofDegToRad(ofRandom(0, 360)), glm::vec3(0, 0, 1)); loc = glm::vec4(loc, 0) * rotZ * rotY * rotX; glm::mat4 rotEx = glm::rotate(glm::mat4(), ofDegToRad(ofRandom(0, 360)), glm::vec3(1, 0, 0)); axis = glm::vec4(axis, 0) * rotEx * rotZ * rotY * rotX; location.push_back(loc); rotAxis.push_back(axis); } } void Trochoid::update() { for (int i = 0; i < location.size(); i++) { glm::vec3 pre = location.at(i); glm::vec3 axis = rotAxis.at(i); glm::mat4 rotM = glm::rotate(glm::mat4(), angleVelocity.at(i) * direction.at(i), axis); glm::vec3 s = glm::vec3(decay.at(i)); glm::mat4 sclM = glm::scale(glm::mat4(), s); glm::vec3 loc = glm::vec4(pre, 0) * rotM * sclM; location.at(i) = loc; } ofVec3f p = origin; for (int i = 0; i < location.size(); i++) { p += location.at(i); } point = p; } void Trochoid::display() { ofEnableBlendMode(OF_BLENDMODE_SCREEN); ofSetColor(ofColor(102, 188, 216), 60); ofVec3f org = origin; for (int i = 0; i < location.size(); i++) { ofNoFill(); ofSetLineWidth(1); ofDrawLine(org, org + location.at(i)); org += location.at(i); } ofSetColor(ofColor(102, 188, 216), 60); ofFill(); org = origin; ofDrawSphere(org, 3); for (int i = 0; i < location.size(); i++) { ofDrawSphere(org + location.at(i), 3); org += location.at(i); } locus.setMode(OF_PRIMITIVE_LINE_STRIP); locus.addVertex(point); locus.addColor(ofColor(255)); locus.draw(); } void Trochoid::getLocations(std::vector<ofVec3f> &loc) { std::vector<ofVec3f> l; l.push_back(origin); for (int i = 0; i < location.size(); i++) { l.push_back(l.back() + location.at(i)); } loc = l; } ofVec3f Trochoid::getPoint() { return point; }
#ifndef Ribbon_hpp
#define Ribbon_hpp
#include <stdio.h>
#include "ofMain.h"
#include "Trochoid.hpp"
#define MAX_LINE (10)
class Ribbon {
public:
Ribbon(ofVec3f c);
~Ribbon();
void setup();
void update();
void display();
void reset();
private:
std::shared_ptr<Trochoid> trochoid;
std::vector<ofVec3f> locations;
std::array<std::vector<ofVec3f>, MAX_LINE> points;
std::array<ofMesh, MAX_LINE> meshes;
std::array<ofColor, MAX_LINE> colors;
ofColor color;
ofVec3f center;
std::shared_ptr<ofFbo> fbo;
};
#endif /* Ribbon_hpp */
#ifndef Ribbon_hpp #define Ribbon_hpp #include <stdio.h> #include "ofMain.h" #include "Trochoid.hpp" #define MAX_LINE (10) class Ribbon { public: Ribbon(ofVec3f c); ~Ribbon(); void setup(); void update(); void display(); void reset(); private: std::shared_ptr<Trochoid> trochoid; std::vector<ofVec3f> locations; std::array<std::vector<ofVec3f>, MAX_LINE> points; std::array<ofMesh, MAX_LINE> meshes; std::array<ofColor, MAX_LINE> colors; ofColor color; ofVec3f center; std::shared_ptr<ofFbo> fbo; }; #endif /* Ribbon_hpp */
#include "Ribbon.hpp"
Ribbon::Ribbon(ofVec3f c)
{
center = c;
}
Ribbon::~Ribbon()
{
}
void Ribbon::setup()
{
trochoid = make_shared<Trochoid>(center, 6, false);
trochoid->setup();
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();
ofVec3f tail = *itr;
ofVec3f head = *(itr + 1);
ofVec3f arm = tail - head;
float len = arm.length();
ofVec3f 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);
}
ofNoFill();
ofSetLineWidth(1);
for (int i = 0; i < MAX_LINE; i++) {
meshes.at(i).setMode(OF_PRIMITIVE_LINE_STRIP);
meshes.at(i).addVertex(points.at(i).back());
meshes.at(i).addColor(colors.at(i));
}
}
void Ribbon::display()
{
ofEnableBlendMode(OF_BLENDMODE_SCREEN);
for (ofMesh m : meshes) {
m.draw();
}
}
void Ribbon::reset()
{
fbo = nullptr;
trochoid = nullptr;
setup();
}
#include "Ribbon.hpp" Ribbon::Ribbon(ofVec3f c) { center = c; } Ribbon::~Ribbon() { } void Ribbon::setup() { trochoid = make_shared<Trochoid>(center, 6, false); trochoid->setup(); 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(); ofVec3f tail = *itr; ofVec3f head = *(itr + 1); ofVec3f arm = tail - head; float len = arm.length(); ofVec3f 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); } ofNoFill(); ofSetLineWidth(1); for (int i = 0; i < MAX_LINE; i++) { meshes.at(i).setMode(OF_PRIMITIVE_LINE_STRIP); meshes.at(i).addVertex(points.at(i).back()); meshes.at(i).addColor(colors.at(i)); } } void Ribbon::display() { ofEnableBlendMode(OF_BLENDMODE_SCREEN); for (ofMesh m : meshes) { m.draw(); } } void Ribbon::reset() { fbo = nullptr; trochoid = nullptr; setup(); }
#ifndef Trochoid_hpp
#define Trochoid_hpp

#include <stdio.h>
#include "ofMain.h"


class Trochoid {
public:
    Trochoid(ofVec3f org, int dim, bool dec);
    ~Trochoid();
    void setup();
    void update();
    void display();
    void getLocations(std::vector<ofVec3f> &loc);
    ofVec3f getPoint();
private:
    Trochoid();
    
    ofVec3f origin;
    ofVec3f point;
    ofMesh locus;
    std::vector<float> angleVelocity;       // radian
    std::vector<int> direction;
    std::vector<float> decay;
    std::vector<float> amplitude;
    std::vector<ofVec3f> location;
    std::vector<ofVec3f> rotAxis;
    bool isDecay;
    int dimension;
};
#endif /* Trochoid_hpp */
#include "Trochoid.hpp"



Trochoid::Trochoid(ofVec3f 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(1, 16);
        angleVelocity.push_back((PI / (180 * 2)) * 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(80, 200));
        std::cout << "[amplitude]" << amplitude[i] << std::endl;
        
        glm::vec3 loc = glm::vec3(amplitude.back(), 0, 0);
        glm::vec3 axis = glm::vec3(0, 0, 1);
        glm::mat4 rotX = glm::rotate(glm::mat4(), ofDegToRad(ofRandom(0, 360)), glm::vec3(1, 0, 0));
        glm::mat4 rotY = glm::rotate(glm::mat4(), ofDegToRad(ofRandom(0, 360)), glm::vec3(0, 1, 0));
        glm::mat4 rotZ = glm::rotate(glm::mat4(), ofDegToRad(ofRandom(0, 360)), glm::vec3(0, 0, 1));
        loc = glm::vec4(loc, 0) * rotZ * rotY * rotX;
        glm::mat4 rotEx = glm::rotate(glm::mat4(), ofDegToRad(ofRandom(0, 360)), glm::vec3(1, 0, 0));
        axis = glm::vec4(axis, 0) * rotEx * rotZ * rotY * rotX;
        
        location.push_back(loc);
        rotAxis.push_back(axis);
    }
}


void Trochoid::update()
{
    for (int i = 0; i < location.size(); i++) {
        glm::vec3 pre = location.at(i);
        glm::vec3 axis = rotAxis.at(i);
        glm::mat4 rotM = glm::rotate(glm::mat4(), angleVelocity.at(i) * direction.at(i), axis);
        glm::vec3 s = glm::vec3(decay.at(i));
        glm::mat4 sclM = glm::scale(glm::mat4(), s);
        glm::vec3 loc = glm::vec4(pre, 0) * rotM * sclM;
        location.at(i) = loc;
    }
    
    ofVec3f p = origin;
    for (int i = 0; i < location.size(); i++) {
        p += location.at(i);
    }
    point = p;
}


void Trochoid::display()
{
    ofEnableBlendMode(OF_BLENDMODE_SCREEN);
    ofSetColor(ofColor(102, 188, 216), 60);
    ofVec3f org = origin;
    for (int i = 0; i < location.size(); i++) {
        ofNoFill();
        ofSetLineWidth(1);
        ofDrawLine(org, org + location.at(i));
        org += location.at(i);
    }
    
    ofSetColor(ofColor(102, 188, 216), 60);
    ofFill();
    org = origin;
    ofDrawSphere(org, 3);
    for (int i = 0; i < location.size(); i++) {
        ofDrawSphere(org + location.at(i), 3);
        org += location.at(i);
    }
    
    locus.setMode(OF_PRIMITIVE_LINE_STRIP);
    locus.addVertex(point);
    locus.addColor(ofColor(255));
    locus.draw();
}


void Trochoid::getLocations(std::vector<ofVec3f> &loc)
{
    std::vector<ofVec3f> l;
    l.push_back(origin);
    for (int i = 0; i < location.size(); i++) {
        l.push_back(l.back() + location.at(i));
    }
    
    loc = l;
}


ofVec3f Trochoid::getPoint()
{
    return point;
}
#ifndef Ribbon_hpp
#define Ribbon_hpp

#include <stdio.h>
#include "ofMain.h"

#include "Trochoid.hpp"


#define MAX_LINE (10)

class Ribbon {
public:
    Ribbon(ofVec3f c);
    ~Ribbon();
    void setup();
    void update();
    void display();
    void reset();
    
private:
    std::shared_ptr<Trochoid> trochoid;
    std::vector<ofVec3f> locations;
    std::array<std::vector<ofVec3f>, MAX_LINE> points;
    std::array<ofMesh, MAX_LINE> meshes;
    std::array<ofColor, MAX_LINE> colors;
    ofColor color;
    ofVec3f center;
    
    std::shared_ptr<ofFbo> fbo;
};
#endif /* Ribbon_hpp */
#include "Ribbon.hpp"


Ribbon::Ribbon(ofVec3f c)
{
    center = c;
}


Ribbon::~Ribbon()
{
    
}


void Ribbon::setup()
{
    trochoid = make_shared<Trochoid>(center, 6, false);
    trochoid->setup();
    
    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();
    ofVec3f tail = *itr;
    ofVec3f head = *(itr + 1);
    
    ofVec3f arm = tail - head;
    float len = arm.length();
    ofVec3f 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);
    }
    
    ofNoFill();
    ofSetLineWidth(1);
    for (int i = 0; i < MAX_LINE; i++) {
        meshes.at(i).setMode(OF_PRIMITIVE_LINE_STRIP);
        meshes.at(i).addVertex(points.at(i).back());
        meshes.at(i).addColor(colors.at(i));
    }
}


void Ribbon::display()
{
    ofEnableBlendMode(OF_BLENDMODE_SCREEN);
    for (ofMesh m : meshes) {
        m.draw();
    }
}


void Ribbon::reset()
{
    fbo = nullptr;
    trochoid = nullptr;
    
    setup();
}

Link to the reference page

ソースコードで使用したAPIの中から要点になりそうなものをいくつか選んでリストアップしました。

categoryAPI/Lib
openframeworksglm::vec3
openframeworksglm::rotate
openframeworksglm::scale
openframeworksglm::mat4
openframeworksofMesh

Development environment

  • openframeworks 0.10.1
  • c++
  • macOS
  • Xcode