0
Media Art II 2013
第4回:openFrameworks
アニメーションを極める
動きを生みだす様々なアルゴリズム
2013年10月7日
多摩美術大学 情報デザイン学科 メディア芸術コース
田所 淳
動きを生みだす様々なアルゴリズム
‣ 乱数や単純な運動だけでなく、より複雑で有機的な動きを生み
だすための手法を紹介
‣ 手持ちの表現の持駒を増やす
‣ 今後の作品制作の表現の幅を拡げる基礎体力に
サンプルファイルのダウンロード
‣ 前回から引続き、サンプルファイルは以下のGithubからダウン
ロードしてください
‣ https://github.com/tado/tau_ma2_13
弾力、ばね、ばねの連結
弾力、ばね、ばねの連結
‣ 「ばね」を数学的に定義する
‣ フックの法則 - バネの伸びが x のとき、それによって生じる力
を F とすると
‣
F = -kx
‣
( k:ばね定数)
振動を繰り返す(単振動)
0
x
F = -kx
ma ...
弾力、ばね、ばねの連結
‣ フックの定理は以下のように書き直すことができる
‣
springForce = -stiffness * stretch
‣
バネの力 = -バネの硬さ * バネの伸び
‣ さらに「バネの伸び」の部分を座標として解釈...
弾力、ばね、ばねの連結
‣ 式を整理
‣
springForce = stiffness * (restPositon - position)
バネの力 = バネの硬さ * (静止位置 - 現在位置)
‣ バネの力から、ばねの移動速度が導きだせ...
弾力、ばね、ばねの連結
‣ まずは、単体のバネを実現してみる
‣ ばねの性質をクラスとしてまとめる → springクラス
‣ 「ばね」は、2つのparticleの間に張られる
‣ Particle A と Particle B
Particl...
弾力、ばね、ばねの連結
‣ ばねの運動は、springクラスのupdateで計算
‣ spring.cpp - update()関数
‣ フックの法則から、2つのParticleにかかる力をそれぞれ計算
void spring::update(...
弾力、ばね、ばねの連結
‣ testAppからは、2つのparticleと、それに挟まれる1つの
springを指定する
‣ testApp.cpp - setup()関数
void testApp::setup(){!
!
! ofBackg...
弾力、ばね、ばねの連結
‣ testAppでは、2つのparticleとspringの更新をする
‣ testApp.cpp - update()関数
void testApp::update(){
!
! //力をリセット
! particl...
弾力、ばね、ばねの連結
‣ あとは、描画するのみ!!
‣ testApp.cpp - draw()関数
void testApp::draw(){
! ofSetColor(255, 255, 255);
!
! //ばねを描画
! mySpr...
弾力、ばね、ばねの連結
‣ 実行結果:空間を漂うバネが描画される
‣ マウスドラッグで操作可能
弾力、ばね、ばねの連結
‣ 次に、ばねを数珠繋ぎにしてみる
‣ spring と particle をそれぞれ動的配列(vector)として作成
‣ 全てのばねの伸縮と、それに伴なう全てのパーティクルにかか
る力を計算する
弾力、ばね、ばねの連結
‣ 数珠繋ぎのばねを生成している箇所
‣ testApp - setup() 関数内
void testApp::setup(){!
! ofBackground(0,0,0);
! ofSetVerticalSync(...
弾力、ばね、ばねの連結
‣ 数珠繋ぎになった、ばねとparticleの更新
‣ testApp - update() 関数内
void testApp::update(){
! //全てのparticleの力をリセット
! for (int i...
弾力、ばね、ばねの連結
‣ 全てのばねとpatricleを描画
‣ testApp - draw() 関数内
void testApp::draw(){
! //全てのばねを描画
! ofSetColor(255, 255, 255, 127)...
弾力、ばね、ばねの連結
‣ 実行結果:数珠繋ぎになったばね
弾力、ばね、ばねの連結
‣ 応用1:ばねを、円弧に数珠繋ぎにして力を加える
弾力、ばね、ばねの連結
‣ 応用2:パーティクル同士をすべて接続して「筋肉」のように
ベクトル場 (Vector Field)
- 流体、磁性体の表現
ベクトル場 (Vector Field) とは
‣ ベクトル場 (Vector Field)
‣ 空間の広がりの中でベクトル的な量の分布
‣ 例えば…
‣ 動いている流体の早さと向き
‣ 磁力や重力などの力の強さと向きなど
‣ ベクトル場をシミ...
‣ ベクトル場 (Vector Field) のイメージ
‣ 向きと方向をもった力が、グリッド上に整列している
ベクトル場 (Vector Field) とは
vectorFirldクラスの設計
‣ まずは、ベクトル場を生成してみる
‣ vectorFieldクラス
‣ ベクトル場を生成し、座標を指定すると、その位置に働く力の
向きと方向を算出する
‣ 座標を指定して新たにベクトル場に力を加えることも...
vectorFirldクラスの設計
‣ vectorFirldクラス:プロパティ
型 変数名 内容
int fieldWidth ベクトルの数、横
int fieldHeight ベクトルの数、縦
int fieldSize ベクトルの総数
i...
vectorFirldクラスの設計
‣ vectorFirldクラス:メソッド
メソッド名と引数・戻り値 説明
vectorField(); コンストラクタ
virtual ~vectorField(); デストラクタ
void setupFi...
vectorFirldクラスの設計
‣ vectorFirldクラス:メソッド (つづき)
メソッド名と引数・戻り値 説明
void addOutwardCircle(float x, float y,
float radius, float ...
ベクトル場を生成
‣ testAppクラスからvectorFieldクラスをインスタンス化して、
画面にベクトル場を生成し描画する
‣ キーをタイプすると、様々な方法でベクトル場に力を付加でき
るようにする
‣ 1:外向きの力
‣ 2:内向きの...
ベクトル場を生成
‣ ベクトル場の初期化
‣ testApp.cpp - setup() 関数
oid testApp::setup(){!
!
! ofSetVerticalSync(true);
! ofSetFrameRate(60);
...
ベクトル場を生成
‣ ベクトル場の描画
‣ testApp.cpp - draw() 関数
void testApp::draw(){
! //ベクトル場を描画
! ofEnableBlendMode(OF_BLENDMODE_ADD);
! ...
ベクトル場を生成
‣ 完成!! : 1∼ 4 のキーで加える力の向きを決定し、マウスをド
ラッグしてベクトル場に力を加えてみる
ベクトル場にパーティクルを浮遊させる
‣ 生成したベクトル場にパーティクルを配置してみる
‣ ベクトル場から、それぞれのパーティクルの座標にかかる力を
算出して、空間の力を受けて浮遊するようにしてみる
‣ 座標上にあるパーティクルにかかる力は ...
ベクトル場にパーティクルを浮遊させる
‣ ベクトル場に配置するパーティクルの初期化
‣ testApp.cpp - setup() 関数
void testApp::setup(){!
!
! ofSetVerticalSync(true);
...
ベクトル場にパーティクルを浮遊させる
‣ ベクトル場からパーティクルにかかる力を算出する
‣ testApp.cpp - update() 関数
void testApp::update(){
!
! for (int i = 0; i < p...
ベクトル場にパーティクルを浮遊させる
‣ あとは、全てのパーティクルを描画するのみ
‣ testApp.cpp - update() 関数
void testApp::draw(){
!
! ofEnableBlendMode(OF_BLEND...
ベクトル場にパーティクルを浮遊させる
‣ 完成:マウスをドラッグするとパーティクルが浮遊する
‣ 最初のサンプルで使用した、マウスの軌跡でドローインングす
るアルゴリズムと、ベクトル場を融合する
‣ マウスをドラッグすると、ベクトル場を自由に描くことができ
るように
ベクトル場 + ドローイング
ベクトル場 + ドローイング
‣ マウスをドラッグすると、その方向と距離でベクトル場に力を
加えるようにする
‣ testApp.cpp - mouseDragged() 関数
void testApp::mouseDragged(int x,...
ベクトル場 + ドローイング
‣ 完成:空間上の粒子を指でなぞるように動かすことが可能
ベクトル場 + ドローイング
‣ 応用:iPadなどのマルチタッチのデバイスと組み合せ
‣ MSAFluid:Memo Akten氏による流体のシミュレーション
‣ http://www.msavisuals.com/msafluid
生物の動き
鳥の群れをシミュレート (Boids)
鳥の群れをシミュレート (Boid)
‣ Boids 「鳥もどき(bird-oid)」
‣ 1987年にCraig Raynoldsによって発表された理論
‣ 3つのルールを規定するだけで鳥の群れをシミュレーションで
きるというもの
‣ 単純な...
鳥の群れをシミュレート (Boid)
‣ Boidsのルール
‣ Separation(引き離し)
‣ 近くの鳥や物体に近づきすぎたらぶつか
らないように離れるルール
‣ Alingment(整列)
‣ 近くの鳥たちと飛ぶスピードや方向を合
わ...
鳥の群れをシミュレート (Boid)
‣ このサンプルでは、particleクラス自身にBoidsのルールをメ
ソッドとして追加している
‣ addForFlocking()
‣ addFlockingForce()
ベクトル場にパーティクルを浮遊させる
‣ Boidsの3つのルールを、particle.cppに追加
void particle::addFlockingForce(){
! // seperation
! if(seperation.coun...
ベクトル場にパーティクルを浮遊させる
‣ Boidsの3つのルールを、particle.cppに追加 (つづき)
void particle::addForFlocking(particle &p){
!
! ofVec3f diff, dif...
鳥の群れをシミュレート (Boid)
‣ 驚くほどリアルな群れの動きが再現される
Upcoming SlideShare
Loading in...5
×

Media Art II 2013 第4回:openFrameworks アニメーションを極める 動きを生みだす様々なアルゴリズム

7,676

Published on

Published in: Education
0 Comments
12 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
7,676
On Slideshare
0
From Embeds
0
Number of Embeds
9
Actions
Shares
0
Downloads
85
Comments
0
Likes
12
Embeds 0
No embeds

No notes for slide

Transcript of "Media Art II 2013 第4回:openFrameworks アニメーションを極める 動きを生みだす様々なアルゴリズム"

  1. 1. Media Art II 2013 第4回:openFrameworks アニメーションを極める 動きを生みだす様々なアルゴリズム 2013年10月7日 多摩美術大学 情報デザイン学科 メディア芸術コース 田所 淳
  2. 2. 動きを生みだす様々なアルゴリズム ‣ 乱数や単純な運動だけでなく、より複雑で有機的な動きを生み だすための手法を紹介 ‣ 手持ちの表現の持駒を増やす ‣ 今後の作品制作の表現の幅を拡げる基礎体力に
  3. 3. サンプルファイルのダウンロード ‣ 前回から引続き、サンプルファイルは以下のGithubからダウン ロードしてください ‣ https://github.com/tado/tau_ma2_13
  4. 4. 弾力、ばね、ばねの連結
  5. 5. 弾力、ばね、ばねの連結 ‣ 「ばね」を数学的に定義する ‣ フックの法則 - バネの伸びが x のとき、それによって生じる力 を F とすると ‣ F = -kx ‣ ( k:ばね定数) 振動を繰り返す(単振動) 0 x F = -kx ma = -kx x = -sin m k t x = Csin(ωt + θ)
  6. 6. 弾力、ばね、ばねの連結 ‣ フックの定理は以下のように書き直すことができる ‣ springForce = -stiffness * stretch ‣ バネの力 = -バネの硬さ * バネの伸び ‣ さらに「バネの伸び」の部分を座標として解釈する ‣ springForce = -stiffness * (position - restPosition) ‣ バネの力 = -バネの硬さ * (現在位置 - ばねの静止位置)
  7. 7. 弾力、ばね、ばねの連結 ‣ 式を整理 ‣ springForce = stiffness * (restPositon - position) バネの力 = バネの硬さ * (静止位置 - 現在位置) ‣ バネの力から、ばねの移動速度が導きだせる ‣ velocity = dumping * (velocity + springFroce) 速度 = 摩擦 * (速度 + バネの力)
  8. 8. 弾力、ばね、ばねの連結 ‣ まずは、単体のバネを実現してみる ‣ ばねの性質をクラスとしてまとめる → springクラス ‣ 「ばね」は、2つのparticleの間に張られる ‣ Particle A と Particle B Particle A Particle B Spring
  9. 9. 弾力、ばね、ばねの連結 ‣ ばねの運動は、springクラスのupdateで計算 ‣ spring.cpp - update()関数 ‣ フックの法則から、2つのParticleにかかる力をそれぞれ計算 void spring::update(){ ! if ((particleA == NULL) || (particleB == NULL)){ ! ! return; ! } ! ! ofVec2f pta = particleA->pos; ! ofVec2f ptb = particleB->pos; ! ! float theirDistance = (pta - ptb).length(); ! float springForce = (springiness * (distance - theirDistance)); ! ofVec2f frcToAdd = (pta-ptb).normalized() * springForce; ! ! particleA->addForce(frcToAdd.x, frcToAdd.y); ! particleB->addForce(-frcToAdd.x, -frcToAdd.y); }
  10. 10. 弾力、ばね、ばねの連結 ‣ testAppからは、2つのparticleと、それに挟まれる1つの springを指定する ‣ testApp.cpp - setup()関数 void testApp::setup(){! ! ! ofBackground(0,0,0); ! ! ofSetVerticalSync(true); ! ofSetFrameRate(60); ! //Particle A 初期設定 ! particle_a.setInitialCondition(400, 400, 0, 0); ! ! //Particle B 初期設定 ! particle_b.setInitialCondition(500, 500, 0, 0); ! //ばね(spring)を、パーティクル間に張る ! mySpring.distance = 100; //ばねの長さ ! mySpring.springiness = 0.1f; //ばねの硬さ ! mySpring.particleA = &particle_a; ! mySpring.particleB = &particle_b; }
  11. 11. 弾力、ばね、ばねの連結 ‣ testAppでは、2つのparticleとspringの更新をする ‣ testApp.cpp - update()関数 void testApp::update(){ ! ! //力をリセット ! particle_a.resetForce(); ! particle_b.resetForce(); ! ! //バネを更新 ! mySpring.update(); ! ! //パーティクルの状態を更新 (壁でバウンド) ! particle_a.bounceOffWalls(); ! particle_a.update(); ! ! particle_b.bounceOffWalls(); ! particle_b.update(); }
  12. 12. 弾力、ばね、ばねの連結 ‣ あとは、描画するのみ!! ‣ testApp.cpp - draw()関数 void testApp::draw(){ ! ofSetColor(255, 255, 255); ! ! //ばねを描画 ! mySpring.draw(); ! ! //particleを描画 ! particle_a.draw(); ! particle_b.draw(); }
  13. 13. 弾力、ばね、ばねの連結 ‣ 実行結果:空間を漂うバネが描画される ‣ マウスドラッグで操作可能
  14. 14. 弾力、ばね、ばねの連結 ‣ 次に、ばねを数珠繋ぎにしてみる ‣ spring と particle をそれぞれ動的配列(vector)として作成 ‣ 全てのばねの伸縮と、それに伴なう全てのパーティクルにかか る力を計算する
  15. 15. 弾力、ばね、ばねの連結 ‣ 数珠繋ぎのばねを生成している箇所 ‣ testApp - setup() 関数内 void testApp::setup(){! ! ofBackground(0,0,0); ! ofSetVerticalSync(true); ! ofSetFrameRate(60); ! ofSetBackgroundAuto(false); ! pimg.loadImage("particle32.png"); ! //particleの配列を生成 ! for (int i = 0; i < 20; i++){ ! ! particle myParticle; ! ! myParticle.setInitialCondition(ofRandom(500,550),ofRandom(500,550),0,0); ! ! particles.push_back(myParticle); ! } ! ! //全ての配列を順番にspringで接続していく ! for (int i = 0; i < (particles.size()-1); i++){ ! ! spring mySpring; ! ! mySpring.distance = 25; ! ! mySpring.springiness = 0.2f; ! ! mySpring.particleA = & (particles[i]); ! ! mySpring.particleB = & (particles[(i+1)%particles.size()]); ! ! springs.push_back(mySpring); ! } }
  16. 16. 弾力、ばね、ばねの連結 ‣ 数珠繋ぎになった、ばねとparticleの更新 ‣ testApp - update() 関数内 void testApp::update(){ ! //全てのparticleの力をリセット ! for (int i = 0; i < particles.size(); i++){ ! ! particles[i].resetForce(); ! } ! //全てのばねの伸縮を計算 ! for (int i = 0; i < springs.size(); i++){ ! ! springs[i].update(); ! } ! ! //全てのparticleの状態を更新 ! for (int i = 0; i < particles.size(); i++){ ! ! particles[i].addDampingForce(); ! ! particles[i].bounceOffWalls(); ! ! particles[i].update(); ! } }
  17. 17. 弾力、ばね、ばねの連結 ‣ 全てのばねとpatricleを描画 ‣ testApp - draw() 関数内 void testApp::draw(){ ! //全てのばねを描画 ! ofSetColor(255, 255, 255, 127); ! for (int i = 0; i < springs.size(); i++){ ! ! springs[i].draw(); ! } ! ! //全てのparticleを描画 ! ofSetColor(255, 255, 255); ! for (int i = 0; i < particles.size(); i++){ ! ! particles[i].draw(); ! } ! }
  18. 18. 弾力、ばね、ばねの連結 ‣ 実行結果:数珠繋ぎになったばね
  19. 19. 弾力、ばね、ばねの連結 ‣ 応用1:ばねを、円弧に数珠繋ぎにして力を加える
  20. 20. 弾力、ばね、ばねの連結 ‣ 応用2:パーティクル同士をすべて接続して「筋肉」のように
  21. 21. ベクトル場 (Vector Field) - 流体、磁性体の表現
  22. 22. ベクトル場 (Vector Field) とは ‣ ベクトル場 (Vector Field) ‣ 空間の広がりの中でベクトル的な量の分布 ‣ 例えば… ‣ 動いている流体の早さと向き ‣ 磁力や重力などの力の強さと向きなど ‣ ベクトル場をシミュレーションできれば、流体は磁性体などの 動きを再現することが可能になるはず
  23. 23. ‣ ベクトル場 (Vector Field) のイメージ ‣ 向きと方向をもった力が、グリッド上に整列している ベクトル場 (Vector Field) とは
  24. 24. vectorFirldクラスの設計 ‣ まずは、ベクトル場を生成してみる ‣ vectorFieldクラス ‣ ベクトル場を生成し、座標を指定すると、その位置に働く力の 向きと方向を算出する ‣ 座標を指定して新たにベクトル場に力を加えることも可能 ‣ 外側に向う力 (噴出?) ‣ 内側に向う力 (吸引?) ‣ 渦巻のように回転する力 (時計回り、反時計回り) ‣ vectorFieldクラスのプロパティとメソッドを整理する ‣ vectorFieldの実装の詳細は省略…
  25. 25. vectorFirldクラスの設計 ‣ vectorFirldクラス:プロパティ 型 変数名 内容 int fieldWidth ベクトルの数、横 int fieldHeight ベクトルの数、縦 int fieldSize ベクトルの総数 int externalWidth ベクトル場の幅 int externalHeight ベクトル場の高さ vector field ベクトルの配列
  26. 26. vectorFirldクラスの設計 ‣ vectorFirldクラス:メソッド メソッド名と引数・戻り値 説明 vectorField(); コンストラクタ virtual ~vectorField(); デストラクタ void setupField(int innerW, int innerH, int outerW, int outerH); ベクトル場の初期化 void clear(); ベクトル場を消去 void fadeField(float fadeAmount); 徐々にベクトル場の力が減衰するようにする void randomizeField(float scale); 全てのベクトル場の力をランダムに生成 void draw(); ベクトル場の様子を描画 ofVec2f getForceFromPos(float xpos, float ypos); 指定した座標にかかる力のベクトルを算出
  27. 27. vectorFirldクラスの設計 ‣ vectorFirldクラス:メソッド (つづき) メソッド名と引数・戻り値 説明 void addOutwardCircle(float x, float y, float radius, float strength); 外向きの力を加える (噴出) void addInwardCircle(float x, float y, float radius, float strength); 内向きの力を加える (吸引) void addClockwiseCircle(float x, float y, float radius, float strength); 時計回りの渦巻 void addCounterClockwiseCircle(float x, float y, float radius, float strength); 反時計回りの渦巻 void addVectorCircle(float x, float y, float vx, float vy, float radius, float strength); 円形の力を加える
  28. 28. ベクトル場を生成 ‣ testAppクラスからvectorFieldクラスをインスタンス化して、 画面にベクトル場を生成し描画する ‣ キーをタイプすると、様々な方法でベクトル場に力を付加でき るようにする ‣ 1:外向きの力 ‣ 2:内向きの力 ‣ 3:時計回りの渦巻 ‣ 4:反時計回りの渦巻 ‣ ベクトル場の力は、徐々に減衰していく
  29. 29. ベクトル場を生成 ‣ ベクトル場の初期化 ‣ testApp.cpp - setup() 関数 oid testApp::setup(){! ! ! ofSetVerticalSync(true); ! ofSetFrameRate(60); ! ofBackground(0, 0, 0); ! ! //ベクトル場の初期化 (画面いっぱいに、横102コ、縦76コのベクトル) ! VF.setupField(102, 76, ofGetWidth(), ofGetHeight()); ! //初期状態は、外向きの力 ! addMode = 1; }
  30. 30. ベクトル場を生成 ‣ ベクトル場の描画 ‣ testApp.cpp - draw() 関数 void testApp::draw(){ ! //ベクトル場を描画 ! ofEnableBlendMode(OF_BLENDMODE_ADD); ! ofSetColor(0,130,130, 200); ! VF.draw(); ! ofDisableBlendMode(); ! }
  31. 31. ベクトル場を生成 ‣ 完成!! : 1∼ 4 のキーで加える力の向きを決定し、マウスをド ラッグしてベクトル場に力を加えてみる
  32. 32. ベクトル場にパーティクルを浮遊させる ‣ 生成したベクトル場にパーティクルを配置してみる ‣ ベクトル場から、それぞれのパーティクルの座標にかかる力を 算出して、空間の力を受けて浮遊するようにしてみる ‣ 座標上にあるパーティクルにかかる力は getForceFromPos() 関数で算出することが可能
  33. 33. ベクトル場にパーティクルを浮遊させる ‣ ベクトル場に配置するパーティクルの初期化 ‣ testApp.cpp - setup() 関数 void testApp::setup(){! ! ! ofSetVerticalSync(true); ! ofSetFrameRate(60); ! ofBackground(0, 0, 0); ! ! //パーティクルを10000個生成 ! for (int i = 0; i < 10000; i++){ ! ! particle myParticle; ! ! myParticle.setInitialCondition ! ! (ofRandom(0,ofGetWidth()),ofRandom(0,ofGetHeight()),0,0); ! ! particles.push_back(myParticle); ! } ! ! //ベクトル場の初期化 (画面いっぱいに、横102コ、縦76コのベクトル) ! VF.setupField(102, 76, ofGetWidth(), ofGetHeight()); ! ! //初期状態は、内向きの力 ! addMode = 2; }
  34. 34. ベクトル場にパーティクルを浮遊させる ‣ ベクトル場からパーティクルにかかる力を算出する ‣ testApp.cpp - update() 関数 void testApp::update(){ ! ! for (int i = 0; i < particles.size(); i++){ ! ! ! ! //particleの力をリセット ! ! particles[i].resetForce(); ! ! ! ! //ベクトル場から、それぞれのparticleにかかる力を算出 ! ! ofVec2f frc; ! ! frc = VF.getForceFromPos(particles[i].pos.x, particles[i].pos.y); ! ! ! ! //Particleの状態を更新 ! ! particles[i].addForce(frc.x, frc.y); ! ! particles[i].addDampingForce(); ! ! particles[i].bounceOffWalls(); ! ! particles[i].update(); ! } ! ! //ベクトル場の力の減衰 ! VF.fadeField(0.998f); }
  35. 35. ベクトル場にパーティクルを浮遊させる ‣ あとは、全てのパーティクルを描画するのみ ‣ testApp.cpp - update() 関数 void testApp::draw(){ ! ! ofEnableBlendMode(OF_BLENDMODE_ADD); ! ! //ベクトル場を描画 ! ofSetColor(0,130,130, 127); ! VF.draw(); ! ! //ベクトル場に配置されたparticleを描画 ! ofSetColor(0, 127, 255)! ; ! for (int i = 0; i < particles.size(); i++){ ! ! particles[i].draw(); ! }! ! ! ofDisableBlendMode(); ! }
  36. 36. ベクトル場にパーティクルを浮遊させる ‣ 完成:マウスをドラッグするとパーティクルが浮遊する
  37. 37. ‣ 最初のサンプルで使用した、マウスの軌跡でドローインングす るアルゴリズムと、ベクトル場を融合する ‣ マウスをドラッグすると、ベクトル場を自由に描くことができ るように ベクトル場 + ドローイング
  38. 38. ベクトル場 + ドローイング ‣ マウスをドラッグすると、その方向と距離でベクトル場に力を 加えるようにする ‣ testApp.cpp - mouseDragged() 関数 void testApp::mouseDragged(int x, int y, int button){ ! ! float diffx = x - prevMouseX; ! float diffy = y - prevMouseY; ! ! VF.addVectorCircle((float)x, (float)y, diffx*0.3, diffy*0.3, 60, 0.3f); ! ! prevMouseX = x; ! prevMouseY = y; }
  39. 39. ベクトル場 + ドローイング ‣ 完成:空間上の粒子を指でなぞるように動かすことが可能
  40. 40. ベクトル場 + ドローイング ‣ 応用:iPadなどのマルチタッチのデバイスと組み合せ ‣ MSAFluid:Memo Akten氏による流体のシミュレーション ‣ http://www.msavisuals.com/msafluid
  41. 41. 生物の動き 鳥の群れをシミュレート (Boids)
  42. 42. 鳥の群れをシミュレート (Boid) ‣ Boids 「鳥もどき(bird-oid)」 ‣ 1987年にCraig Raynoldsによって発表された理論 ‣ 3つのルールを規定するだけで鳥の群れをシミュレーションで きるというもの ‣ 単純な規則を用いて群体としての複雑な振る舞いを再現できる ことを示した ‣ Craig ReynoldsのBoidsの解説ページ ‣ http://www.red3d.com/cwr/boids/
  43. 43. 鳥の群れをシミュレート (Boid) ‣ Boidsのルール ‣ Separation(引き離し) ‣ 近くの鳥や物体に近づきすぎたらぶつか らないように離れるルール ‣ Alingment(整列) ‣ 近くの鳥たちと飛ぶスピードや方向を合 わせようとするルール ‣ Cohesion(結合) ‣ 鳥たちが多くいる方へ向かって飛ぶルー ル
  44. 44. 鳥の群れをシミュレート (Boid) ‣ このサンプルでは、particleクラス自身にBoidsのルールをメ ソッドとして追加している ‣ addForFlocking() ‣ addFlockingForce()
  45. 45. ベクトル場にパーティクルを浮遊させる ‣ Boidsの3つのルールを、particle.cppに追加 void particle::addFlockingForce(){ ! // seperation ! if(seperation.count > 0){ ! ! seperation.sum /= (float)seperation.count; ! ! float sepFrc ! = seperation.strength; ! ! frc -= (seperation.sum.normalized() * sepFrc); ! } ! ! // alignment ! if(alignment.count > 0){ ! ! alignment.sum /= (float)alignment.count; ! ! float alignFrc ! = alignment.strength; ! ! frc += (alignment.sum!! * alignFrc); ! } ! ! // cohesion ! if(cohesion.count > 0){ ! ! cohesion.sum /= (float)cohesion.count; ! ! cohesion.sum -= pos; ! ! float cohFrc ! = cohesion.strength; ! ! frc += (cohesion.sum.normalized() * cohFrc); ! } ! }
  46. 46. ベクトル場にパーティクルを浮遊させる ‣ Boidsの3つのルールを、particle.cppに追加 (つづき) void particle::addForFlocking(particle &p){ ! ! ofVec3f diff, diffNormalized; ! float distance; ! ! diff! ! ! = p.pos - pos; ! distance! ! = diff.length(); ! diffNormalized! = diff; ! diffNormalized.normalize(); ! if( distance > 0 && distance < seperation.distance ){ ! ! seperation.sum += diffNormalized; ! ! seperation.count++; ! } ! ! if( distance > 0 && distance < alignment.distance ){ ! ! alignment.sum += p.vel.getNormalized(); ! ! alignment.count++; ! } ! ! if( distance > 0 && distance < cohesion.distance ){ ! ! cohesion.sum += p.pos; ! ! cohesion.count++; ! } }
  47. 47. 鳥の群れをシミュレート (Boid) ‣ 驚くほどリアルな群れの動きが再現される
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×