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