変換

変換を利用し,図形を移動,回転,スケーリングします.

基礎となるプログラム

以下に今回の基礎となるプログラムを示します.軸を描画する部分を別関数(axis)としました.

void setup()
{
  size(640, 480, P3D);
}

void draw()
{
  background(127, 127, 127);
  camera(100, -100, 100, 0, 0, 0, 0, 1, 0);
  axis(100);
}

void axis(float l)
{
  stroke(255, 0, 0);
  line(0, 0, 0, l, 0, 0);
  stroke(0, 255, 0);
  line(0, 0, 0, 0, l, 0);
  stroke(0, 0, 255);
  line(0, 0, 0, 0, 0, l);
}

これで3D空間は以下のようになります.

changecam.png

図形を追加

動かす図形を追加します.

図形は,図形を描画する関数(sphereandaxis)を追加します.動かした図形の向きが分かるよう,小さな軸を描くようにしています.

void draw()
{
  ...
  sphereandaxis();
}

void sphereandaxis()
{
  axis(30);
  stroke(0, 0, 0);
  sphere(20);
}
spherezero.png

まだ特に変換の命令を書いていませんので,球は原点に置かれ,軸に沿った向きを向いています.

移動(平行移動)

球を上(-Y方向)に移動させてみましょう.

図形を移動させるためには,図形を描画する直前に変換関数,今回は移動(平行移動)関数,translateを使います.

例えば,translate(0, -50, 0);と書けば,「図形をY方向に-50動かせ」ということになります.

void draw()
{
  background(127, 127, 127);
  camera(100, -100, 100, 0, 0, 0, 0, 1, 0);
  axis(100);
  translate(0, -50, 0);
  sphereandaxis();
}
sphereymove.png

回転

回転には,任意の軸で回転させるrotate関数,各軸で回転させるrotateX,rotateY,rotateZ関数が用意されています.

以下の例ではY軸(0, 1, 0)を基準に45度回転させています.よって,rotateY(radians(45));と書いても同じ結果が得られます.

void draw()
{
  background(127, 127, 127);
  camera(100, -100, 100, 0, 0, 0, 0, 1, 0);
  axis(100);
  rotate(radians(45), 0, 1, 0);
  sphereandaxis();
}
sphereroty45.png

スケーリング(拡大縮小)

スケーリングにはscale関数を使用します.以下の例では球をY軸方向のみ2倍します.それ以外の軸は等倍(1倍)です.

void draw()
{
  background(127, 127, 127);
  camera(100, -100, 100, 0, 0, 0, 0, 1, 0);
  axis(100);
  scale(1,2,1);
  sphereandaxis();
}
scaley2.png

pushMatrix,popMatrix

draw関数内では,変換関数が記憶されます.

例えば,以下のように座標(50,0,0),(0,0,50)の二か所に図形を描画したいとします.

twospheretrue.png

以下のようなコードを思い浮かべるかもしれません.

void draw()
{ 
  background(127, 127, 127);
  camera(100, -100, 100, 0, 0, 0, 0, 1, 0);
  axis(100);
  
  translate(50, 0, 0);
  sphereandaxis();
  translate(0, 0, 50);
  sphereandaxis();
}

しかし上記のコードを実行すると,以下の結果になります.

twospherefalse.png

1個目の図形を描画するためにtranslate(50, 0, 0);を実行すると,それが記憶されます.

1個目の図形を描画したのち,2個目の図形を描画するため,続けてtranslate(0, 0, 50);を行うと,下図のように,まず,translate(0, 0, 50);「図形をZ方向に50動かせ」が実行され,次に記憶されたtranslate(50, 0, 0);「図形をX方向に50動かせ」も実行されます.そのため2個目の図形は(50,0,50)に描画されることになります.

flow01.png

そこでpushMatrix,popMatrixの出番です.答えから書くと以下のようになります.

void draw()
{
  background(127, 127, 127);
  camera(100, -100, 100, 0, 0, 0, 0, 1, 0);
  axis(100);
 
  pushMatrix();
  translate(50, 0, 0);
  sphereandaxis();
  popMatrix();
  translate(0, 0, 50);
  sphereandaxis();
}

pushMatrix関数は,pushMatrix関数が呼ばれた時点での状態(位置,回転,スケール)を記憶します.popMatrixは先のpushMatrix関数で記憶した状態を復元します.具体的な動作は以下を参照してください.

flow02.png

課題の提出先・提出方法

講義中に完成しチェックを受けた課題については提出不要です.

\\nas002.term.usmc.dendai.ac.jp\授業用ワークスペース\千住キャンパス\後期\未来科学部\⊂霾鵐瓮妊ア学科\FI1メディア演習C(CG)(森谷友昭)月34\第03回

指定されたファイル名で,.pdeファイルのみ提出してください.

提出締め切り:10月25日(金) 18:00

課題1

4つの球をY軸回転させなさい.

提出ファイル名:BASIC3_1.pde

basic3_1.png
  • ヒント:4つの球を配置したあと,それらをまとめてY軸回転させるイメージ

課題2

原点に太陽があるとして(太陽は何も描画しなくてよい),地球と月の動きを再現しなさい.

提出ファイル名:BASIC3_2.pde

basic3_2.png
  • それぞれの大小と,公転と自転程度を再現していればよい(宇宙学的には〜...と厳密には見ない)

ヒント:

 //地球(ただし自転していない)
 rotateY(rad);
 translate(50, 0, 0);
 sphereandaxis();

 //月(ただし地球の周りをまわっていない)
 //popMatrixで行列スタックをリセットしなければ
 //ここからは地球を基準にした座標系になっている
  
 translate(30, 0, 0);
 scale(0.5, 0.5, 0.5);
 sphereandaxis();

任意課題

以下のアニメーションを作成しなさい.

提出ファイル名:ADVANCE3_1.pde

advance3_1.png
  • ヒント:for文,もしくは再帰(1年後前期ではまだ学習してない)を使っても可能

添付ファイル: fileadvance3_1.png 461件 [詳細] filebasic3_2.mp4 791件 [詳細] filebasic3_2.png 430件 [詳細] filebasic3_1.png 403件 [詳細] filekadai3.mp4 650件 [詳細] filekadai2.mp4 282件 [詳細] filekadai1.mp4 842件 [詳細] filetwospheretrue.png 356件 [詳細] filetwospherefalse.png 312件 [詳細] filespherezero.png 331件 [詳細] filesphereymove.png 341件 [詳細] filesphereroty45.png 421件 [詳細] filescaley2.png 324件 [詳細] fileflow02.png 669件 [詳細] fileflow01.png 406件 [詳細] filechangecam.png 145件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2019-10-21 (月) 11:48:22