メディア・アートII 第3回 openFrameworks基礎 OOoF : オブジェクト指向 oF
Upcoming SlideShare
Loading in...5
×
 

メディア・アートII 第3回 openFrameworks基礎 OOoF : オブジェクト指向 oF

on

  • 3,066 views

 

Statistics

Views

Total Views
3,066
Views on SlideShare
1,709
Embed Views
1,357

Actions

Likes
4
Downloads
50
Comments
0

9 Embeds 1,357

http://yoppa.org 929
http://bussorenre.hatenablog.jp 349
http://scrap.kow-luck.com 39
http://cloud.feedly.com 28
http://naoyashiga.hatenablog.com 7
http://digg.com 2
http://safe.txmblr.com 1
http://feedly.com 1
http://webcache.googleusercontent.com 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

CC Attribution License

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

メディア・アートII 第3回 openFrameworks基礎 OOoF : オブジェクト指向 oF メディア・アートII 第3回 openFrameworks基礎 OOoF : オブジェクト指向 oF Presentation Transcript

  • メディア・アートII 第3回 openFrameworks基礎 OOoF : オブジェクト指向 oF 2013年9月30日 多摩美術大学情報デザイン学科メディア芸術コース 田所淳
  • 先週の復習 ‣ ベクトルを使用したアニメーション ‣ 摩擦力と重力をシミュレーションした大量のパーティクル!
  • 先週の復習 ‣ 実際のコードは下記のGistを参照 ‣ https://gist.github.com/tado/6709400 ‣ ※「Gist」 - GitHub上のコードの断片を共有するサービス
  • 今日のテーマ OOoF = Object Oriented + openFrameworks
  • ‣ オブジェクト指向プログラミング ‣ Object Oriented Programming (OOP) ‣ オブジェクト指向でProcessingのプログラムを作る ‣ そもそもオブジェクト指向とは? ‣ 簡単なプログラムを、オブジェクト指向で書いてみる ‣ クラスの定義 ‣ クラスの呼びだし オブジェクト指向プログラミングとは?
  • ‣ オブジェクト指向プログラミング言語のイメージ プログラミング・パラダイムの変遷 オブジェクト オブジェクト オブジェクト オブジェクト
  • ‣ OOPの特徴 ‣ 相互にメッセージを送り合う「オブジェクト」の集まりとして プログラムを構成 ‣ オブジェクトは、プロパティとメソッドから構成される ‣ カプセル化 - 必要のない情報は隠す ‣ インヘリタンス(継承) - あるオブジェクトが他のオブジェク トの特性を引き継ぐ ‣ ポリモーフィズム(多態性・多様性) - プログラミング言語の 各要素が複数の型に属することを許す オブジェクト指向プログラミングの概念
  • ‣ オブジェクト ‣ プロパティとメソッド ‣ カプセル化 ‣ 継承 (インヘリタンス) ‣ 多態性、多相性 (ポリモーフィズム) OOP、5つのポイント
  • ‣ オブジェクト指向プログラムのポイント:その1 ‣ オブジェクトの集まりとしてプログラムを構成 ‣ オブジェクト同士がメッセージを送りあう OOP:ポイントその1
  • ‣ オブジェクト指向プログラムのポイント:その2 ‣ オブジェクトは、プロパティ(性質、状態)と、メソッド(動作、 ふるまい) から構成される 状態1 状態2 状態3 オブジェクト メ ソ ッ ド 1 メ ソ ッ ド 2 メ ソ ッ ド 3 メ ソ ッ ド 4 OOP:ポイントその2
  • ‣ 例:「りんご」をオブジェクトとして考える 赤 5.0 甘い ふじ 実 が な る 成 長 す る 落 ち る 腐 る 青 4.0 すっぱい 青リンゴ 実 が な る 成 長 す る 落 ち る 腐 る OOP:ポイントその2
  • ‣ オブジェクト指向プログラムのポイント:その3 ‣ 必要のない情報は隠す (カプセル化) ‣ プログラムの実装全てを知る必要はない ‣ 必要なインターフェイス(接点)だけ見せて、あとは隠す To invent programs, you need to be able to capture abstractions and ex design. It’s the job of a programming language to help you do this. The process of invention and design by letting you encode abstractions tha It should let you make your ideas concrete in the code you write. Surf the architecture of your program. All programming languages provide devices that help express abstrac are ways of grouping implementation details, hiding them, and giving a common interface—much as a mechanical object separates its interfa illustrated in “Interface and Implementation” . Figure 2-1 Interface and Implementation 9 10 11 8 7 6 implementationinterface インターフェイス 実装 OOP:ポイントその3
  • ‣ オブジェクト指向プログラムのポイント:その4 ‣ インヘリタンス(継承) ‣ オブジェクトから新たなオブジェクトを派生させる 植物 生物 動物 果物 穀物 りんご ふじ 紅玉 デリシャス バナナ マンゴー OOP:ポイントその4
  • ‣ オブジェクト指向プログラムのポイント:その5 ‣ ポリモーイズム(多態性、多様性) ‣ オブジェクトはメッセージを受け取りそれに応じた処理を行う ‣ メッセージの処理方法は、オブジェクト自身が知っていて、そ の処理はオブジェクトによって異なる getName() オブジェクトA:人間 「田所 淳」 getName() オブジェクトB:車 「トヨタカローラ」 OOP:ポイントその5
  • ‣ クラス ‣ クラスとは:オブジェクトの「型紙」 ‣ クラスをインスタンス化 (実体化) することでインスタンス (オブジェクト)となる 色 重さ(g) 味 リンゴ (クラス) 実 が な る 成 長 す る 落 ち る 腐 る 赤 5.0 甘い ふじ (インスタンスオブジェクト) 実 が な る 成 長 す る 落 ち る 腐 る 青 4.0 すっぱい 青リンゴ (インスタンスオブジェクト) 実 が な る 成 長 す る 落 ち る 腐 る インスタンス化 クラス
  • ‣ いままで扱ってきた、testApp も一つのクラス ‣ メソッド - setup(), update(), draw() ...etc. ‣ プロパティ - testApp全体で使用する変数 testAppもクラス クラス変数 setup() update() draw () exit() testApp
  • ‣ これまでのようにtestAppにどんどん機能を追加すると、様々 な弊害が ‣ 可読性の低下、機能ごとに再利用できない、拡張が困難 ..etc. testApp単体の限界 testApp testApp 肥大化
  • ‣ 機能ごとにオブジェクトを分けてプロジェクトを構成する ‣ オブジェクトが相互に連携 testApp単体の限界 testApp Rectangle Particle Control Panel
  • OOP実践編 クラスを作る
  • OOP実践編 - クラスを作る ‣ まずはシンプルなサンプルを発展させる ‣ 1つのパーティクル(粒)を描く ‣ 同じプログラムをOOPで書き直してみる
  • OOP実践編 - クラスを作る ‣ ランダムな場所に、1つ静止したパーティクルを描く ‣ https://gist.github.com/tado/6709701
  • #include "testApp.h" void testApp::setup(){ // 画面基本設定 ofSetFrameRate(60); ofBackground(63); ofSetCircleResolution(32); // 画面内のランダムな場所を指定 position.x = ofRandom(ofGetWidth()); position.y = ofRandom(ofGetHeight()); } ... void testApp::draw(){ // 設定した場所に円を描く ofSetHexColor(0x3399cc); ofCircle(position, 10); } OOP実践編 - クラスを作る ‣ testApp.cpp - コード抜粋
  • OOP実践編 - クラスを作る ‣ このプログラムをクラス化してみる ‣ クラス名:Particle ‣ プロパティ (状態、変数): ‣ ofVec2f position : 初期位置 ‣ メソッド (ふるまい、関数): ‣ draw( ) : パーティクルを描く
  • OOP実践編 - クラスを作る ‣ こんな風に図示します (UMLクラス図) Particle + position:ofVec2f + draw():void ←クラス名 ←プロパティ ←メソッド
  • OOP実践編 - クラスを作る ‣ 次にXcodeを操作して、プロジェクトにクラスのためのファイ ルを追加します!
  • OOP実践編 - クラスを作る ‣ ファイルのリストの「src」フォルダを右クリック ‣ リストから「New File (新規ファイル)」を選択
  • OOP実践編 - クラスを作る ‣ Mac OS X > C and C++ > C++ File を選択
  • OOP実践編 - クラスを作る ‣ 「Particle」という名前で「src」フォルダに保存
  • OOP実践編 - クラスを作る ‣ ファイルリストは以下のようになるはず ‣ あとは、それぞれのファイルにコーディングしていく
  • クラスの記述
  • クラスの記述 ‣ まずはヘッダーファイル (Particle.h) から ‣ レシピの材料と手順の一覧! ‣ 材料 → 状態、性質 → つまり、プロパティ(変数) ‣ 手順 → ふるまい、動作 → つまり、メソッド(関数) ‣ そのクラスのプロパティとメソッドを記述 ‣ 外部から参照するものは、public: 以下に書く
  • #pragma once #include "ofMain.h" class Particle { public: void draw(); ofVec2f position; }; クラスの記述 ‣ Particle.h ‣ https://gist.github.com/tado/6710045
  • #pragma once #include "ofMain.h" class Particle { public: void draw(); ofVec2f position; }; クラスの記述 ‣ Particle.h ‣ https://gist.github.com/tado/6710045 インクルードガード Buildの際に複数回読みこまれないためのしくみ
  • #pragma once #include "ofMain.h" class Particle { public: void draw(); ofVec2f position; }; クラスの記述 ‣ Particle.h ‣ https://gist.github.com/tado/6710045 oFの機能を使うためのライブラリを 必ず読み込む
  • #pragma once #include "ofMain.h" class Particle { public: void draw(); ofVec2f position; }; クラスの記述 ‣ Particle.h ‣ https://gist.github.com/tado/6710045 クラス名
  • #pragma once #include "ofMain.h" class Particle { public: void draw(); ofVec2f position; }; クラスの記述 ‣ Particle.h ‣ https://gist.github.com/tado/6710045 public: 以下は外部に公開される
  • #pragma once #include "ofMain.h" class Particle { public: void draw(); ofVec2f position; }; クラスの記述 ‣ Particle.h ‣ https://gist.github.com/tado/6710045 メソッド:draw() - 円を描く
  • #pragma once #include "ofMain.h" class Particle { public: void draw(); ofVec2f position; }; クラスの記述 ‣ Particle.h ‣ https://gist.github.com/tado/6710045 プロパティ:position - 初期位置
  • #pragma once #include "ofMain.h" class Particle { public: void draw(); ofVec2f position; }; クラスの記述 ‣ Particle.h ‣ https://gist.github.com/tado/6710045#file-oneparticleclass01-particle-h 最後に必ずセミコロンをつける
  • クラスの記述 ‣ つぎに実装ファイル(Particle.cpp)を書く ‣ 円を描くための全ての手続きを記述していく ‣ 現在は、draw() 関数のみ
  • #include "Particle.h" void Particle::draw(){ ofSetHexColor(0x3399cc); ofCircle(position, 10); } クラスの記述 ‣ Particle.cpp ‣ https://gist.github.com/tado/6710045#file-oneparticleclass01-particle-cpp
  • #include "Particle.h" void Particle::draw(){ ofSetHexColor(0x3399cc); ofCircle(position, 10); } クラスの記述 ‣ Particle.cpp ‣ https://gist.github.com/tado/6710045#file-oneparticleclass01-particle-cpp 必ずヘッダーファイルを読み込む
  • #include "Particle.h" void Particle::draw(){ ofSetHexColor(0x3399cc); ofCircle(position, 10); } クラスの記述 ‣ Particle.cpp ‣ https://gist.github.com/tado/6710045#file-oneparticleclass01-particle-cpp 戻り値 クラス名::関数名(引数) クラス名を名前空間として使用している 他のクラスのdraw()関数との混同を避けている
  • #include "Particle.h" void Particle::draw(){ ofSetHexColor(0x3399cc); ofCircle(position, 10); } クラスの記述 ‣ Particle.cpp ‣ https://gist.github.com/tado/6710045#file-oneparticleclass01-particle-cpp 円を描画
  • クラスの記述 ‣ 最後に作成したクラスを、testAppから呼び出します ‣ ヘッダーファイル testApp.h で MoveCircle を宣言 ‣ これだけで、クラスが実体化(インスタンス化)される ‣ クラス名:Particle ‣ インスタンス:particle ‣ testApp.h ‣ https://gist.github.com/tado/6710045#file-oneparticleclass01-testapp-h Particle particle;
  • クラスの記述 ‣ メインの実装ファイル、testApp.cpp で作成したインスタンス を使用して円を描かせる ‣ https://gist.github.com/tado/6710045#file-oneparticleclass01-testapp-cpp ‣ testApp::setup( ) で円の初期位置を指定 ‣ testApp::draw( ) でParticleのdraw( )メソッドを呼びだし particle.position.x = ofRandom(ofGetWidth()); particle.position.y = ofRandom(ofGetHeight()); particle.draw();
  • クラスの記述 ‣ 完成!!
  • クラスの配列
  • クラスの配列 ‣ 1つのクラスから、大量のオブジェクト(インスタンス)を生成 することも可能 ‣ クラスの配列を定義する ‣ 「クラス = 工場」「オブジェクト = 車」というイメージ ‣ 例えば、100個のParticleクラスのオブジェクト ‣ static const int NUM = 100; Particle particle[NUM];
  • クラスの配列 ‣ クラスの配列(Array)のイメージ particle[0] particle[1] particle[2] . . . Particle particle[NUM] NUM個 particle[NUM]
  • クラスの配列 ‣ あとは for文を使用して反復して処理していく ‣ testApp::setup() で初期化 ‣ testApp::draw() で描画 ‣ for(int i = 0; i < NUM; i++){ float posX = ofRandom(ofGetWidth()); float posY = ofRandom(ofGetHeight()); particle[i].setup(ofVec2f(posX, posY)); } for(int i = 0; i < NUM; i++){ particle[i].draw(); }
  • クラスの配列 ‣ 先程のパーティクル1粒表示のプログラムを改造して、100粒 のパーティクルを表示させてみる ‣ Particleクラスはそのまま ‣ testApp.h ‣ https://gist.github.com/tado/6710857#file-particlearray-testapp-h ‣ testApp.cpp ‣ https://gist.github.com/tado/6710857#file-particlearray-testapp-cpp
  • クラスの配列 ‣ 完成 !!
  • パーティクルシステムを作る - 1 重力と摩擦力の表現
  • パーティクルシステムを作る! ‣ いよいよ、パーティクルを動かしてみましょう! ‣ 先週のアルゴリズムを全て実装していく void setInit(); void resetForce(); void updateForce(); void updatePos(); void checkBounds();
  • パーティクルシステムを作る! ‣ UMLクラス図で表現 Particle + position:ofVec2f + velocity:ofVec2f + force:ofVec2f + friction:float + radius:float + setup(ofVec2f position, ofVec2f velocity):void + resetForce():void + addForce(ofVec2f force):void + updateForce():void + updatePos():void + checkBounds(float xmin, float ymin, float xmax, float ymax):void + draw():void
  • パーティクルシステムを作る! ‣ 汎用的に使えるParticleクラス ‣ コードはGithub参照 ‣ https://gist.github.com/tado/6711018
  • パーティクルシステムを作る! ‣ 汎用Particleクラスの使用例:その1 ‣ 重力の影響を受けながら、摩擦抵抗のある空間を跳ねまわる パーティクル ‣ マウスクリックで、その場所で大量生成される ‣ 先週最後に作成したサンプルのクラス版 摩擦力 重力
  • パーティクルシステムを作る! ‣ 実装の詳細は、Githubを参照 ‣ testApp.h ‣ https://gist.github.com/tado/6711076#file-particlesystem- example01-testapp-h ‣ testApp.cpp ‣ https://gist.github.com/tado/6711076#file-particlesystem- example01-testapp-cpp
  • パーティクルシステムを作る! ‣ 完成!!
  • パーティクルシステムを作る - 2 vector (動的配列) の活用
  • vector (動的配列) の活用 ‣ Particleクラス、さらに応用 ‣ 次のようなインタラクションを実現したい: ‣ マウスをドラッグしている間、パーティクルがマウスの場所か ら生成され続ける ‣ 生成されたパーティクルは、そのまま画面に残る ‣ キーボードで「c」のキーを押すとクリア ‣ Particleの配列は、いくつ確保すれば良いのか? ‣ 1000? 10000? 1000000? ‣ 無限大のArrayを作成することはできない…
  • vector (動的配列) の活用 ‣ Arrayの数が確定しない particle[0] particle[1] particle[2] . . . Particle particle[NUM] NUM個 particle[NUM] → 不明 → 不明 → 不明
  • vector (動的配列) の活用 ‣ 配列の上限の数がわからない場合 ‣ Array (静的配列) ではなく、要素数を自由に変更できる動的な 配列を使用すると便利 ‣ C++ では 「vector」 が比較的扱いやすい ‣ 「vector<型の種類> 配列名」となる ‣ 例: Particleクラスの動的配列、particleを宣言 vector<Particle> particle;
  • vector (動的配列) の活用 ‣ vector (動的配列) のイメージ particle[0] particle[1] particle[2] . . . vector<Particle> particle 数は可変
  • vector (動的配列) の活用 ‣ Vectorの配列要素の操作 ‣ 配列の末尾に要素を追加 → push_back() ‣ 例:Particleのオブジェクトpを、particleに追加 ‣ 配列の末尾に要素を削除 → pop_back() ‣ 配列の全ての要素をクリア → clear() particle.push_back(p); particle.clear(); particle.pop_back();
  • vector (動的配列) の活用 ‣ 実装例 ‣ こちらもGistを参照 (ParticleクラスはそのままでOK!) ‣ testApp.h ‣ https://gist.github.com/tado/6712412#file-particlevector- testapp-h ‣ testApp.cpp ‣ https://gist.github.com/tado/6712412#file-particlevector- testapp-cpp
  • vector (動的配列) の活用 ‣ 完成!!
  • パーティクルシステムを作る - 3 パーティクル表現の応用
  • パーティクル表現の応用 ‣ さらに様々な表現の応用をしてみる ‣ 例えば、それぞれのパーティクルを直接描画するのではなく、 パーティクルの場所に画像を置いてみる ‣ こんな画像
  • パーティクル表現の応用 ‣ Particleクラスはそのまま ‣ testApp.h ‣ https://gist.github.com/tado/6714705#file-particlesystem- image-test-h ‣ testApp.cpp ‣ https://gist.github.com/tado/6714705#file-particlesystem- image-test-cpp
  • パーティクル表現の応用 ‣ 画像による美しいパーティクル!!
  • パーティクル表現の応用 ‣ さらに、応用 ‣ それぞれのパーティクルを、曲線で結んでみる ‣ 曲線を描くには ‣ ofBeginShape() ‣ ofCurveVertex() ...頂点の数だけ繰り返し ‣ ofEndShape()
  • パーティクル表現の応用 ‣ 変更点は、testApp.cpp の draw() のみ ‣ testApp.cpp ‣ https://gist.github.com/tado/6714750#file-particlesystem- line-test-cpp
  • パーティクル表現の応用 ‣ 曲線で接続されたパーティクル!
  • 来週までの課題 ‣ 来週までの課題!! ‣ 現状の2次元のパーティクルシステムのプログラムを改造し て、3次元空間でパーティクルが拡散するプログラムヘ ‣ ヒント: ‣ ofVec2f → (x, y) 二次元ベクトル ‣ ofVec3d → (x, y, z) 三次元ベクトル