[work 110] Bezier curve silhouette

[work 110] Bezier curve silhouette

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 "Curve.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::vector<std::shared_ptr<Curve>>> curves;
    
    ofRectangle window;
};
#include "ofApp.h"


ofApp::ofApp(){
    
}

ofApp::~ofApp(){
    
}

//--------------------------------------------------------------
void ofApp::setup(){
    double fps = 30;
    
    ofSetFrameRate(fps);
    ofBackground(255);
    ofSetBackgroundAuto(true);
    ofSetVerticalSync(true);
    
    for (int col = 0; col < 2; col++) {
        std::vector<std::shared_ptr<Curve>> cs;
        for (int row = 0; row < 2; row++) {
            std::shared_ptr<Curve> c = make_shared<Curve>();
            c->setup();
            cs.push_back(c);
        }
        curves.push_back(cs);
    }
    
    window.setFromCenter(ofGetWidth() / 2, ofGetHeight() / 2, ofGetWidth() * 0.8, ofGetHeight());
}

//--------------------------------------------------------------
void ofApp::update(){
    for (std::vector<std::shared_ptr<Curve>> cs : curves) {
        for (std::shared_ptr<Curve> c : cs) {
            c->update();
        }
    }
}

//--------------------------------------------------------------
void ofApp::draw(){
    int col = curves.size();
    int colIdx = 0;
    
    for (std::vector<std::shared_ptr<Curve>> cs : curves) {
        int row = cs.size();
        int rowIdx = 0;
        for (std::shared_ptr<Curve> c : cs) {
            float x = window.getLeft() + (window.width / (col + 1)) * (colIdx + 1);
            float y = window.getTop() + (window.height / (row + 1)) * (rowIdx + 1);
            
            ofPushMatrix();
            ofTranslate(x, y);
            c->display();
            ofPopMatrix();
            
            rowIdx++;
        }
        colIdx++;
    }
}

//--------------------------------------------------------------
void ofApp::keyPressed(int key){
    if (key == 's') {
        ofImage img;
        img.grabScreen(0, 0, ofGetWidth(), ofGetHeight());
        img.save("screenshot.png");
    }
}
#ifndef Curve_hpp
#define Curve_hpp

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

class Curve {
public:
    Curve();
    ~Curve();
    void setup();
    void update();
    void display();
    
private:
    ofRectangle window;
    std::array<ofVec2f, 4> points;
    std::array<float, 4> times;
    std::vector<ofVec2f> interPoints;
};
#endif /* Curve_hpp */
#include "Curve.hpp"


Curve::Curve()
{
    
}


Curve::~Curve()
{
    
}


void Curve::setup()
{
    window.setFromCenter(0, 0, 200, 200);
    for (float &t : times) {
        t = ofRandom(10000);
    }
}


void Curve::update()
{
    float m = ofNoise(times.at(0));
    points.at(0) = (1 - m) * window.getTopLeft() + m * window.getBottomLeft();
    m = ofNoise(times.at(3));
    points.at(3) = (1 - m) * window.getTopRight() + m * window.getBottomRight();
    
    float length = (points.at(3) - points.at(0)).length() * 0.5;
    float angle = ofMap(ofSignedNoise(times.at(1)), -1, 1, -90, 90);
    ofVec2f dir = ofVec2f(1, 0);
    points.at(1) = points.at(0) + dir.rotate(angle) * length;
    
    angle = ofMap(ofSignedNoise(times.at(2)), -1, 1, -90, 90);
    dir = ofVec2f(-1, 0);
    points.at(2) = points.at(3) + dir.rotate(angle) * length;
    
    interPoints.clear();
    int max = 20;
    for (int i = 1; i < max; i++) {
        float step = 1 / (float)max;
        ofVec2f p = ofBezierPoint(points.at(0), points.at(1), points.at(2), points.at(3), step * i);
        interPoints.push_back(p);
    }
    
    for (float &t : times) {
        t += 0.02;
    }
}


void Curve::display()
{
    ofSetColor(0);
    ofNoFill();
    ofSetLineWidth(3);
    ofDrawRectangle(window);
    
    ofFill();
    ofSetLineWidth(2);
    for (int i = 0; i < interPoints.size(); i++) {
        ofVec2f p;
        if (i % 2 == 0) {
            ofSetColor(0, 0, 255);
            p.x = interPoints.at(i).x;
            p.y = window.getTop();
        } else {
            ofSetColor(255, 0, 0);
            p.x = interPoints.at(i).x;
            p.y = window.getBottom();
        }
        ofDrawLine(p, interPoints.at(i));
    }
    
    ofSetColor(0, 0, 0);
    ofFill();
    ofDrawCircle(points.at(0), 5);
    ofDrawCircle(points.at(3), 5);
}

Link to the reference page

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

categoryAPI/Lib
openframeworksofBezierPoint
openframeworksofDrawLine

Development environment

  • openframeworks 0.10.1
  • c++
  • macOS
  • Xcode