yoppa.org


第4回: Web応用1 – Webブラウザでプログラミング、p5.js入門

この講義のここまで前半3回では「Web基礎」と題して、HTMLとCSSの基本、そしてTumblrを使用したオンライン・ポートフォリオの作成について解説してきました。前半のまとめとして、作成したオンライン・ポートフォリオのベースとなる部分を提出してもらいます。提出方法は授業内で指示します。

いよいよ後半は、サウンド&ネットのサウンドのパートとも協力して、Web上で音を使用した作品を公開することを最終目標に、新たな内容に進んでいきます。

JavaScript – Webブラウザでプログラミングする

これまで取り扱ってきた、HTMLやCSSは人工的に仕様が策定された言語ではありますが、プログラミング言語ではありませんでした(HTMLはマークアップ言語、CSSはスタイルシート言語)。

HTMLやCSSとは別に、Webブラウザ上で動作させることのできるプログラミング言語が存在します。その代表的な言語がJavaScriptです。

現在、Webサイトは「文書」を載せるためのメディアから、「アプリケーション」を作動させるためのプラットフォームへとその姿を変えつつあります。そのための技術を総称して(広義の)HTML5と呼ばれ、次世代のWeb技術として注目されています。

JavaScriptはこうしたHTML5の技術を支える根幹となるプログラミング言語といえます。

※ 注意: プログラミング言語のJavaとJavaScriptは、名称が似ているので関連する技術と勘違いされがちですが、全く関係ありません。「ハム」と「ハムスター」くらい違います。

JavaScriptのためのライブラリ

JavaScirptはプログラミング言語や開発環境をダウンロードしたり設定しなくても、Webブラウザさえあえればすぐにプログラミングが可能です。ただし、JavaScript単体でプログラミングするには、ある程度のプログラミングに関する知識と学習が必要となります。

JavaScriptでは、開発を容易にするための拡張機能として、ライブラリ(Library)と呼ばれる、汎用性の高い複数のプログラムを再利用可能な形でひとまとまりにしたものが数多く開発され、フリーウェアとして配布されています。

代表的なものだけでも数多くのライブラリが存在しています。

こうした数多くのライブラリの中から、今回はp5.jsというライブラリを使用していきたいと考えています。

p5.js

p5.jsはアーティストでプログラマーのLauren McCarthyさんを中心に、Processing Foundationやニューヨーク大学ITPのサポートで開発されています。

p5.jsを採用した理由はいくつかあります。

  • 既に春学期にProcessingを学んでいるので、導入が楽
  • テキストやビデオ(Webcamからの入力を含む)、サウンドといったHTML5の他の要素を使用できる
  • わかりやすい開発環境(p5 editor)が存在する
  • Processingの開発コミュニティーとの相互交流がある

様々な利点からp5.jsを活用していくことにしました。

p5.jsをはじめよう!

p5.jsの開発する場合、2通りの開発方法があります。

  • p5.jsのライブラリを手動でリンクして、テキストエディタで編集する方法
  • p5.jsの専用の開発環境(p5.js editor)を使う方法 – ただし現状ではOS X版のみ

今回は、設定が容易な専用の開発環境である「p5.js editor」を使用する二つ目の方法で導入を行います。

p5.jsのダウンローロページから、Editorの欄にある「p5.js editor」をダウンロードします。

ダウンロードした、p5.zipを展開すると、p5.appというアプリケーションが生成されます。

screenshot_389

このアイコンをダブルクリックするとエディターが起動します。

screenshot_390

まず手始めに、以下のように入力してみましょう。

function setup() {

}

function draw() {
  ellipse(50, 50, 80, 80);
}

入力したら、画面左上の実行ボタンをクリックします。するとWebブラウザが起動して、円が表示されます。

screenshot_391

さらにプログラムに追加します。

function setup() {
  createCanvas(640, 480);
}

function draw() {
  if (mouseIsPressed) {
    fill(0);
  } else {
    fill(255);
  }
  ellipse(mouseX, mouseY, 80, 80);
}

このプログラムを実行してみましょう。マウスの位置に円が移動します。また、マウスをクリックしたときには黒い円、マウスボタンを押していない時には白い円になります。

screenshot_392

Processingとp5.jsの違い

ここまでやってきたように、p5.jsはProcessingにとても近い文法で簡単にWebブラウザ上でプログラミングが可能です。ただし、p5.jsとProcessingは微妙に違っている部分もあります。

Processingとp5.jsの違いは、p5.jsのGithubページ内のドキュメントにまとまっています。このドキュメントを参照しながら、違いについて解説します。

実習: p5.js演習

後半は、実習形式で進めます。以下の内容で個人で作業を行ってください。

1. サンプルを実行

  • p5.jsのサンプルページのExample以下にある、様々なサンプルをEditorにコピペして実行してみる。
  • 実行したサンプルからひとつお気に入りのプログラムを選択する。

2. サンプルを改造

  • 選択したサンプルの数値や色、動きなどを変更して、別のプグラムに改造する。

3. 発表

  • プログラムを発表、サンプルの何を変更したのか解説

C++の疑問: 値渡し、参照渡し、ポインタ渡し

※ 末尾に追記あり。

C++、いろいろ未だにわからにことだらけなのだけれど、関数に値を送る場合の

  • 値渡し
  • 参照渡し
  • ポインタ渡し

の違いがいまだにすっきりと整理できていない。

C++、自分の場合はoFで使うことがほとんどなので、oFのコードで実験してすっきりしてみようとシンプルなコードを書いてみた。

力をベクトルで与えると運動するParticleというクラスを以前から作っていたいので、これはそのまま流用。長くなるのでコードの内容は割愛。

Particleを操作するためのMoverというクラスをつくってみた。このMoverクラスは3種類の方法でParticleのインスタンスを受けとることができる

  • A: 値渡し
  • B: 参照渡し
  • C: ポインタ渡し

Mover.h

#pragma once
#include "ofMain.h"
#include "Particle.h"

class Mover{
public:
    void setParticle(Particle p);       // 値渡し
    void setParticleRef(Particle &p);   // 参照渡し
    void setParticlePtr(Particle *p);   // ポインタ渡し
    
    void update();
    
    Particle particleA;
    Particle particleB;
    Particle *particleC;
};

Mover.cpp

#include "Mover.h"

// A: オブジェクトの値渡し
void Mover::setParticle(Particle p){
    particleA = p;
    particleA.velocity = ofVec2f(10.0, 0);
}

// B: オブジェクトの参照渡し
void Mover::setParticleRef(Particle &p){
    particleB = p;
    particleB.velocity = ofVec2f(10.0, 0);
}

// C: オブジェクトのポインタ渡し
void Mover::setParticlePtr(Particle *p){
    particleC = p;
    particleC->velocity = ofVec2f(10.0, 0);
}

// それぞれのオブジェクトを更新
void Mover::update(){
    particleA.resetForce();
    particleA.update();

    particleB.resetForce();
    particleB.update();

    particleC->resetForce();
    particleC->update();
}

これを、ofAppから呼びだしてみる。

ofApp.cpp

#include "ofApp.h"

//--------------------------------------------------------------
void ofApp::setup(){
    ofSetFrameRate(60);
    ofBackground(0);

    // パーティクルの初期位置を設定
    particleA.position = ofVec2f(10, 10);
    particleB.position = ofVec2f(10, 110);
    particleC.position = ofVec2f(10, 210);
    
    // A: オブジェクトの値渡し
    mover.setParticle(particleA);
    // B: オブジェクトの参照渡し
    mover.setParticleRef(particleB);
    // C: オブジェクトのポインタ渡し
    mover.setParticlePtr(&particleC);
}

//--------------------------------------------------------------
void ofApp::update(){
    mover.update();
}

//--------------------------------------------------------------
void ofApp::draw(){
    // A: 値渡しの描画
    ofSetColor(ofColor::red);
    particleA.draw();
    // B: 参照渡しの描画
    ofSetColor(ofColor::blue);
    particleB.draw();
    // C: ポインタ渡しの描画
    ofSetColor(ofColor::yellow);
    particleC.draw();
}

実行結果はどうなったかというと

  • A: 値渡し → 動かない
  • B: 参照渡し → 動かない
  • C: ポインタ渡し → 動いた

Aの値渡しが動かないのは、まあ予想内の挙動。そして、Cのポインタ渡しでは狙い通りofAppのParticleのインスタンスもMoverから更新され、無事動いた。

解せないのは、Bの参照渡しの挙動。参照渡しはオブジェクトの実体ではなく、あくまでその参照として渡っているので、ofApp側のインスタンスも連動して更新されると考えていたのだが、このコードではそうならなかった。うーん、何故なんでしょう。

C++はムズカシイネ…

プロジェクト全体は下記にあります。

【追記】: Facebookでコメントしていただき、参照渡しがうまくいかなかった原因判明。Mover.cppの11行目で、”particleB = p;”と代入している。ここでpをparticleBにコピーしてしまっていて、その結果参照から外れてしまったということのようだ。うーん、なるほど。参照渡しはクラスのメンバとして扱うのは難しいですね…

こう修正したら、参照渡しでも動きました。クラス変数を参照渡しするには、コンストラクタの初期値として渡す必要あるみたい。ううむ、扱い難しいですね。

Mover.h

#pragma once
#include "ofMain.h"
#include "Particle.h"

class Mover{
    
public:
    // 参照渡しは、コンストラクタのイニシャライザで
    Mover(Particle &particleB):particleB(particleB){};

    void setParticle(Particle p);       // 値渡し
    void setParticlePtr(Particle *p);   // ポインタ渡し
    
    void update();
    
    Particle particleA;
    Particle &particleB;
    Particle *particleC;
};

Mover.cpp

#include "Mover.h"

// A: オブジェクトの値渡し
void Mover::setParticle(Particle p){
    particleA = p;
    particleA.velocity = ofVec2f(10.0, 0);
}

// C: オブジェクトのポインタ渡し
void Mover::setParticlePtr(Particle *p){
    particleC = p;
    particleC->velocity = ofVec2f(10.0, 0);
}

// それぞれのオブジェクトを更新
void Mover::update(){
    particleA.resetForce();
    particleA.update();

    particleB.resetForce();
    particleB.update();

    particleC->resetForce();
    particleC->update();
}

ofApp.cpp

#include "ofApp.h"

//--------------------------------------------------------------
void ofApp::setup(){
    ofSetFrameRate(60);
    ofBackground(0);

    // パーティクルの初期位置を設定
    particleA.position = ofVec2f(10, 10);
    particleB.position = ofVec2f(10, 110);
    particleB.velocity = ofVec2f(10, 0);
    particleC.position = ofVec2f(10, 210);
    
    // B:参照渡しは、コンストラクタで渡す
    mover = new Mover(particleB);
    
    // A: オブジェクトの値渡し
    mover->setParticle(particleA);
    
    // C: オブジェクトのポインタ渡し
    mover->setParticlePtr(&particleC);
}

//--------------------------------------------------------------
void ofApp::update(){
    mover->update();
}

//--------------------------------------------------------------
void ofApp::draw(){
    // A: 値渡しの描画
    ofSetColor(ofColor::red);
    particleA.draw();
    // B: 参照渡しの描画
    ofSetColor(ofColor::blue);
    particleB.draw();
    // C: ポインタ渡しの描画
    ofSetColor(ofColor::yellow);
    particleC.draw();
}

第4回: openFrameworks基本 – 動きを極める、アニメーションのための様々なアルゴリズム

今回は、前回の内容をさらに発展させて、動きを生みだすための様々な手法について、サンプルを参照しながら解説していきます。

扱う動きは、実際に自然界に存在する様々な現象をシミュレーションします。以下のような内容を取り上げます。

  • 引力、反発力
  • 万有引力
  • ばね、弾力

こうした様々な動きを生みだすアルゴリズムを理解することで、作品の表現力が格段に高まります。徐々に難易度が増してきましたが、ステップバイステップで、少しずつ理解していきましょう!

前回までの内容

前回は、動きを生みだす3つのベクトル(ofVec2f)を使用しました。

  • 位置ベクトル
  • 速度ベクトル
  • 力ベクトル

これらのベクトルとくみあわせて、動き、摩擦、重力などを表現しました。それらの動きを1つにまとめてParticleと名付けて再利用可能なクラスとして独立させました。

Particleクラス

今回は、このParticleクラスをさらに発展させていきます。

引力、反発力

引力(Attraction Force)と、反発力(Repulsion Force)について考えます。

今回は、2次元の平面上での引力と反発力を扱います。ある一点を指定して、その一点に向かって平面上に引き付ける力(引力)と、ある一点から外に向けて反発する力(反発力)を設定します。全ての方面へ同じ力がかかる場合、力の中心から円形に力が働くようになります。また、中心点の距離が近ければ近いほど、大きな力が働くことになります。

fig01

この力をParticleのクラスのメソッド(クラスの関数)として実装します。いろいろな実装方法がありますが、今回は以下のように作成してみました。

引き付けあう力を加える – addAttractionForce

// 引き付けあう力
void Particle::addAttractionForce(float x, float y, float radius, float scale){
    // 力の中心点を設定
    ofVec2f posOfForce;
    posOfForce.set(x,y);
    // パーティクルと力の中心点との距離を計算
    ofVec2f diff = position - posOfForce;
    float length = diff.length();
    // 力が働く範囲かどうか判定する変数
    bool bAmCloseEnough = true;
    // もし設定した半径より外側だったら、計算しない
    if (radius > 0){
        if (length > radius){
            bAmCloseEnough = false;
        }
    }
    // 設定した半径の内側だったら
    if (bAmCloseEnough == true){
        // 距離から点にかかる力ベクトルを計算
        float pct = 1 - (length / radius);
        diff.normalize();
        force.x = force.x - diff.x * scale * pct;
        force.y = force.y - diff.y * scale * pct;
    }
}


反発する力を加える – addRepulsionForce

// 反発する力
void Particle::addRepulsionForce(float x, float y, float radius, float scale){
    // 力の中心点を設定
    ofVec2f posOfForce;
    posOfForce.set(x,y);
    // パーティクルと力の中心点との距離を計算
    ofVec2f diff = position - posOfForce;
    float length = diff.length();
    // 力が働く範囲かどうか判定する変数    
    bool bAmCloseEnough = true;
    // もし設定した半径より外側だったら、計算しない
    if (radius > 0){
        if (length > radius){
            bAmCloseEnough = false;
        }
    }
    // 設定した半径の内側だったら
    if (bAmCloseEnough == true){
        // 距離から点にかかる力ベクトルを計算
        float pct = 1 - (length / radius);
        diff.normalize();
        force.x = force.x + diff.x * scale * pct;
        force.y = force.y + diff.y * scale * pct;
    }
}

これらのメソッドを加えて、Particleクラスを拡張します。

引力のサンプル1 – クリックした点に引き付ける力

引力と反発力を加味したパーティクルを平面上にランダムに配置して、マウスをクリックするとその点に引き付けられる(引力)がはたらくようにしてみます。大量の点の描画は、前回にも使用したVBO Meshを使用して高速化を計ります。

パーティクルにかかる引力は、testApp::update()で計算します。以下のようにしてみました。

void ofApp::update(){
    // パーティクルの数だけ計算
    for (int i = 0; i < particles.size(); i++){
        // 力をリセット
        particles[i].resetForce();
        // もし引力がはたらいていたら
        if (atraction) {
            // マウスの位置に引力を加える
            particles[i].addAttractionForce(mouseX, mouseY, ofGetWidth(), 0.1);
        }
        // パーティクル更新
        particles[i].update();
        // 画面の端にきたら反対側へ
        particles[i].throughOfWalls();
    }
}

空間内に引力が働き、複雑な動きとパターンが生まれます。

Experiment of Attraction from Atsushi Tadokoro on Vimeo.

引力のサンプル2 – 万有引力

では、次に、全てのパーティクル同士で引力がはたらくようにしてみましょう。つまり、「全ての質点(物体)は互いに gravitation(=引き寄せる作用、引力、重力)を及ぼしあっている」という万有引力の法則を実装してみます。

このために、引力と反発力のための関数、addAttractionForceとaddRepulsionForceに、もうひとつバリエーションを増やします。新たなバージョンは力の中心点にベクトル(ofVec2f)ではなくパーティクルのオブジェクトParticleを参照できるようにします。

引き付けあう力Particle版 – addAttractionForce

void Particle::addAttractionForce(Particle &p, float radius, float scale){
    // 力の中心点を設定
    ofVec2f posOfForce;
    // Particleへの参照から座標を取得、力の中心に設定
    posOfForce.set(p.position.x, p.position.y);
    // パーティクルと力の中心点との距離を計算
    ofVec2f diff = position - posOfForce;
    float length = diff.length();
    // 力が働く範囲かどうか判定する変数
    bool bAmCloseEnough = true;
    // もし設定した半径より外側だったら、計算しない
    if (radius > 0){
        if (length > radius){
            bAmCloseEnough = false;
        }
    }
    // 設定した半径の内側だったら
    if (bAmCloseEnough == true){
        // 距離から点にかかる力ベクトルを計算
        float pct = 1 - (length / radius);
        diff.normalize();
        force.x = force.x - diff.x * scale * pct;
        force.y = force.y - diff.y * scale * pct;
        // 参照したパーティクルの力を計算して更新
        p.force.x = p.force.x + diff.x * scale * pct;
        p.force.y = p.force.y + diff.y * scale * pct;
    }
}


反発する力Particle版 – addRepulsionForce

void Particle::addRepulsionForce(Particle &p, float radius, float scale){
    // 力の中心点を設定
    ofVec2f posOfForce;
    // Particleへの参照から座標を取得、力の中心に設定
    posOfForce.set(p.position.x,p.position.y);
    // パーティクルと力の中心点との距離を計算
    ofVec2f diff = position - posOfForce;
    float length = diff.length();
    // 力が働く範囲かどうか判定する変数
    bool bAmCloseEnough = true;
    // もし設定した半径より外側だったら、計算しない
    if (radius > 0){
        if (length > radius){
            bAmCloseEnough = false;
        }
    }
    // 設定した半径の内側だったら
    if (bAmCloseEnough == true){
        // 距離から点にかかる力ベクトルを計算
        float pct = 1 - (length / radius);
        diff.normalize();
        force.x = force.x + diff.x * scale * pct;
        force.y = force.y + diff.y * scale * pct;
        // 参照したパーティクルの力を計算して更新
        p.force.x = p.force.x - diff.x * scale * pct;
        p.force.y = p.force.y - diff.y * scale * pct;
    }
}


このメソッドをofAppで活用します。生成したパーティクルの全ての間で引力を設定するには、以下のようにupdate()内で、for文を二重にして全ての組み合わせについて計算していきます。

ofApp::update()

void ofApp::update(){
    for (int i = 0; i < particles.size(); i++){
        // 力をリセット
        particles[i].resetForce();
        // パーティクル同士の反発する力
        for (int j = 0; j < i; j++){
            particles[i].addAttractionForce(particles[j], 120.0, 0.001);
        }
        // マウスをクリックした点に引力を加える
        if (atraction) {
            particles[i].addAttractionForce(mouseX, mouseY, ofGetWidth(), 0.1);
        }
        // 力と位置の更新
        particles[i].update();
        // 壁の端にきたら、反対側へ
        particles[i].throughOfWalls();
    }
}


この内容を実装します。

万有引力が実現できました。徐々にお互いが引き付けあうグループが生まれます。

Experiment of Attraction 2 from Atsushi Tadokoro on Vimeo.

引力のサンプル3 – 質量を加味した万有引力

万有引力の強さは、距離だけでなく物体の質量によって強さが変化します。

万有引力の大きさFは、物体の質量を M,m 、物体間の距離を r とすると、以下の式が成立します。Gは万有引力定数と呼ばれる比例定数です。

つまり、力の大きさは、物体同士の質量の積(かけ算)を距離の二乗で割った値に比例するということです。

この質量による力の変化を加味して、さらに万有引力を拡張してみましょう。それぞのParticleクラスに質量(mass)というプロパティーを追加して、このmassの値によって、力を変化させてみます。testApp::update() を以下のように更新しました。

void ofApp::update(){
    for (int i = 0; i < particles.size(); i++){
        particles[i].resetForce();
        // パーティクル同士の引き付けあう力
        for (int j = 0; j < i; j++){
            // 引力の強さは、2つの物体の質量の積に比例する
            float strength = particles[j].mass * particles[i].mass * 0.001;
            // 質量を加味した力を引力に加える
            particles[i].addAttractionForce(particles[j], 200, strength);
        }
        particles[i].update();
        particles[i].throughOfWalls();
    }
}


この内容を加えてプログラムを更新します。

さらにリアルな世界になりました。混沌から銀河が生成されるようにも感じられます。

Experiment of Attraction 3 from Atsushi Tadokoro on Vimeo.

ばねの力(弾力)

次に、ばねにかかる力(弾力)について考えてみます。ばねに働く力に関する計算は、フックの法則によって求まります。この式のFは力、Xはばねの長さ、kは「ばね定数」と呼ばればね固有の強さを表しています。

この式の解釈は簡単です。つまり、ばねは伸びた長さに比例して力が発生するということです。

この法則を利用して、ばねの動きを生みだしていきましょう。

今回は、ばねの両端にはParticleがあり、この2つのParticleを接続するばねSpringがあると考えます。

fig02

2つのParticleオブジェクトにかかる力から位置を更新します。この力を計算するために、Springという新たなクラスを作成しました。

Spring.h

#pragma once

#include "ofMain.h"
#include "Particle.h"

class Spring {
    
public:
    // コンストラクタ
    Spring();

    // 両端のParticleへの参照
    Particle *particleA;
    Particle *particleB;

    // 力をかけていない状態のばねの長さ
    float distance;
    // ばね定数
    float springiness;
    
    void update();
    void draw();    
};


Spring.cpp

#include "Spring.h"

//---------------------------------------------------------------------
Spring::Spring(){
    // 初期化、最初はばねを空(NULL)に
    particleA = NULL;
    particleB = NULL;
}

//---------------------------------------------------------------------
void Spring::update(){
    // もし両端にParticleが設定されていない場合、何もしない
    if ((particleA == NULL) || (particleB == NULL)){
        return;
    }
    // 両端のParticleの位置を取得
    ofVec2f pta = particleA->position;
    ofVec2f ptb = particleB->position;
    // 距離を算出
    float theirDistance = (pta - ptb).length();
    // 距離からばねにかかる力を計算(フックの法則)
    float springForce = (springiness * (distance - theirDistance));
    // ばねの力から、両端への力ベクトルを計算
    ofVec2f frcToAdd = (pta-ptb).normalized() * springForce;
    // それぞれのParticleに力を加える
    particleA->addForce(ofVec2f(frcToAdd.x, frcToAdd.y));
    particleB->addForce(ofVec2f(-frcToAdd.x, -frcToAdd.y));
}

//---------------------------------------------------------------------
void Spring::draw(){
    // もし両端にParticleが設定されていない場合、何もしない
    if ((particleA == NULL) || (particleB == NULL)){
        return;
    }
    // ばねを描画
    ofLine(particleA->position.x, particleA->position.y, particleB->position.x, particleB->position.y);
}


ばね サンプル1 – 単体のばね

では、このクラスを利用して、ばねを作成してみましょう。Particleクラスはそのまま利用します。

空間にバネが表示されます。マウスをドラッグすると、ばねの片方の端を移動可能です。

screenshot_388

ばね サンプル2 – ばねの連結

では、次にばねをどんどん連結してみましょう。SpringクラスとParticleクラスが既に作成されているので、とても簡単に応用可能です。連結数は最大数を変更できるよう、それぞれvector(可変長配列)として用意します。

SpringクラスとParticleクラスはそのまま利用して、ofAppのみを変更します。

Spring 1 from Atsushi Tadokoro on Vimeo.

ばね サンプル3 – ばねと引力・反発力

せっかくParticleに引力と反発力を実装しているので、これとばねを組合せてみたいと思います。ばねを連結して、それぞれのPartile同士に反発力を生成します。すると、どのような動きになるでしょうか? さらにここではマウスをクリックするとそれぞれのParticleに対する引力、クリックしていない場合には反発力として作用するようにしています。

今回もofAppのみの変更です。

弾力をもった、ひとつの物体のようになりました。ばね定数(springness)や、Particle同士の反発力を調整することで、様々な表情をコントロール可能です。

Spring 2 from Atsushi Tadokoro on Vimeo.

また、描画の際にParticleをSpringを描くのではなく、輪郭をひとつの線分として描き内部を塗ることで、さらに面白い効果が生まれます。

Spring 3 from Atsushi Tadokoro on Vimeo.

本日はここまで!


第3回: Web基礎3 – TumblrをCMSとして使用する、オンラインポートフォリオの設計

今日の内容

今回で、Web基礎のパートは最終回です(来週からは応用編に入ります)。今回はTumblrをより深く活用して、CMS(コンテンツ・マネジメント・システム)として使用する方法について考えていきます。

前半は、講義形式でTumblrのCMSとして使用するための機能、「静的ページ」と「タグ」について解説します。後半は、実習編として、実際に作業をしながらそれぞれのオンラインポートフォリオのページを作成していきます。

TumblrをCMSとして使用する

Tumblrは、テーマをそのまま使用する限りは、時系列に投稿が列挙されるBlog的な仕組みになっています。もちろん、このまま使用しても良いのですが、Tumblrをオンライン・ポートフォリオとして使用する場合、もう少し工夫が必要となってきます。

例えば、略歴やページの説明などといった内容は、投稿が増えても埋もれてしまわないように、常に固定で表示される仕組みが必要でしょう。また、今後自分自身の作品を載せていくにあたり、単純に時系列で並ぶだけでは雑然としたものになってしまいます。例えば、授業ごとに分類したり、作品の種類によって分類したりといったように、投稿をカテゴライズする必要があります。

まず始めに、こうした機能を実現するための「静的ページ」と「タグによる分類」について説明します。

スライド資料

実習

後半は実習とします。以下の内容の作業を各自行ってください。来週の授業で提出します。

1. 解析

  • デザインが優れていると思うオンラインポートフォリオ(アーティスト個人、デザイン企業、グループなど)のWebサイトをひとつ選択する
  • 選択したサイトの構造を、サイトマップを記述しながら解析する(手書き、アプリの使用などは自由)

2. 制作

  • ピックアップしたサイトを参考にしながら、自分のオンラインポートフォリオのワイヤーフレームを作成
  • 自分のオンラインポートフォリオのサイトマップを作成
  • 作成した設計に従って、Tumblrでベースとなる部分を作成する
    • テーマ
    • メニュー
    • 固定ページ
    • テスト投稿

次回の授業で以下のものを提出してもらいます!!

  • 参考にしたオンラインポートフォリオのURL
  • 解析したサイトマップ
  • 作成したTumblrの(自分の)オンラインポートフォリオのURL
  • 最終的に完成した際のサイトマップ

第3回: openFrameworks基本 – プログラムの構造をつくる、OOP入門

Githubでのサンプル配布

今回から講義内で使用するサンプルプログラムをGithubというWebサービスを使用して、配布していきます。

Githubの仕組みを理解するためには、まずGitというバージョン管理システムについて簡単に知っておく必要があります。

バージョン管理システムとは、コンピュータ上のファイルの変更履歴を管理するためのシステムで、主にプログラムのソースコードやテキストファイルなどの管理に用いられます。プログラミングをしていて、更新した内容がうまく作動せず、過去の特定の時点まで状態を戻す必要になる場合があります。そのために、毎回変更を加える前に手動でバックアップするのは面倒ですし、ファイル容量も無駄に使用してしまいます。現在のソフトウェア開発の現場では、バージョン管理システムを使用して効率的に作業履歴を管理、運用していく方法が主流となっています。

Gitはバージョン管理システムのひとつで、現在主流となっているシステムの一つです。その特徴は「分散型バージョン管理システム」という構造で、これは「リポジトリ」と呼ばれる更新の全履歴を含んだデータを複製することができて、複数の場所で分散して管理することが可能となっているものです。

まず、Gitについての基本的な概念と操作方法を、下記のサイトを参考にしながら解説します。

この講義で配布したサンプルは、毎週更新されていく予定です。ですので、それぞれの履修者は、自分のPC上に授業サンプルのリポジトリのクローンを作成し、毎週差分データをPullして更新していくようにしましょう。以下のような手順になります。

  1. Githubにアカウントを作成
  2. Githubのクライアントアプリをインストール(Mac / Win
  3. Githubから、授業のリポジトリをクローン
  4. リポジトリを変更して自分のオリジナルのサンプルにする場合には、ブランチを作成
  5. 毎週の講義でサンプルの更新があった場合には、リポジトリをPullして差分を更新

前回の復習

では、早速Githubのリポジトリを参考にしながら、前回までの復習をしてきましょう。

まず、ランダムに静止した丸を画面上に描くプログラムを作成しました。乱数の生成 ofRandom() を ofApp::setup() 内で行うのがポイントです。また、位置を記録するにあたり、2次元のベクトルデータを扱うofVec2fを使用して、x座標とy座標をまとめて「位置ベクトル」として管理している点にも注意してください。

つぎに、この仕組みを応用して、一気に大量の静止する円を生成しました。ポイントは、位置ベクトルを保存するofVec2fを配列(Array)として用意して、値をロッカーに入れるようなイメージで次々と格納しているところです。

次にアニメーションについて考えます。位置をあらわすベクトルpositionに加えて、速度を記録するためのベクトルvelocityをofVec2fとして新規に準備します。velocityもまずsetup()内でランダムに値を生成して格納し、update()内で現在の位置に速度を加算します。そのことで次のフレームの位置が算出されます。あとは、新規に計算された位置に点を描くだけで、全ての点が独立してアニメーションします。

現在のフレームの位置ベクトル + 速度ベクトル = 次のフレームの位置ベクトル

position += velocity;
14091901

また、このサンプルでは画面の上下左右の端にくるとバウンドするような工夫をしています。点の位置をマイフレーム常に監視しておき、画面の上下もしくは左右の端にきた瞬間にvelocityに-1をかけ算しています。このことはちょうど力が反転することを意味します。つまりこの計算がバウンドを生みだしているのです。

if (position.x < 0 || position.x > ofGetWidth()) {
    velocity.x *= -1;
}
if (position.y < 0 || position.y > ofGetHeight()) {
    velocity.y *= -1;
}

これで、壁にあたって跳ね返る動きが1つの点が作成できました。次にこの点を大量に複製してみましょう。考え型は、静止したランダムな場所の点と同様です。位置ベクトルの配列position[]に加えて、速度ベクトルの配列velocity[]を作成します。これをfor文をつかって点の数だけ演算していけば良いのです。

これで大量に動く点が作成できました。次にこれらの一つ一つの点に摩擦力(friction)が加わるようにしてみたいと思います。摩擦力とは例えば空気抵抗や接地面の抵抗などと考えてください。この摩擦力は常に速度ベクトルと反対の方向に働きます。図示すると以下のように考えられるでしょう。

14091902

この摩擦力を実装するにあたり、色々方法はあるのですが、速度ベクトルのかけ算と考えると実装が楽になります。例えば摩擦力が0.1だとすると、最初1だった速度ベクトルは0.9になります。さらに次のフレームでは0.9 x 0.9、その次には、0.9 x 0.9 x 0.9… というように指数的に減速していきます。

これらの力の関係をあらわすため、位置ベクトルpositon、速度ベクトルvelocityに加えて、力を計算するためのベクトルforceを導入します。この3つのofVec2fの配列を用いて摩擦力を加味した次のフレームの位置を算出します。

for (int i = 0; i < CIRCLE_NUM; i++) {
    // 力をリセット
    force[i].set(0, 0);
    // 摩擦力の計算
    force[i] -= velocity[i] * friction;
    // 力から速度を算出
    velocity[i] += force[i];
    // 速度から位置を算出
    position[i] += velocity[i];

    ...(省略)

}

今後のプログラムの拡張を見据えて、プログラムを役割ごとに整理していきましょう。現在のupdate()の部分をその内容によって、以下のように別々の関数にしていきます。

  • setup()
    • setInit() : 初期設定
  • update()
    • resetForce() : 力をリセット
    • updateForce() : 力を更新
    • updatePos() : 位置の更新
    • checkBounds() : 画面からはみ出たらバウンドさせる

これを実装すると以下のようになります。

次に重力加えてみましょう。重力は常に一定方向にかかり続ける力と考えられます。摩擦力と違って重力は速度ベクトルの大きさに関わらず、つねに一定の力が掛り続けます。

14091903

この機能を実現するために、それぞれの点に力を加えるaddForce()という関数を実装します。これは、引数にofVec2fをとり、全ての点に対して指定した力のベクトルを加えるというものです。

void ofApp::addForce(ofVec2f _force){
    // 力を加える
    for (int i = 0; i < CIRCLE_NUM; i++) {
        force[i] += _force;
    }
}

この関数を使用して重力を加えた処理をします。今回は下向きに重力をかけています。update()内は以下のようになります。

void ofApp::update(){
    resetForce(); // 力をリセット
    addForce(ofVec2f(0, 0.5)); // 重力を加える
    updateForce(); // 力の更新 (摩擦)
    updatePos(); // 円の座標を全て更新
    // 画面からはみ出たらバウンドさせる
    checkBounds(0, 0, ofGetWidth(), ofGetHeight());
    // 枠内に収める
    constrain(0, 0, ofGetWidth(), ofGetHeight());
}

基本の動きが決まれば、あとは数を膨大に増やしたり、マウスのクリックで再度繰り返すなどいろいろな工夫が可能となります。また、初期化の際の速度ベクトルの乱数の計算を工夫することで、きれいに円形に拡がるようにすることが可能です。角度と距離をランダムに生成して、三角関数を使用して座標にしています。

for (int i = 0; i < CIRCLE_NUM; i++) {
    position[i].x = initPos.x;
    position[i].y = initPos.y;
    float length = ofRandom(20);
    float angle = ofRandom(PI * 2);
    velocity[i].x = cos(angle) * length;
    velocity[i].y = sin(angle) * length;
    force[i].set(0, 0);
}

ここまでで、以下の映像のような動きが作成できました。今回はさらにこうした動きについて理解を深めるとともに、プログラムの構造についても考えていきます。

openFrameworks examples for Tamabi ma2 from Atsushi Tadokoro on Vimeo.

プログラムを構造化する – オブジェクト指向プログラミング(OOP)

ここまでのプログラムは全てofApp.hとofApp.cppに変更を加えていきました。現在のような単一の機能のプロジェクトであれば、これでもあまり問題はありません。しかし、このプロジェクトに様々な機能を加えていこうとすると、徐々にofAppが肥大化していきプログラム全体の把握が徐々に困難になってきます。例えばエラーが起こった際も、ofAppのどの部分がおかしいのか不具合の発生箇所を切り出すことが難しく、また機能ごとの更新も手間取るようになってしまいます。

プロジェクトを機能ごとに分割して、より見通しの良い構造にしていきたいと思います。openFrameworksは、C++というプログラミング言語がベースになっています。C++ではその構造の根底に「オブジェクト指向プログラミング(Object Oriented Programming)」という考えかたがあります。

オブジェクト指向とは、プログラムを「オブジェクト(Object)」という小さなプログラムの集合として構成するプログラミングの手法です。このオブジェクトはそれぞれが自律しています。そして、お互いにメッセージを送受信して全体の機能を支えます。

14091904

次に、この一つ一つのオブジェクトに注目します。オブジェクトは、その挙動を2つのカテゴリーにわけて定義しています。一つはそのオブジェクトの「Property(属性)」です。Propertyは、例えば色、サイズ、形、数など定まった性質を定義します。もう一つは、オブジェクトの「Method(手続)」です。Methodは、一連の処理をまとめたものと考えてください。

  • Property: 属性、状態、データ
  • Method: 操作、手続、行為
14091905

では、先程の重力と摩擦力を適用したひとつひとつの点を、オブジェクトとして考えたらどうなるでしょう? Property(属性)とMethod(手続)という観点から例えば以下のように整理できないでしょうか。

オブジェクト名Perticle
Property位置
速度

摩擦係数
Method初期設定
力をリセット
力を加える
力を更新
位置の更新
バウンドさせる
枠内に収める

PropetyとMethodの内容が、ここまでで作成してきたプログラムの構造と密接に関連していることに注目してください。よくみると、以下のような関連が見えてきます。

  • Property: 変数
    • ofVec2f position
    • ofVec2f velocity
    • ofVec2f force
  • Method: 関数
    • void setInit(ofVec2f initPos);
    • void resetForce();
    • void addForce(ofVec2f force);
    • void updateForce();
    • void updatePos();
    • void checkBounds(float xmin, float ymin, float xmax, float ymax);
    • void constrain(float xmin, float ymin, float xmax, float ymax);

つまり、オブジェクトとは変数と関数によって記述された、プログラムの構成単位と考えられます。

では、変数と関数を表に整理してみます。

Perticle
+ position : ofVec2f
+ velocity : ofVec2f
+ force : ofVec2f
+ setInit(ofVec2f initPos) : void
+ setInit(ofVec2f initPos) : void
+ resetForce() : void
+ addForce(ofVec2f force) : void
+ updateForce() : void
+ checkBounds(float xmin, float ymin, float xmax, float ymax) : void
+ constrain(float xmin, float ymin, float xmax, float ymax) : void

この設計図に従って、ひとつひとつの点をオブジェクトにしてみましょう。C++ではオブジェクトを生成するには、まずその設計図を書くことから始めます。このオブジェクトの設計図のことを「クラス(Class)」と呼びます。まずクラスを記述して、これを実体化(インスタンス化)することによって、オブジェクトが生まれます。金属のパーツを作るのに、まず金型を作成し、金型が完成した後で金属を流し込んで実際のパーツを生成するようなイメージです。一度金型(クラス)を生成してしまえば、何度でもくりかえしパーツを生成することが可能です。

14091906

クラスの記述は、ヘッダーファイル(.h)と実装ファイル(.cpp)にわけて記述します。この方法はofApp.hとofApp.cppを思い出すかもしれません。実は、ofAppもクラスです。ofAppクラスは、main.cppで実体化(インスタンス化)されています。

では、一つ一つの点をParticleクラスと名付けて、それぞれ「Particle.h」と「Particle.cpp」として記述してみます。クラスの記述には様々なルールがあります。実際のクラスを作成しながら、Xcodeでの操作方法、記述の細かなルールなどを確認していきます。

クラスを追加する

クラスは独立した新規のファイルとしてプロジェクトに追加します。Xcodeでは以下のような手順でファイルを追加します。

  • ファイルのリストの「src」フォルダを右クリックして、リストから「New File…」を選択
14091907
  • Mac OS X > C and C++ > C++ File を選択
14091908
  • 「Particle」という名前で「src」フォルダに保存、各種設定は、そのままで
14091909

この手順でクラスがファイルとしてプロジェクトに追加されます。Xcodeの左側のコラムのファイルツリーは、以下のようになります。

14091910

このParticle.hとParticle.cppに、点の運動の1粒分を記述します。

openFrameworksでは、まず始めにmain.cppが実行されます。main.cppは、ofAppクラスをインスタンス化して実行します。ですので、ParticleクラスはofAppに読み込んでインスタンス化するという構造になっています。図示すると以下のような形になります。

14091911

この構造を踏まえて、ofApp.hとofApp.cppを作成してみましょう。

これで、先週の復習で作成したプログラムと同じ動きが、複数のクラスによって実現できました。では、この作成したParticleクラスを活用して、いろいろ表現してみましょう。

無限に増殖、全体数を変更可能にする

マウスをドラッグしている間は、パーティクルが増殖し続けるようにしてみたいと思います。ここで問題となるのは、ここまでのやり方ではまず始めにパーティクルの最大数(CIRCLE_NUM)が決められてしまっている点です。このため、後から想定した数よりも多くのパーティクルが必要になっても配列に格納することができません。

こうした際にとても便利な仕組みがあります。これまで使用してきた最大数が固定された配列はarrayと呼ばれます。それに対して、C++では必要に応じて要素の数を変更できる可変長の配列が存在します。可変長配列は何種類かあるのですが、ここでは、vectorという仕組みを使用してみます。vectorはarrayと違って、自動的に領域の拡張が行われます。

14091912

vectorの定義は以下のように行います。

vector< 型の種類> 変数名

例えば、Particleクラスをvectorをつかって可変長の配列にしたいのであれば、以下のようになります。

vector particles;

vectorを使用するには、まず対象となるクラスを個別にインスタンス化し、必要であればプロパティの初期値を設定した後で、push_back()というメソッドを用いてvectorの末尾にインスタンスを追加します。今回のParticleの例でいうと、以下のようにして新規に一粒ぶんを追加しています。

// 一時格納用にParticleのインスタンスpを生成
Particle p;

// 摩擦係数を設定
p.friction = 0.01;

// 重力は0に
p.gravity.set(0, 0);

// 初期位置を設定
p.setInit(ofVec2f(x, y));

// 初期速度を設定
float length = ofRandom(3.0);
float angle = ofRandom(PI * 2);
p.velocity.x = cos(angle) * length;
p.velocity.y = sin(angle) * length;

// Vectorに追加
particles.push_back(p);

push_back()の他にもvectorには様々な機能があります。代表的なものを以下にまとめます。

名前説明
push_back末尾へ要素追加
pop_back末尾から要素削除
insert要素の挿入
erase要素の削除
clear全要素削除
size要素の数

では、実際にプログラムしてみましょう。

このプログラムで、ドラッグし続けると無限にパーティクルが増殖するプログラムが完成しました。

screenshot_346

曲線で結ぶ

では、全ての点を出現順に線で結んだらどうなるでしょう? 実際に試してみましょう。

たくさんの点を曲線で結ぶには、ofCurveVertex()を使用します。使用方法は以下のようにofBeginShape()とofEndShaper()で上下を囲んで、その中で頂点を指定していくという方法で全ての座標を指定します。

ofBeginShape();
ofCurveVertex(x0, y0);
ofCurveVertex(x1, y1);
ofCurveVertex(x2, y2);
...
ofEndShape();

このプログラムを実行すると、全ての点が曲線で結ばれて、線が自動的に拡散していくような不思議な効果が生まれます。

screenshot_347

応用: 高速化の工夫 – VBO Meshをつかう

ここまでで、大量の点を一気に描画することができるようになりました。この点が数千個単位の数でしたら問題ありません。しかし、点の数が数万、数十万と増えていくにつれ、徐々に描画が追い付かなくなりコマ落ちするようになってきます。

ここで高速化の工夫をしてみたいと思います。大量の点を高速に描くための方法はいろいろありますが、ここでは、VBO Meshというものを使用してみます。これは、「頂点バッファーオブジェクト(Vertex Buffer Object = VBO)」という方法を用いて、大量の頂点の座標メモリに保存して処理するのではなく、GPU(ビデオカード)のRAMに予めデータを置いておきPC本体から毎回データを転送しなくても良いようにするOpenGLの仕組みです。この方法により大量の頂点を使用するようなプログラムの描画の高速化が期待できます。

このプログラムでは下記のようなコードでofVboMeshという仕組みを用いて高速描画を実現しています。

// VBO Meshの作成
ofVboMesh mesh;

// 頂点を点で描画
mesh.setMode(OF_PRIMITIVE_POINTS);

// メッシュに格納していた頂点情報をクリア
mesh.clear();
    
// パーティクルの位置をVBO Meshに頂点の座標として記録
for (int i = 0; i < particles.size(); i++) {
    mesh.addVertex(ofVec3f(particles[i].position.x, particles[i].position.y, 0));
}
// メッシュを描画
mesh.draw();

マシンの性能にもよりますが、数万から数十万単位のパーティクルもコマ落ちすることなく描画可能です。

screenshot_348

応用: 画面をフェードさせる

最後にちょっとしたエフェクトを追加してみましょう。setup()で以下の命令を実行すると、毎回の画面の更新が止まります。つまり、物体が移動した全ての軌跡が残ることになります。

//画面の更新をOFFに
ofSetBackgroundAuto(false);

これに加えて、draw()で描画する前に、画面全体を半透明の四角形で塗り潰します。これによって、徐々にフェードアウトするような効果が生まれます。四角形の透明度を調整することでフェードアウトする時間が調整することが可能です。

// 画面をフェード
ofSetColor(0, 0, 0, 15);
ofRect(0, 0, ofGetWidth(), ofGetHeight());

ofVboMesh particle test from Atsushi Tadokoro on Vimeo.


第2回: openFrameworks、プログラミングはじめの一歩

創作のためのプログラミング

今回から、openFraeworksを中心に使用しながら、様々な創作のためのプログラミング技術を学んでいこうと思います。

プログラミングをするという行為は、最初のうちはなかなか思い通りにいかず苦痛を伴うものです。しかし、プログラミングに関わらず創作に関する多くの技術は、集中して没頭するうちに徐々に身についていくものです。楽器の練習やデッサン技術などを思いだしてみてください。

苦労して身についけた技術は、一度習得していまえば、今度はすぐに無くなることはありません。もちろん、最新の技術は耐えず変化していきます。しかし、今回から数回にわたってやっていくプログラミングの基礎、言い換えるなら「プログラミング的な思考法」は一度マスターすれば、一生使える財産です。

また、プログラミングができるようになると、コンピュータが既存のアプリケーションの機能を使う単純な道具から、道具自体を生みだすことのできる創作のための強力なエンジンとなります。もちろんプログラミングをしないで作品をつくるというのも一つの手段です。しかし、プログラミングができることで、創作の可能性の幅が大きく拡がります。

最初のうちは、いろいろ苦労はあると思いますが、じっくりと身につけていきましょう。

openFrameworksプログラミング初めの一歩

今回は、openFrameworksの導入を行います。前半は講義形式で以下の内容をステップバイステップで解説していきます。

  • 新規プロジェクトの作成方法
  • プロジェクトファイルの構成
  • openFrameworksのフレームワークの構造
  • ヘッダファイルとソースファイル
  • setup → update → draw
  • 座標
  • 図形を描く
  • 色を指定する
  • 変数とその種類
  • アニメーションの基本

後半は、クイズ形式でプログラミングの様々な手法を学んでいきます。クイズの解答のスライドは講義終了後にアップします。


第2回 Web基礎2 – Tumblrをつかう、Tumblrのカスタマイズ

CMS(Contents Management System)とは

企業のホームページや、ニュースなどの情報サイトでは、常に大量のWebページを扱い頻繁に更新しています。このような大規模なWebサイトでは、手作業で1ページずつHTMLとCSSを記述していては膨大な作業量になってしまいます。

現在では多くのWebサイトで「コンテンツマネジメントシステム(Contents Management System = CMS)」と呼ばれる、Webサイトを構成するテキストや画像などのデジタルコンテンツを統合・体系的に管理し、配信など必要な処理を行うシステムを使用しています。CMSを利用することで、簡単にページを追加、更新、管理することが可能となり、またサイト全体のデザインの統一やアクセス解析など、様々な機能を使用することが可能となります。

CMSには、様々なものがあり、フリーで利用できるものもあれば、有料のものもあります。またそのデザインの自由度やセットアップの難易度などもまちまちです。現在使用されてい主なCMSには以下のようなものがあります。

ちなみに、いま開いているこのyoppa.orgのサイトは、WordPressを使用しています。

参考: Usage of content management systems for websites

TumblrをCMSとして使用する

今回のサウンド&ネットは、Webの基礎の第2回目として、Tumblerを使っていきます。

Tumblrは、一般的にはマイクロブログ(短い文章や、画像などを投稿するWebサービス)とSNSを合わせたようなものと説明されますが、使用方法や設計によってはCMSとして活用することも可能です。またTumblrを利用する利点として、完全に無料で複数のサイトを運用可能です。

今回は、TumblrをCMSとして利用できるようになるよう、ステップ・バイ・ステップで設定方法を学んでいきます。最終的には、自分自身の作品をアーカイブするオンラインポートフォリオをTumblrをCMSとして使用して開設し公開できるところまでを目標とします。

今回スライド資料を参照しながら進めていきます。下記の内容で進めていきます。

  • Tumblrの概要
  • アカウントの作成、投稿、リブログ
  • Tumblrを使用しているサイト紹介
  • Tumblrのカスタマイズ 1 – テーマの選択、テーマのカスタマイズ
  • Tumblrのカスタマイズ 2 – HTMLとCSSを編集
  • Tumblrのカスタマイズ 3 – CMSとしてのTumblrの使用

頑張りましょう!


第1回: クリエイティブコーディングの現状、openFrameworksのセットアップ

2014年、クリエイティブコーディングの状況

この演習の火曜日(田所担当)では、コード(プログラム)を使用して作品を制作するための技術を実践的に学びます。

現在、こうしたアート、デザインといった表現のためのコーディング環境は「クリエイティブ・コーディング」と呼ばれ、徐々に注目を集めるようになってきています。初回の授業の今回は、まずこうした「クリエイティブ・コーディング」をとりまく現状を紹介し、それが自身の作品にどう生かすことができるのか考えていきましょう。

参考: The Art of Creative Coding

参考サイト: CreativeApplications

Creative Applications

Processing

Processingは、2001年に当時MITメディアラボの学生であった、Casey ReasとBen Fryによって開発された、オープンソースのプログラミング言語であり、統合開発環境(IDE)です。Processingのアニメーションの基本構造、setup → draw という考え方は、それに続くopenFrameworksやCinderといった開発環境に大きな影響を与えています。

Processingは、Javaをベースに作られています。文法がシンプルでわかりやすく、グラフィカルな表現、アニメーション、3D、インタラクションといった作品制作に活用可能な多くの機能が提供されているので、コードによる表現を始めてみたい場合、まずProcessingから始めることをお勧めします。

2014年9月現在の安定版は、ver.2.2.1です。また、プレリリース版として、ver.3.0a3が出ています。

参考図書:

参考: Hello Processing

openFrameworks

openFrameworksは、シンプルで先端的なフレームワークによって創作活動を支援するためのオープンソースのC++ツールキットです。openFrameworksの特徴は、メディアアートやインタラクティブなプロジェクトを制作する際に必要となる様々なライブラリーを、すぐに使えるようにパッケージングした点といえます。

つまりopenFrameworksには、それ自身に先進的な機能があるわけではありません。openFrameworksの価値は、むしろ既存の技術を使いやすい形で統合的に扱えるという点にあります。このことを例えて、ソフトウェア開発のための「糊」のようなものと例えられることもあります。

of_diagram

openFrameworksは、openFrameworksはザック・リーバーマン(Zach Lieberman)、セオドア・ワトソン(Theodore Watson), アルトロ・カストロ(Arturo Castro)を中心にして、oFコミュニティーとともに開発されています。

参考: oF Showreel

OF Showreel from openFrameworks on Vimeo.

参考図書:

Cinder

Cinderは、比較的新しい開発環境で、2010年にBarbarian GroupのAndrew Bellを中心に開発されました。openFrameworksと同様にC++をベースにしています。Cinderの特徴は、後発の環境であるという利点から、BoostライブラリーなどC++の新しい機能を積極的に取り入れて、よりモダンな開発環境を目指しているという印象を受けます。

参考: Addition/Subtraction(Flight 404)

Addition/Subtraction from flight404 on Vimeo.

vvvv

vvvvは簡単なプロトタイピングや開発に特化したプログラミング環境で、その特徴は、Max/MSPやPdに似た、ビジュアルプログラミングが可能な点でしょう。フィジカルインタフェース、リアルタイムモーショングラフィックス、オーディオ、ビデオなどをたくさんの人が同時に操作するようなマルチメディア環境を簡単に構築できるように設計されています。

joreg、Max Wolf、Sebastian Gregor、Sebastian Oschatzを中心とした、vvvv groupにより開発、運営されています。

参考図書

Pure data

Pure Data(Pd)は、オープンソースのビジュアルプログラミング環境で、音響合成やサンプリングしたデジタルサウンドの処理、MIDIやOSCなどのコントロール信号のやりとり、2Dや3Dにグラフィクス、デバイスとの連携などが可能です。1996年にMiller Pucketteによって開発され、現在も開発は継続しています。

Pdには、大きく分けて2つのバージョンがあります。

  • Pd vanilla : Miller Pucketteによって書かれた、Pure Dataのコア機能。音声信号の処理とMIDIの処理に焦点を絞っている。
  • Pd extended : Pdコミュニティーにより開発された様々なライブラリーを統合したバージョン。グラフィクス用ライブラリ(GEM)や、OSCによるコミュニケーション、オーディオビジュアル、物理モデル、センサー技術など様々な機能を盛り込んでいる。

screenshot_267

参考図書

Javascript libraries

Webの技術は、2000年代後半あたりを境に急激に変化しつつあります。その変化を一言でいうと、Webブラウザが扱う対象が「文書」から「アプリケーション」になったことです。

誕生当初のWWWは、科学技術文書を公開し共有するための仕組みでした。しかし現在は、オーディオやビデオなどのマルチメディア、ショッピング、地図やスケジューラーやワードプレセッサーといったアプリケーション、さらにはそれ自身がオペレーションシステムとして使用されるようになり、様々な機能を含む広い概念へと進化しています。

そうした位置付け、機能の進化にあわせて、WWWを構成する技術も大きく変化してきました。そして今もなお変化する途上にあります。

現在のWWWを構成する技術は、代表的なものだけでも数多くあげられます。

  • Javascript
  • HTML5
  • Offline web, Local storage
  • Vieo, Audio
  • Canvas
  • WebGL

参考:The Evolution of the Web(Webの進化)

screenshot_260

こうした環境の変化をうけて、Web制作のための様々なフレームワーク、ライブラリが登場しています。ここでは、主にグラフィックとサウンドに関するJavascriptのライブラリーの代表的なものを紹介します。

p5.js

p5.jsは、Processingの文法をJavascriptでも使用できるようにしたライブラリです。同じようなJavascriptのライブラリとしてProcessing.jsがあります。両者はよく似ているのですが、Processing.jsが、Java版のProcessingのコードをそのまま動かすことができるように設計されているのに対して、p5.jsはよりJavasciriptに近づけた文法になっています。

例えば、setup〜drawというProcessingの基本的な構造を記述する場合、Processing.jsであれば以下のようにJava版と変わりません。

void setup(){
  ...
}

void draw(){
  ...
}

一方、p5.jsでは、Javascirptの関数の定義の方法を採用しています。

function setup() {
  ...
}

function draw() {
  ...
}

p5.jsの利点は、よりJavascriptのネイティブの機能に近いため、他のHTML5のオブジェクトとの連携が容易な点です。例えば、HTMLでボタンやスライダーをデザインして、その値をp5.jsで受けて描画するというようなことが可能です。また、サウンド機能のライブラリなども用意されています。

参考: Hello p5.js

screenshot_265

Three.js

Three.jsは、Mr.Doobを中心にオープンソースで開発が進められている、Webブラウザで3Dグラフィクスを高速に表示する仕組み「WebGL」のためのライブラリです。Three.jsはWebGLの冗長な仕様をうまく吸収して、扱いやすいインターフェイスでWebGLのプログラミングができるように工夫されています。現在では、WebGLにおけるデファクトスタンダードに近い扱いとなっています。コンピューターのGPU(グラフィクスカード)をフルに活用して表示するので、非常に高速な3D表示が可能となります。

d3.js

d3.jsは、データビジュアライゼーションに特化した、Javascriptのライブラリです。Scalable Vector Graphics(SVG)、JavaScript、HTML5をフルに活用して、読み込んだデータを動的に表示することが可能です。Michael Bostock、Jeffrey Heer、Vadim Ogievetskyを中心に、オープンソースで開発が進められています。

d3.jsは、NYTimesの記事内で用いられるデータビジュアライゼーションに使用されていることでも有名です。NYTimesの記事は以下にアーカイブされています。

openFrameworksのセットアップ

前半でみてきたように、現在、様々な開発フレームワーク、ライブラリ、言語が存在しています。そして、それらの多くはオープンソースで公開されていて、フリーで利用することが可能です。それぞれ得意不得意があるのですが、この演習では、差し当って汎用的にプログラミングが可能でさらに処理速度や拡張性に優れているという観点から、openFrameworksを使用することにします。

後半は、openFrameworksの環境設定をしていきましょう。

openFrameworksのセットアップの手順は、openFrameworksの公式サイトにとてもよくまとまった資料があります。こちらを参照しながらセットアップを進めていきましょう。

それぞれの開発環境でセットアップを完了したら、付属のサンプルをビルドして、openFrameworksでどのようなことが可能なのか、体験してみてください。


第1回: Web基礎1 – Web制作はじめの一歩

インターネットの歴史

「WWW = インターネット」と誤用されることがありますが、これは正しくありません。WWWはインターネットの中に含まれていますが、インターネットはWWW以外にも多くの機能を持っています。例えば、email(SMTP)は今でも頻繁に利用されますが、WWW登場するよりもずっと昔からある仕組みです。その他、Skypeなどで用いられるP2P(Peer to Peer)技術、ファイル転送のための仕組み(FTP, SFTP)などWWW以外のインターネットの利用は数多くあります。

インターネット自体の歴史は、WWWよりさらに昔に遡り、1960年代の末から研究が始まり、1970年代には主に大学や研究施設を結ぶ研究者のネットワークとして実用化され、発展してきた歴史があります。

1969年ARPANET(インターネットの前身)開始直後のネットワーク図。カリフォルニア大学ロサンゼルス校(UCLA)、カリフォルニア大学サンタバーバラ校(UCSB)、ユタ大学、スタンフォード研究所(SRI; Stanford Research Institute)の4拠点

1972年のネットワーク接続図。

Webの進化と現状

World Wide Web(WWW)がティム・バーナーズ=リーによって生み出されたのは1991年、いまからほぼ四半世紀前になります。

誕生当初のWWWは、科学技術文書を公開し共有するための仕組みでした。しかし現在は、オーディオやビデオなどのマルチメディア、ショッピング、地図やスケジューラーやワードプレセッサーといったアプリケーション、さらにはそれ自身がオペレーションシステムとして使用されるようになり、様々な機能を含む広い概念へと進化しています。

そうした位置付け、機能の進化にあわせて、WWWを構成する技術も大きく変化してきました。そして今もなお変化する途上にあります。

現在のWWWを構成する技術は、代表的なものだけでも数多くあげられます。

  • Javascript
  • HTML5
  • Offline web, Local storage
  • Vieo, Audio
  • Canvas
  • WebGL
  • …etc.

ひとことで言うと、現在のWWWは、「文書」から「アプリケーション」へと変化しつつあると言えるでしょう。

参考: ティム・バーナーズ=リーが示す次のウェブ(TED)

http://www.ted.com/talks/tim_berners_lee_on_the_next_web?language=ja

参考: The Evolution of the Web

http://www.evolutionoftheweb.com/

screenshot_260

参考: W3C HTML5

http://www.w3.org/html/logo/

screenshot_261

速習 HTMLとCSS

WWWを構成する技術が大きく変化したとはいえ、その根本のを支える技術はバージョンアップを続けながら、ずっと続いています。それは「HTML(Hyper Text Markup Language)」と「CSS(Cascading Style Sheet)」という2つの技術です。

  • HTML(Hyper Text Markup Language)
  • CSS(Cascading Style Sheet)

この2つは、車輪の両輪のように両者で分担してWebページの表示を定義しています。この2つの分担は以下のように要約できます。

  • HTML : 意味、構造
  • CSS : 体裁(デザイン)、表現

構造と体裁を分離する、という発想がWebサイトを制作・デザインしていく際のポイントとなります。常に意識するようにしましょう。

授業の前半では、まずこの2つの技術について、すばやく理解していきたいと思います。

サンプルファイルの配布

※ ちなみにこのサンプルは、多摩美術大学情報デザイン学科メディア芸術コース – コース概要のページをアレンジしました。

index.html

< !DOCTYPE html>


  
  多摩美術大学美術学部情報デザイン学科メディア芸術コース
  


  

多摩美術大学 情報デザイン学科 メディア芸術コース

Art & Media Cource Department of Information Desing Tama Art University

Overview / コース概要

多摩美術大学情報デザイン学科「メディア芸術コース」は、デジタル・テクノロジーやバイオ・メディアを活用したインスタレーション/パフォーマンスや映像音響作品を中心に、インタラクティヴなインスタレーション、オーディオビジュアル・パフォーマンス、ソフトウエア・アート、バイオ・アート、デジタル・アニメーション、フューチャー・シネマといった、多彩なメディア芸術表現に取り組んでいます。テクノロジーと人間の関係のダイナミックな変化を背景に、情報と物質が一体化したポスト情報化時代の作品制作を通じて、21世紀の芸術・デザイン、さらには科学・技術・哲学の統合的な理解を目指した、実践的な制作研究を行っています。現在、コースはそれぞれ独自のテーマを持つ4つのラボから構成されています。それぞれのラボが自律かつ共同しながら、相乗的に独自の創造的文化をつくりだしています。

Overview - Creating new framework of art

Art & Media Course in Information Design Department of Tama Art University manages various kinds of art forms by utilizing digital technologies and bio medias, such like interactive installations, audio & visual performances, software arts, bio arts, digital animations, and future cinemas. Through the background of recent dynamic changes of relationship between technology and human society, we aim to bring up new types of multi-skilled creators who can transcend the traditional boundaries of fine arts, science, engineering, mathematics and philosophy.The Course has established unique creative environment configured by four individual laboratories which has their own research themes.

After Graduating / 卒業後の進路

良質のメディア芸術作品は、インタラクション・デザインの可能性を開拓する実験場であり、創造的なアーティストはイノベーションを牽引する先進的なユーザーです。情報芸術コースの卒業生は、内外で多数の賞を受賞するメディア・アーティストや映像作家をはじめ、ウェブ、インターフェイス/インタラクション、ソフトウェア/デバイスに関連する企業や独立系プロダクション、広告、イベント、ゲーム、編集・制作などの映像音楽産業全般で幅広く活躍しています。

After Graduating

Excellent media art is a test site for pathfinding the possibility of interaction design, and artists are advanced user for driving innovations. Many of our graduates has won prizes, and others are also taking an active part of web design, interaction design, software and device related independent productions.

style.css

body{
  margin:0;
  padding:0;
}

header, section{
  background-color:#ffffff;
  color:#8144ff;
  width: 960px;
  margin: 0 auto;
}

a {
  color:#8144ff;
}

header h1{
  text-align:center;
  font-size: 1.2em;
  font-weight: 100;
}

nav {
  padding: 4em 0;
  border-bottom: 1px solid #8144ff;
}

nav ul{
  width:960px;
  margin:0 auto;
  font-size: 0.8em;
  text-align:center;
}

nav li {
  display: inline;
  border-left: 1px solid #8144ff;
  padding: 0 2em;
}

section {
  clear:both;
}

section h1{
  margin:2em 0;
  font-weight:100;
  font-size: 1.4em;
}

section h2{
  font-weight: 100;
  border-top: 1px solid #8144ff;
  border-bottom: 1px solid #8144ff;
  font-size: 0.9em;
  padding: 1.5em 0;
  margin: 1.5em 0;
}

section p{
  padding: 1em 12%;
  line-height:2.0;
  font-size:0.85em;
}

section img{
  border: 1px solid #8144ff;
  padding: 5px;
  margin: 1em 12%;
  text-align:center;
}

footer {
  background-color:#ede5ff;
  padding: 1em;
}

footer p {
  color:#8144ff;
  width: 960px;
  margin: 0 auto;
  font-size: 0.6em;
  text-align: right;
}

ファイルをダウンロードしたら圧縮を展開しましょう。2つのファイルが入っています。

  • index.html
  • style.css

この中から、「index.html」をWebブラウザで開いてみましょう。下記のキャプチャー画面のようなページが閲覧できます。

screenshot_263

HTML(Hypertext Markup Language)

では、このWebページを構成している、HTMLとCSSについて解析していきましょう。

「HTML」という用語の成り立ちが、そのコンセプトを的確にあらわしています。それぞれの文字は「HyperText Markup Language」という文字の頭文字からとられています。単語ごとに意味を分解していくと以下のようになります。

  • Hypertext – ハイパーリンク(いわゆるリンク)で複数の文書(テキスト)を相互に関連付け、結び付ける仕組み
  • Markup – 文書の中に目印をつけて、文章の構造(段落など)関する指定を記述すること
  • Language – 言語

つまり、HTMLとは

「文書の中に目印をつけて構造を記述した、ハイパーテキストを記述するための言語」

という意味になります。この目印(Markup)という概念がHTML記述のキーとなります。

HTMLの基本的な考えかた

HTMLは、文書の見た目ではなく構造を記述しています。ここでいう構造とは、例えば、段落、見出し、箇条書き、画像といったその文書の中での役割のことを指しています。

構造を記述する際に、HTMLではその文書の中に目印を記入していきます。この目印をつける行為を「マークアップ(Markup)」といいます。そしてこのマークの目印で囲まれた部分を、その文書の「要素(element)」と読んでいます。

HTMLではその要素の開始位置と終了位置を指定することで、囲まれる領域を要素として明示します。開始位置をあらわすマークを「開始タグ」、終了位置をあらわすマークを「終了タグ」と呼びます。開始タグと終了タグで囲まれた範囲を「要素内容」と呼んでいます。

  • HTMLは、文書の見た目ではなく構造を記述したもの
  • 文書内の役割に応じて目印をつけて構造化する
    • 段落、見出し、箇条書、インライン画像、リンク…など
    • 文書内の役割を「要素」と呼ぶ
  • タグ(tag): 文書の中につけられた目印、“< … >” という三角括弧が目印。
    • 開始タグ: どこからその要素かを示す。“< タグの種類>” 例:文書のタイトルの始まり
    • 終了タグ: どこまでがその要素かを示す。“” 例:文書のタイトルの始まり

HTMLの要素(タグ)の記述の基本のようになります。

要素内容

例:

多摩美術大学

複数のタグが入れ子構造(ネスト)されることもあります。

例:


  多摩美術大学

今日、最低限憶えたい要素(タグ)

以下の要素(タグ)の使い方と意味を押さえれば、基本的なWebページの作成が可能です。頑張って使い方をマスターしましょう!

  • 文書全体の構造をつくる要素
    • html
    • head
    • body
  • 文書内の意味による構造
    • header
    • nav
    • section
    • footer
  • 見出し
    • h1, h2, h3, h4, h5, h6
  • 文書内での役割
    • p
    • ul, li
    • a
    • img

CSS(Cascading Style Sheets)

HTML文書の体裁(デザイン)を指定するための仕組み。HTML(構造)とCSS(デザイン)を分離するという理念を理解することが重要です。構造を担当するのがHTML、そして体裁(デザイン)を担当するのがCSSです。

CSSの基本文法は以下のようになっています。

セレクタ {
  プロパティ(特性):値;
  プロパティ(特性):値;
  プロパティ(特性):値;
  ...
}

「セレクタ」とは、そのデザインをどこに適用するのか場所を指し示すものです。例えばセレクタを「h1」にすると、h1の見出しに対して指定のデザインが適用されます。セレクタには、さらに様々な複雑な指定方法があるのですが、ここではあまり深入りせず、徐々に学んでいこうと思います。興味のある方は、以下のリンクを参照してください。

セレクタに続いて中括弧 {…} で囲まれた部分が、具体的なデザインの指示にあたります。2つのキーワードが並んでいます「プロパティ(特性)」と「値」です。プロパティとは、デザインの「何を」変えるのかという指定です。プロパティは例えば「文字の色」「背景の色」「余白」「文字の大きさ」「行揃え」「行の間隔」など膨大な数が存在します。一度には覚えるのは大変なので、基本的なものから少しずつマスターしていきましょう。

セレクタとコロン「:」で区切られて、次に「値」を指定します。この値は、プロパティーの種類によって変化します。例えばプロパティが色に関するものであれば色の値になりますし、長さに関するプロパティであれば値は長さの値になります。値の使いかたも多岐に渡るので、徐々に覚えていきましょう。

これらを組合せると、以下の例のようになります。

例:

p {
  color: #333333;
  font-family: sans-serif;
  font-size: 0.9em;
}

最低限覚えておきたい、CSSプロパティー

文字や画像に関するプロパティーで、まずは、以下のプロパティーと値の使い方を把握すると良いでしょう。

プロパティー 意味
color 色の値 文字の色
background-color 色の値 背景の色
font-size 長さの値 フォントの大きさ
font-weight 長さの値 フォントの太さ
line-height 長さの値 行間の大きさ
text-align left, center, light, justify 行揃え

ここで、値の指定として「色の値」と「長さの値」という2つの値が指定されています。色と長さには、CSSで決められた値の単位を指定します。色や長さの単位は、いくつか種類があり、用途や好みに応じて使い分けることが可能となっています。

単位 値の指定方法
色の値 色の名前 (red, blue, yellow, white…etc.)
16進数でRGBの値 (#000000 〜 #ffffff)
RGBを0〜255の10進数で(rgb(0,0,0)〜rgb(255,255,255))
長さの値 em:1文字分の大きさが1em
% :パーセント指定
pt:ポイント (72pt = 1in)
px:ピクセル (画面上の最小単位)

Box Model – CSSのレイアウトの基本

CSSでは、矩形(長方形)に囲まれた範囲をひとつのデザインの単位として考え、その配置や余白の大きさ、枠線、背景色などを指定することでページ全体をレイアウトしていきます。長方形の積み木を汲み上げて一つのデザインにしていくようなイメージです。

このデザインの基本単位となる矩形をBoxと呼んでいて、このBoxには共通の属性(プロパティー)が備わっています。これをCSSのBox Modelといいます。CSSでWebページの全体のレイアウトやデザインをするには、このBox modelの理解が欠かせません。

段落や見出し、インライン画像など、全てのコンテント(Content)の周囲には、表示/非表示に関わらず周囲に枠線(border)が存在しています。この枠線を挟んで、コンテントと枠線との間の内側の余白をpadding、枠線の外側の余白をmarginと呼びます。

border、padding、marginには、CSSから様々な方法で指定が可能です。

margin:12px;                  /* 上下左右に12pxのマージン */

padding-top:10px;             /* 上10pxのパディング */
padding-right:20px;           /* 右20pxのパディング */
padding-bottom:30px;          /* 下30pxのパディング */
padding-left:40px;            /* 左40pxのパディング */

margin: 10px 20px 30px 40px;  /*上、右、下、左の順に指定 */
padding: 10px 20px;           /*上下、左右順に指定 */

border: 1px solid #cccccc;       /* 1pxの実線、色は #cccccc */
border-bottom: 2px dashed blue;  /* 下の枠だけに2pxの破線、色は青 */

この他にも様々な方法でBox Modelのプロパティーは指定可能です。実際にいろいろ試しながら身につけていきましょう。

実習

  • サンプルのCSSと、その結果のデザインを見比べて、CSSのプロパティと値の意味を解読する
  • サンプルのCSSを、自分の好みに改造する
  • 次回、発表・提出してもらいます!

次回までの課題

次回からは、TumblrというWebサービスをつかって、オンラインポートフォリオを制作していきます。そのためには会員登録が必要です(無料)。来週までに会員登録を済ませておきましょう。

来週までに以下の内容を課題とします。

課題: Tumblrの会員登録をして、最低5つ投稿する!!

Tumblr

Tumblrとは?

  • https://www.tumblr.com/
  • ブログとSNS(ソーシャルネットワーキングサービス)が一体化したような、統合マイクロブログサービス。
  • 2007年、David Karpによってサービス開始。
  • 登録は無料
  • Twitterでいうところの、リツイートに相当する、リブログ(Reblog)という仕組みが特徴
  • デザインのカスタマイズの自由度が高い
  • 独自のドメインで運用することも可能

授業内で登録の手順を説明するので、次回の授業までに各自登録を済ませてきてください。