#author("2017-06-18T22:01:55+09:00","default:kyo-in","kyo-in") #author("2017-06-18T22:02:53+09:00","default:kyo-in","kyo-in") **変換 [#xcf42b7c] 変換を利用し,図形を移動,回転,スケーリングします. **基礎となるプログラム [#s90bd6e0] 以下に今回の基礎となるプログラムを示します.軸を描画する部分を別関数(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空間は以下のようになります. #ref(../第1回/changecam.png,50%); **図形を追加 [#cea44165] 動かす図形を追加します. 図形は,図形を描画する関数(cubeandaxis)を追加します.動かした図形の向きが分かるよう,小さな軸を描くようにしています. void draw() { ... cubeandaxis(); } void cubeandaxis() { axis(30); stroke(0, 0, 0); sphere(20); } #ref(./spherezero.png,50%); まだ特に変換の命令を書いていませんので,球は原点に置かれ,軸に沿った向きを向いています. **移動(平行移動) [#e52abf71] 球を上(-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); cubeandaxis(); } #ref(./sphereymove.png,50%); **回転 [#rebfbe59] 回転には,任意の軸で回転させる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); cubeandaxis(); } #ref(./sphereroty45.png,50%); **スケーリング(拡大縮小) [#da1ab45a] スケーリングには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); cubeandaxis(); } #ref(./scaley2.png,50%); **pushMatrix,popMatrix [#d0f22e48] draw関数内では,変換関数が記憶されます. 例えば,以下のように座標(50,0,0),(0,0,50)の二か所に図形を描画したいとします. #ref(./twospheretrue.png,50%); 以下のようなコードを思い浮かべるかもしれません. void draw() { background(127, 127, 127); camera(100, -100, 100, 0, 0, 0, 0, 1, 0); axis(100); translate(50, 0, 0); cubeandaxis(); translate(0, 0, 50); cubeandaxis(); } しかし上記のコードを実行すると,以下の結果になります. #ref(./twospherefalse.png,50%); 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)に描画されることになります. #ref(./flow01.png,50%); そこで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); cubeandaxis(); popMatrix(); translate(0, 0, 50); cubeandaxis(); } pushMatrix関数は,pushMatrix関数が呼ばれた時点での状態(位置,回転,スケール)を記憶します.popMatrixは先のpushMatrix関数で記憶した状態を復元します.具体的な動作は以下を参照してください. #ref(./flow02.png,50%); **課題1 [#gf8a6a9c] 以下のアニメーションを作成しなさい. -ヒント:まずは1個 #ref(kadai1.wmv); **課題2 [#l43204f0] 以下のアニメーションを作成しなさい. -ヒント:小さい球4つは逆方向にまわっていることに注意 #ref(kadai2.wmv); **任意課題 [#o38d66bd] 以下のアニメーションを作成しなさい. -ヒント:再帰,足は一本ずつ描くしかない? -ヒント:再帰.足は一本ずつ描くしかない? #ref(kadai3.mp4);