#author("2024-04-18T12:27:43+09:00","default:kyo-in","kyo-in")
#author("2024-05-28T17:37:05+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]
動かす図形を追加します.

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

 void draw()
 {
   ...
   sphereandaxis();
 }
 
 void sphereandaxis()
 {
   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);
   sphereandaxis();
 }

#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);
   sphereandaxis();
 }

#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);
   sphereandaxis();
 }

#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);
   sphereandaxis();
   translate(0, 0, 50);
   sphereandaxis();
 }

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

#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);
   sphereandaxis();
   popMatrix();
   translate(0, 0, 50);
   sphereandaxis();
 }

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

#ref(./flow02.png,50%);

**課題の提出先・提出方法 [#h475884f]
招待されているBoxアップロードフォルダ「第3回」に自身の学籍番号のフォルダ(アルファベット大文字,例:20FI999)を''自身で作成し'',その中に各課題,指定された名前で完成させたスケッチフォルダごとアップロードしてください.

''提出締め切り:5月7日(火) 23:59''
''提出締め切り:6月18日(火) 23:59''

BOXアップロードフォルダの招待メールが来ていない,また,WebClassで本講義が見えない方は森谷まで連絡ください.

**課題1 [#gf8a6a9c]
4つの球をY軸回転させなさい.

提出スケッチフォルダ名:BASIC3_1

#ref(kadai1.mp4);
#ref(./basic3_1.png,50%);

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

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

提出スケッチフォルダ名:BASIC3_2

#ref(basic3_2.mp4);
#ref(./basic3_2.png,50%);

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

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

**任意課題 [#o38d66bd]
以下のアニメーションを作成しなさい.

提出スケッチフォルダ名:ADVANCE3_1

#ref(./advance3_1.png,75%);

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

#ref(kadai3.mp4);

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS