Top Banner
メディア・アートII 第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション 2013年9月16日 多摩美術大学情報デザイン学科メディア芸術コース 田所淳
75

メディア・アートII 第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

Jan 24, 2015

Download

Documents

 
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

メディア・アートII 第2回 openFrameworks基礎配列、くりかえし、乱数ベクトルを使用したアニメーション

2013年9月16日多摩美術大学情報デザイン学科メディア芸術コース田所淳

Page 2: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

本日の内容‣ openFrameworksのプログラムの基礎

‣ 今後の作品制作のための基礎体力をつけていきます!

‣ 乱数(ランダム)‣ 配列とくりかえし‣ 条件分岐‣ ベクトルを使用した運動の表現‣ 大量の物体を動かす

Page 3: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

本日の内容‣ ただ、プログラミングを書き写すだけではつまらない…‣ クイズ形式で進めてみます!

Page 4: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

準備‣ まずは、先週の復習‣ 新規プロジェクトの生成 - ProjectGeneratorの使い方

Page 5: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

Q1: 乱数について

Page 6: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

Q1: 乱数について‣ ランダム(規則性のない)場所に、静止した円を描きなさい‣ プログラムを実行するたびに、違う場所に描かれるように

‣ ヒント:‣ 円を描く - ofCircle(x, y, radius);‣ ランダムな数を生成 - ofRandom(min, max);

Page 7: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

#include "testApp.h"

void testApp::setup(){ // 画面基本設定 ofSetFrameRate(60); ofBackground(63); ofSetCircleResolution(32);}

void testApp::update(){}

void testApp::draw(){ // ランダムな場所に半径40pxの円を描く ofCircle(ofRandom(ofGetWidth()), ofRandom(ofGetHeight()), 40);}

... 後略

Q1: 乱数について‣ よくある間違い - testApp.cpp‣ どうなるか、実験してみる

Page 8: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

Q1: 解答

Page 9: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

Q1: 乱数について - 解答‣ setup() であらかじめランダムな座標を生成しておく‣ 生成した座標は、グローバルな変数に格納 (testApp.hに)‣ その変数の値を参照して、draw() で円を描く

Page 10: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

#pragma once

#include "ofMain.h"

class testApp : public ofBaseApp{ public: void setup(); void update(); void draw();

... // 円の位置 float posX; float posY; };

Q1: 乱数について - 解答‣ testApp.h

Page 11: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

#include "testApp.h"

void testApp::setup(){ // 画面基本設定 ofSetFrameRate(60); ofBackground(63); ofSetCircleResolution(32); // 画面内のランダムな場所を指定 posX = ofRandom(ofGetWidth()); posY = ofRandom(ofGetHeight());}

...

void testApp::draw(){ // 設定した場所に円を描く ofSetHexColor(0x3399cc); ofCircle(posX, posY, 20);}

...

Q1: 乱数について - 解答‣ testApp.cpp

Page 12: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

Q1: 乱数について - 解答‣ 実行するたびに、ランダムな場所に円が描かれる

Page 13: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

Q2: たくさんの図形をランダムな場所に描く

Page 14: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

Q2: たくさんの図形をランダムな場所に描く‣ 100個の静止した円をランダムな場所に描く‣ 半径は40pxで統一

Page 15: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

Q2: たくさんの図形をランダムな場所に描く‣ ヒント 1: 配列 - たくさんの値を保存する‣ 例えば、100個のposXを保存するための「箱」は以下のようにしたら準備できる

‣ この箱には、[] で囲まれた部分に連番でナンバリングされる

‣ この仕組みで、100個の、posXとposYが確保できる

float posX[100];

posX[0] posX[1]posX[2]...posX[99]

← 0から開始する

← 0~99までで100個ぶん

Page 16: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

Q2: たくさんの図形をランダムな場所に描く‣ ヒント 2: くりかえし ‣ for文を使用する‣ 例えば、0~99の100回くりかえす構文

‣ カウンタ変数 i を賢く利用する

for (int i = 0; i < 100; i++) { 《処理の内容》}

for (int i = 0; i < 100; i++) { posX[i] = ????; posY[i] = ????;}

Page 17: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

Q2: 解答

Page 18: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

#pragma once

#include "ofMain.h"

class testApp : public ofBaseApp{ public: void setup(); void update(); void draw(); ... // 位置の配列を生成 float posX[100]; float posY[100];};

Q2: 解答‣ testApp.h

Page 19: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

#include "testApp.h"

void testApp::setup(){ // 画面基本設定 ofSetFrameRate(60); ofBackground(63); ofSetCircleResolution(32); // 画面内のランダムな場所を円の数だけ指定 for (int i = 0; i < 100; i++) { posX[i] = ofRandom(ofGetWidth()); posY[i] = ofRandom(ofGetHeight()); }}

...

void testApp::draw(){ ofSetHexColor(0x3399cc); // 画面内のランダムな場所を円の数だけ描画 for (int i = 0; i < 100; i++) { ofCircle(posX[i], posY[i], 20); }}

Q2: 解答‣ testApp.cpp

Page 20: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

Q2: 解答‣ 100個の円が、ランダムな場所に描かれる

Page 21: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

Q2: 解答‣ 参考: ‣ 数を変更したい場合、いろいろ修正箇所あり‣ 1箇所だけを変更すると、数がすぐに変更できるようにしたい!‣ testApp.hに、クラスの定数(const)として数を指定する‣ 正式には、静的メンバ変数による定数

‣ クラスの定数は、以下のような書式になる

‣ 例: 定数「CIRCLE_NUM」を100と定義

static const int 変数名 = 値;

static const int CIRCLE_NUM = 100;

Page 22: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

#pragma once

#include "ofMain.h"

class testApp : public ofBaseApp{ public: void setup(); void update(); void draw();

...

// 描画する円の数を指定 static const int CIRCLE_NUM = 100; // 位置の配列を生成 float posX[CIRCLE_NUM]; float posY[CIRCLE_NUM];};

Q2: 解答‣ 定数で数を定義バージョン: testApp.h

Page 23: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

#include "testApp.h"

void testApp::setup(){ // 画面基本設定 ofSetFrameRate(60); ofBackground(63); ofSetCircleResolution(32); // 画面内のランダムな場所を円の数だけ指定 for (int i = 0; i < CIRCLE_NUM; i++) { posX[i] = ofRandom(ofGetWidth()); posY[i] = ofRandom(ofGetHeight()); }}

...

void testApp::draw(){ ofSetHexColor(0x3399cc); // 画面内のランダムな場所を円の数だけ描画 for (int i = 0; i < CIRCLE_NUM; i++) { ofCircle(posX[i], posY[i], 20); }}

Q2: 解答‣ 定数で数を定義バージョン: testApp.cpp

Page 24: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

Q2: 解答‣ 例: 円の数を、100 → 400個に

Page 25: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

Q3: たくさんの図形をアニメーション

Page 26: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

Q3: たくさんの図形をアニメーション‣ 次に表示するプログラムを改造して、100個の円が同時に動きまわるアニメーションにする

‣ 開始位置と、円の移動速度と方向はランダムに

Page 27: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

#pragma once

#include "ofMain.h"

class testApp : public ofBaseApp{ public: void setup(); void update(); void draw();... // 位置 float positionX; float positionY; // 速度 float velocityX; float velocityY;};

Q3: たくさんの図形をアニメーション‣ ヒントプログラム: testApp.h

Page 28: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

#include "testApp.h"void testApp::setup(){ // 画面基本設定 ofSetFrameRate(60); ofBackground(63); ofSetCircleResolution(32); // ランダムな場所と速度を指定 positionX = ofRandom(ofGetWidth()); positionY = ofRandom(ofGetHeight()); velocityX = ofRandom(-10, 10); velocityY = ofRandom(-10, 10);}void testApp::update(){ // 円の座標を更新 positionX += velocityX; positionY += velocityY; // 画面からはみ出ないように if (positionX < 0 || positionX > ofGetWidth()) { velocityX *= -1; } if (positionY < 0 || positionY > ofGetHeight()) { velocityY *= -1; }}

Q3: たくさんの図形をアニメーション‣ ヒントプログラム: testApp.cpp

Page 29: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

void testApp::draw(){ ofSetHexColor(0x3399cc); // 円を描画 ofCircle(positionX, positionY, 20);}

Q3: たくさんの図形をアニメーション‣ ヒントプログラム: testApp.cpp

Page 30: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

Q3: たくさんの図形をアニメーション‣ ヒント: 位置と速度をそれぞれ配列にする‣ 定数を定義して、数はすぐに変更できるように

‣ static const int CIRCLE_NUM ‣ positionX[CIRCLE_NUM]‣ positionY[CIRCLE_NUM]‣ velocity X[CIRCLE_NUM]‣ velocityY[CIRCLE_NUM]

‣ 最初の位置と速度、座標の変更、描画、すべての処理をくりかえして100回行う → for文

Page 31: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

Q3: 解答

Page 32: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

#pragma once

#include "ofMain.h"

class testApp : public ofBaseApp{ public:... // 描画する円の数を指定 static const int CIRCLE_NUM = 100; // 位置の配列を生成 float posX[CIRCLE_NUM]; float posY[CIRCLE_NUM]; // 速度の配列を生成 float speedX[CIRCLE_NUM]; float speedY[CIRCLE_NUM];};

Q3: 解答‣ testApp.h

Page 33: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

#include "testApp.h"

void testApp::setup(){ // 画面基本設定 ofSetFrameRate(60); ofBackground(63); ofSetCircleResolution(32); // 画面内のランダムな場所と速度を円の数だけ指定 for (int i = 0; i < CIRCLE_NUM; i++) { posX[i] = ofRandom(ofGetWidth()); posY[i] = ofRandom(ofGetHeight()); speedX[i] = ofRandom(-10, 10); speedY[i] = ofRandom(-10, 10); }}

void testApp::update(){ // 円の座標を全て更新 for (int i = 0; i < CIRCLE_NUM; i++) { posX[i] += speedX[i]; posY[i] += speedY[i];

Q3: 解答‣ testApp.cpp

Page 34: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

// 画面からはみ出たらバウンドさせる if (posX[i] < 0 || posX[i] > ofGetWidth()) { speedX[i] *= -1; } if (posY[i] < 0 || posY[i] > ofGetHeight()) { speedY[i] *= -1; } }}

//--------------------------------------------------------------void testApp::draw(){ ofSetHexColor(0x3399cc); // 画面内のランダムな場所を円の数だけ描画 for (int i = 0; i < CIRCLE_NUM; i++) { ofCircle(posX[i], posY[i], 20); }}

...

Q3: 解答‣ testApp.cpp

Page 35: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

Q3: 解答‣ 100個の円が、同時に動く(はず!)

Page 36: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

ベクトルによる運動の表現

Page 37: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

ベクトルによる運動の表現‣ ここまでの、(x, y)座標それぞれに変数を用意する方法‣ ビギナー的表現

‣ より運動を表現するための高度な書式をマスターしたい‣ 「ベクトル (Vector)」を理解する!

Page 38: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

ベクトルによる運動の表現‣ ベクトル = 幾何学的空間における、大きさと向きを持った量

Page 39: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

ベクトルによる運動の表現‣ 例: 原点(0,0)から(2,3)の座標までのベクトル

‣ このベクトルは、OA = (2,3) と記述される→

Page 40: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

ベクトルによる運動の表現‣ ベクトルは、足し算することができる‣ 例: a = (-2,3) と b = (4,2) の2つのベクトルを足す‣ a + b = (-2+4,3+2) = (2,5)

Page 41: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

ベクトルによる運動の表現‣ ベクトルは、引き算も可能‣ 例: a = (-2, 3) , b = (4, 2)‣ a - b = (-2-4,3-2) = (-6,1)

Page 42: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

ベクトルによる運動の表現‣ 位置ベクトル‣ いままで扱ってきた2次元平面の座標 (x, y) は、原点 (0, 0) を始点としたベクトルと捉えることができる → 位置ベクトル

Page 43: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

ベクトルによる運動の表現‣ 速度ベクトル‣ 「速度 (velocity)」とは、単位時間あたりの物体の移動の変位‣ 日常的な「速さ (speed)」と「速度 (velocity)」を区分する‣ 1フレームごとの座標の変化 = 向きと大きさをもった「速度ベクトル」

位置ベクトル a

位置ベクトル b速度ベクトル

Page 44: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

ベクトルによる運動の表現‣ openFrameworksで、ベクトルを表現‣ 2次元のベクトルは「ofVec2f」を使用する

‣ 例:位置ベクトルと速度ベクトルの宣言

‣ 「ベクトル名.x」「ベクトル名.y」: ベクトルの、x方向の成分と y方向の成分をとりだす

‣ 例:位置ベクトルの(x, y)座標を設定する‣

ofVec2f position; // 位置ベクトルpositionを宣言ofVec2f velocity; // 速度ベクトルvelocityを宣言

position.x = 100; // 位置ベクトルpositionのx成分を100にposition.y = 100; // 位置ベクトルpositionのx成分を50に

Page 45: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

Q4: ベクトルで運動を表現する

Page 46: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

Q4: ベクトルで運動を表現する‣ Q3 で作成した、たくさんの図形を動かすサンプルを、ベクトル(ofVec2f)で書き直してみる

‣ ヒント:100個ぶんの位置ベクトルと速度ベクトルは以下のように宣言される

// 描画する円の数を指定static const int CIRCLE_NUM = 100; // 位置ベクトルの配列ofVec2f position[CIRCLE_NUM]; // 速度ベクトルの配列ofVec2f velocity[CIRCLE_NUM];

Page 47: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

Q4: 解答

Page 48: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

#pragma once

#include "ofMain.h"

class testApp : public ofBaseApp{ public:

... // 描画する円の数を指定 static const int CIRCLE_NUM = 100; // 位置ベクトルの配列 ofVec2f position[CIRCLE_NUM]; // 速度ベクトルの配列 ofVec2f velocity[CIRCLE_NUM];};

Q4: 解答‣ testApp.h

Page 49: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

#include "testApp.h"void testApp::setup(){ // 画面基本設定 ofSetFrameRate(60); ofBackground(63); ofSetCircleResolution(32); // 画面内のランダムな場所と速度を円の数だけ指定 for (int i = 0; i < CIRCLE_NUM; i++) { position[i].x = ofRandom(ofGetWidth()); position[i].y = ofRandom(ofGetHeight()); velocity[i].x = ofRandom(-10, 10); velocity[i].y = ofRandom(-10, 10); }}void testApp::update(){ // 円の座標を全て更新 for (int i = 0; i < CIRCLE_NUM; i++) { position[i] += velocity[i];

// 画面からはみ出たらバウンドさせる if (position[i].x < 0 || position[i].x > ofGetWidth()) { velocity[i].x *= -1; }

Q4: 解答‣ testApp.cpp

Page 50: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

if (position[i].y < 0 || position[i].y > ofGetHeight()) { velocity[i].y *= -1; } }}

void testApp::draw(){ ofSetHexColor(0x3399cc); // 画面内のランダムな場所を円の数だけ描画 for (int i = 0; i < CIRCLE_NUM; i++) { ofCircle(position[i], 20); }}

Q4: 解答‣ testApp.cpp

Page 51: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

Q4: 解答‣ おなじ運動が、とてもすっきりと記述できた!!

Page 52: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

応用: さらにリアルな運動の表現摩擦力

Page 53: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

応用: さらにリアルな運動の表現‣ 摩擦力 (Friction) を表現してみる‣ 摩擦力 = その物体の進行方向逆向きに働く力

速度ベクトル

摩擦力

Page 54: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

応用: さらにリアルな運動の表現‣ 摩擦力を加えた運動の計算アルゴリズム

円の位置と初期速度を設定

力をリセット

摩擦力を加味した力を更新

力から速度を計算、座標を更新

画面からはみ出ていないかチェック

Page 55: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

応用: さらにリアルな運動の表現‣ プログラムの可読性を高める工夫‣ 処理のかたまりを「関数 (function) 」としてまとめる

Page 56: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

応用: さらにリアルな運動の表現‣ 関数 (function)‣ 引数 (ひきすう, argument) - 関数に渡す値 (入力)‣ 返り値 (return value) - 関数が返す値 (出力)

関数

引数1 引数2 引数3

戻り値

Page 57: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

応用: さらにリアルな運動の表現‣ C++での関数の書き方

‣ 例えば、int型の数の二乗を計算する関数

‣ もし戻り値がない関数の場合、戻り値の型は「void」にする

戻り値の型 名前空間::関数名(引数1, 引数2, 引数3...){ 関数の処理の内容}

int testApp::poweroftwo(int a){! return a * a;}

Page 58: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

応用: さらにリアルな運動の表現‣ 先程の処理の流れを以下の関数として定義

void setInit();

void resetForce();

void updateForce();

void updatePos();

void checkBounds();

Page 59: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

#pragma once

#include "ofMain.h"

class testApp : public ofBaseApp{ public:

...

void setInit(); // 初期設定 void resetForce(); // 力をリセット void updateForce(); // 力を更新 void updatePos(); // 位置の更新 void checkBounds(); // 画面からはみ出たらバウンドさせる static const int CIRCLE_NUM = 100; // 描画する円の数を指定 ofVec2f position[CIRCLE_NUM]; // 位置ベクトルの配列 ofVec2f velocity[CIRCLE_NUM]; // 速度ベクトルの配列 ofVec2f force[CIRCLE_NUM]; // 力ベクトルの配列 float friction = 0.01; // 摩擦係数};

応用: さらにリアルな運動の表現‣ testApp.h

Page 60: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

...void testApp::setup(){ // 画面基本設定 ofSetFrameRate(60); ofBackground(63); ofSetCircleResolution(32); setInit(); // 円を初期化}

void testApp::update(){ resetForce(); // 力をリセット updateForce(); // 力の更新 (摩擦) updatePos(); // 円の座標を全て更新 checkBounds(); // 画面からはみ出たらバウンドさせる}

void testApp::draw(){ ofSetHexColor(0x3399cc); // 画面内のランダムな場所を円の数だけ描画 for (int i = 0; i < CIRCLE_NUM; i++) { ofCircle(position[i], 20); }}

応用: さらにリアルな運動の表現‣ testApp.cpp

Page 61: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

void testApp::setInit(){ // 画面内のランダムな場所と速度を円の数だけ指定 for (int i = 0; i < CIRCLE_NUM; i++) { position[i].x = ofGetWidth()/2; position[i].y = ofGetHeight()/2; velocity[i].set(ofRandom(-30, 30), ofRandom(-30, 30)); force[i].set(0, 0); }}

void testApp::resetForce(){ // 力をリセット for (int i = 0; i < CIRCLE_NUM; i++) { force[i].set(0, 0); }}

void testApp::updateForce(){ // 力の更新 (摩擦) for (int i = 0; i < CIRCLE_NUM; i++) { force[i] = force[i] - velocity[i] * friction; }}

応用: さらにリアルな運動の表現‣ testApp.cpp

Page 62: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

void testApp::updatePos(){ // 円の座標を全て更新 for (int i = 0; i < CIRCLE_NUM; i++) { velocity[i] += force[i]; position[i] += velocity[i]; }}

void testApp::checkBounds(){ // 画面からはみ出たらバウンドさせる for (int i = 0; i < CIRCLE_NUM; i++) { if (position[i].x < 0 || position[i].x > ofGetWidth()) { velocity[i].x *= -1; } if (position[i].y < 0 || position[i].y > ofGetHeight()) { velocity[i].y *= -1; } }}

応用: さらにリアルな運動の表現‣ testApp.cpp

Page 63: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

応用: さらにリアルな運動の表現‣ 動きの勢いが、徐々に摩擦で減速していく

Page 64: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

応用: さらにリアルな運動の表現重力

Page 65: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

応用: さらにリアルな運動の表現‣ 重力 (Gravity) を表現してみる‣ つねに下にむかって、一定の力をかけ続ける

摩擦力

重力

Page 66: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

#pragma once

#include "ofMain.h"

class testApp : public ofBaseApp{ public:

... void setInit(); // 初期設定 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); // 描画する円の数を指定 static const int CIRCLE_NUM = 100;

応用: さらにリアルな運動の表現‣ testApp.h

Page 67: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

// 位置ベクトルの配列 ofVec2f position[CIRCLE_NUM]; // 速度ベクトルの配列 ofVec2f velocity[CIRCLE_NUM]; // 力ベクトルの配列 ofVec2f force[CIRCLE_NUM]; // 摩擦係数 float friction = 0.01;}

応用: さらにリアルな運動の表現‣ testApp.h

Page 68: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

#include "testApp.h"

void testApp::setup(){ // 画面基本設定 ofSetFrameRate(60); ofBackground(63); ofSetCircleResolution(32); setInit(); // 円を初期化}

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

応用: さらにリアルな運動の表現‣ testApp.cpp

Page 69: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

void testApp::draw(){ ofSetHexColor(0x3399cc); // 画面内のランダムな場所を円の数だけ描画 for (int i = 0; i < CIRCLE_NUM; i++) { ofCircle(position[i], 20); }}

void testApp::setInit(){ // 画面内のランダムな場所と速度を円の数だけ指定 for (int i = 0; i < CIRCLE_NUM; i++) { position[i].x = ofGetWidth()/2; position[i].y = ofGetHeight()/2; velocity[i].set(ofRandom(-30, 30), ofRandom(-30, 30)); force[i].set(0, 0); }}

void testApp::resetForce(){ // 力をリセット for (int i = 0; i < CIRCLE_NUM; i++) { force[i].set(0, 0); }}

応用: さらにリアルな運動の表現‣ testApp.cpp

Page 70: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

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

void testApp::updateForce(){ // 力の更新 (摩擦) for (int i = 0; i < CIRCLE_NUM; i++) { force[i] = force[i] - velocity[i] * friction; }}

void testApp::updatePos(){ // 円の座標を全て更新 for (int i = 0; i < CIRCLE_NUM; i++) { velocity[i] += force[i]; position[i] += velocity[i]; }}

応用: さらにリアルな運動の表現‣ testApp.cpp

Page 71: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

void testApp::constrain(float xmin, float ymin, float xmax, float ymax){ // 枠内に収める for (int i = 0; i < CIRCLE_NUM; i++) { if (position[i].x < xmin) { position[i].x = xmin; } if (position[i].y < ymin) { position[i].y = ymin; } if (position[i].x > xmax) { position[i].x = xmax; } if (position[i].y > ymax) { position[i].y = ymax; } }}

void testApp::checkBounds(float xmin, float ymin, float xmax, float ymax){ // 画面からはみ出たらバウンドさせる for (int i = 0; i < CIRCLE_NUM; i++) { if (position[i].x < xmin || position[i].x > xmax) { velocity[i].x *= -1; }

応用: さらにリアルな運動の表現‣ testApp.cpp

Page 72: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

if (position[i].y < ymin || position[i].y > ymax) { velocity[i].y *= -1; } }}

応用: さらにリアルな運動の表現‣ testApp.cpp

Page 73: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

応用: さらにリアルな運動の表現‣ リアルな運動が再現される

Page 74: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

応用: さらにリアルな運動の表現‣ 数を大量に増やしてみる!

Page 75: メディア・アートII  第2回 openFrameworks基礎 配列、くりかえし、乱数 ベクトルを使用したアニメーション

サンプルファイルのダウンロード‣ 今日は、ここまで!

‣ 全てのサンプルは以下からダウンロードできます‣ https://github.com/tado/tau_ma2_13