[work 57] Delaunay diagram – revolving points –

[work 57] Delaunay diagram – revolving points –

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 "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<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);
    
    ofVec2f base = ofVec2f(1, 0);
    float width = 30;
    for (int i = 0; i < 10; i++) {
        ofVec2f p = base * (width * (i + 1));
        points.push_back(p);
    }
    
    rect = ofRectangle(-(ofGetWidth() / 2), -(ofGetHeight() / 2), ofGetWidth(), ofGetHeight());
    delaunay.setup(rect, points);
}

//--------------------------------------------------------------
void ofApp::update(){
    float angleV = 10;
    int div = 1;
    
    delaunay.getTriangle(triangles);
    
    for (ofVec2f &p : points) {
        p.rotate(angleV / div);
        div += 1;
    }
    delaunay.setup(rect, points);
}

//--------------------------------------------------------------
void ofApp::draw(){
    
    ofPushMatrix();
    ofTranslate(ofGetWidth() / 2, ofGetHeight() / 2);
    
    for (std::array<ofVec2f, 3> a : triangles) {
        ofNoFill();
        ofSetColor(0);
        ofDrawTriangle(a[0], a[1], a[2]);

        ofFill();
        ofSetColor(0);
        ofDrawCircle(a[0], 3);
        ofDrawCircle(a[1], 3);
        ofDrawCircle(a[2], 3);

        ofNoFill();
        ofSetColor(0);
        ofDrawCircle(a[0], 6);
        ofDrawCircle(a[1], 6);
        ofDrawCircle(a[2], 6);
    }
    ofPopMatrix();
}
#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);
        }
    }
}

Link to the reference page

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

categoryAPI/Lib
openframeworksofDrawTriangle
openCVcv::Subdiv2D

Development environment

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