[work 18] Harmonograph(Orthogonal)
![[work 18] Harmonograph(Orthogonal)](https://i0.wp.com/tsukuru.hayato-works.com/wp-content/uploads/2019/03/outFrameImg0900-1.png?fit=1280%2C720&ssl=1)
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 "Harmonograph.hpp"
#define MAX_HARMONOGRAPH (9)
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::unique_ptr<Harmonograph>> h;
std::vector<ofVec2f> origin;
};
#include "ofApp.h"
ofApp::ofApp(){
for (int i = 0; i < MAX_HARMONOGRAPH; i++) {
h.push_back(std::unique_ptr<Harmonograph>(new Harmonograph(ofVec2f(100, 100))));
}
origin.push_back(ofVec2f(ofGetWidth() / 2 - 300, ofGetHeight() / 2 - 300));
origin.push_back(ofVec2f(ofGetWidth() / 2 - 100, ofGetHeight() / 2 - 300));
origin.push_back(ofVec2f(ofGetWidth() / 2 + 100, ofGetHeight() / 2 - 300));
origin.push_back(ofVec2f(ofGetWidth() / 2 - 300, ofGetHeight() / 2 - 100));
origin.push_back(ofVec2f(ofGetWidth() / 2 - 100, ofGetHeight() / 2 - 100));
origin.push_back(ofVec2f(ofGetWidth() / 2 + 100, ofGetHeight() / 2 - 100));
origin.push_back(ofVec2f(ofGetWidth() / 2 - 300, ofGetHeight() / 2 + 100));
origin.push_back(ofVec2f(ofGetWidth() / 2 - 100, ofGetHeight() / 2 + 100));
origin.push_back(ofVec2f(ofGetWidth() / 2 + 100, ofGetHeight() / 2 + 100));
}
ofApp::~ofApp(){
}
//--------------------------------------------------------------
void ofApp::setup(){
double fps = 30;
ofSetFrameRate(fps);
ofBackground(0);
ofSetBackgroundAuto(true);
for (int i = 0; i < h.size(); i++) {
h[i]->setup();
}
}
//--------------------------------------------------------------
void ofApp::update(){
for (int i = 0; i < h.size(); i++) {
h[i]->update();
}
}
//--------------------------------------------------------------
void ofApp::draw(){
for (int i = 0; i < h.size(); i++) {
ofPushMatrix();
ofTranslate(origin[i].x, origin[i].y);
h[i]->display();
ofPopMatrix();
}
}
#ifndef Harmonograph_hpp
#define Harmonograph_hpp
#include <stdio.h>
#include "ofMain.h"
#define H_DIMENSION (2)
class Harmonograph {
public:
Harmonograph(ofVec2f org);
~Harmonograph();
void setup();
void update();
void display();
private:
Harmonograph();
ofVec2f setPoint();
ofVec2f origin;
ofVec2f point;
ofMesh locus;
std::vector<float> angle; // radian
std::vector<float> angleVelocity;
std::vector<int> direction;
std::vector<float> decay;
std::vector<float> amplitude;
std::vector<ofVec2f> location;
std::vector<ofVec2f> rail0;
std::vector<ofVec2f> rail1;
};
#endif /* Harmonograph_hpp */
#include "Harmonograph.hpp"
Harmonograph::Harmonograph(ofVec2f org)
{
origin = org;
}
Harmonograph::~Harmonograph()
{
}
void Harmonograph::setup()
{
int k = 0;
std::cout << "Create Harmonograph" << std::endl;
for (int i = 0; i < H_DIMENSION; i++) {
k = (int)ofRandom(4);
angle.push_back(PI / 2 * k);
std::cout << "[angle]" << angle[i] << std::endl;
k = (int)ofRandom(1, 16);
angleVelocity.push_back((PI / (180 * 5)) * 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;
decay.push_back(0.9999);
amplitude.push_back(ofRandom(80,100));
std::cout << "[amplitude]" << amplitude[i] << std::endl;
location.push_back(ofVec2f(0,0));
}
rail0.push_back(ofVec2f(origin.x + std::sin(-PI/2) * amplitude[0], origin.y));
rail0.push_back(ofVec2f(origin.x + std::sin(PI/2) * amplitude[0], origin.y));
rail1.push_back(ofVec2f(origin.x, origin.y + std::sin(-PI/2) * amplitude[1]));
rail1.push_back(ofVec2f(origin.x, origin.y + std::sin(PI/2) * amplitude[1]));
}
void Harmonograph::update()
{
location[0].x = origin.x + std::sin(angle[0]) * amplitude[0];
location[0].y = origin.y;
location[1].x = origin.x;
location[1].y = origin.y + std::sin(angle[1]) * amplitude[1];
angle[0] += angleVelocity[0] * direction[0];
angle[1] += angleVelocity[1] * direction[1];
amplitude[0] *= decay[0];
amplitude[1] *= decay[1];
point = setPoint();
}
void Harmonograph::display()
{
ofSetColor(255,255,0,128);
ofDrawLine(location[0].x, location[0].y, location[1].x, location[1].y);
ofDrawCircle(location[0].x, location[0].y, 5);
ofDrawCircle(location[1].x, location[1].y, 5);
ofSetColor(255,255,0,128);
ofDrawLine(rail0[0].x, rail0[0].y, rail0[1].x, rail0[1].y);
ofDrawLine(rail1[0].x, rail1[0].y, rail1[1].x, rail1[1].y);
locus.addVertex(ofVec3f(point.x, point.y, 0));
locus.addColor(ofColor(255));
locus.drawVertices();
}
ofVec2f Harmonograph::setPoint()
{
return (location[0] + location[1]) / 2;
}
Link to the reference page
ソースコードで使用したAPIの中から要点になりそうなものをいくつか選んでリストアップしました。
| category | API/Lib |
| openframeworks | ofMesh addVertex |
| c++ | std::vector |
| c++ | std::unique_ptr |
Development environment
- openframeworks 0.10.1
- c++
- macOS
- Xcode