[work 85] Make “A” with cubes
![[work 85] Make “A” with cubes](https://i0.wp.com/tsukuru.hayato-works.com/wp-content/uploads/2019/08/outFrameImg1800.png?fit=1280%2C720&ssl=1)
Movie
Source code
about
- キューブで”A”を形成する
- キューブは目的の場所に向かって進む
- 目的の場所に到達したら停止する
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 "Cube.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:
ofCamera cam;
std::vector<std::shared_ptr<Cube>> cube;
ofTrueTypeFont font;
std::vector<ofVec3f> targets;
float size;
int col;
int row;
};
#include "ofApp.h"
ofApp::ofApp(){
}
ofApp::~ofApp(){
}
//--------------------------------------------------------------
void ofApp::setup(){
double fps = 30;
ofSetFrameRate(fps);
ofBackground(255);
ofSetBackgroundAuto(true);
ofSetVerticalSync(true);
ofEnableDepthTest();
ofEnableSmoothing();
cam.setGlobalPosition(ofVec3f(600, 1200, 800));
cam.lookAt(glm::vec3(0, 0, 0));
font.load("font/Helvetica.ttc", 10);
ofTexture tex = font.getStringTexture("A");
ofFbo fbo;
fbo.allocate(tex.getWidth(), tex.getHeight());
fbo.begin();
ofClear(0);
tex.draw(0, 0);
fbo.end();
ofPixels pix;
fbo.readToPixels(pix);
for (int i = 0; i < pix.getWidth(); i++) {
for (int j = 0; j < pix.getHeight(); j++) {
if (pix.getColor(i, j) != ofColor(0, 0, 0, 0)) {
targets.push_back(ofVec3f(i, 0, j));
}
}
}
size = 150;
row = pix.getWidth() + (pix.getWidth() % 2) + 2;
col = pix.getHeight() + (pix.getHeight() % 2) + 2;
}
//--------------------------------------------------------------
void ofApp::update(){
int count = ofGetFrameNum() % (int)ofGetTargetFrameRate();
if ((count == 0) && (targets.empty() == false)) {
int index = (int)ofRandom(targets.size());
ofVec3f offset = ofVec3f((int)(-row / 2), 0, (int)(-col / 2)) + ofVec3f(2, 0, 2);
cube.push_back(make_shared<Cube>(ofVec3f(0, 0, (int)(-col / 2)), size));
cube.back()->setup();
cube.back()->setTarget(offset + targets.at(index));
auto itr = targets.begin();
targets.erase(itr + index);
}
for (std::shared_ptr<Cube> c : cube) {
c->update();
}
}
//--------------------------------------------------------------
void ofApp::draw(){
cam.begin();
ofSetRectMode(OF_RECTMODE_CENTER);
for (int i = -row / 2; i < row / 2; i++) {
for (int j = -col / 2; j < col / 2; j++) {
ofPushMatrix();
ofSetColor(240, 201, 194);
ofNoFill();
ofTranslate(ofVec3f(i * size, -size / 2, j * size));
ofRotateDeg(90, 1, 0, 0);
ofDrawRectangle(0, 0, 0, size, size);
ofPopMatrix();
}
}
for (std::shared_ptr<Cube> c : cube) {
c->display();
}
cam.end();
}
//--------------------------------------------------------------
void ofApp::keyPressed(int key){
if (key == 's') {
ofImage img;
img.grabScreen(0, 0, ofGetWidth(), ofGetHeight());
img.save("screenshot.png");
}
}
#ifndef Cube_hpp
#define Cube_hpp
#include <stdio.h>
#include "ofMain.h"
#include "ofxEasing.h"
enum CUBE_MOVE {
CUBE_F = 0, // forward
CUBE_B, // back
CUBE_R, // right
CUBE_L, // left
CUBE_U, // up
CUBE_D, // down
CUBE_P, // pause
CUBE_MAX
};
class Cube {
public:
Cube();
Cube(ofVec3f p, float s);
~Cube();
void setup();
void update();
void display();
void setTarget(ofVec3f t);
private:
void move(CUBE_MOVE dir);
void randMove();
void targetMove();
ofVec3f center;
ofVec3f position;
ofVec3f transToRAxis;
ofVec3f moveTo;
ofVec3f target;
float size;
ofColor colFrame;
ofColor colFace;
bool pause;
int updateCount;
ofVec3f rAxis;
float rAngle;
};
#endif /* Cube_hpp */
#include "Cube.hpp"
Cube::Cube()
{
size = 150;
position = ofVec3f(0, 0, 0);
}
Cube::Cube(ofVec3f p, float s)
{
size = s;
position = p;
}
Cube::~Cube()
{
}
void Cube::setup()
{
center = ofVec3f(0, 0, 0);
moveTo = ofVec3f(0, 0, 0);
rAxis = ofVec3f(0, 0, 0);
target = ofVec3f(0, 0, 0);
rAngle = 0;
colFrame = ofColor(0);
colFace = ofColor(ofRandom(255), ofRandom(255), ofRandom(255));
pause = false;
updateCount = 0;
}
void Cube::update()
{
int loopMax = (int)ofGetTargetFrameRate();
int loopCount = updateCount % loopMax;
updateCount++;
if (loopCount == 0) {
rAngle = 0;
position += moveTo;
targetMove();
} else {
if (pause == false) {
rAngle = (int)ofxeasing::map(loopCount, 0, loopMax - 1, 0, 90, ofxeasing::quart::easeInOut);
}
}
}
void Cube::display()
{
ofPushMatrix();
ofTranslate(position * size);
ofTranslate(transToRAxis * -1);
ofRotateDeg(rAngle, rAxis.x, rAxis.y, rAxis.z);
ofTranslate(transToRAxis);
ofSetColor(colFace);
ofFill();
ofDrawBox(center, size * 0.8);
ofSetColor(colFrame);
ofNoFill();
ofDrawBox(center, size);
ofPopMatrix();
}
void Cube::setTarget(ofVec3f t)
{
target = t;
}
void Cube::move(CUBE_MOVE dir)
{
pause = false;
if (dir == CUBE_F) { // Forward(Z-axis(+))
rAxis = ofVec3f(1, 0, 0);
transToRAxis = ofVec3f(0, 1, -1) * size * 0.5;
moveTo = ofVec3f(0, 0, 1);
} else if (dir == CUBE_B) { // Back(Z-axis(-))
rAxis = ofVec3f(-1, 0, 0);
transToRAxis = ofVec3f(0, 1, 1) * size * 0.5;
moveTo = ofVec3f(0, 0, -1);
} else if (dir == CUBE_R) { // Right(X-axis(-))
rAxis = ofVec3f(0, 0, 1);
transToRAxis = ofVec3f(1, 1, 0) * size * 0.5;
moveTo = ofVec3f(-1, 0, 0);
} else if (dir == CUBE_L) { // Left(X-axis(+))
rAxis = ofVec3f(0, 0, -1);
transToRAxis = ofVec3f(-1, 1, 0) * size * 0.5;
moveTo = ofVec3f(1, 0, 0);
} else if (dir == CUBE_U) {
rAxis = ofVec3f(1, 0, 0);
transToRAxis = ofVec3f(0, -1, -1) * size * 0.5;
moveTo = ofVec3f(0, 1, 0);
} else if (dir == CUBE_D) {
rAxis = ofVec3f(-1, 0, 0);
transToRAxis = ofVec3f(0, 1, -1) * size * 0.5;
moveTo = ofVec3f(0, -1, 0);
} else { // Pause
pause = true;
rAxis = ofVec3f(0, 0, 0);
transToRAxis = ofVec3f(0, 0, 0);
moveTo = ofVec3f(0, 0, 0);
}
}
void Cube::randMove()
{
int dir = (int)ofRandom(CUBE_MAX);
move((CUBE_MOVE)dir);
}
void Cube::targetMove()
{
ofVec3f t;
t.x = (int)target.x - (int)position.x;
t.y = (int)target.y - (int)position.y;
t.z = (int)target.z - (int)position.z;
if (t != ofVec3f(0, 0, 0)) {
float px = std::abs(t.x) / (std::abs(t.x) + std::abs(t.y) + std::abs(t.z));
float py = std::abs(t.y) / (std::abs(t.x) + std::abs(t.y) + std::abs(t.z));
float pz = std::abs(t.z) / (std::abs(t.x) + std::abs(t.y) + std::abs(t.z));
float p = ofRandom(1);
if (p < px) {
if (t.x > 0) {
move(CUBE_L);
} else {
move(CUBE_R);
}
} else if ((p >= px) && (p < px + py)) {
if (t.y > 0) {
move(CUBE_U);
} else {
move(CUBE_D);
}
} else {
if (t.z > 0) {
move(CUBE_F);
} else {
move(CUBE_B);
}
}
} else {
move(CUBE_P);
}
}
Link to the reference page
ソースコードで使用したAPIの中から要点になりそうなものをいくつか選んでリストアップしました。
| category | API/Lib |
| openframeworks | ofTrueTypeFont |
| openframeworks | ofFbo |
| openframeworks | ofTexture |
| openframeworks | ofPixels |
| openframeworks | ofTranslate |
| openframeworks | ofRotateDeg |
| openframeworks | ofEnableDepthTest |
| openframeworks | ofxeasing map |
Development environment
- openframeworks 0.10.1
- c++
- macOS
- Xcode