[work 55] Flow field – cross –
![[work 55] Flow field – cross –](https://i0.wp.com/tsukuru.hayato-works.com/wp-content/uploads/2019/06/outFrameImg0450-3.png?fit=1024%2C576&ssl=1)
Movie
Source code
about
- Flow Field上に十字に配置した長方形を描く
- Flowに従って透明度と回転角度を変化させる
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 "FlowField.hpp"
#include "Shape.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:
shared_ptr<FlowField> ff;
int resolution;
std::vector<shared_ptr<Shape>> shapes;
};
#include "ofApp.h"
ofApp::ofApp(){
}
ofApp::~ofApp(){
}
//--------------------------------------------------------------
void ofApp::setup(){
double fps = 30;
ofSetFrameRate(fps);
ofBackground(255);
ofSetBackgroundAuto(true);
ofSetVerticalSync(true);
resolution = 40;
ff = make_shared<FlowField>(resolution);
ff->setup();
ofVec2f point;
int cols = ofGetWidth() / resolution;
int rows = ofGetHeight() / resolution;
for (int i = 0; i < cols; i++) {
for (int j = 0; j < rows; j++) {
point.x = i * resolution + (resolution / 2);
point.y = j * resolution + (resolution / 2);
shapes.push_back(make_shared<Shape>(point, resolution, resolution));
}
}
}
//--------------------------------------------------------------
void ofApp::update(){
ff->update();
for (shared_ptr<Shape> &s: shapes) {
s->follow(ff);
}
}
//--------------------------------------------------------------
void ofApp::draw(){
for (shared_ptr<Shape> &s: shapes) {
s->display();
}
}
#ifndef FlowField_hpp
#define FlowField_hpp
#include <stdio.h>
#include "ofMain.h"
class FlowField {
public:
FlowField(int r);
~FlowField();
void setup();
void update();
void display();
ofVec2f lookup(ofVec2f pos);
private:
int cols, rows;
int resolution;
float xoff, yoff, zoff;
std::vector<std::vector<ofVec2f>> field;
};
#endif /* FlowField_hpp */
#include "FlowField.hpp"
FlowField::FlowField(int r)
{
resolution = r;
cols = ofGetWidth() / resolution;
rows = ofGetHeight() / resolution;
field.assign(cols, std::vector<ofVec2f>(rows, ofVec2f(0, 0)));
}
FlowField::~FlowField()
{
}
void FlowField::setup()
{
zoff = 0;
}
void FlowField::update()
{
xoff = 0;
for (int x = 0; x < cols; x++) {
yoff = 0;
for (int y = 0; y < rows; y++) {
float theta = ofMap(ofNoise(xoff, yoff, zoff), 0, 1, 0, TWO_PI);
ofVec2f dir = ofVec2f(std::cos(theta), std::sin(theta));
field[x][y] = dir.normalize();
yoff += 0.05;
}
xoff += 0.05;
}
zoff += 0.01;
}
void FlowField::display()
{
for (int x = 0; x < cols; x++) {
for (int y = 0; y < rows; y++) {
ofPushMatrix();
ofTranslate(x * resolution, y * resolution);
ofNoFill();
ofSetColor(255);
ofDrawRectangle(0, 0, resolution, resolution);
ofVec2f c = ofVec2f(resolution / 2, resolution / 2);
int len = resolution * 3 / 4;
ofVec2f t0 = c - (field[x][y] * len / 2);
ofVec2f t1 = c + (field[x][y] * len / 2);
ofSetColor(255, 255, 0);
ofDrawLine(t0.x, t0.y, t1.x, t1.y);
ofPopMatrix();
}
}
}
ofVec2f FlowField::lookup(ofVec2f pos)
{
int col = (int)ofClamp(pos.x / resolution, 0, cols - 1);
int row = (int)ofClamp(pos.y / resolution, 0, rows - 1);
return field[col][row];
}
#ifndef Shape_hpp
#define Shape_hpp
#include <stdio.h>
#include "ofMain.h"
#include "FlowField.hpp"
class Shape {
public:
Shape(ofVec2f pos, float w, float h);
~Shape();
void display();
void follow(shared_ptr<FlowField> &flow);
private:
ofColor color1, color2;
ofVec2f location;
float angle;
float width;
float height;
};
#endif /* Shape_hpp */
#include "Shape.hpp"
Shape::Shape(ofVec2f pos, float w, float h)
{
color1 = ofColor(ofRandom(255),ofRandom(255),ofRandom(255));
color2 = ofColor(128);
location = pos;
width = w;
height = h;
}
Shape::~Shape()
{
}
void Shape::display()
{
ofPushMatrix();
ofTranslate(location.x, location.y);
ofRotateDeg(angle);
ofSetRectMode(OF_RECTMODE_CENTER);
ofFill();
ofSetColor(color1, ofMap(angle, -180, 180, 0, 255));
ofDrawRectangle(0, 0, width, 5);
ofDrawRectangle(0, 0, 5, height);
ofPopMatrix();
ofPushMatrix();
ofTranslate(location.x, location.y);
ofSetRectMode(OF_RECTMODE_CENTER);
ofNoFill();
ofSetColor(color2);
ofSetLineWidth(5);
ofDrawRectangle(0, 0, width, height);
ofPopMatrix();
}
void Shape::follow(shared_ptr<FlowField> &flow)
{
ofVec2f dir = flow->lookup(location);
ofVec2f org = ofVec2f(1, 0);
angle = org.angle(dir);
}
Link to the reference page
ソースコードで使用したAPIの中から要点になりそうなものをいくつか選んでリストアップしました。
| category | API/Lib |
| openframeworks | ofNoise |
| openframeworks | ofVec2f |
| c++ | std::vector |
Development environment
- openframeworks 0.10.1
- c++
- macOS
- Xcode