こんにちは、現在 Dxlib を用いて3Dゲームを作成しています。
その中であらかじめ指定した座標を任意点中心に回転し、図形を回転するプログラムを作成しています。そこで起きた問題です。
以下にコードの一部をはりますが、このコードではたまにベクトルが計算されず定義した値がそのまま出力される(もしくは、計算されているけれどアンダーフロー等で代入されてない?)ことが起こります。この計算されない現象を防ぐためにはどの部分をどのように訂正すればよいでしょうか。
環境はVS2017,Windows10です。
なお変数は すべて float型 です。
お力添えよろしくお願いします。
void Vector(VECTOR *V) { //原点中心にベクトル回転 *V = VTransform(*V, Matrix_hand_X); *V = VTransform(*V, Matrix_hand_Y); *V = VTransform(*V, Matrix_hand_Z); //平行移動 *V = VTransform(*V, Matrix_hand); } //angleから0を除外する if (Angle_G[0] == 0 || Angle_G[1] == 0 || Angle_G[2] == 0) { if (Angle_G[0] == 0) { angle_X= 0.0000000000000000000000001f; } if (Angle_G[1] == 0) { angle_Y = 0.0000000000000000000000001f; } if (Angle_G[2] == 0) { angle_Z = 0.0000000000000000000000001f; } } else { angle_X = Angle_G[0]; angle_Y = Angle_G[1]; angle_Z = Angle_G[2]; } /////////////////////////////////////////// //行列定義///////////////////////////////// Vect_stick_root = VGet(position_X, position_Y, -position_Z); //ここを中心に回転 //最初からstick_rootとの差を入れておくことで平行移動を1回減らす Vect_palm_joint1 = VGet(-55, 0, -205); Vect_palm_joint2 = VGet(55, 0, -205); Vect_palm_nail1 = VGet(-30, 0, -230); Vect_palm_nail2 = VGet(30, 0, -230); //たまにここで定義した値のまま出力される //平行移動行列 Matrix_hand = MGetTranslate(Vect_stick_root); //原点中心回転行列 Matrix_hand_X = MGetRotX(angle_X); Matrix_hand_Y = MGetRotY(angle_Y); Matrix_hand_Z = MGetRotZ(angle_Z); //////////////////////////////////////////// //種々の行列計算 Vector(&Vect_palm_joint1); Vector(&Vect_palm_joint2); Vector(&Vect_palm_nail1); Vector(&Vect_palm_nail2); //これらの計算結果がほしい
なぜfloatの必要が?doubleで最近のPCは問題ないと思います。オーバーフローとかそういう問題なら治るはずです。
Vect_palm_nail1は処理されているけど、Vect_palm_nail2は処理されてないんでしょうか? そもそも、angle0を嫌う理由がわからないんですが、なぜそんな処理が入っているんでしょう?
yukkuriさんへ Dxlibにおいて図形描画の座標指定はすべてfloat型で指定するという決まりがあります。ベクトルの計算結果をdoubleからfloatへ変更する際、丸め誤差がおきると考えfloat型で計算しようしています。
izmktrさんへ 紛らわしい記述ですみません。Vect_palm_nail2だけでなくすべてのベクトルに当てはまる問題です。コメントの位置が悪かったです。また、angle=0を嫌う理由ですがゲーム内にangleでの割り算が入る箇所がありセグメンテーション違反になるためです。
「たまに」って何ですか? 同じ回転角度を与えて計算させてもその時々で結果が異なるということですか? それとも,ある特定の回転角度を与えたときにだけ変化しないベクトルがあるということですか?
floatで0割りの場合は、結果がInfになるだけで、セグメンテーション違反は起こりません また、angleで割り算をする処理が思いつかないし、Lerpだとしたらこのコードでも問題があります
回答2件
あなたの回答
tips
プレビュー