Loc How to ー【位置】の使い方とカメたち
上の 画像を描く例題(LocHowTo)はここの解説とは直接には関係ないが、解説を読んだ後でメインスクリプトを眺めると、復習になる。
(LOGO2Dを使わずに直接Locを使ってカメを動かすとすると、スクリプトでどう書くことになるか・・・の一つの回答)
(LOGO2Dを使わずに直接Locを使ってカメを動かすとすると、スクリプトでどう書くことになるか・・・の一つの回答)
下には、関数コマンド版のKAME2Dと対応するクラスオブジェクト版LOGO2Dの実装内容を対比させている。この実装を例にとって「使われ方」を説明しよう。
なお、P5の描画関数群(translate(),line(),pushMatrix(),popMatrix(),resetMatrix())については、山本徹さんのFunFunFun Proce55ingの解説がわかり易くて楽しい。
なお、P5の描画関数群(translate(),line(),pushMatrix(),popMatrix(),resetMatrix())については、山本徹さんのFunFunFun Proce55ingの解説がわかり易くて楽しい。
<KAME2D=関数コマンド版> <LOGO2D=クラスオブジェクト版>
class LOGO2D {
(P5) Loc pos;
Loc dir;
KAME2DはP5の局所座標系を活用するので、クラスに仕立てることもないが、LOGO2DはP5の局所座標系とは独立に動かなければならない(thoruさんのわがままを参照)ので、カメの「状態(位置と向き)」を保持するクラス仕立てとした。class LOGO2D {
(P5) Loc pos;
Loc dir;
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()は最初のカメの位置を指定する。何回も呼ばれる可能性があるのですべての「状態」を「元に戻し」ておく必要がある。resetMatrix(); stack.clear();
translate(xloc,yloc); pos.move(xloc,yloc,0);
dir.move(0,1,0);
return this;
} }
【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だけ線を描きながら進む。line(0,0,0,step); lineL(pos, dir.mul(step));
janpu(step); return janpu(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だけジャンプする。translate(0, step); pos.shift(dir.mul(step));
return this;
} }
【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()はカメの「向いている方向」を反時計回りにまわす。rotate(radians(degree)); dir.rotateZ(radians(degree));
return this;
} }
【KAME2D】
P5のrotate()で局所座標系をZ軸中心に回転させる。
【LOGO2D】
カメの「向き」をZ軸中心に回転させる。。
void koko() { LOGO2D koko() {
pushMatrix(); stack.push(pos);
stack.push(dir);
return this;
} }
koko()は、カメのいまの「状態」を記憶にとどめる。(先入れ後出し=スタック動作)pushMatrix(); stack.push(pos);
stack.push(dir);
return this;
} }
【KAME2D】
P5のpushMatrix()で、現在の状態(局所座標系)をP5に覚えさせる。(スタック)
【LOGO2D】
カメの記憶のための専用スタッククラスに、カメのいまの「位置」と「向き」を積む。
void sakki() { LOGO2D sakki() {
popMatrix(); dir = stack.pop();
pos = stack.pop();
return this;
} }
sakki()は直前に覚えた「状態」を思い出すが、次のsakki()ではもっと昔の記憶を取り戻す。popMatrix(); dir = stack.pop();
pos = stack.pop();
return this;
} }
【KAME2D】
P5のpopMatrix()で、さっき覚えてもらった状態(局所座標系)に戻す。
【LOGO2D】
カメの記憶のための専用スタッククラスから、さっき積んだ「位置」と「向き」を取り戻す。
*スタックは「先入れ後出し」なので,入れた順番と逆順に取り出すこと!
なお、日本語サポートサイトからたどれるP5インフォメーション→言語が参考になる。
(解説してあるのは一昔前の版だから注意が必要だけど、loop()→draw()の読み替えだけで大抵OK)
山本徹(thoru)さんがFunProce55ingを始められました。(わくわく)
例題集は習作集と区別するためにこちらに置いた。