ページ 11

行列で移動させた後の座標の習得

Posted: 2012年12月28日(金) 22:53
by マサヒコ
ほんとに件名のとおりなんですが、
DXライブラリで行列を使って移動させたあとのモデルの座標を知るにはどうすればいいのでしょうか?

コード:

//MPos モデルの座標
void Target::Roll(int Pad)
{
	//-----左右回転-----//
	//R1を押したら
	if((Pad & PAD_INPUT_6) && !(Pad & PAD_INPUT_5)){
		//回転させる角度を右へ(+)
		Angle = DX_PI_F/180.0f;
	}
	//L1を押したら
	if((Pad & PAD_INPUT_5) && !(Pad & PAD_INPUT_6)){
		//回転させる角度を左へ(-)
		Angle = DX_PI_F/-180.0f;
	}
	//どっちも押されてたら
	if((Pad & PAD_INPUT_6) && (Pad & PAD_INPUT_5)){
		Angle = 0;
	}
	//どっちも押されてなければ
	if(!(Pad & PAD_INPUT_6) && !(Pad & PAD_INPUT_5)){
		Angle = 0;
	}

	ModelAngle = ModelAngle + Angle;
	//モデルの角度が360ならゼロに戻す
	if((ModelAngle == DX_PI_F*2) || (ModelAngle == -DX_PI_F*2)){
		ModelAngle=0;
	}
	m1 = MGetRotY(ModelAngle);//回転
	m2 = MGetTranslate(MPos);//平行移動
	m3 = MMult(m2,m1);//行列を掛け合わす
	MV1SetMatrix(MHandle,m3);//行列をモデルに設定

こんな感じにプログラミングするとモデルは原点を中心に常に原点に一方向を見せながらMPos分離れて回ります。
(ちょうど地球を中心に回る月みたいな感じです)
ここで回転するということは座標が変化してるわけですが、その変化した後のワールド座標を知りたいのです。
行列で計算して出すのならどんな計算をすればいいのか知りたいです。

よろしくお願いします。

環境  Windows7 Visual Studio2008 C++ DXライブラリ

Re: 行列で移動させた後の座標の習得

Posted: 2012年12月28日(金) 23:18
by softya(ソフト屋)
元の座標に対して、ベクトルを演算すれば求めることはできます。
「DXライブラリ置き場 3D関係関数リファレンスページ」
http://homepage2.nifty.com/natupaji/DxL ... tml#R11N12

Re: 行列で移動させた後の座標の習得

Posted: 2012年12月29日(土) 07:58
by 史上最悪のデスペナ
単純にMV1GetPositionという関数を使うのも手ですよ

Re: 行列で移動させた後の座標の習得

Posted: 2012年12月29日(土) 12:03
by softya(ソフト屋)
あれ? マトリクスで移動させた座標をMV1GetPositionで得られましたっけ?

Re: 行列で移動させた後の座標の習得

Posted: 2012年12月29日(土) 12:51
by 史上最悪のデスペナ
済みません、今チェックしてきましたができませんでした

別の問題ですが

Posted: 2012年12月29日(土) 20:13
by マサヒコ
>>softya(ソフト屋)さん
便利な関数があるとわ…。リファレンス読みなおして勉強してきます。
>>史上最悪のデスペナさん
検証ありがとうございます。

ところで違った問題なんですが回転に関して変な動きをしてしまっているので原因が分かる人いましたらアドバイス貰いたいです。
他にトピック立てたほうがいいでしょうか?

コード:

//JikiPos 自機(回転の中心)の座標
//MPos 回転したいモデルの座標
//=====自機を中心にした左右回転=====//
void Target::Roll(int Pad,VECTOR JikiPos){

	//R1を押したら
	if((Pad & PAD_INPUT_6) && !(Pad & PAD_INPUT_5)){
		//回転させる角度を右へ(-)
		Angle = DX_PI_F/-60.0f;
	}
	//L1を押したら
	if((Pad & PAD_INPUT_5) && !(Pad & PAD_INPUT_6)){
		//回転させる角度を左へ(+)
		Angle = DX_PI_F/60.0f;
	}
	//どっちも押されてたら
	if((Pad & PAD_INPUT_6) && (Pad & PAD_INPUT_5)){
		Angle = 0;
	}
	//どっちも押されてなければ
	if(!(Pad & PAD_INPUT_6) && !(Pad & PAD_INPUT_5)){
		Angle = 0;
	}

	//座標を計算
	//AD = bx-ax
	//BD = by-ay
	//cx = AD*cosθ -BD*sinθ +ax
	//cy = AD*sinθ +BD*cosθ +ay

	MPos.x = (MPos.x-JikiPos.x)*cos(Angle)- (MPos.z-JikiPos.z)*sin(Angle) +JikiPos.x;
	MPos.z = (MPos.x-JikiPos.x)*sin(Angle)+ (MPos.z-JikiPos.z)*cos(Angle) +JikiPos.z;

        //座標をセット
	MV1SetPosition(MHandle,MPos);
}

こうすると自機を中心にモデルが回転してくれるのですがずっと回転していると自機(中心)にモデルが近寄ってきてしまいます。
どこが原因で起こっているのでしょうか?

Re: 行列で移動させた後の座標の習得

Posted: 2012年12月29日(土) 21:19
by マサヒコ
すみません。自己解決しました。
計算方法を変えるたら近寄らなくなりました。
なぜだかはよくわかりませんがよしということで。
ありがとうございました。

コード:

//Kyori モデルと自機の距離
//=====自機を中心にした左右回転=====//
void Target::Roll(int Pad,VECTOR JikiPos){
	//座標を計算しやすいものに変換
	Jx = JikiPos.x;
	Jz = JikiPos.z;
	Tx = MPos.x;
	Tz = MPos.z;
	//自機とモデルの距離を計算
	Kyori = pow((Jx-Tx),2) + pow((Jz-Tz),2);
	Kyori = sqrt(Kyori);

	//R1を押したら
	if((Pad & PAD_INPUT_6) && !(Pad & PAD_INPUT_5)){
		//回転させる角度を右へ(-)
		Angle = DX_PI_F/-60.0f;
	}
	//L1を押したら
	if((Pad & PAD_INPUT_5) && !(Pad & PAD_INPUT_6)){
		//回転させる角度を左へ(+)
		Angle = DX_PI_F/60.0f;
	}
	//どっちも押されてたら
	if((Pad & PAD_INPUT_6) && (Pad & PAD_INPUT_5)){
		Angle = 0;
	}
	//どっちも押されてなければ
	if(!(Pad & PAD_INPUT_6) && !(Pad & PAD_INPUT_5)){
		Angle = 0;
	}
	
	//角度を計算
	ModelAngle = ModelAngle + Angle;
	//モデルの角度が360ならゼロに戻す
	if((ModelAngle == DX_PI_F*2) || (ModelAngle == -DX_PI_F*2)){
		ModelAngle=0;
	}
	//座標を計算
	Tx = Kyori*cos(ModelAngle) + Jx;
	Tz = Kyori*sin(ModelAngle) + Jz;

	//座標をセット
	MPos.x = Tx;
	MPos.z = Tz;
	MV1SetPosition(MHandle,MPos);

Re: 行列で移動させた後の座標の習得

Posted: 2012年12月29日(土) 21:42
by softya(ソフト屋)
最初のは、一言で言えば計算誤差の累積だと思います。

Re: 行列で移動させた後の座標の習得

Posted: 2012年12月29日(土) 22:46
by マサヒコ
そうなると自分には修正は難しそうです。
精度の良さまで考えてプログラミングできるような実力はないです。
また、これから先の課題になりそうです。
ありがとうございまいた。