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