円と直線の当たり判定はどうしたらいいでしょうか?

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
蒼碧

円と直線の当たり判定はどうしたらいいでしょうか?

#1

投稿記事 by 蒼碧 » 14年前

こんにちは
直線と円の当たり判定がわからないので質問させて頂きました。

前提として龍神録のようなシューティングゲームです。
・弾の判定が一瞬で、描画せず、射撃後すべての当たり判定を総当りして直線上にある一番近いキャラクターにダメージが入る
という関数を実装したいのですが、どうしたらいいでしょうか?

X,Yは自分のキャラの座標 角度は射撃した角度で
Character_tは配列Enemyのアドレスを渡しています。
Character_t構造体はそのままEnemy.x、Enemy.yという感じです。

コード:

void JudgeBlast(int X,int Y,double Angle,Character_t* Enemy){
      int NearEnemy;//最も近い敵の番号
	for(int i=0;i<MAXENEMY;i++){

	}
      EnemyDamageBlast(NearEnemy);
}
とにかく総当りして、一番近い敵の番号をNearEnemyに入れてダメージ判定をしたいです。
ですが、座標と角度から円の当たり判定がわからないです。
このような解説サイトも見たのですが
http://www004.upp.so-net.ne.jp/s_honma/ ... stance.htm
座標と角度から・・・というのがやはりよくわかりません。
どういう計算を入れたらいいでしょうか?

アバター
h2so5
副管理人
記事: 2212
登録日時: 15年前
住所: 東京
連絡を取る:

Re: 円と直線の当たり判定はどうしたらいいでしょうか?

#2

投稿記事 by h2so5 » 14年前

tan 関数を使うことで角度から傾きが出ますから、
それと座標を合わせれば解説サイトにあるような直線の式が得られます。

beatle
記事: 1281
登録日時: 14年前
住所: 埼玉
連絡を取る:

Re: 円と直線の当たり判定はどうしたらいいでしょうか?

#3

投稿記事 by beatle » 14年前

結局やりたいのはこういうことでしょうか?

点(X,Y)を通り、角度がAngleの直線をlとする。
直線lに最も近い敵の番号iを求める。
(言い換えれば、点(Enemy.x,Enemy.y)と直線lとの距離が最短となるiを求める)

アバター
h2so5
副管理人
記事: 2212
登録日時: 15年前
住所: 東京
連絡を取る:

Re: 円と直線の当たり判定はどうしたらいいでしょうか?

#4

投稿記事 by h2so5 » 14年前

>beatleさん

僕は、

点(X,Y)を通り、角度がAngleの直線をlとする。
直線lと交差している円(敵)のなかで、円の中心が点(X,Y)に最も近いものを求める。

と解釈しました。

蒼碧

Re: 円と直線の当たり判定はどうしたらいいでしょうか?

#5

投稿記事 by 蒼碧 » 14年前

h2so5 さんが書きました:>beatleさん

僕は、

点(X,Y)を通り、角度がAngleの直線をlとする。
直線lと交差している円(敵)のなかで、円の中心が点(X,Y)に最も近いものを求める。

と解釈しました。
そうです。
紛らわしい言い方ですいません。

tan()を少し調べてみたのですが、
この返り値のdoubleはx,yと一緒にどのようにして
y=ax+bのような形にすればいいですか?

アバター
h2so5
副管理人
記事: 2212
登録日時: 15年前
住所: 東京
連絡を取る:

Re: 円と直線の当たり判定はどうしたらいいでしょうか?

#6

投稿記事 by h2so5 » 14年前

点(X, Y) を通り傾きが a の直線の式は
(y - Y) = a(x - X)
になります。

蒼碧

Re: 円と直線の当たり判定はどうしたらいいでしょうか?

#7

投稿記事 by 蒼碧 » 14年前

色々調べていて遅くなりました。
やってみたのですが、当たり判定がなかなかおかしいです。
XWIN,YWINにはメインループに使われたウィンドウのサイズが入っています。
テスト用として画面の中心から見て角度を変えて、Enemyから10の範囲に入ったら”あたり”と表示します。
しかし、実際には点からさらに30度ほどずれた所であたりと出てしまいます。
どうしたら良いでしょうか?


//Y=tan(Angle)*X;
//点(x1,y1)から直線y=mx+nへの垂線の距離を求める公式
//(y1-m*x1-n)/√(1+m^2)
というのを前提に

コード:

JudgeBlast(XWIN/2,YWIN/2,angle,Enemy);

コード:

void JudgeBlast(int X,int Y,double Angle,Character_t* Enemy){
		double Range=(Enemy.y-(tan(Angle)*Enemy.x))/(sqrt(1+tan(Angle)*tan(Angle)));
		printfDx("点との距離=%f",Range);
		if(10>Range)printfDx("あたり");
}

アバター
h2so5
副管理人
記事: 2212
登録日時: 15年前
住所: 東京
連絡を取る:

Re: 円と直線の当たり判定はどうしたらいいでしょうか?

#8

投稿記事 by h2so5 » 14年前

関数 JudgeBlast 内で引数 X, Y が一度も使われていませんよ

蒼碧

Re: 円と直線の当たり判定はどうしたらいいでしょうか?

#9

投稿記事 by 蒼碧 » 14年前

なるほど!

コード:

double Range=(Enemy.y-(tan(Angle)*Enemy.x))/(sqrt(1+tan(Angle)*tan(Angle)));

コード:

double Range=((Enemy.y-Y)-(tan(Angle)*(Enemy.x-X)))/(sqrt(1+tan(Angle)*tan(Angle)));
このように変更したところそれっぽい数値がでました!

あとはなんていうか、第一象限と第三象限あたりに向いてる線をプラスの値に戻す事と、
指定方向にのみ当たりを判定すればいいんですね

後者は今向いてる角度と敵への角度がPI/2~-PI/2の範囲内にあればわかりそうです!

h2so5さんありがとうございました!

閉鎖

“C言語何でも質問掲示板” へ戻る