xlib_playground5.html (4154B)
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <meta name="viewport" content="width=device-width,initial-scale=1"> 6 <link rel="stylesheet" type="text/css" href="/style.css"> 7 <link rel="icon" type="image/x-icon" href="/pics/favicon.ico"> 8 <title>Xlibで遊んでみる5</title> 9 </head> 10 <body> 11 <header> 12 <a href="/">主頁</a> | 13 <a href="/about.html">自己紹介</a> | 14 <a href="/journal">日記</a> | 15 <a href="/farm">農業</a> | 16 <a href="/kitchen">台所</a> | 17 <a href="/computer">電算機</a> | 18 <a href="/poetry">詩</a> | 19 <a href="/books">本棚</a> | 20 <a href="/gallery">絵</a> | 21 <a href="https://git.mtkn.jp">Git</a> 22 </header> 23 <main> 24 <article> 25 <h1>Xlibで遊んでみる5</h1> 26 <time>2023-01-03</time> 27 28 <p> 29 前回: <a href="xlib_playground4.html">Xlibで遊んでみる4</a> 30 </p> 31 <p> 32 言語: C言語<br /> 33 ソースコード: <a href="https://git.mtkn.jp/xlib_playground">git</a> 34 </p> 35 36 <h2>円の衝突判定とその処理</h2> 37 <p> 38 前回四角形で行っていた衝突判定とその処理を今回は円でした。衝突の判定は二つの円の中心間の距離と、各円の半径の和を比較するだけなので簡単である: 39 </p> 40 <pre><code>struct circle { 41 float ppx, ppy; // previous position (center) 42 float px, py; // current position (center) 43 float vx, vy; // velocity 44 int r; // radius 45 int m; // mass 46 }; 47 48 int 49 circle_test_collision(struct circle *c1, struct circle *c2) 50 { 51 return (c1->px - c2->px) * (c1->px - c2->px) + 52 (c1->py - c2->py) * (c1->py - c2->py) < 53 (c1->r + c2->r) * (c1->r + c2->r); 54 } 55 </code></pre> 56 57 <p> 58 衝突後は前回と同じく弾性衝突として処理した。四角形とは違い、衝突方向の場合分けが不要なので楽である。 59 </p> 60 <pre><code> 61 void 62 circle_handle_collision_mm(struct circle *c1, struct circle *c2) 63 { 64 if (!circle_test_collision(c1, c2)) 65 return; 66 67 float col_px = c2->px - c1->px; 68 float col_py = c2->py - c1->py; 69 float col_pr = sqrtf(col_px * col_px + col_py * col_py); 70 col_px /= col_pr; 71 col_py /= col_pr; 72 73 c1->px = c1->px - col_px / 2; 74 c1->py = c1->py - col_py / 2; 75 c2->px = c2->px + col_px / 2; 76 c2->py = c2->py + col_py / 2; 77 } 78 79 void 80 circle_handle_collision_elastic(struct circle *c1, struct circle *c2) 81 { 82 if(!circle_test_collision(c1, c2)) 83 return; 84 85 float col_px = c2->px - c1->px; 86 float col_py = c2->py - c1->py; 87 float col_pr = sqrtf(col_px * col_px + col_py * col_py); 88 col_px /= col_pr; 89 col_py /= col_pr; 90 float nor_px = col_py; 91 float nor_py = -col_px; 92 93 float m1 = c1->m; 94 float m2 = c2->m; 95 96 float col_1v = c1->vx * col_px + c1->vy * col_py; 97 float col_2v = c2->vx * col_px + c2->vy * col_py; 98 99 float col_1vxn = (2*m2/(m1+m2)*col_2v + (m1-m2)/(m1+m2)*col_1v) * col_px; 100 float col_1vyn = (2*m2/(m1+m2)*col_2v + (m1-m2)/(m1+m2)*col_1v) * col_py; 101 float col_2vxn = (2*m1/(m1+m2)*col_1v + (m2-m1)/(m1+m2)*col_2v) * col_px; 102 float col_2vyn = (2*m1/(m1+m2)*col_1v + (m2-m1)/(m1+m2)*col_2v) * col_py; 103 104 float nor_1vx = nor_px * (c1->vx * nor_px + c1->vy * nor_py); 105 float nor_1vy = nor_py * (c1->vx * nor_px + c1->vy * nor_py); 106 float nor_2vx = nor_px * (c2->vx * nor_px + c2->vy * nor_py); 107 float nor_2vy = nor_py * (c2->vx * nor_px + c2->vy * nor_py); 108 109 c1->vx = col_1vxn + nor_1vx; 110 c1->vy = col_1vyn + nor_1vy; 111 c2->vx = col_2vxn + nor_2vx; 112 c2->vy = col_2vyn + nor_2vy; 113 114 circle_handle_collision_mm(c1, c2); 115 } 116 </code></pre> 117 118 <h2>完成品</h2> 119 <p> 120 <a href="https://git.mtkn.jp/xlib_playground/file/ex5/ex5.c.html">git</a> 121 </p> 122 <p> 123 <video controls> 124 <source src="videos/ex5.webm" type="video/webm"> 125 </video> 126 </p> 127 128 <h2>参考</h2> 129 <ul> 130 <li><a href="https://tronche.com/gui/x/xlib/">The Xlib Manual(html conversion)</a></li> 131 </ul> 132 <p> 133 次の記事: <a href="xlib_playground6.html">Xlibで遊んでみる6</a> 134 </p> 135 </article> 136 137 </main> 138 <footer> 139 <address>info(at)mtkn(dot)jp</address> 140 <a href="http://creativecommons.org/publicdomain/zero/1.0?ref=chooser-v1" rel="license noopener noreferrer">CC0 1.0</a> 141 </footer> 142 </body> 143 </html>