www.mtkn.jp

Manuscripts for my personal webpage.
git clone https://git.mtkn.jp/www.mtkn.jp
Log | Files | Refs | LICENSE

xlib_playground5.html (3308B)


      1 +++
      2 date = '2023-01-03T00:00:00+09:00'
      3 draft = false
      4 title = 'Xlibで遊んでみる5'
      5 +++
      6 <time>2023-01-03</time>
      7 
      8 <p>
      9 前回: <a href="xlib_playground4.html">Xlibで遊んでみる4</a>
     10 </p>
     11 <p>
     12 言語: C言語<br />
     13 ソースコード: <a href="https://git.mtkn.jp/xlib_playground">git</a>
     14 </p>
     15 
     16 <h2>円の衝突判定とその処理</h2>
     17 <p>
     18 前回四角形で行っていた衝突判定とその処理を今回は円でした。衝突の判定は二つの円の中心間の距離と、各円の半径の和を比較するだけなので簡単である:
     19 </p>
     20 <pre><code>struct circle {
     21 	float ppx, ppy;  // previous position (center)
     22 	float px, py;    // current position (center)
     23 	float vx, vy;    // velocity
     24 	int r;           // radius
     25 	int m;           // mass
     26 };
     27 
     28 int
     29 circle_test_collision(struct circle *c1, struct circle *c2)
     30 {
     31 	return (c1-&gt;px - c2-&gt;px) * (c1-&gt;px - c2-&gt;px) +
     32 	       (c1-&gt;py - c2-&gt;py) * (c1-&gt;py - c2-&gt;py) &lt;
     33 		   (c1-&gt;r + c2-&gt;r) * (c1-&gt;r + c2-&gt;r);
     34 }
     35 </code></pre>
     36 
     37 <p>
     38 衝突後は前回と同じく弾性衝突として処理した。四角形とは違い、衝突方向の場合分けが不要なので楽である。
     39 </p>
     40 <pre><code>
     41 void
     42 circle_handle_collision_mm(struct circle *c1, struct circle *c2)
     43 {
     44 	if (!circle_test_collision(c1, c2))
     45 		return;
     46 
     47 	float col_px = c2-&gt;px - c1-&gt;px;
     48 	float col_py = c2-&gt;py - c1-&gt;py;
     49 	float col_pr = sqrtf(col_px * col_px + col_py * col_py);
     50 	col_px /= col_pr;
     51 	col_py /= col_pr;
     52 
     53 	c1-&gt;px = c1-&gt;px - col_px / 2;
     54 	c1-&gt;py = c1-&gt;py - col_py / 2;
     55 	c2-&gt;px = c2-&gt;px + col_px / 2;
     56 	c2-&gt;py = c2-&gt;py + col_py / 2;
     57 }
     58 
     59 void
     60 circle_handle_collision_elastic(struct circle *c1, struct circle *c2)
     61 {
     62 	if(!circle_test_collision(c1, c2))
     63 		return;
     64 
     65 	float col_px = c2-&gt;px - c1-&gt;px;
     66 	float col_py = c2-&gt;py - c1-&gt;py;
     67 	float col_pr = sqrtf(col_px * col_px + col_py * col_py);
     68 	col_px /= col_pr;
     69 	col_py /= col_pr;
     70 	float nor_px = col_py;
     71 	float nor_py = -col_px;
     72 
     73 	float m1 = c1-&gt;m;
     74 	float m2 = c2-&gt;m;
     75 
     76 	float col_1v = c1-&gt;vx * col_px + c1-&gt;vy * col_py;
     77 	float col_2v = c2-&gt;vx * col_px + c2-&gt;vy * col_py;
     78 
     79 	float col_1vxn = (2*m2/(m1+m2)*col_2v + (m1-m2)/(m1+m2)*col_1v) * col_px;
     80 	float col_1vyn = (2*m2/(m1+m2)*col_2v + (m1-m2)/(m1+m2)*col_1v) * col_py;
     81 	float col_2vxn = (2*m1/(m1+m2)*col_1v + (m2-m1)/(m1+m2)*col_2v) * col_px;
     82 	float col_2vyn = (2*m1/(m1+m2)*col_1v + (m2-m1)/(m1+m2)*col_2v) * col_py;
     83 
     84 	float nor_1vx = nor_px * (c1-&gt;vx * nor_px + c1-&gt;vy * nor_py);
     85 	float nor_1vy = nor_py * (c1-&gt;vx * nor_px + c1-&gt;vy * nor_py);
     86 	float nor_2vx = nor_px * (c2-&gt;vx * nor_px + c2-&gt;vy * nor_py);
     87 	float nor_2vy = nor_py * (c2-&gt;vx * nor_px + c2-&gt;vy * nor_py);
     88 
     89 	c1-&gt;vx = col_1vxn + nor_1vx;
     90 	c1-&gt;vy = col_1vyn + nor_1vy;
     91 	c2-&gt;vx = col_2vxn + nor_2vx;
     92 	c2-&gt;vy = col_2vyn + nor_2vy;
     93 
     94 	circle_handle_collision_mm(c1, c2);
     95 }
     96 </code></pre>
     97 
     98 <h2>完成品</h2>
     99 <p>
    100 <a href="https://git.mtkn.jp/xlib_playground/file/ex5/ex5.c.html">git</a>
    101 </p>
    102 <p>
    103 <video controls>
    104 <source src="videos/ex5.webm" type="video/webm">
    105 </video>
    106 </p>
    107 
    108 <h2>参考</h2>
    109 <ul>
    110 <li><a href="https://tronche.com/gui/x/xlib/">The Xlib Manual(html conversion)</a></li>
    111 </ul>
    112 <p>
    113 次の記事: <a href="xlib_playground6.html">Xlibで遊んでみる6</a>
    114 </p>
    115