[work 88] Trochoid 3D

[work 88] Trochoid 3D

Movie

Source code

about

  • トロコイドの3Dバージョン
  • 各アームの長さと回転軸は固定する

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 "Trochoid.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<Trochoid> trochoid;
    
    ofEasyCam cam;
};
#include "ofApp.h"


ofApp::ofApp(){
    
}

ofApp::~ofApp(){
    
}

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

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

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

//--------------------------------------------------------------
void ofApp::keyPressed(int key){
    if (key == 's') {
        ofImage img;
        img.grabScreen(0, 0, ofGetWidth(), ofGetHeight());
        img.save("screenshot.png");
    }
}
#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;
    location.push_back(origin);
    
    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;
        axis = glm::vec4(axis, 0) * rotZ * rotY * rotX;
        
        location.push_back(loc);
        rotAxis.push_back(axis);
    }
}


void Trochoid::update()
{
    for (int i = 0; i < location.size() - 1; i++) {
        glm::vec3 pre = location.at(i + 1);
        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 + 1) = loc;
    }
    
    ofVec3f p = ofVec3f(0, 0, 0);
    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 = location.at(0);
    for (int i = 0; i < location.size() - 1; i++) {
        ofNoFill();
        ofSetLineWidth(1);
        ofDrawLine(org, org + location.at(i + 1));
        org += location.at(i + 1);
    }
    
    ofSetColor(ofColor(102, 188, 216), 60);
    org = ofVec3f(0, 0, 0);
    for (int i = 0; i < location.size(); i++) {
        ofFill();
        ofDrawSphere(org + location.at(i), 5);
        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(location.at(0));
    for (int i = 1; i < location.size(); i++) {
        l.push_back(l.back() + location.at(i));
    }
    
    loc = l;
}


ofVec3f Trochoid::getPoint()
{
    return point;
}

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