質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
Processing

Processingは、オープンソースプロジェクトによるCGのためのプログラミング言語です。Javaをベースにしており、グラフィック機能に特化しています。イメージの生成やアニメーションなど、視覚的なフィードバックを簡単に得ることが可能です。

Q&A

2回答

1685閲覧

processingのpushmatrixの意味

yum_taro_potato

総合スコア7

Processing

Processingは、オープンソースプロジェクトによるCGのためのプログラミング言語です。Javaをベースにしており、グラフィック機能に特化しています。イメージの生成やアニメーションなど、視覚的なフィードバックを簡単に得ることが可能です。

0グッド

1クリップ

投稿2018/02/21 14:17

processingのpushmatrixの意味がいまいちピンときません。
pushmatrixとは「現在の座標を保存する」ためのものらしいのですが、
その「現在の座標を保存する」という表現がよくわかりません。
3Dで表示するときに必要な呪文だと思っておいたほうがいいのでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答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

KSwordOfHaste

総合スコア18394

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問