前橋工科大学 - デザイン演習 II 2020
「家具の映像」制作チュートリアル (1)
制作に必要なもの
- ノートPC
- Processing
- もし持っていなければ下記からインストール
- https://processing.org/
「家具の映像」をどう実現するか
- 再生方法 → フルスクリーンで
- 方法は直接レクチャー
- 生活を遮らないもの
- ゆっくりとした変化
- 絶えず変化しつづける
- 同じパターンの繰り返しは避ける → ランダム
- 色合いの工夫 : HSBによる指定
Processingの基本の確認
- setup() 初期設定 : 最初に1度だけ実行される
- draw() 描画 : 一定間隔でくりかえし実行、繰り返す速さ : fps (frame per second)
code_01 : シンプルなアニメーションのサンプル
//変数 float x, y; void setup(){ size(1920, 1080); frameRate(30); //変数の初期化 x = 0; y = height/2; } void draw(){ background(0); fill(31, 127, 255); ellipse(x, y, 100, 100); //変数を更新してアニメーション x = x + 5; }
ランダム
- ランダム : 規則性の無い数、範囲を指定して使用する
- random(100) : 0 ~ 100のランダムな数
- random(100, 200) : 100 ~ 200のランダムな数
code_02 : ランダムな場所にランダムな大きさの円を描く
void setup(){ size(1920, 1080); frameRate(30); //最初に背景を1度だけ塗る background(0); } void draw(){ //ランダムな座標と大きさを生成 float x = random(width); float y = random(height); float diameter = random(20, 200); //円を描く noStroke(); fill(31, 127, 255, 128); ellipse(x, y, diameter, diameter); }
色彩について
- RGBで色彩をコントロールするのは難しい
code_03 : RGBのランダム
void setup(){ size(1920, 1080); frameRate(30); //最初に背景を1度だけ塗る background(0); } void draw(){ //ランダムな座標と大きさを生成 float x = random(width); float y = random(height); float diameter = random(20, 200); //円を描く noStroke(); //RGBのランダム fill(random(256), random(256), random(256), 128); ellipse(x, y, diameter, diameter); }
- RGBではなくHSBカラーモードを使用する、HSB = Hue(色相)、Saturation(彩度)、Brightness(明度)
code_04 : HSBのランダム
void setup(){ size(1920, 1080); frameRate(30); //カラーをHSBモードに colorMode(HSB, 360, 100, 100, 100); //最初に背景を1度だけ塗る background(0); } void draw(){ //ランダムな座標と大きさを生成 float x = random(width); float y = random(height); float diameter = random(20, 200); //円を描く noStroke(); //HSBでランダムな色彩を生成 fill(random(100, 200), 80, 90, 70); ellipse(x, y, diameter, diameter); }
物体の数を制限する : 繰り返しとリスト
- 現状では永遠に円が増殖してしまう
- 一定の数で制限することはできないだろうか?
- 繰り返し (for文) とリストを利用する
- x, y, diameter をそれぞれリスト(floatList)に
- 指定した数を超えたらリストの先頭の要素を消去する
code_05 : リストと繰り返しで最大数を制限
FloatList x; FloatList y; FloatList diameter; FloatList hue; void setup() { size(1920, 1080); frameRate(30); //カラーをHSBモードに colorMode(HSB, 360, 100, 100, 100); //リストを初期化 x = new FloatList(); y = new FloatList(); diameter = new FloatList(); hue = new FloatList(); } void draw() { background(0); //ランダムな値をリストに追加 x.append(random(width)); y.append(random(height)); diameter.append(random(100, 400)); hue.append(random(100, 200)); //最大数を100に限定 if(x.size() > 100){ //先頭の要素を消去 x.remove(0); y.remove(0); diameter.remove(0); hue.remove(0); } //リストの数だけ繰り返し for (int i = 0; i < x.size(); i++) { //円を描く noStroke(); //HSBでランダムな色彩を生成 fill(hue.get(i), 80, 90, 50); ellipse(x.get(i), y.get(i), diameter.get(i), diameter.get(i)); } }
要素をクラスへ
- だいぶプログラムが煩雑になってきた
- パラメータ毎にリストがあるのはちょっと煩雑
- 「ランダムな円」という要素を独立したプログラムへ → クラス
code_06 : クラス化した増殖する円
ArrayList<Dot> dots = new ArrayList<Dot>(); void setup() { size(1920, 1080); frameRate(60); //カラーをHSBモードに colorMode(HSB, 360, 100, 100, 100); } void draw() { background(0); //1秒に1回追加 if(frameCount % 60 == 0){ //Dotをリストに追加 dots.add(new Dot()); } //最大数を100に限定 if(dots.size() > 100){ //先頭の要素を消去 dots.remove(0); } //リストの数だけ繰り返し for (int i = 0; i < dots.size(); i++) { //円を描く dots.get(i).draw(); } } class Dot { float x, y, diameter, hue; Dot(){ x = random(width); y = random(height); diameter = random(100, 400); hue = random(100, 200); } void draw(){ noStroke(); fill(hue, 80, 90, 50); ellipse(x, y, diameter, diameter); } }
個別のオブジェクトを動かす
- 円をクラス化すれば、個別にアニメーションさせることも簡単にできる
- 例えばゆっくりと膨張しながら薄くなっていく円
code_07 : 膨張しながらフェードアウトする円
ArrayList<Dot> dots = new ArrayList<Dot>(); void setup() { size(1920, 1080); frameRate(60); //カラーをHSBモードに colorMode(HSB, 360, 100, 100, 100); } void draw() { background(0); //1秒に1回追加 if (frameCount % 60 == 0) { //Dotをリストに追加 dots.add(new Dot()); } //リストの数だけ繰り返し for (int i = 0; i < dots.size(); i++) { //もし透明度が0より小さかったら消去 if (dots.get(i).alpha < 0) { dots.remove(i); } //円を描く dots.get(i).draw(); } } class Dot { float x, y, diameter, speed, hue, alpha, alphaSpeed; Dot() { x = random(width); y = random(height); diameter = 0; hue = random(100, 200); alpha = 100; speed = random(0.2, 0.8); alphaSpeed = random(0.05, 0.1); } void draw() { noStroke(); fill(hue, 80, 90, alpha); ellipse(x, y, diameter, diameter); diameter += speed; alpha -= alphaSpeed; } }
応用1 : 色相をシフトさせる
- それぞれの円の色相を少しずつ変化させてみる
code_08 : 色相のシフト
ArrayList<Dot> dots = new ArrayList<Dot>(); void setup() { size(1920, 1080); frameRate(60); //カラーをHSBモードに colorMode(HSB, 360, 100, 100, 100); } void draw() { background(0); //4秒に1回追加 if (frameCount % 240 == 0) { //Dotをリストに追加 dots.add(new Dot()); } //リストの数だけ繰り返し for (int i = 0; i < dots.size(); i++) { //もし透明度が0より小さかったら消去 if (dots.get(i).alpha < 0) { dots.remove(i); } //円を描く dots.get(i).draw(); } } class Dot { float x, y, diameter, speed, hue, alpha, alphaSpeed, hueBase; Dot() { x = random(width); y = random(height); diameter = 0; hue = (random(100, 200) + (frameCount / 60.0)) % 360; alpha = 100; speed = random(0.1, 0.4); alphaSpeed = random(0.01, 0.03); } void draw() { noStroke(); fill(hue, 80, 90, alpha); ellipse(x, y, diameter, diameter); diameter += speed; alpha -= alphaSpeed; } }
応用2 形を変化させる
code_09 : 円から矩形に
ArrayList<Dot> dots = new ArrayList<Dot>(); void setup() { size(1920, 1080, P2D); frameRate(60); //カラーをHSBモードに colorMode(HSB, 360, 100, 100, 100); } void draw() { background(0); //4秒に1回追加 if (frameCount % 240 == 0) { //Dotをリストに追加 dots.add(new Dot()); } //リストの数だけ繰り返し for (int i = 0; i < dots.size(); i++) { //もし透明度が0より小さかったら消去 if (dots.get(i).alpha < 0) { dots.remove(i); } //円を描く dots.get(i).draw(); } } class Dot { float x, y, diameter, speed, hue, alpha, alphaSpeed, hueBase; Dot() { x = random(width); y = random(height); diameter = 0; hue = (random(100, 200) + (frameCount / 60.0)) % 360; alpha = 100; speed = random(0.1, 0.4); alphaSpeed = random(0.01, 0.03); } void draw() { noStroke(); fill(hue, 60, 100, alpha); rectMode(CENTER); rect(x, y, diameter, diameter); diameter += speed; alpha -= alphaSpeed; } }
応用3 違う動きに
- 高さを画面いっぱいにした矩形を左右に動かす
- 左右の辺に到達したら折り返す
- アルファの値を変化させて色の重なりを楽しむ
code_10 : 重なる矩形
ArrayList<Rect> rects = new ArrayList<Rect>(); void setup() { size(1920, 1080); frameRate(60); //カラーをHSBモードに colorMode(HSB, 360, 100, 100, 100); } void draw() { background(0, 0, 70); //4秒に1回追加 if (frameCount % 240 == 0) { //Dotをリストに追加 rects.add(new Rect()); } //リストの数だけ繰り返し for (int i = 0; i < rects.size(); i++) { //矩形を描く rects.get(i).draw(); //もし透明度が0より小さかったら消去 if (rects.get(i).alpha < 0) { rects.remove(i); } } } class Rect { float x, w, speed, hue, alpha, alphaSpeed; Rect() { //初期値を設定 w = random(500, 1000); x = random(-w, width); speed = random(-0.5, 0.5); hue = random(360); alpha = 0; alphaSpeed = 0.2; } void draw() { noStroke(); fill(hue, 60, 100, alpha); rect(x, 0, w, height); x += speed; //両端で跳ね返り if (x < -width || x > width) { speed *= -1; } //フェードイン if(alpha > 100){ alphaSpeed *= 1; alpha = 100; } alpha += alphaSpeed; } }