今回で、HTML入門の3回目になりました。HTMLの主要な要素についての入門編は今回で最後になります。今回は、情報を整理するための要素に着目します。まず始めに、いわゆる「箇条書き」で情報を簡素に列挙するための構造「リスト」を構成する、ul要素、ol要素、li要素を紹介します。次に、表形式で行と列の2次元で情報を整理するための構造「テーブル」を構成する、table要素、tr要素、th要素、td要素を紹介します。
スライド資料
本日のスライド資料は下記のリンクから参照してください。
先週の復習
まず始めに先週作成したコードを復習してみましょう。ベクトル(ofVec2f)を使用したアニメーションのサンプルです。
このサンプルのポイントとなるのは、動きを2つのベクトルで表現している部分です。
- ofVec2f location : 位置を記録するためのベクトル → 位置ベクトル
- ofVec2f velocity : 速度を記録するためのベクトル → 速度ベクトル
ベクトルとは、大きさと向きをもった量のことです。下記の図のV(実際には上に→)がベクトルに相当します。ベクトルはx方向のベクトルとy方向ベクトルに分解することが可能です。下記の図ではVx, Vyがベクトルの成分に相当します。また、それぞれのベクトル成分の大きさが1のベクトルを「単位ベクトル」と呼んでいます。この図では、I と J が相当します。
ここまでのまとめ
物体の位置の座標は、原点からみたベクトルと捉えることも可能です。座標の原点から物体の位置の座標まで矢印を引いてベクトルを生成します。このベクトルを「位置ベクトル」と呼んでいます。位置ベクトルは2次元空間のみに適用されるわけではありません。1次元や3次元空間でもベクトルで位置を表現可能です。
速度もベクトルで表現可能です。位置ベクトルPがあったとして、そこにベクトルを加えると次の位置ベクトルQが求められます。この位置ベクトルに加えるベクトルを速度と考えます。このベクトルを「速度ベクトル」と呼びます。
サンプルプログラムに戻ると、まずsetup()で位置ベクトルと速度ベクトルの初期値を決めています。
void ofApp::setup(){
(中略)
//位置と速度を初期化
location = ofVec2f(ofGetWidth()/2, ofGetHeight()/2); //画面の中心に
velocity = ofVec2f(ofRandom(-10, 10), ofRandom(-10, 10)); //ランダムな速度で
}
update()で、位置ベクトルに速度ベクトルを加えて、次のフレームの位置ベクトルを求めています。
void ofApp::update(){
location += velocity; //速度から位置を更新
}
展開1 : 物体の数を増やしてみる – 配列とくりかえし
では、この運動する物体の数を増やすにはどうすれば良いでしょうか? まず単純に思いつくのは、物体の位置ベクトルと速度ベクトルを、物体の数だけ増やして定義する方法ではないでしょうか。
例:
しかしこの方法だと、10個くらいまでは対応できそうですが、100個、1000個、10000個と物体の数を増やそうとしたときに破綻することは確実です。
こういうときに便利な仕組みが「配列」という仕組みです。変数を値を1つだけ入れられる「箱」とすると配列は大量の値を番号をつけて管理する「ロッカー」のようなイメージで捉えると理解し易いでしょう。
先程のサンプルを改造して100個の位置と速度を記録する配列を利用してアニメーションしてみましょう。
配列は多くの場合、繰り返しの構文「for文」と一緒に使用されます。for文と配列をつかうと全ての配列の処理を一気に処理することが可能となるからです。for文と配列の関係の概略は以下のイメージになるでしょうか。
for(int i = 0; i < NUM; i++){
配列[i]の処理を行う
}
これを踏まえてサンプルをみてみます。まずヘッダーファイルで配列を準備しています。このとき配列の上限の数を指定する必要があるのですが、すぐに変更できるように定数として定義しているところにも注目してください。
#pragma once
#include "ofMain.h"
class ofApp : public ofBaseApp{
public:
(中略)
//配列の最大数を定数として定義
static const int NUM = 100;
//配列を定義
ofVec2f location[NUM]; //NUM個の位置ベクトル
ofVec2f velocity[NUM]; //NUM個の速度ベクトル
};
次にこの配列をofApp::setup()で初期化しています。for文と配列の組み合わせがここで使用されています。
void ofApp::setup(){
(中略)
//NUM回くりかえし
for (int i = 0; i < NUM; i++) {
//位置と速度を初期化
location[i] = ofVec2f(ofGetWidth()/2, ofGetHeight()/2);
velocity[i] = ofVec2f(ofRandom(-10, 10), ofRandom(-10, 10));
}
}
update()とdraw()では、それぞれ配列の値をくりかえし参照しながら全ての物体の位置を更新して描画しています。
void ofApp::update(){
//NUM回くりかえし
for (int i = 0; i < NUM; i++) {
location[i] += velocity[i];
}
}
void ofApp::draw(){
//NUM回くりかえし
for (int i = 0; i < NUM; i++) {
//計算した位置に円を描画
ofSetColor(31, 12, 255); //円の色
ofDrawCircle(location[i], 20); //半径40の円を描画
ofDrawCircle(location[i], 20); //半径40の円を描画
//画面の端でバウンドするように
if (location[i].x < 0 || location[i].x > ofGetWidth()) {
velocity[i].x *= -1; //横向きの速度を反転(バウンド)
}
if (location[i].y < 0 || location[i].y > ofGetHeight()) {
velocity[i].y *= -1; //横向きの速度を反転(バウンド)
}
}
}
展開2 : 数の上限がわからない時には? – 可変長配列 vector を使う
ではこのプログラムの応用で、最初は0個だった物体が、時間の経過とともにどんどんと増えていくようなプログラムにしてみたいと思います。
ここで重大な問題が発生します。物体の数をどんどん増やしていきたい場合、最初に配列を定義する際の上限値をいくつにすれば良いのでしょうか? 例えば
ofVec2f location[999999999];
ofVec2f velocity[999999999];
というように、普通では超えそうもない大きな数で余裕をもって指定しておくという方法も可能ですが、あまり賢い方法ではありません。
こうしたときに便利な仕組みとして、可変長配列というものがあります。可変長配列とこれまで使用してきた固定長の配列(Array)との違いは、配列の長さを後から自由に変更可能であるという点です。
実際にサンプルをみながら、その使い方を理解しましょう。
まず、位置と速度、それぞれの可変長配列vectorの宣言をみてみましょう。vectorの宣言は少し複雑です。
vector< 配列の型> 配列名;
実際のサンプルではofApp.hで宣言されています。それぞれofVec2fで位置と速度の可変長配列を生成しています。
#pragma once
#include "ofMain.h"
class ofApp : public ofBaseApp{
public:
(中略)
//可変長配列(vector)を定義
vector location; //位置ベクトル
vector velocity; //速度ベクトル
};
配列へ値を追加、削除する方法はいくつか存在します。差し当って以下の命令を覚えましょう。
- 配列名.push_back(追加する要素) : 配列の末尾に要素を追加
- 配列名.pop_back(追加する要素) : 配列の末尾に要素を削除
- 配列名.clear() : 配列を全消去
ofApp.cpp::uprdate() でフレームを更新するたびに、1つ要素を位置ベクトル、速度ベクトルそれぞれの配列の末尾に追加しています。
void ofApp::update(){
(中略)
//新規に位置ベクトルと速度ベクトルを生成し、配列に追加
location.push_back(ofVec2f(ofGetWidth()/2, ofGetHeight()/2));
velocity.push_back(ofVec2f(ofRandom(-10, 10), ofRandom(-10, 10)));
}
展開3 : 一定の数に制限する
このままずっと増殖されることも可能ですが、ある一定の上限値を決めて、その数まで増えたら可変長配列vectorの先頭の要素を消していくようにしてみましょう。
まずofApp.hで上限値を決めています。
int max_num;
この値をもとに、update()で一定の数より増えたら先頭の要素を消すようにしています。
void ofApp::update(){
(中略)
//もし上限値を超えたら、先頭の要素を削除する
if(location.size() > max_num){
location.erase(location.begin());
velocity.erase(velocity.begin());
}
}
展開4 : マウスをドラッグした位置から物体を生成
応用例として、マウスをドラッグすると、そのドラッグした位置から物体が生成されるようにしてみましょう。
ポイントは1つだけです。update()で定義していた要素を追加する一連の命令を、mouseDragged()に移動しています。
void ofApp::mouseDragged(int x, int y, int button){
//新規に位置ベクトルと速度ベクトルを生成し、配列に追加
location.push_back(ofVec2f(x, y));
velocity.push_back(ofVec2f(ofRandom(-2, 2), ofRandom(-2, 2)));
//もし上限値を超えたら、先頭の要素を削除する
if(location.size() > max_num){
location.erase(location.begin());
velocity.erase(velocity.begin());
}
}
注意!! : TidalCycles 0.8からSuperDirtが標準となり、SuperColliderとの連携も大幅に簡略化されました。新しいバージョンでの連携方法は下記を参照してください。
前回の「Tidalでライブコーディング! – 実践編」に引き続いて、応用編です。
Tidalは、基本はDirtというサンプルファイルを再生する専用のプログラムでサンプルを再生しています。しかし、TidalにはOSC (Open Sound Control) を送出する機能があります。このOSC機能を利用することで、SuperColliderやMax/MSP、Pdなど様々な外部の音源を使用してTidalで作成したパターンを再生することが可能です。
今回は、TidalをSuperColliderを連携してみます。
基本: 簡単なサンプル
まずは簡単なサンプルで試してみます。Sin波を生成する楽器をSuperCollider側に作成します。
(
//単純な楽器の定義
SynthDef("scsine", {
arg freq;
var out, env;
out = SinOsc.ar(freq).dup();
env = EnvGen.ar(Env.perc(), doneAction:2);
Out.ar(0, out*env);
}).add;
);
ここで1つ注意すべき点は、Tidalから演奏する楽器は一度鳴らし始めると自動的に停止することはありません。ですので、あらかじめエンベロープを設定しておき、一定の時間で音が終了するよう、doneAction:2を設定したエンベロープを適用しておく必要があります。
SynthDefの作成が完了したら、SuperColliderをBootして、作成したSynthDefを実行しておきます。
これに対応するTidal側のプログラムを作成します。まず、SuperColliderで作成した楽器と連携する準備をします。まず楽器 “scsine” を定義して、引数の初期値を設定しています。その上で、SuperColliderに渡すTidal側の変数を定義します。
-- 楽器 "scsine" を定義して、引数の初期値を設定
(sc, shape) < - scStream "scsine" [ F "freq" (Just 440.0)] 0
-- SuperColliderに値を渡す変数を定義
let freq = makeF shape "freq"
あとは、変数を使用してパターンを作成していきます。
-- パターン生成
sc $ freq "440 660 110 220"
sc $ freq "440 [660 110] [220 880] 330"
sc $ jux(iter 8) $ freq "440 [660 110] [220 880] 330"
sc $ jux(iter 8) $ jux (iter 4) $ freq "440 [660 110] [220 880] 330"
sc silence
応用: 2つの楽器を定義して演奏
少し複雑なサンプルをみてみましょう。まず2つの楽器 “schh” と “scbass” を用意します。
(
// 1つ目の楽器 "schh" の定義
SynthDef("schh", {
arg vol=1.2, freq=3000, atk=0.01, rel=0.2, pos=0;
var sig, rev, filt, env, pan, out;
sig=WhiteNoise.ar(0.5);
filt=RHPF.ar(sig, freq, LFDNoise3.kr(0.5).range(0.001, 2) );
rev=FreeVerb.ar(filt, 0.7, 1);
pan=Pan2.ar(rev, pos, vol);
env=EnvGen.ar(Env.perc(atk, rel), doneAction:2);
out=pan*env;
Out.ar(0, out);
}).add;
// 2つ目の楽器 "scbass" の定義
SynthDef("scbass", {
arg freq = 52.8, pos = 0.0, vol = 1.0;
var bass =
SinOsc.ar(0, (Sweep.ar(1.0, 2pi * [freq, 740]) + (pi/3)).wrap(-pi, pi), [2, 0.05]).mean.tanh *
EnvGen.ar(Env([0, 0.5, 0.4, 0], [0, 0.2, 0.01], -5), doneAction: 2);
bass = Pan2.ar(bass, pos) * vol;
bass = CompanderD.ar(bass);
Out.ar(0, bass);
}).add;
);
この楽器を演奏するためのTidal側のプログラムは以下のようになります。
(sc1, shape1) < - scStream "schh"
[ F "vol" (Just 1.2),
F "freq" (Just 3000),
F "atk" (Just 0.01),
F "rel" (Just 0.2),
I "pos" (Just 0)
] 0
(sc2, shape2) <- scStream "scbass"
[ F "freq" (Just 50),
F "pos" (Just 0.0),
F "vol" (Just 1.0)
] 0
let vol1 = makeF shape1 "vol"
freq1 = makeF shape1 "freq"
atk1 = makeF shape1 "atk"
rel1 = makeF shape1 "rel"
pos1 = makeF shape1 "pos"
freq2 = makeF shape2 "freq"
pos2 = makeF shape2 "pos"
vol2 = makeF shape2 "vol"
cps(150/120)
sc1 $ freq1 "8000 [0 12000] 300 9000" |+| vol1 "4.0"
sc2
$ every 2 (jux (iter 4))
$ stack [
freq2 "50 [60 40] 10 80" |+| pos2 "-1 1 -0.6 0.6" |+| vol2 "2.0",
freq2 "40 80" |+| pos2 "-0.6 0.6" |+| vol2 "2.0"
]
sc1 silence
sc2 silence
Window環境でのTidal
Tidalは基本的にはUnixベースの環境を前提としているため、Windowsで動かすには、いろいろ設定が必要です。
TidalをWindowsで動かすために、まずCygwinという、Windowsオペレーティングシステム上で動作するUNIXライクな環境をインストールし、そこに必要なライブラリーをインストールした後、Tidalの環境を構築します。
Cygwinのインストール
下記のリンクからダウンロードします。
インストーラーでインストールを進めると、途中でパッケージを選択する画面になります。ここで、下記のパッケージをsearchから検索して、表示されたパッケージのバージョン番号をチェックをしてインストールする設定にします。
git
gcc-core
make
gcc-g++
libsndfile
libsndfile-devel
libsamplerate
libsamplerate-devel
Portaudioのインストール
Portaudioは、パッケージ化されていないので、ダウンロードして手動でビルドする必要があります。まずPortaudioのダウンロードページに行き、安定板(2016年4月現在はpa_stable_v19_20140130.tgz)をダウンロードします。ダウンロードしたpa_stable_v19_20140130.tgzをCygwinのホームにコピーします。その上で、下記のコマンドでPortaudioをインストールします。
cd ~
tar xvzf pa_stable_v19_20140130.tgz
cd portaudio
./configure && make && make install
Libioのインストール
OSCをやりとりするためのライブラリーlibioもapt-cygではインストールできません。libioのサイトのDownloadにある最新の安定版(2016年4月現在はliblo 0.28)をダウンロードして、下記の手順でインストールします。
cd ~
tar xvzf liblo-0.28.tar.gz
cd liblo-0.28
./configure && make && make install
Dirtのインストール
Tidalで使用するサンプラー、Dirtをインストールします。Dirtはgithubからクローンします。
cd ~
git clone --recursive http://github.com/tidalcycles/Dirt.git
ダウンロードしたら、ビルドします。
cd Dirt
make dirt-pa
Haskellのインストール
Tidalのベースとなっているプログラミング言語Haskellをインストールします。まずHaskellのインストールページを開きます。
自動的にWindowsでのインストールのページが表示されます。使用している環境にあわせて、32bit版か62bit版のHaskellのインストーラーをダウンロードします。ダウンロードが完了したら、インストーラーを起動してHaskellをインストールします。
Haskellをインストールしたら、Cygwinを再起動してください。
Tidalのインストール
Cygwinを起動して、下記のコマンドでTidalをインストールします。
cabal update
cabal install cabal-install
cabal install tidal
これで、完了です!
Atomの設定
Windows版でも、Atomをエディターとして使用可能です。OS X版と同様に、まずAtomをインストールした後、Tidalパッケージを追加します。
TidalパッケージのSettingを開きます。ここでghci.exeへのパスを正しいものに変更します。
- 例: C:\Program Files\Haskell Platform\7.10.3\bin\ghci.exe
あとは、テストでコードを実行させてみて音が鳴れば、設定完了です!!
d1 $ sound "909 bass"
先週に引き続いて、Processingを用いたプログラミングの基本を解説します。まず始めに、数値や文字などの値を格納するための「箱」のような機能「変数」について解説します。その後で、変数を活用しながら、何度もくりかえして処理を行う方法について考えていきます。
スライド資料
今回も前回に引き続き、HTMLの要素について、その構造や使用方法について解説していきます。今回は、文書ないにハイパーリンクを設定する「a」要素、画像を貼り付ける「img」要素、リスト(いわゆる箇条書き)のための「ul」「ol」「li」といった要素をとりあげます。どれも、文書の構造を記述するためにとても重要な要素です。しっかりと理解して身に付けましょう。
スライド資料
本日のスライド資料は下記のリンクから参照してください。
今日やること
火曜日のワークショップでは、openFrameworksを開発環境の軸として使用していきます。今回はまずopenFrameworksの開発環境を準備して、付属のサンプルをいろいろ見てみます。その後、簡単なプログラムを作成してみます。
- openFrameworksって何?
- 開発環境を準備する
- openFrameworksのダウンロード
- Mac: Xcodeのセットアップ
- Win: Visual Studioのセットアップ
- サンプルを動かしてみる
- 新規プロジェクトの作成
- 簡単な形を描画/アニメーション
- 課題
openFrameworksって何?
イントロダクション: ビデオを視聴
OF Showreel from openFrameworks on Vimeo.
openFramwroksとは何か?
openFrameworksとは何なのか、openFrameworksのトップページに掲載されている文章が端的に表現しています。
- openFrameworks is an open source C++ toolkit for creative coding.
- openFrameworksは創造的なコーディングのためのC++のオープンソースツールキットです
ポイントは3つあります。
- クリエイティブ・コーディングのためのもの
- C++で書かれている
- オープンソースである
また、さらに深くopenFrameworksのデザインの哲学を理解するために、以下のページを読んでみましょう。
- openFrameworksを構成する様々なライブラリー
- グラフィクス:OpenGL, GLEW, GLUT, libtess2, cairo
- オーディオの入出力と分析:rtAudio, PortAudio, OpenAL, Kiss FFT または FMOD
- フォント:FreeType
- イメージの読込と保存:FreeImage
- 動画の再生と取込:Quicktime,GStreamer, videoInput
- 様々なユーティリティー:Poco
- コンピュータビジョン:OpenCV
-3Dモデルの読み込み:Assimp
- openFramworksデザイン哲学のポイント
- 協調的
- シンプルさ
- 一貫していて直感的
- クロスプラットフォーム
- パワフル
- 拡張性
- みんなでやろう Do it with others (DIWO)
どんな作品を作ることができるのか?
それでは、openFramworksでどんな作品を作ることができるのでしょうか? 様々な方法で調べることが可能です。まずすぐに思いつく方法は、一般的な検索エンジン(google)やSNSを利用する方法です。
より質の高い情報に絞って検索する方法として、エディターによってキュレーションされたサイトで調べる方法があります。クリエイティブ・コーディングのジャンルでは、CreativeApplicationsがお勧めです。とても質の高い情報が日々更新されています。
CreativeApplicationsでは、開発環境ごとに絞り込んで検索することも可能です。openFrameworksに絞りこんで作品をみてみましょう
大量の作品がみつかります。
開発環境を準備する
openFrameworksは、Processingなどのように開発環境がアプリケーションに用意されているということはありません。「openFramwroksとは何か?」のところで解説したように、openFrameworksは「糊」のように様々なライブラリーを繋ぎとめている存在でしかありません。
openFrameworksで開発するには、まず、使用しているOSにあわせて統合開発環境(IDE)を準備します。IDEのセットアップ方法はオフィシャルサイトにとても丁寧に解説させています。まずはこの資料を参照してセットアップしましょう。
IDEのセットアップ
- Mac OS X
- Windows (3種類の開発環境) ※初心者はVisualStudioが無難かもしれません…
openFrameworks本体のダウンロード
2016年4月現在の最新版である、v.0.9.3をOSと選択した開発環境にあわせてダウンロードします。
サンプルを動かしてみる
openFrameworksには大量のサンプルプロジェクトが内包されています。まずはサンプルをどんどん動かしてみましょう。そして、そのサンプルが何をしているのか考えてみましょう。
参考: openFrameworks 0.8.0 examples screen captures
新規プロジェクトの作成
ほとんどのプラットフォーム (OS X、Windows、Linux) では、新しいProject Generatorを使用することが可能です。Project Generatorを起動してみましょう。
プロジェクトは、openFramewroksのフォルダ内の「apps」フォルダ内に作成することをお薦めします。例えば、simpleSketch というプロジェクトを作成し apps/myApps 内に置くとします、つまりopenFrameworksのルートからのフルパスは apps/myApps/simpleSketch になります。例えばいろいろなプロジェクトに取り組んでいる場合などに、「apps」内に新規にフォルダを作成することも可能です。
openFrameworksをハードディスクのどこに配置したかによって、設定を調整する必要があるかもしません。
重要なポイントは、openFramewroksのプロジェクトは相対的に機能するというところです。つまり、プロジェクトはopenFrameworksのライブラリのフォルダを、相対的に参照しています (例 : ../../../libs) 。もし、プロジェクトを作成したら、openFrameworksのルートフォルダからの階層構造を保持したままにしておく必要があります。あるいは、もしフォルダの階層を変えたいのであれば、Project Generatorを使用してアップデートすることも可能です。
今日の課題 : とりあえずやってみる!
「習うより慣れろ」という方針で、簡単なアニメーションのプログラムを提示しますので、その内容を解析し改造してみてましょう!
サンプルプログラム
まずは課題のプログラムのソースをみてみましょう! ポイントとなる部分にはコメントが入れてあります。そのコメントをみながらプログラムの内容を解析してみましょう。
理解のためのポイント
基本図形の描き方
openFrameworksの基本図形は、ofGraphicsクラスにまとめられています。ドキュメントを参照してみましょう。
色の設定
ベクトル (速度と位置の表現)
※ 現段階では、「x座標とy座標を一緒にしたもの」というざっくりとした理解でOK!
何を改造するのか?
- 初心者向け
- 上級者向け
- 動き (直線運動以外の動き)
- 大きさの変化
- 力の表現 (摩擦、重力 …etc.)
提出方法
- 課題のリポジトリをClone
- assingment1フォルダ内に新規にプロジェクトを作成、プロジェクト名は本名、Githubユーザー名など(例: AtsushiTadokoro)
- Templateを参考にプログラム作成
- 完了したら、リポジトリにPush
- 次回火曜日のWSまで!
今回は、「かたちとコード」の関連について考えていきます。
まず始めに、1950年代〜70年代の、コンピューター黎明期から発展期におけるコード(プログラム)による様々な視覚表現について紹介します。過去の作家がどのようなアイデアで、何を表現しようとしてきたのか、その歴史を辿ります。
後半は、いよいよProcessingでの実践に入ります。今回は、まずProcessingの操作基本を復習し、簡単な図形を描きます。
スライド資料
今回から、いよいよWebサイトの制作を開始します。実際に作業を初める前に、先週解説したWebを構成する重要な3つの技術、URL、HTTP、HTMLについて復習します。この仕組みを理解した上で、今回からはHTMLという言語について学んでいきます。HTMLとはどのような言語なのか、どうやって記述するのかといった基本について解説します。
スライド資料
スライド資料は下記のリンクから参照してください。
今回は、初めての授業となりますので、まずはこの授業の概要、授業の進め方、スケジュール、採点と成績についてガイダンスを行います。
授業の概要を理解した上で、前半はこの授業の主題となる「メディア芸術」とは何かということを簡単に整理します。そして後半は、この授業で当面の間使用する予定の開発環境であるProcessingの導入を行います。
授業スライド