[work 58] Untitled

[work 58] Untitled

Movie

Source code

about

x = cos( θ1) * length, y = sin(θ2) * lengthとする点(Mover)を描く
振幅(length)や角(θ1, θ2)の変化速度はランダムに設定する
上記の法則に従った複数の点を使ってドロネー図を描く

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 "Mover.hpp"
#include "Delaunay.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<Mover>> movers;
    std::vector<ofVec2f> points;
    std::vector<std::array<ofVec2f, 3>> triangles;
    
    ofVec2f center;
    ofRectangle rect;
    Delaunay2d delaunay;
};
#include "ofApp.h"


ofApp::ofApp(){
    
}

ofApp::~ofApp(){
    
}

//--------------------------------------------------------------
void ofApp::setup(){
    double fps = 30;
    
    
    ofSetFrameRate(fps);
    ofBackground(255);
    ofSetBackgroundAuto(true);
    ofSetVerticalSync(true);
    
    for (int i = 0; i < 10; i++) {
        movers.push_back(make_shared<Mover>());
        movers.back()->setup();
    }
    
    rect = ofRectangle(0, 0, ofGetWidth(), ofGetHeight());
}

//--------------------------------------------------------------
void ofApp::update(){
    for (shared_ptr<Mover> m : movers) {
        m->update();
        points.push_back(m->getLocation());
    }
    
    delaunay.setup(rect, points);
    delaunay.getTriangle(triangles);
    
    points.clear();
}

//--------------------------------------------------------------
void ofApp::draw(){
    
    ofPushMatrix();
    for (std::array<ofVec2f, 3> a : triangles) {
        ofNoFill();
        ofSetColor(0);
        ofDrawTriangle(a[0], a[1], a[2]);
    }
    ofPopMatrix();
    
    for (shared_ptr<Mover> m : movers) {
        m->display();
    }
}
#ifndef Delaunay_hpp
#define Delaunay_hpp

#include <stdio.h>
#include "ofMain.h"
#include <opencv2/opencv.hpp>



class Delaunay2d {
public:
    Delaunay2d();
    ~Delaunay2d();
    void setup(ofRectangle rect, std::vector<ofVec2f> points);
    void getTriangle(std::vector<std::array<ofVec2f, 3>> &tlist);
    
private:
    cv::Subdiv2D sd;
    std::vector<cv::Vec6f> triangleList;
    cv::Rect area;
};
#endif /* Delaunay_hpp */
#include "Delaunay.hpp"


Delaunay2d::Delaunay2d()
{
    
}

Delaunay2d::~Delaunay2d()
{
    
}


void Delaunay2d::setup(ofRectangle rect, std::vector<ofVec2f> points)
{
    area.x = (int)rect.x;
    area.y = (int)rect.y;
    area.width = (int)rect.width;
    area.height = (int)rect.height;
    sd.initDelaunay(area);
    
    for (ofVec2f ofxp : points) {
        cv::Point2f pt;
        pt.x = ofxp.x;
        pt.y = ofxp.y;
        
        if(rect.inside(ofxp.x, ofxp.y)) {
            sd.insert(pt);
        } else {
            std::cout << "[Warning] out of area:" << pt.x << "," << pt.y << std::endl;
        }
    }
    sd.getTriangleList(triangleList);
}


void Delaunay2d::getTriangle(std::vector<std::array<ofVec2f, 3>> &tlist)
{
    std::array<ofVec2f, 3> a;
    ofRectangle r = ofRectangle(area.x, area.y, area.width, area.height);
    
    tlist.clear();
    
    for (cv::Vec6f v6f : triangleList) {
        a[0].x = v6f[0];
        a[0].y = v6f[1];
        a[1].x = v6f[2];
        a[1].y = v6f[3];
        a[2].x = v6f[4];
        a[2].y = v6f[5];
        
        if (r.inside(a[0]) && r.inside(a[1]) && r.inside(a[2])) {
            tlist.push_back(a);
        }
    }
}
#ifndef Mover_hpp
#define Mover_hpp

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

class Mover {
public:
    Mover();
    ~Mover();
    void setup();
    void update();
    void display();
    ofVec2f getLocation();
    
private:
    ofVec2f location;
    ofVec2f center;
    int stepx, stepy;
    float angleX, angleY;
    float length;
};
#endif /* Mover_hpp */
#include "Mover.hpp"


Mover::Mover()
{
    
}


Mover::~Mover()
{
    
}


void Mover::setup()
{
    angleX = ofRandom(0, 360);
    angleY = ofRandom(0, 360);
    stepx = (int)ofRandom(1, 5);
    stepy = (int)ofRandom(1, 5);
    length = ofRandom(100, 250);
    center = ofVec2f(ofGetWidth() / 2, ofGetHeight() / 2);
}


void Mover::update()
{
    float radX = TWO_PI * angleX / 360;
    float radY = TWO_PI * angleY / 360;
    location = center + (ofVec2f(std::cos(radX), std::sin(radY)) * length);
    angleX += stepx;
    angleY += stepy;
}


void Mover::display()
{
    ofFill();
    ofSetColor(0);
    ofDrawCircle(location, 3);
    
    ofNoFill();
    ofSetColor(0);
    ofDrawCircle(location, 6);
}


ofVec2f Mover::getLocation()
{
    return location;
}

Link to the reference page

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

categoryAPI/Lib
openframeworksofDrawTriangle
openCVcv::Subdiv2D

Development environment

  • openframeworks 0.10.1
  • c++
  • macOS
  • Xcode
  • openCV