Xlibで遊んでみる5
前回: Xlibで遊んでみる4
言語: C言語
ソースコード: git
円の衝突判定とその処理
前回四角形で行っていた衝突判定とその処理を今回は円でした。衝突の判定は二つの円の中心間の距離と、各円の半径の和を比較するだけなので簡単である:
struct circle {
float ppx, ppy; // previous position (center)
float px, py; // current position (center)
float vx, vy; // velocity
int r; // radius
int m; // mass
};
int
circle_test_collision(struct circle *c1, struct circle *c2)
{
return (c1->px - c2->px) * (c1->px - c2->px) +
(c1->py - c2->py) * (c1->py - c2->py) <
(c1->r + c2->r) * (c1->r + c2->r);
}
衝突後は前回と同じく弾性衝突として処理した。四角形とは違い、衝突方向の場合分けが不要なので楽である。
void
circle_handle_collision_mm(struct circle *c1, struct circle *c2)
{
if (!circle_test_collision(c1, c2))
return;
float col_px = c2->px - c1->px;
float col_py = c2->py - c1->py;
float col_pr = sqrtf(col_px * col_px + col_py * col_py);
col_px /= col_pr;
col_py /= col_pr;
c1->px = c1->px - col_px / 2;
c1->py = c1->py - col_py / 2;
c2->px = c2->px + col_px / 2;
c2->py = c2->py + col_py / 2;
}
void
circle_handle_collision_elastic(struct circle *c1, struct circle *c2)
{
if(!circle_test_collision(c1, c2))
return;
float col_px = c2->px - c1->px;
float col_py = c2->py - c1->py;
float col_pr = sqrtf(col_px * col_px + col_py * col_py);
col_px /= col_pr;
col_py /= col_pr;
float nor_px = col_py;
float nor_py = -col_px;
float m1 = c1->m;
float m2 = c2->m;
float col_1v = c1->vx * col_px + c1->vy * col_py;
float col_2v = c2->vx * col_px + c2->vy * col_py;
float col_1vxn = (2*m2/(m1+m2)*col_2v + (m1-m2)/(m1+m2)*col_1v) * col_px;
float col_1vyn = (2*m2/(m1+m2)*col_2v + (m1-m2)/(m1+m2)*col_1v) * col_py;
float col_2vxn = (2*m1/(m1+m2)*col_1v + (m2-m1)/(m1+m2)*col_2v) * col_px;
float col_2vyn = (2*m1/(m1+m2)*col_1v + (m2-m1)/(m1+m2)*col_2v) * col_py;
float nor_1vx = nor_px * (c1->vx * nor_px + c1->vy * nor_py);
float nor_1vy = nor_py * (c1->vx * nor_px + c1->vy * nor_py);
float nor_2vx = nor_px * (c2->vx * nor_px + c2->vy * nor_py);
float nor_2vy = nor_py * (c2->vx * nor_px + c2->vy * nor_py);
c1->vx = col_1vxn + nor_1vx;
c1->vy = col_1vyn + nor_1vy;
c2->vx = col_2vxn + nor_2vx;
c2->vy = col_2vyn + nor_2vy;
circle_handle_collision_mm(c1, c2);
}
完成品
参考
次の記事: Xlibで遊んでみる6