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->px - c2->px) * (c1->px - c2->px) + 32 (c1->py - c2->py) * (c1->py - c2->py) < 33 (c1->r + c2->r) * (c1->r + c2->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->px - c1->px; 48 float col_py = c2->py - c1->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->px = c1->px - col_px / 2; 54 c1->py = c1->py - col_py / 2; 55 c2->px = c2->px + col_px / 2; 56 c2->py = c2->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->px - c1->px; 66 float col_py = c2->py - c1->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->m; 74 float m2 = c2->m; 75 76 float col_1v = c1->vx * col_px + c1->vy * col_py; 77 float col_2v = c2->vx * col_px + c2->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->vx * nor_px + c1->vy * nor_py); 85 float nor_1vy = nor_py * (c1->vx * nor_px + c1->vy * nor_py); 86 float nor_2vx = nor_px * (c2->vx * nor_px + c2->vy * nor_py); 87 float nor_2vy = nor_py * (c2->vx * nor_px + c2->vy * nor_py); 88 89 c1->vx = col_1vxn + nor_1vx; 90 c1->vy = col_1vyn + nor_1vy; 91 c2->vx = col_2vxn + nor_2vx; 92 c2->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