3Dホーミング弾の実装につまずいています。

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
KRNKRS
記事: 40
登録日時: 12年前
連絡を取る:

3Dホーミング弾の実装につまずいています。

#1

投稿記事 by KRNKRS » 11年前

こんにちは。

私は現在、3D空間における遅れて追従してくるタイプのホーミング弾の実装についてつまずいます。
いろいろと調べたり、自分なりに試行錯誤してみたのですが思うように行かず、こちらで質問させていただいた次第です。

以下ソースコードですが、注意すべきかもしれない点として、「Effekseer」をホーミング弾として用いています。

コード:

	//生成された各弾の移動処理
	for(int i=0; i<255; i++){		
		if(reimu.g_handleArray[i] != -1) {
			//ターゲットへのベクルを算出(仮目標:vec(0,25,0) - 今の座標)
			vecTarget[i] = VSub(VGet(0,25,0), VGet(reimu.g_Pos[i].x , reimu.g_Pos[i].y, reimu.g_Pos[i].z ));
			//弾の正面(進行方向)ベクトル
			vecForward[i] = VNorm(VGet(oldVector[i].x - reimu.g_Pos[i].x , oldVector[i].y - reimu.g_Pos[i].y, oldVector[i].z - reimu.g_Pos[i].z ));
			
			//ターゲットまでの角度
			float Seki = VDot(vecForward[i],vecTarget[i]);
			float Zetai = sqrt(VSquareSize(vecForward[i])) * sqrt(VSquareSize(vecTarget[i]));
			float angleDiff = acos(Seki/Zetai);
			//1秒間に回転させる角度
			float angleAdd = 60.0f * DX_PI / 180.0f;
			//回転させる度合い
			angle[i] = ( angleAdd / angleDiff );
			//進行方向ベクトルを算出
			goAngle[i] = angleDiff - angle[i];
			goVec[i] = VGet(cos(goAngle[i]), sin(goAngle[i]), tan(goAngle[i]));

			oldVector[i].x = reimu.g_Pos[i].x;
			oldVector[i].y = reimu.g_Pos[i].y;
			oldVector[i].z = reimu.g_Pos[i].z;

			//ターゲットへのベクトル直接(成功:ちゃんと目標地点に向かう)
			//reimu.g_Pos[i].x += vecTarget.x;
			//reimu.g_Pos[i].y += vecTarget.y;
			//reimu.g_Pos[i].z += vecTarget.z;

			//弾の進行方向ベクトル(成功?:その場から動かない。初速与えてないので当たり前かもしれない。)
			//reimu.g_Pos[i].x += vecForward.x;
			//reimu.g_Pos[i].y += vecForward.y;
			//reimu.g_Pos[i].z += vecForward.z;

			//追従計算後
			reimu.g_Pos[i].x += goVec[i].x;
			reimu.g_Pos[i].y += goVec[i].y;
			reimu.g_Pos[i].z += goVec[i].z;

			//座標指定
			g_manager->SetLocation( reimu.g_handleArray[i], ::Effekseer::Vector3D( reimu.g_Pos[i].x , reimu.g_Pos[i].y, reimu.g_Pos[i].z ) );
			//倍率指定
			if(reimu.Size[i] < 5.0f)reimu.Size[i] += 0.05f;
			g_manager->SetScale(reimu.g_handleArray[i],reimu.Size[i],reimu.Size[i],reimu.Size[i]);
		}
	}

どの点が誤っているのか助言をいただけないでしょうか?
よろしくお願いいたします。

KRNKRS
記事: 40
登録日時: 12年前
連絡を取る:

Re: 3Dホーミング弾の実装につまずいています。

#2

投稿記事 by KRNKRS » 11年前

すいません。
どのようにうまく行かないのか書いていませんでした。

本来期待する挙動は、もちろん少し遅れる感じに目標に向かって角度を変化させながら進行させるというものですが、上記のコードですと、全く見当違いの方向へ、しかもプルプル震えながら何処かに行ってしまうという状況です。

以上、追記でした。

アバター
usao
記事: 1889
登録日時: 12年前
連絡を取る:

Re: 3Dホーミング弾の実装につまずいています。

#3

投稿記事 by usao » 11年前

全体的に
何を計算してるのかがさっぱりわからないです.
ざっと読んだ感じ,以下のようです.


>line 7 : vecForward = ...
は,コメントから判断すると,引く方向が逆じゃないかと思うのですが,どうなんでしょう?
(あと,VNorm()というのが,単位ベクトルを得る関数なのだとすれば,
 後段で vecForwardの長さをわざわざ計算する必要は無いと思う)

>line12 : angleDiff = ...
ここは「現在位置→ターゲット」方向と,「現在の前進方向」との間の角度
を求めていると思いますが,これだけだとこの2つのベクトルで作られる平面上で
「どっち側に(例えば,右or左)」旋回すべきかはわからないと思いますが,その点は大丈夫なのでしょうか?

>line16 : angle = ...
ここから本格的に意味がわかりません.
例えば,angleDiffが「1度」だったら,この値は「60度」になる(実際の単位はラジアンだけど). で,

>line18 : goAngle = ...
が,今回回転すべき角度を出そうとしていると思うのですが,この例だと -59度になります.
(1度しか方向差が無いのに,そんなに回転すべきだろうか?)

最後に,この値を用いて,
>line19 : goVec = ...
line36~を見るに,これが実際の弾の移動量に相当するものと思われるのですが,
3次元空間上での自由な方向への旋回(による差分)がこんな式で得られるとは思えません.

アバター
usao
記事: 1889
登録日時: 12年前
連絡を取る:

Re: 3Dホーミング弾の実装につまずいています。

#4

投稿記事 by usao » 11年前

フレーム間での最大旋回角が小さい
(例えば最大でも30度とか45度だとかいう)場合であれば,
添付図のような解き方をすれば面倒が無くて良いかもしれません.

(プログラムの他所で 真面目な(?)3次元計算をしているなら
 そっちを共通で使った方が良いかと思いますが)
添付ファイル
クリップボード01.png

KRNKRS
記事: 40
登録日時: 12年前
連絡を取る:

Re: 3Dホーミング弾の実装につまずいています。

#5

投稿記事 by KRNKRS » 11年前

返信有難うございます。

未だ理解ができていない状況ですが、返信内容を頼りにもう少し試行錯誤してみようと思います。
ありがとうございました。

閉鎖

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