63
Media Art II 2011 第4回:openFrameworks、 パーティクルを動かす 静的配列と動的配列 2011年9月27日 多摩美術大学 情報デザイン学科 情報芸術コース 田所 淳

openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

Embed Size (px)

DESCRIPTION

 

Citation preview

Page 1: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

Media Art II 2011 第4回:openFrameworks、パーティクルを動かす静的配列と動的配列

2011年9月27日多摩美術大学 情報デザイン学科 情報芸術コース田所 淳

Page 2: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

今日の内容‣ 先週のオブジェクト指向プログラミング(OOP)の復習‣ OOPの5つのポイント

‣ クラスの作成 → インスタンス化 → オブジェクト‣ パーティクル(粒)を大量に複製してみる

‣ 複製した大量のオブジェクトを効率的に扱うには‣ オブジェクトを配列に格納する → 変数のロッカー

‣ 静的配列と動的配列‣ 静的配列 = 固定長配列 (Array)‣ 動的配列 = 可変長配列 (Vector)

Page 3: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

先週の復習オブジェクト指向プログラミング

Page 4: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

‣ オブジェクト指向プログラミング‣ Object Oriented Programming (OOP)‣ オブジェクト指向でProcessingのプログラムを作る‣ そもそもオブジェクト指向とは?

‣ 簡単なプログラムを、オブジェクト指向で書いてみる‣ クラスの定義‣ クラスの呼びだし

オブジェクト指向プログラミングとは?

Page 5: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

‣ オブジェクト指向プログラミング言語のイメージ

プログラミング・パラダイムの変遷

オブジェクト

オブジェクト

オブジェクト

オブジェクト

Page 6: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

‣ OOPの特徴‣ 相互にメッセージを送り合う「オブジェクト」の集まりとしてプログラムを構成

‣ オブジェクトは、プロパティとメソッドから構成される‣ カプセル化 - 必要のない情報は隠す‣ インヘリタンス(継承) - あるオブジェクトが他のオブジェクトの特性を引き継ぐ

‣ ポリモーフィズム(多態性・多様性) - プログラミング言語の各要素が複数の型に属することを許す

オブジェクト指向プログラミングの概念

Page 7: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

‣ オブジェクト‣ プロパティとメソッド‣ カプセル化‣ 継承 (インヘリタンス)‣ 多態性、多相性 (ポリモーフィズム)

OOP、5つのポイント

Page 8: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

‣ オブジェクト指向プログラムのポイント:その1‣ オブジェクトの集まりとしてプログラムを構成‣ オブジェクト同士がメッセージを送りあう

OOP:ポイントその1

Page 9: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

‣ オブジェクト指向プログラムのポイント:その2‣ オブジェクトは、プロパティ(性質、状態)と、メソッド(動作、ふるまい) から構成される

状態1状態2状態3

オブジェクト

メソッド1 メソッド2

メソッド3メソッド4

OOP:ポイントその2

Page 10: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

‣ 例:「りんご」をオブジェクトとして考える

赤5.0甘い

ふじ

実がなる

成長する

落ちる腐る

青4.0

すっぱい

青リンゴ実がなる

成長する

落ちる腐る

OOP:ポイントその2

Page 11: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

‣ オブジェクト指向プログラムのポイント:その3‣ 必要のない情報は隠す (カプセル化)‣ プログラムの実装全てを知る必要はない‣ 必要なインターフェイス(接点)だけ見せて、あとは隠す

It’s this resemblance to real things that gives objects much of their power and appeal. They can notonly model components of real systems, but equally as well fulfill assigned roles as components insoftware systems.

Interface and Implementation

To invent programs, you need to be able to capture abstractions and express them in the programdesign. It’s the job of a programming language to help you do this. The language should facilitate theprocess of invention and design by letting you encode abstractions that reveal the way things work.It should let you make your ideas concrete in the code you write. Surface details shouldn’t obscurethe architecture of your program.

All programming languages provide devices that help express abstractions. In essence, these devicesare ways of grouping implementation details, hiding them, and giving them, at least to some extent,a common interface—much as a mechanical object separates its interface from its implementation, asillustrated in “Interface and Implementation” .

Figure 2-1 Inte rfa ce a nd Im ple m e nta tion

910

11

87 6

implementationinterface

Looking at such a unit from the inside, as the implementor, you’d be concerned with what it’scomposed of and how it works. Looking at it from the outside, as the user, you’re concerned onlywith what it is and what it does. You can look past the details and think solely in terms of the rolethat the unit plays at a higher level.

The principal units of abstraction in the C language are structures and functions . Both, in differentways, hide elements of the implementation:

� On the data side of the world, C structures group data elements into larger units which can thenbe handled as single entities. While some code must delve inside the structure and manipulatethe fields separately, much of the program can regard it as a single thing—not as a collection ofelements, but as what those elements taken together represent. One structure can include others,so a complex arrangement of information can be built from simpler layers.

14 Inte rfa ce a nd Im ple m e nta tion2007-12-11 | © 2007 Apple Inc. All Rights Reserved.

C H A P T E R 2

O bje ct-O rie nte d P rogra m m ing

インターフェイス 実装

OOP:ポイントその3

Page 12: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

‣ オブジェクト指向プログラムのポイント:その4‣ インヘリタンス(継承)‣ オブジェクトから新たなオブジェクトを派生させる

植物

生物

動物

果物 穀物

りんご

ふじ 紅玉 デリシャス

バナナ マンゴー

OOP:ポイントその4

Page 13: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

‣ オブジェクト指向プログラムのポイント:その5‣ ポリモーイズム(多態性、多様性)‣ オブジェクトはメッセージを受け取りそれに応じた処理を行う‣ メッセージの処理方法は、オブジェクト自身が知っていて、その処理はオブジェクトによって異なる

getName()

オブジェクトA:人間

「田所 淳」

getName()

オブジェクトB:車

「トヨタカローラ」

OOP:ポイントその5

Page 14: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

‣ クラス‣ クラスとは:オブジェクトの「型紙」‣ クラスをインスタンス化 (実体化) することでインスタンス(オブジェクト)となる

色重さ(g)味

リンゴ(クラス)

実がなる

成長する

落ちる腐る

赤5.0甘い

ふじ(インスタンスオブジェクト)

実がなる

成長する

落ちる腐る

青4.0

すっぱい

青リンゴ(インスタンスオブジェクト)

実がなる

成長する

落ちる腐る

インスタンス化

クラス

Page 15: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

‣ いままで扱ってきた、testApp も一つのクラス‣ メソッド - setup(), update(), draw() ...etc.‣ プロパティ - testApp全体で使用する変数

testAppもクラス

クラス変数

setup() update()

draw()exit()

testApp

Page 16: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

‣ これまでのようにtestAppにどんどん機能を追加すると、様々な弊害が

‣ 可読性の低下、機能ごとに再利用できない、拡張が困難 ..etc.

testApp単体の限界

testApp testApp肥大化

Page 17: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

‣ 機能ごとにオブジェクトを分けてプロジェクトを構成する‣ オブジェクトが相互に連携

testApp単体の限界

testApp

Rectangle

Particle

ControlPanel

Page 18: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

OOP実践編パーティクルを動かす

Page 19: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

OOP実践編:パーティクルを動かす‣ 実際にプログラムの実例を参照しながら理解する‣ パーティクル (Particles = 粒子) が空間内を飛びまわるプログラムを作成してみる

‣ 最初は1つの粒‣ 大量の粒を個別に動かすには?‣ オブジェクトの配列を利用すると便利

‣ 2種類の配列‣ 静的配列 (Array):固定長の配列‣ 動的配列 (Vector):可変長の配列

Page 20: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

パーティクルのイメージ‣ 一定方向に向けて移動する力を持つ‣ ただし、常に反対方向の抵抗(摩擦など)を受けている

物体にかかる力 (force)F = ma力 = 質量 x 加速度ニュートンの運動方程式

抵抗力 (damping)

Page 21: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

パーティクルクラスを設計する‣ パーティクルクラスに必要な要素

‣ クラス名:Particle

‣ プロパティ(状態)‣ 現在位置:pos (ofVec2f)‣ 速度:vel (ofVec2f)‣ 力:frc (ofVec2f)

‣ ※ ofVec2f とは?‣ ofPoint (x座標, y座標)に加えて、距離の算出や2点間の角度の計算など、ベクトル計算に特化したクラス

‣ of v007からは、ofVectorMathとして標準で使用可能

Page 22: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

パーティクルクラスを設計する‣ パーティクルクラスに必要な要素 (つづき)

‣ メソッド (動作)‣ コンストラクタ(後述):Particle()‣ デストラクタ(後述):~Particle()‣ 力のリセット:recetForce()‣ 力を加える:addForce()‣ 抵抗力(摩擦)を加える:addDampingForce()‣ 状態の初期化:setInitialCondition()‣ 位置更新:update()‣ 描画:draw()

Page 23: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

コンストラクタとデストラクタ‣ コンストラクタ、デストラクタ:特殊なメソッド

‣ コンストラクタ‣ クラスがインスタンス化された際に実行される‣ つまり初期化の関数‣ 関数名はかならずクラス名と同じにする

‣ デストラクタ‣ クラスが廃棄された際に実行される‣ 終了処理‣ 関数名は「~クラス名」にする

Page 24: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

Particleクラスの実装‣ ヘッダーファイル:Particle.h#pragma once

#include "ofMain.h"

class Particle {public:! ofVec2f pos; //位置 ofVec2f vel; //速度 ofVec2f frc; //力(加速度) float damping; //摩擦力 Particle(); virtual ~Particle(){}; void resetForce(); void addForce(float x, float y); void addDampingForce(); void setInitialCondition(float px, float py, float vx, float vy); void update(); void draw(); protected:private:};

Page 25: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

Particleクラスの実装‣ 実装ファイル:Particle.cpp#include "Particle.h"

//コンストラクタ(初期化)Particle::Particle(){! setInitialCondition(0,0,0,0);! damping = 0.01f;}

//力(加速度)をリセットvoid Particle::resetForce(){ frc.set(0,0);}

//力を加えるvoid Particle::addForce(float x, float y){ frc.x = frc.x + x; frc.y = frc.y + y;}

//抵抗力の計算void Particle::addDampingForce(){ frc.x = frc.x - vel.x * damping; frc.y = frc.y - vel.y * damping;}

Page 26: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

Particleクラスの実装‣ 実装ファイル:Particle.cpp (つづき)//初期状態を設定void Particle::setInitialCondition(float px, float py, float vx, float vy){ pos.set(px,py);! vel.set(vx,vy);}

//更新void Particle::update(){!! vel = vel + frc;! pos = pos + vel; }

//描画void Particle::draw(){ ofCircle(pos.x, pos.y, 3);}

Page 27: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

testAppを設計‣ testAppから、Particleを呼びだしてみる‣ Particleクラスをインスタンス化、名前を「p」に

‣ testAppのsetup()内‣ Particleを初期設定:p.setInitialCondition()

‣ testAppのupdate()では…‣ Particleの力をリセット:p.restForce()‣ Particleの抵抗力を計算:p.addDampingForce()‣ Particleの位置を更新:p.update()

‣ testAppのdraw()で‣ Particleを描画:p.draw()

Page 28: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

testAppクラスの実装‣ ヘッダーファイル:testApp.h#pragma once

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

class testApp : public ofSimpleApp{!public: 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(); //クラスParticleをインスタンス化 Particle p;};

Page 29: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

testAppクラスの実装‣ 実装ファイル:testApp.cpp#include "testApp.h"

void testApp::setup(){!! ofSetVerticalSync(true);! ofSetFrameRate(60);! ofBackground(0, 0, 0);! p.setInitialCondition(ofGetWidth()/2, ofGetHeight()/2, ofRandom(-10,10), ofRandom(-10,10));}

void testApp::update(){! p.resetForce();! p.addDampingForce();! p.update(); }

void testApp::draw(){! ofSetColor(255, 255, 255);! p.draw();}

【後略】

Page 30: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

testAppクラスの実装‣ 完成

Page 31: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

インタラクションを追加‣ マウスをクリックすると、クリックした位置からパーティクルを放出するように改造

‣ 参考:testAppのマウスに関するインタラクション‣ void mouseMoved(int x, int y );‣ マウスを移動

‣ void mouseDragged(int x, int y, int button);‣ マウスをドラッグ

‣ void mousePressed(int x, int y, int button);‣ マウスのボタンを押した瞬間

‣ void mouseReleased();‣ マウスの押していたボタンを離した瞬間

Page 32: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

testAppクラスの実装‣ testApp.cppに、下記の処理を追加するvoid testApp::mousePressed(int x, int y, int button){! p.setInitialCondition(x,y,ofRandom(-10,10), ofRandom(-10,10));}

Page 33: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

testAppクラスの実装‣ 完成:マウスを画面上でクリックしてみる

Page 34: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

クイズ:重力を追加する‣ testAppを少しだけ変更して、パーティクルに重力を適用してみる

‣ 重量とは、常にパーティクルに一定に係りつづける力‣ Particleには既に力を加える関数addForce()を実装済み

重力 (Velocity)

Page 35: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

複数のパーティクルを同時に動かす静的配列(Array)と、動的配列(Vector)

Page 36: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

複数のパーティクルを同時に動かす‣ 複数のパーティクルを同時に動かすようにする‣ パーティクルのオブジェクトを格納するやりかたに工夫が必要‣ 複数のオブジェクトを格納するには、配列を利用‣ 配列 = 値を格納するロッカーのようなもの

p[0]

p[1]

p[2]...

配列

NUM個

Page 37: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

静的(固定長)配列と、動的(可変長)配列‣ 要素の数が固定された配列と、必要に応じて自由に長さをかえることのできる配列がある

‣ 静的配列:Array - 配列の数をあらかじめ指定する必要‣ 例:Particleクラスのオブジェクトpを100個格納

‣ 動的配列列:Vector - 配列の数を指定する必要はない‣ 例:Particleクラスのオブジェクトpを動的配列に

Particle p[100];

vector <Particle> p;

Page 38: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

複数のパーティクルを同時に動かす(Array版)‣ まずは静的配列(Array)で実装してみる‣ Particleクラス(Particle.hとParticle.cpp)はそのまま変更なしに使用可能

p[0]

p[1]

p[2]...

Particle p[NUM]

NUM個

p[NUM]

Page 39: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

複数のパーティクルを同時に動かす(Array版)‣ ヘッダーファイル:testApp.h#pragma once

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

#define NUM 100

class testApp : public ofSimpleApp{!public: 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(); //クラスParticleの配列 (NUM個) Particle p[100];};

Page 40: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

複数のパーティクルを同時に動かす(Array版)‣ 実装ファイル:testApp.cpp#include "testApp.h"

void testApp::setup(){!! ofSetVerticalSync(true);! ofSetFrameRate(60);! ofBackground(0, 0, 0);}

void testApp::update(){ for (int i = 0; i < NUM; i++) { p[i].resetForce(); p[i].addForce(0, 0.1); p[i].addDampingForce(); p[i].update(); }}

void testApp::draw(){! ofSetColor(255, 255, 255); for (int i = 0; i < NUM; i++) { p[i].draw(); }}

Page 41: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

複数のパーティクルを同時に動かす(Array版)‣ 実装ファイル:testApp.cpp

【中略】

void testApp::mousePressed(int x, int y, int button){ for (int i = 0; i < NUM; i++) { p[i].setInitialCondition(x, y, ofRandom(-10,10), ofRandom(-10,10)); }}

Page 42: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

複数のパーティクルを同時に動かす(Array版)‣ 完成:画面上でマウスクリック!

Page 43: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

複数のパーティクルを動かす(vector版)‣ 同じ動きを、動的配列(Vector)で置き換える

particles[0]

particles[1]

particles[2]...

Vector <Particle> particles

数は可変

Page 44: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

複数のパーティクルを動かす(vector版)‣ Vectorの配列要素の操作

‣ 配列の末尾に要素を追加 → push_back()‣ 例:Particleのオブジェクトpを、particlesに追加

‣ 配列の末尾に要素を削除 → pop_back()

‣ 配列の全ての要素をクリア → clear()

particles.push_back(p);

particles.clear();

particles.pop_back();

Page 45: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

複数のパーティクルを動かす(vector版)‣ ヘッダーファイル:testApp.h#pragma once#include "ofMain.h"#include "Particle.h"

#define NUM 100

class testApp : public ofSimpleApp{!public: 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(); //クラスParticleの動的配列particles vector <Particle> particles;};

Page 46: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

複数のパーティクルを動かす(vector版)‣ 実装ファイル:testApp.cpp#include "testApp.h"

void testApp::setup(){!! ofSetVerticalSync(true);! ofSetFrameRate(60);! ofBackground(0, 0, 0);}

void testApp::update(){ for (int i = 0; i < particles.size(); i++) { particles[i].resetForce(); particles[i].addForce(0, 0.1); particles[i].addDampingForce(); particles[i].update(); }}

void testApp::draw(){! ofSetColor(255, 255, 255); for (int i = 0; i < particles.size(); i++) { particles[i].draw(); }}

Page 47: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

複数のパーティクルを動かす(vector版)‣ 実装ファイル:testApp.cpp【中略】

void testApp::mousePressed(int x, int y, int button){ particles.clear(); for (int i = 0; i < NUM; i++) { //Particleをインスタンス化 → myParticle Particle myParticle; //初期化 float vx = ofRandom(-10, 10); float vy = ofRandom(-10, 10); myParticle.setInitialCondition(x, y, vx, vy); //作成したオブジェクトを配列の末尾に追加 particles.push_back(myParticle); }}

Page 48: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

複数のパーティクルを動かす(vector版)‣ 完成:画面上でマウスクリック!

Page 49: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

応用編:パーティクルをどんどん追加‣ 動的配列の利点を活用‣ 最大数の制限なく、どんどんパーティクルを追加していく

‣ ユーザからのインタラクション:‣ マウスをドラッグすると、パーティクルを1つ追加‣ ドラッグしつづけると、どんどん増えていく‣ キーボードで「c」キーを入力すると、全部消去

‣ 今回もParticleクラスは一切変更の必要なし

Page 50: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

応用編:パーティクルをどんどん追加‣ ヘッダーファイル:testApp.h#pragma once

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

class testApp : public ofSimpleApp{!public: 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(); //クラスParticleの動的配列particles vector <Particle> particles;};

Page 51: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

応用編:パーティクルをどんどん追加‣ 実装ファイル:testApp.cpp#include "testApp.h"

void testApp::setup(){!! ofSetVerticalSync(true);! ofSetFrameRate(60);! ofBackground(0, 0, 0);}

void testApp::update(){ for (int i = 0; i < particles.size(); i++) { particles[i].resetForce(); particles[i].addDampingForce(); particles[i].update(); }}

void testApp::draw(){! ofSetColor(255, 255, 255);! //画面左上にメッセージを表示! string message = "current particle num = " + ofToString(particles.size(),0);! ofDrawBitmapString(message, 20, 20);

for (int i = 0; i < particles.size(); i++) { particles[i].draw(); }}

Page 52: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

応用編:パーティクルをどんどん追加‣ 実装ファイル:testApp.cpp (つづき)void testApp::keyPressed (int key){! //'c'キーでパーティクルを全部消去! if (key == 'c') {! ! particles.clear();! }! //'f'キーでフルスクリーン表示! if (key == 'f') {! ! ofToggleFullscreen();! }}

【中略】

void testApp::mouseDragged(int x, int y, int button){! //マウスをドラッグするとパーティクルが追加される! Particle myParticle;! float vx = ofRandom(-3, 3);! float vy = ofRandom(-3, 3);! myParticle.setInitialCondition(x, y, vx, vy);! particles.push_back(myParticle);}

【後略】

Page 53: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

応用編:パーティクルをどんどん追加‣ 完成:画面上をドラッグしてパーティクルを追加

Page 54: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

実習:パーティクルをつかって表現‣ Particleクラスと動的配列をつかって、表現してみる

‣ Patricleクラス自体を自由にカスタマイズしてもOK‣ Particleの位置情報を活用‣ 入力の方法を工夫する‣ Particleの動きを変更‣ 色や形を工夫‣ ...etc

Page 55: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

実習:パーティクルをつかって表現‣ 応用例その1:

‣ Particleの位置に点を描くのではなく、それぞれの点を結ぶカーブを描く

‣ ofCarbeVertex() をつかう‣ testApp.cpp の draw()を書き換える

Page 56: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

実習:パーティクルをつかって表現‣ 実装ファイル:testApp.cpp (drawのみ書き換え)【前略】

void testApp::draw(){! ofSetColor(255, 255, 255);! //画面左上にメッセージを表示! string message = "current particle num = " ! + ofToString(particles.size(),0);! ofDrawBitmapString(message, 20, 20);!! ofNoFill();! ofBeginShape();! for (int i = 0; i < particles.size(); i++){! ! ofCurveVertex(particles[i].pos.x, particles[i].pos.y);! }! ofEndShape();}

【後略】

Page 57: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

実習:パーティクルをつかって表現‣ 完成:画面上をドラッグして線を描く

Page 58: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

実習:パーティクルをつかって表現‣ 応用例その2:

‣ ビットマップ画像でパーティクルを描く‣ ofImageを使うと、外部画像ファイルを読みこんで表示可能‣ ofImageの詳細の解説は、また別途行う予定

‣ パーテイクルの位置に、ビットマップ画像を配置していく‣ X座標 → particles[i].pos.x;‣ Y座標 → particles[i].pos.y;

Page 59: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

実習:パーティクルをつかって表現‣ ヘッダーファイル:testApp.h#pragma once

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

class testApp : public ofSimpleApp{!public: 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(); //クラスParticleの動的配列particles vector <Particle> particles;! //ビットマップ画像! ofImage img;};

Page 60: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

実習:パーティクルをつかって表現‣ 実装ファイル:testApp.cpp (1 / 3)#include "testApp.h"

void testApp::setup(){!! ofSetVerticalSync(true);! ofSetFrameRate(60);! ofBackground(0, 0, 0);! ofEnableBlendMode(OF_BLENDMODE_ADD);

! //イメージファイルを読込み! img.loadImage("particle32.png");}

void testApp::update(){ for (int i = 0; i < particles.size(); i++) { particles[i].resetForce(); particles[i].addDampingForce(); particles[i].update(); }}

Page 61: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

実習:パーティクルをつかって表現‣ 実装ファイル:testApp.cpp (2 / 3)void testApp::draw(){! //画面左上にメッセージを表示! ofSetColor(255, 255, 255);! string message = "current particle num = " + ofToString(particles.size(),0);! ofDrawBitmapString(message, 20, 20);

! //パーティクルの位置に画像を表示! for (int i = 0; i < particles.size(); i++){! ! float posx = particles[i].pos.x - 16;! ! float posy = particles[i].pos.y - 16;! ! img.draw(posx, posy);! }}

void testApp::keyPressed (int key){! //'c'キーでパーティクルを全部消去! if (key == 'c') {! ! particles.clear();! }! //'f'キーでフルスクリーン表示! if (key == 'f') {! ! ofToggleFullscreen();! }}

Page 62: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

実習:パーティクルをつかって表現‣ 実装ファイル:testApp.cpp (3 / 3)

【中略】

void testApp::mouseDragged(int x, int y, int button){! //マウスをドラッグするとパーティクルが追加される! Particle myParticle;! float vx = ofRandom(-1, 1);! float vy = ofRandom(-1, 1);! myParticle.setInitialCondition(x, y, vx, vy);! particles.push_back(myParticle);}

【後略】

Page 63: openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII

実習:パーティクルをつかって表現‣ 完成:画面上をドラッグすると画像が表示される