[work 77] A to Z
![[work 77] A to Z](https://i0.wp.com/tsukuru.hayato-works.com/wp-content/uploads/2019/08/outFrameImg0000.png?fit=1024%2C576&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 "Morphing.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::shared_ptr<Morphing> morph;
};
#include "ofApp.h"
ofApp::ofApp(){
}
ofApp::~ofApp(){
}
//--------------------------------------------------------------
void ofApp::setup(){
double fps = 30;
ofSetFrameRate(fps);
ofBackground(255);
ofSetBackgroundAuto(true);
ofSetVerticalSync(true);
morph = make_shared<Morphing>();
morph->setup();
}
//--------------------------------------------------------------
void ofApp::update(){
morph->update();
}
//--------------------------------------------------------------
void ofApp::draw(){
morph->display();
}
//--------------------------------------------------------------
void ofApp::keyPressed(int key){
if (key == 's') {
ofImage img;
img.grabScreen(0, 0, ofGetWidth(), ofGetHeight());
img.save("screenshot.png");
}
}
#ifndef Morphing_hpp
#define Morphing_hpp
#include <stdio.h>
#include "ofMain.h"
#include "ofxEasing.h"
class Morphing {
public:
Morphing();
~Morphing();
void setup();
void update();
void display();
private:
void setTarget(char c);
void arrangeVec();
std::shared_ptr<ofTrueTypeFont> font;
std::string morphStr;
int index;
bool morphUpdate;
std::vector<std::vector<glm::vec3>> drawPoint;
std::vector<std::vector<glm::vec3>> target;
std::vector<std::vector<glm::vec3>> org;
int count;
ofRectangle boundingBox;
};
#endif /* Morphing_hpp */
#include "Morphing.hpp"
Morphing::Morphing()
{
}
Morphing::~Morphing()
{
}
void Morphing::setup()
{
font = make_shared<ofTrueTypeFont>();
font->load("font/Helvetica.ttc", 60, false, false, true);
count = 1;
index = 0;
morphUpdate = true;
morphStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
setTarget(morphStr.at(index));
index++;
org = target;
}
void Morphing::update()
{
int maxFrame = (int)ofGetTargetFrameRate();
if (morphUpdate) {
if (count != 0) {
drawPoint.clear();
for (int i = 0; i < target.size(); i++) {
std::vector<glm::vec3> tmp;
for (int j = 0; j < target.at(i).size(); j++) {
float step = ofxeasing::map(count, 0, maxFrame - 1, 0, 1, ofxeasing::elastic::easeOut);
tmp.push_back(org.at(i).at(j) + (target.at(i).at(j) - org.at(i).at(j)) * step);
}
drawPoint.push_back(tmp);
}
} else {
if (index < morphStr.size()) {
org.clear();
org = target;
setTarget(morphStr.at(index));
index++;
arrangeVec();
} else {
morphUpdate = false;
}
}
count = (count + 1) % maxFrame;
}
}
void Morphing::display()
{
ofSetPolyMode(OF_POLY_WINDING_NONZERO);
ofPushMatrix();
ofSetColor(0);
ofNoFill();
ofTranslate((ofGetWidth() / 2) - boundingBox.width / 2, (ofGetHeight() / 2) + boundingBox.height / 2);
for (std::vector<glm::vec3> p : drawPoint) {
ofBeginShape();
ofVertices(p);
ofEndShape();
}
ofPopMatrix();
}
void Morphing::setTarget(char c)
{
std::string str(1, c);
std::vector<ofPath> paths = font->getStringAsPoints(str, true, false);
float amp = 5;
float minX = FLT_MIN;
float maxY = 0;
float maxW = 0;
float maxH = 0;
target.clear();
for (ofPath path : paths) {
std::vector<ofPolyline> lines = path.getOutline();
minX = std::min(minX, lines.at(0).getBoundingBox().x * amp);
maxY = std::max(maxY, lines.at(0).getBoundingBox().y * amp);
maxW = std::max(maxW, lines.at(0).getBoundingBox().width * amp);
maxH = std::max(maxH, lines.at(0).getBoundingBox().height * amp);
for (ofPolyline pl : lines) {
std::vector<glm::vec3> points = pl.getVertices();
for (glm::vec3 &p : points) {
p *= amp;
}
target.push_back(points);
}
}
boundingBox.x = minX;
boundingBox.y = maxY;
boundingBox.width = maxW;
boundingBox.height = maxH;
}
void Morphing::arrangeVec()
{
// resize
if (org.size() > target.size()) {
// thin out
while (org.size() != target.size()) {
org.pop_back();
}
} else {
// packing
while (org.size() != target.size()) {
std::vector<glm::vec3> tmp(1, boundingBox.getCenter());
org.push_back(tmp);
}
}
for (int i = 0; i < org.size(); i++) {
if (org.at(i).size() > target.at(i).size()) {
// thin out
while (org.at(i).size() != target.at(i).size()) {
org.at(i).pop_back();
}
} else {
// packing
while (org.at(i).size() != target.at(i).size()) {
org.at(i).push_back(boundingBox.getCenter());
}
}
}
}
Link to the reference page
ソースコードで使用したAPIの中から要点になりそうなものをいくつか選んでリストアップしました。
| category | API/Lib |
| openframeworks | ofTrueTypeFont |
| openframeworks | ofPath |
| openframeworks | ofPolyLine |
| openframeworks | glm::vec3 |
| openframeworks | ofxeasing map |
Development environment
- openframeworks 0.10.1
- c++
- macOS
- Xcode