Classiclll's Blog

an old boy

Loc How to ー【位置】の使い方とカメたち

イメージ 1



前の記事でクラスLocの全容をざっと説明したので、今回はLocの使い(使われ)方をこれまたざっと解説したい。

上の 画像を描く例題(LocHowTo)はここの解説とは直接には関係ないが、解説を読んだ後でメインスクリプトを眺めると、復習になる。
(LOGO2Dを使わずに直接Locを使ってカメを動かすとすると、スクリプトでどう書くことになるか・・・の一つの回答)

下には、関数コマンド版のKAME2Dと対応するクラスオブジェクト版LOGO2Dの実装内容を対比させている。この実装を例にとって「使われ方」を説明しよう。
なお、P5の描画関数群(translate(),line(),pushMatrix(),popMatrix(),resetMatrix())については、山本徹さんのFunFunFun Proce55ingの解説がわかり易くて楽しい。

 <KAME2D=関数コマンド版>          <LOGO2D=クラスオブジェクト版>
                     class LOGO2D {
    (P5)              Loc pos;
                      Loc dir;
KAME2DはP5の局所座標系を活用するので、クラスに仕立てることもないが、LOGO2DはP5の局所座標系とは独立に動かなければならない(thoruさんのわがままを参照)ので、カメの「状態(位置と向き)」を保持するクラス仕立てとした。

void saisho(float xloc, float yloc) {     LOGO2D saisho(float xloc, float yloc) {
 resetMatrix();               stack.clear();
 translate(xloc,yloc);            pos.move(xloc,yloc,0);
                      dir.move(0,1,0);
                      return this;
}                     }
saisho()は最初のカメの位置を指定する。何回も呼ばれる可能性があるのですべての「状態」を「元に戻し」ておく必要がある。
【KAME2D】
 P5のresetMatrix()で元に戻し、translate()でP5の局所座標系原点を(再)設定する。
【LOGO2D】
 カメの「記憶(後述)」をカラにし、カメの「状態(位置と向き)」を(再)設定する。
   *LGO2Dはreturnがやたら多いけど、こうしとくとpos.shift(dir).mul(5)な風に書ける。

void mae(float step) {          LOGO2D mae(float step) {
 line(0,0,0,step);             lineL(pos, dir.mul(step));
 janpu(step);               return janpu(step);
}                     }
mae()はカメの「向いている方向」にstepだけ線を描きながら進む。
【KAME2D】
 P5のline()で(現在の局所座標系での)Y軸方向に長さstepの線を引いてjanpu()を呼ぶ。
【LOGO2D】
 専用の直線描画メソッドでカメの「位置」posから「前方」に長さstepの線を引いてjanpu()を呼ぶ。
   *専用の直線描画メソッドの実際の実装はこれと異なる。(説明のしやすさから)

void janpu(float step) {          LOGO2D janpu(float step) {
 translate(0, step);             pos.shift(dir.mul(step));
                       return this;
}                     }
janpu()はカメの「向いている方向」にstepだけジャンプする。
【KAME2D】
 P5のtranslate()でY軸方向にstepだけ進んだ点に(局所)原点を移す。
【LOGO2D】
 カメの「位置」posを「前方」にstepの位置まで移す。

void muki(float degree) {          LOGO2D muki(float degree) {
 rotate(radians(degree));          dir.rotateZ(radians(degree));
                       return this;
}                      }
muki()はカメの「向いている方向」を反時計回りにまわす。
【KAME2D】
 P5のrotate()で局所座標系をZ軸中心に回転させる。
【LOGO2D】
 カメの「向き」をZ軸中心に回転させる。。

void koko() {                LOGO2D koko() {
 pushMatrix();                stack.push(pos);
                        stack.push(dir);
                        return this;
}                      }
koko()は、カメのいまの「状態」を記憶にとどめる。(先入れ後出し=スタック動作)
【KAME2D】
 P5のpushMatrix()で、現在の状態(局所座標系)をP5に覚えさせる。(スタック)
【LOGO2D】
 カメの記憶のための専用スタッククラスに、カメのいまの「位置」と「向き」を積む。

void sakki() {               LOGO2D sakki() {
popMatrix();                 dir = stack.pop();
                       pos = stack.pop();
                       return this;
}                      }
sakki()は直前に覚えた「状態」を思い出すが、次のsakki()ではもっと昔の記憶を取り戻す。
【KAME2D】
 P5のpopMatrix()で、さっき覚えてもらった状態(局所座標系)に戻す。
【LOGO2D】
 カメの記憶のための専用スタッククラスから、さっき積んだ「位置」と「向き」を取り戻す。
   *スタックは「先入れ後出し」なので,入れた順番と逆順に取り出すこと!


なお、日本語サポートサイトからたどれるP5インフォメーション→言語が参考になる。
(解説してあるのは一昔前の版だから注意が必要だけど、loop()→draw()の読み替えだけで大抵OK)
山本徹(thoru)さんがFunProce55ingを始められました。(わくわく)
例題集は習作集と区別するためにこちらに置いた。