[work 108] Rubik’s Cube
Movie
Source code
about
- ルービックキューブをシャッフルした状態から6面そろうまで
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: ofEasyCam cam; std::shared_ptr<Cube> cube; };
#include "ofApp.h" ofApp::ofApp(){ } ofApp::~ofApp(){ } //-------------------------------------------------------------- void ofApp::setup(){ double fps = 30; ofSetFrameRate(fps); ofBackground(0); ofSetBackgroundAuto(true); ofSetVerticalSync(true); ofEnableDepthTest(); cube = make_shared<Cube>(); cube->setup(); cam.setPosition(400, 400, 400); cam.lookAt(glm::vec3(0, 0, 0)); } //-------------------------------------------------------------- void ofApp::update(){ cube->update(); } //-------------------------------------------------------------- void ofApp::draw(){ cam.begin(); cube->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" struct Command { int rotDir; int rotPosition; glm::vec3 rotAxis; }; class Cube { public: Cube(); ~Cube(); void setup(); void update(); void display(); private: void shuffle(); std::vector<ofBoxPrimitive> boxes; float size; float offset; int rotAngle; int rotDir; int rotPosition; glm::vec3 rotAxis; std::vector<Command> cmd; }; #endif /* Cube_hpp */
#include "Cube.hpp" Cube::Cube() { } Cube::~Cube() { } void Cube::setup() { size = 100; offset = 3; for (int x = -1; x <= 1; x++) { for (int y = -1; y <= 1; y++) { for (int z = -1; z <= 1; z++) { ofBoxPrimitive b; b.set(size); b.setPosition(x, y, z); b.setSideColor(0, ofColor(255, 255, 255)); b.setSideColor(1, ofColor(0, 255, 0)); b.setSideColor(2, ofColor(0, 0, 255)); b.setSideColor(3, ofColor(255, 255, 0)); b.setSideColor(4, ofColor(255, 102, 12)); b.setSideColor(5, ofColor(255, 0, 0)); boxes.push_back(b); } } } shuffle(); rotAngle = 0; } void Cube::update() { if (rotAngle == 0) { if (!cmd.empty()) { Command c = cmd.back(); rotPosition = c.rotPosition; rotAxis = c.rotAxis; rotDir = c.rotDir * (-1); // reverse cmd.pop_back(); } else { rotDir = 0; // pause } } else { for (ofBoxPrimitive &b : boxes) { glm::vec3 loc = b.getPosition(); glm::vec3 m, n; // for ignore errors m.x = (int)(loc * rotAxis).x; m.y = (int)(loc * rotAxis).y; m.z = (int)(loc * rotAxis).z; n.x = (int)(rotAxis * rotPosition).x; n.y = (int)(rotAxis * rotPosition).y; n.z = (int)(rotAxis * rotPosition).z; if (m == n) { loc = glm::vec4(loc, 0) * glm::rotate(glm::mat4(), ofDegToRad(rotDir), rotAxis); b.setPosition(loc); b.rotateDeg(rotDir * (-1), rotAxis); } b.setPosition(loc); } } rotAngle = (rotAngle + 1) % 91; } void Cube::display() { for (ofBoxPrimitive &b : boxes) { glm::vec3 loc = b.getPosition(); glm::vec3 drawPos = loc * (size + offset); b.setPosition(drawPos); b.draw(); b.setPosition(loc); } } void Cube::shuffle() { for (int i = 0; i < 10; i++) { Command c; std::array<int, 3> a{-1, 0, 1}; c.rotPosition = a.at((int)ofRandom(a.size())); float p = ofRandom(1); if (p < (1.0 / 3.0)) { c.rotAxis = glm::vec3(1, 0, 0); } else if (p < (2.0 / 3.0)) { c.rotAxis = glm::vec3(0, 1, 0); } else { c.rotAxis = glm::vec3(0, 0, 1); } std::array<int, 2> d{-1, 1}; c.rotDir = d.at((int)ofRandom(d.size())); for (ofBoxPrimitive &b : boxes) { glm::vec3 loc = b.getPosition(); glm::vec3 m, n; // for ignore errors m.x = (int)(loc * c.rotAxis).x; m.y = (int)(loc * c.rotAxis).y; m.z = (int)(loc * c.rotAxis).z; n.x = (int)(c.rotAxis * c.rotPosition).x; n.y = (int)(c.rotAxis * c.rotPosition).y; n.z = (int)(c.rotAxis * c.rotPosition).z; if (m == n) { loc = glm::vec4(loc, 0) * glm::rotate(glm::mat4(), ofDegToRad(c.rotDir * 90), c.rotAxis); // for ignore errors loc.x = std::round(loc.x); loc.y = std::round(loc.y); loc.z = std::round(loc.z); b.setPosition(loc); b.rotateDeg((c.rotDir * 90) * (-1), c.rotAxis); } } cmd.push_back(c); } }
Link to the reference page
ソースコードで使用したAPIの中から要点になりそうなものをいくつか選んでリストアップしました。
category | API/Lib |
openframeworks | ofBoxPrimitive |
openframeworks | glm::vec3 |
openframeworks | glm::rotate |
Development environment
- openframeworks 0.10.1
- c++
- macOS
- Xcode