processingのpushmatrixの意味がいまいちピンときません。
pushmatrixとは「現在の座標を保存する」ためのものらしいのですが、
その「現在の座標を保存する」という表現がよくわかりません。
3Dで表示するときに必要な呪文だと思っておいたほうがいいのでしょうか?
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

回答2件
0
現在の座標'系'を保存する、と言ったほうがいいかな、と思います。
それと、3Dだからという話ではなく...
translateとかrotate, scaleで座標系をいじりますよね。現状を保存するのがpushMatrixです。もちろん、保存するのはさらにいじったあとで「現状」に戻したいからなので、保存した状態を呼び出すpopMatrixと組みで使うのが原則です。
例えば、花火っぽい画を描いてみるなら、まずロリポップみたいな画を一つ描きましょうか。
processing
1void setup(){ 2 size(300,300); 3 background(0,10,64); 4} 5void draw(){ 6 translate(width/2,height/2); //画面真ん中に原点を移動 7 stroke(255,255,0); 8 line(0,10,0,100); //放射状線の一つを描く 9 translate(0,100); //線の端に原点を移動 10 noStroke(); 11 fill(255,0,0); 12 ellipse(0,0,10,10); //線の端に●を描く 13}
このロリポップを、真ん中に戻ってちょっと回していくつも描けばちょっと花火っぽくなるでしょう。じゃあ真ん中に戻るには...
translate(width/2,height/2);
とすると、線の端に移動した原点を元に新しい原点を計算しちゃうので、画面の真ん中には戻れません。ということで、pushMatrix/popMatrixの出番です。
drawの方をちょっと変えてみましょう。
final int DIV=10; void draw() { translate(width/2, height/2); //画面真ん中に原点を移動 for (int i=0; i<DIV; i++) { rotate(2*PI/DIV);//放射状にするためちょっと回す pushMatrix();//今の座標系を覚える stroke(255, 255, 0); line(0, 10, 0, 100); //放射状線の一つを描く translate(0, 100); //線の端に原点を移動 noStroke(); fill(255, 0, 0); ellipse(0, 0, 10, 10); //線の端に●を描く popMatrix();//座標系を戻す } }
さらに花火の先っちょを描くと一層効果を実感出来るのでは。なお、push/popという名称から想像できるようにスタック構造になります。
processing
1final int DIV=10; 2void draw() { 3 translate(width/2, height/2); //画面真ん中に原点を移動 4 for (int i=0; i<DIV; i++) { 5 rotate(2*PI/DIV);//放射状にするためちょっと回す 6 pushMatrix();//今の座標系を覚える 7 stroke(255, 255, 0); 8 line(0, 10, 0, 100); //放射状線の一つを描く 9 translate(0, 100); //線の端に原点を移動 10 noStroke(); 11 fill(255, 0, 0); 12 ellipse(0, 0, 10, 10); //線の端に●を描く 13 for(int j=0;j<DIV;j++){//さらに「花火」を描く 14 rotate(2*PI/DIV); 15 pushMatrix(); 16 stroke(255,255,0); 17 line(0,10,0,20); 18 translate(0,20); 19 noStroke(); 20 fill(255,0,0); 21 ellipse(0,0,5,5); 22 popMatrix(); 23 } 24 popMatrix();//座標系を戻す 25 } 26} 27
投稿2018/03/18 06:42

退会済みユーザー
総合スコア0
0
pushMatrixのことを「現在の座標を保存する」機能といってしまうといささか舌足らずな表現ではないでしょうか?
3D/2Dでの回転・移動・スケーリングなどの座標変換をアフィン変換と呼びますが、それら任意の組み合わせは単一の行列で表現できます。その行列のことをアフィン変換行列といったりしますがmatrixとはその「行列」のことを意味します。
つまりpushMatrixとは「現在のアフィン変換の設定を(後でpopMatrixで回復できるよう)ある専用のスタックに覚えておく」という機能なのです。座標を保存するのではなく座標変換の設定を保存するわけです。
これができると
1 現在の座標変換状態をpush(A)
2 何かを描画
3 さらに移動/回転/スケーリングを加える(B)
4 何かを描画
5 さらに移動/回転/スケーリングを加える(C)
6 何かを描画
7 (A)で保存しておいた座標変換状態へ復帰
のようなことができます。(B)(C)でどんな移動/回転/スケーリング変換をしようとも簡単にその「変換前の状態」に戻せるわけですね。
この機能があると例えば多数の可動関節で接続されたような複雑な階層モデルを空間上に配置・描画するという処理を単純化できたりします。例えば人体のモデルを3D上空間上に配置する際に
- 右肩を原点になるように移動し、角度Aだけ回転させて右腕を配置
- 座標変換を元に戻す
- 今度は左肩を原点になるように移動し、角度Bだけ回転させて左腕を配置
- さらにまた戻して今度は右足を・・・
といった具合に、わかりやすく処理できるのです。
3Dで表示するときに必要な呪文
2D/3Dグラフィックプログラミングにおいてアフィン変換が何か、アフィン変換と行列演算の関係などを正しく理解すると、前述したような「複雑な関係を持つモデルを空間上に配置する」といった処理を理解したり考えたりすることが容易になります。よって座標変換を伴うグラフィック処理を行うのでしたらアフィン変換や行列演算を学ぶことをお奨めします。
投稿2018/02/21 15:48
総合スコア18404
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。