« 2008年04月 | メイン | 2008年06月 »

2008年05月 アーカイブ

2008年05月18日

弾性衝突円盤アプレット

何かJavaのGraphics2Dクラスを使ったプログラミングの練習をしようと思って、昔作ったことがある思い出のアプリをJavaで作ってみた。
弾性衝突円盤アプレットのページへ

各円盤は面積に比例した質量を持ち、壁や他の円盤に完全弾性衝突する。
後は説明不要だと思う。
Pentium3だと動作がちょっと重いかも知れない。

大昔、X68000のHuman68k(つまりウィンドウシステムでない)上で動くものを作った時は、アセンブラで書いてスプライトを使って衝突計算アルゴリズムもかなり練って速度を出したのだが、今回、Javaのコードをほとんど工夫せずに書き、描画処理は単純に消して描いての繰り返しで、しかもJavaアプレットとしてブラウザ上で動かすと、遜色ない速度が出たので、驚いた。68000MPUとCeleron 3.2GHzの性能はかくも違うのか。PCの性能の進歩はなんと速いことか。

割とシンプルなコードになったので、ソースコード、説明を添えて公開するつもりだったが、時間が無かったので、とりあえずアプレットだけ先に公開することにした。

円盤の描画は、先にBufferedImageの画像を用意しておいて、背景を塗りつぶしてGraphics#drawImageでペタペタ貼っているだけである。当方の環境ではちらつきが目立たないので、ダブルバッファリングは省略した。
円盤同士の衝突の計算は、円盤の速度の衝突点方向の成分を求めて、高校の物理で習う完全弾性衝突の式を当てはめて、その方向の速度の変化を求めている。

結局Graphics2Dの機能は使わなかった。非矩形の画像の重ね合わせに必要だと思ったのだが、java.awt.imageのBufferedImageクラスのαプレーンを使えば難なくできた。
別の新たなネタを探さねばならない。

続きを読む "弾性衝突円盤アプレット" »

2008年05月24日

数式画像作成CGI

TeXの数式をPNG画像に変換するCGIを作ってみた。

例:\sum_{k=0}^{n-1}x^k = \frac{1-x^n}{1-x}

2008年05月31日

円盤の衝突計算

弾性衝突円盤アプレットの衝突計算について、悲しいことに式を求めるのにかなり時間を費やしたので、忘れないように記録する。これが無いと、自分でもソースコードを理解できなくなってしまう。

まず直線上の衝突について考える。物体1,2の質量をm1,m2、衝突前の速度をv1,v2、衝突後の速度をv1',v2'とすると、完全弾性衝突の場合、運動量保存の法則より
m_1v_1+m_2v_2=m_1v'_1+m_2v'_2
-\frac{v'_1-v'_2}{v_1-v_2}=1
が成り立つ。速度変化に注目してこれを整理すると、
v'_1-v_1=\frac{-2m_2(v_1-v_2)}{m_1+m_2}
v'_2-v_2=\frac{-2m_1(v_2-v_1)}{m_1+m_2}
が得られる。これは、
v_{tmp}=\frac{m_1v_1+m_2v_2}{m_1+m_2}---(1)
と置くと、
v'_1-v_1=2(v_{tmp}-v_1)---(2)
v'_2-v_2=2(v_{tmp}-v_2)---(3)
と整理できる。

次に平面上の衝突について考える。
ball_hit.png
図のように円盤と円盤が衝突する場合の速度変化については、円盤の中心同士を結ぶ線上の方向の
速度が衝突によって変化し、衝突方向でない速度成分は変化しないので、衝突方向の速度V1r、V2rについて、上記の式(1)~(3)により速度の変化を求めれば良い。つまり、 Pを円盤の中心間を結ぶベクトル、V1,V2を円盤1,2の速度ベクトル、v1r,v2rを円盤1,2のP方向の速度、V1,v1rの衝突後の速度をそれぞれV1',v1r'とすると、円盤の速度変化は
\vec{V'_1}-\vec{V_1} = \frac{\vec{P}}{|\vec{P}|}(v'_{1r}-v_{1r})
である。

v1rの計算については、θをPとV1の間の角度とすると、
v_{1r} = |\vec{V_1}|\cos{\theta}
であり、PとV1との内積は
\vec{V_1}\cdot\vec{P} = |\vec{V_1}||\vec{P}|\cos{\theta}
だから、
v_{1r} = \frac{\vec{V_1}\cdot\vec{P}}{|\vec{P}|}
で求められる。同様に
v_{2r} = \frac{\vec{V_2}\cdot\vec{P}}{|\vec{P}|}
となる。

直線の場合の式(1)と同様に
v_{tmp}=\frac{m_1v_{1r}+m_2v_{2r}}{m_1+m_2} \left (=\frac{1}{|\vec{P}|}\frac{m_1<br />
(\vec{V_1}\cdot\vec{P})+m_2(\vec{V_2}\cdot\vec{P})}{m_1+m_2}\right )
と置くと、(2)より
¥vec{V'_1}-¥vec{V_1} = ¥frac{¥vec{P}}{|¥vec{P}|}(v'_{1r}-v_{1r}) = 2¥frac{¥vec{P}}{|¥vec{P}|}(v_{tmp}-v_{1r})
となる。vtmpとv1rの両方に1/|P|が入っているので、計算上の便宜のため、
v_{1r} = \vec{V_1}\cdot\vec{P}
v_{2r} = \vec{V_2}\cdot\vec{P}
と置き直すと、
¥vec{V'_1}-¥vec{V_1}=2¥frac{¥vec{P}}{|¥vec{P}|^2}(v_{tmp}-v_{1r})
¥vec{V'_2}-¥vec{V_2}=2¥frac{¥vec{P}}{|¥vec{P}|^2}(v_{tmp}-v_{2r})
が得られる。2次元のベクトルをX軸成分とY軸成分に分けて
\vec{P}=(P_x,P_y), \vec{V_n}=(V_{nx},V_{ny})
とスカラー表記にすると、
|\vec{P}|^2 = P_x^2+P_y^2, \vec{V_n}\cdot\vec{P}=V_{nx}P_x+V_{ny}P_y
なので、円盤同士の衝突による速度変化は、
\vec{V'_1}-\vec{V_1} = \left (\frac{2P_x}{P_x^2+P_y^2}(v_{tmp}-v_{1r}),\frac{2P_y}{P_x^2+P_y^2}(v_{tmp}-v_{1r}) \right )
\vec{V'_2}-\vec{V_2} = \left (\frac{2P_x}{P_x^2+P_y^2}(v_{tmp}-v_{2r}),\frac{2P_y}{P_x^2+P_y^2}(v_{tmp}-v_{2r}) \right )
v_{tmp}=\frac{m_1v_{1r}+m_2v_{2r}}{m_1+m_2}
v_{1r} = V_{1x}P_x+V_{1y}P_y
v_{2r} = V_{2x}P_x+V_{2y}P_y
で求められることがわかる。

About 2008年05月

2008年05月にブログ「Weblog on mebius.tokaichiba.jp」に投稿されたすべてのエントリーです。過去のものから新しいものへ順番に並んでいます。

前のアーカイブは2008年04月です。

次のアーカイブは2008年06月です。

他にも多くのエントリーがあります。メインページアーカイブページも見てください。

Powered by
Movable Type 3.35