proga 0601

28
人工言語入門 A 第6回 3Dプログラミング 2009年6月1日 千葉商科大学政策情報学部 担当:田所淳

Upload: atsushi-tadokoro

Post on 08-Jul-2015

921 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: Proga 0601

人工言語入門 A 第6回

3Dプログラミング2009年6月1日千葉商科大学政策情報学部担当:田所淳

Page 2: Proga 0601

3Dプログラミング

• Processingで3DCGプログラミング• 3Dの座標系• OpenGLとは• 2Dのアニメーションを3Dに拡張してみる• 3D座標で図形を描く• 視点の移動• 3Dのを用いた高度なアニメーション

Page 3: Proga 0601

コンピュータで3Dを表現するには

• コンピュータ画面で3Dを表現したい• コンピュータのディスプレイは、2D (縦横に並んだピクセル)• 奥行は擬似的に表現するしかない• 画面に、立体や空間などの3次元の存在を投影して描画する• = 3DCG (3次元グラフィックス)

投影

スクリーン

(架空の) 3次元物体

Page 4: Proga 0601

コンピュータで3Dを表現するには

• 2次元平面に3次元の存在を投影するには、様々な数学的な知識が必要• Processingではこうした演算を自動的に行うことが可能• 3次元の座標系をそのまま使用できる• 表示のためのライブラリ(OpenGL)も標準で使用可

Page 5: Proga 0601

3D空間の座標系

• X (幅)、 Y (高さ) に加えて、奥行を表現する座標軸 Z が加わる。

x

y

z

Page 6: Proga 0601

3Dプログラミング基本

• まず2Dの図形を回転するプログラムを作成してみる• translateで画面の中心を座標の原点に• 以下の処理を繰り返す• 背景描画• rotateで回転• rectを描画• 回転する角度を更新

Page 7: Proga 0601

float rot=0;

void setup(){ size(400,400); colorMode(HSB,360,100,100,100); frameRate(30); smooth(); fill(200,100,100); stroke(0,0,100); rectMode(CENTER);}

void draw(){ background(0,0,20); translate(width/2,height/2); rotate(rot); rect(0,0,200,200); rot += 0.1;}

3Dプログラミング基本

• 2D平面上を回転する四角形

Page 8: Proga 0601

3Dプログラミング基本

Page 9: Proga 0601

3Dプログラミング基本

• 回転する四角形のプログラム• 2D的な視点では平面上で回転している• 3D的な視点に変更してみる• Z軸を中心軸としてXY平面上に置いてある物体が回転している

• では軸をZ軸ではなく、他の軸(X軸、Y軸)にすると果してどうなるのか

• 回転する軸を指定してrotateする場合

• rotateX(angle) // X軸を中心に回転• rotateY(angle) // Y軸を中心に回転軸を中心に回転• rotateZ(angle) // Z軸を中心に回転軸を中心に回転

Page 10: Proga 0601

3Dプログラミング基本

• 3D座標を用いたプログラミングをする際の注意点• レンダラー (描画の際の方式) を指定する• P3D• Processing専用の3D描画エンジン

• OpenGL• 3Dグラフィックスのためのプログラムインターフェイス• 非常に高速に動作し、高精度な3D画像を描画できる

Page 11: Proga 0601

• P3Dを使用する場合• size関数に以下の指定をする

size (幅, 高さ, P3D);

• OpenGLを使用する場合• プログラムの先頭でOpenGLのライブラリを読み込み

import processing.opengl.*;

• size関数に以下の指定をする

size(幅, 高さ, OPENGL);

3Dプログラミング基本

Page 12: Proga 0601

import processing.opengl.*;

float rot=0;void setup(){ size(400,400,OPENGL); colorMode(HSB,360,100,100,100); frameRate(30); fill(200,100,100); stroke(0,0,100); rectMode(CENTER);}

void draw(){ background(0,0,20); translate(width/2,height/2); rotateX(rot); rect(0,0,200,200); rot += 0.1;}

3Dプログラミング基本

• OpenGLを使用

Page 13: Proga 0601

3Dプログラミング基本

Page 14: Proga 0601

import processing.opengl.*;float rotX=0, rotY=0, rotZ=0;

void setup(){ size(400,400,OPENGL); colorMode(HSB,360,100,100,100); frameRate(30); fill(200,100,100); stroke(0,0,100); rectMode(CENTER);}

void draw(){ background(0,0,20); translate(width/2,height/2); rotateX(rotX); rotateY(rotY); rotateZ(rotZ); rect(0,0,200,200); rotX += 0.1; rotY += 0.2; rotZ += 0.3;}

3Dプログラミング基本

• XYZ軸をそれぞれ回転

Page 15: Proga 0601

3Dプログラミング基本

Page 16: Proga 0601

• 3次元の基本図形を描く関数• 直方体:box

box(size);box(width, height, depth);

3Dプリミティブ

Page 17: Proga 0601

• 今まで使用してきた2Dの図形のための関数には、Z軸の情報を付加して3D空間で描画することも可能なものもある

• 例:線(line)

line(x1, y1, x2, y2); //2Dline(x1, y1, z1, x2, y2, z2); //3D

• 引数の数で自動的に判断している

3D空間でのアニメーション

Page 18: Proga 0601

• 3次元空間上の線のアニメーション• ランダムな位置(x, y, z)にZ軸上に並行になるように線をたくさん描く• 線のZ座標の値を徐々に変化させてアニメーションにする• 配列を用いて、たくさんの図形を一度に動かしてみる

3D空間でのアニメーション

Page 19: Proga 0601

import processing.opengl.*;

int NUM = 5000;float[] x = new float[NUM];float[] y = new float[NUM];float[] z = new float[NUM];color[] col = new color[NUM];

void setup(){ size(400,400,OPENGL); colorMode(HSB,360,100,100,100); frameRate(30); noFill(); stroke(200,100,100); smooth(); for(int i=0; i<NUM; i++){ x[i] = random(width); y[i] = random(height); z[i] = random(-5000,0); col[i] = color(random(200,240),random(50,100),random(100)); }}

3D空間でのアニメーション

• 手前に向って移動してくる線 (1/2)

Page 20: Proga 0601

void draw(){ background(0); for(int i=0; i<NUM; i++){ stroke(color(col[i])); line(x[i],y[i],z[i],x[i],y[i],z[i]+100); z[i]+=20; if(z[i]>100){ z[i] -= 5000; } }}

3D空間でのアニメーション

• 手前に向って移動してくる線 (2/2)

Page 21: Proga 0601

3D空間でのアニメーション

Page 22: Proga 0601

import processing.opengl.*;

int NUM = 100;float[] x = new float[NUM];float[] y = new float[NUM];float[] z = new float[NUM];float[] rot = new float[NUM];float[] rSpeed = new float[NUM];color[] col = new color[NUM];

void setup(){ size(400,400,OPENGL); colorMode(HSB,360,100,100,100); frameRate(30); noStroke(); smooth(); for(int i=0; i<NUM; i++){ x[i] = random(width); y[i] = random(height); z[i] = random(-5000,0); rot[i] = 0; rSpeed[i] = random(-0.1,0.1); col[i] = color(random(0,360),random(100),random(100),50); }}

3D空間でのアニメーション

• 手前に向って降ってくる、立方体 (1/2)

Page 23: Proga 0601

void draw(){ background(0); for(int i=0; i<NUM; i++){ fill(color(col[i])); pushMatrix(); translate(x[i],y[i],z[i]); rotateX(rot[i]); rotateY(rot[i]); rotateZ(rot[i]); box(30); popMatrix(); z[i]+=20; rot[i] += rSpeed[i]; if(z[i]>100){ z[i] -= 5000; } }}

3D空間でのアニメーション

• 手前に向って降ってくる、立方体 (2/2)

Page 24: Proga 0601

3D空間でのアニメーション

Page 25: Proga 0601

import processing.opengl.*;

float a; int NUM = 128; float offset = PI/NUM; color[] colors = new color[NUM];

void setup() { size(400, 400, OPENGL); noStroke(); colorMode(HSB,360,100,100,100); frameRate(30); for(int i=0; i<NUM; i++) { colors[i] = color(i*2+100,70,100,25); } lights();}

3D空間でのアニメーション

• 少しずつスピードを変化させながら回転する立方体 (1/2)

Page 26: Proga 0601

void draw() { background(0); lights(); translate(width/2, height/2, -20); a+=0.01; for(int i=0; i<NUM; i++) { pushMatrix(); fill(colors[i]); rotateY(a+offset*i); rotateX(a/2+offset*i); rotateZ(a/3+offset*i); box(width/2); popMatrix(); }}

3D空間でのアニメーション

• 少しずつスピードを変化させながら回転する立方体 (2/2)

Page 27: Proga 0601

3D空間でのアニメーション

Page 28: Proga 0601

参考:3Dを用いたインタラクティブ表現

• “For All Seasons”, Andreas Muller• http://www.hahakid.net/forallseasons/forallseasons.html