みけCATのにっき(仮)
つれづれなるまゝに、日くらし、PCにむかひて、心に移りゆくよしなし事を、そこはかとなく書きつくれば、あやしうこそものぐるほしけれ。
(本当か!?)
出典

衝突の計算

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

衝突の計算

投稿記事 by みけCAT » 14年前

物理で反発係数や運動量を習いました。
そして、問題集に平面上での円盤の衝突の計算があったので、プログラムにしてみました。

計算部分のコード

CODE:

typedef struct {
	double x;
	double y;
	double vx;
	double vy;
	double m;
	double r;
} chara_t;

static void dumpcalc(chara_t* ca,chara_t* cb,double e) {
	/*2物体の中心の角度*/
	double angle;
	/*その角度でのsinとcos*/
	double sin_a,cos_a;
	/*分解した速度*/
	/*s:垂直 h:平行*/
	double ca_s_v,ca_h_v,cb_s_v,cb_h_v;
	/*衝突後の分解した平行方向の速度*/
	double ca_h_v_2,cb_h_v_2;
	/*角度を求める*/
	angle=atan2(cb->y-ca->y,ca->x-cb->x);
	/*sinとcosを求めておく*/
	sin_a=sin(angle);
	cos_a=cos(angle);
	/*速度を分解する*/
	/*cos(pi/2-angle)==sin(angle)*/
	/*sin(pi/2-angle)==cos(angle)*/
	ca_s_v=ca->vx*sin_a+ca->vy*cos_a;
	ca_h_v=ca->vx*cos_a-ca->vy*sin_a;
	cb_s_v=cb->vx*sin_a+cb->vy*cos_a;
	cb_h_v=cb->vx*cos_a-cb->vy*sin_a;
	/*近づいていなければキャンセル*/
	if(cb_h_v-ca_h_vm+cb_h_v*cb->m-cb->m*e*(ca_h_v-cb_h_v))/(ca->m+cb->m);
	cb_h_v_2=(ca_h_v*ca->m+cb_h_v*cb->m+ca->m*e*(ca_h_v-cb_h_v))/(ca->m+cb->m);
	/*分解した速度を元に戻す*/
	ca->vx=ca_s_v*sin_a+ca_h_v_2*cos_a;
	ca->vy=ca_s_v*cos_a-ca_h_v_2*sin_a;
	cb->vx=cb_s_v*sin_a+cb_h_v_2*cos_a;
	cb->vy=cb_s_v*cos_a-cb_h_v_2*sin_a;
}
間違っていたら(あっていても)コメントをいただけると嬉しいです。

フルのサンプルプログラムを添付します。
物体AはASDWキーで操作、物体Bは矢印キーで操作です。
ゲームパッドを使うとき(スティックが2本付いているものを使用してください)は、
左スティックで物体Aを操作、右スティックで物体Bを操作です。
添付ファイル

[拡張子 zip は無効化されているため、表示できません]


アバター
GRAM
記事: 164
登録日時: 14年前

Re: 衝突の計算

投稿記事 by GRAM » 14年前

うーん、何というかやりたいことを全部一つにまとめるのってよくないと思うんですよね。
たとえばベクトルの成分を取り出す操作ってこの処理に限った話じゃないですよね。
そういうのって分けて書いてみてはどうですか?

それに速度や位置もベクトルですよね。
そういうのってひとまとめにしてはどうですか?

それから円盤同士の衝突程度であれば
重心系を使うとスマートにできます。

このへんが自分が思ったところですね。
コードは・・・あってるかどうかぱっと見ではわからないのです。

アバター
bitter_fox
記事: 607
登録日時: 14年前

Re: 衝突の計算

投稿記事 by bitter_fox » 14年前

全体的に改行が少なくてキツキツなんで、もうちょっと改行した方がいいように思います。