質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

解決済

1回答

3158閲覧

クォータニオンの成分操作。

退会済みユーザー

退会済みユーザー

総合スコア0

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

0クリップ

投稿2019/08/22 16:00

編集2019/08/23 01:41

前提・実現したいこと

Unity標準アセットのFirstPersonCharacterのMouseLook.csにおいて、
クォータニオンの成分を処理して、おそらく角度制限していると思うのですが、
なぜこのような処理で角度制限できるのかわかりません。

・質問1。
下記のコードにおいて、
angleX = Mathf.Clamp (angleX, MinimumX, MaximumX);
の行以外、全てわからないのですが、なぜ角度制限ができてしまうのでしょうか?
q.xをq.wで割るという所から分からないです。

C#

1 Quaternion ClampRotationAroundXAxis(Quaternion q) 2 { 3 q.x /= q.w; 4 q.y /= q.w; 5 q.z /= q.w; 6 q.w = 1.0 f; 7 8 float angleX = 2.0 f * Mathf.Rad2Deg * Mathf.Atan (q.x); 9 10 angleX = Mathf.Clamp (angleX, MinimumX, MaximumX); 11 12 q.x = Mathf.Tan (0.5 f * Mathf.Deg2Rad * angleX); 13 14 return q; 15 }

・質問2。 
回転した後に、ClampRotationAroundXAxisで角度制限しているみたいですが、
角度制限はClampRotationAroundXAxisの内部処理のようにクォータニオンの成分に分けて処理しないと
角度制限できないのでしょうか?
他の方法があれば教えていただきたいです。
また、他の方法があったとしても、ClampRotationAroundXAxisのような方法で処理するメリットとかあるのでしょうか?

C#

1 float yRot = CrossPlatformInputManager.GetAxis("Mouse X") * XSensitivity; 2 float xRot = CrossPlatformInputManager.GetAxis("Mouse Y") * YSensitivity; 3 4 m_CharacterTargetRot *= Quaternion.Euler (0f, yRot, 0f); 5 m_CameraTargetRot *= Quaternion.Euler (-xRot, 0f, 0f); 6 7 if(clampVerticalRotation) 8 m_CameraTargetRot = ClampRotationAroundXAxis (m_CameraTargetRot);

試したこと

クォータニオンの成分に関しては全くわからなかったので、下記サイト等を調べました。

https://qiita.com/edo_m18/items/5db35b60112e281f840e
https://kamino.hatenablog.com/entry/rotation_expressions

下記のように分解されるのはわかりましたが、
(わかったというよりも丸暗記するしかないということで納得しましたが)

C#

1x=nxsin(θ/2) 2y=nysin(θ/2) 3z=nzsin(θ/2) 4w=cos(θ/2)

上記と下記の関連性がわかりません。下記は上記と無関係なのでしょうか?

q.x /= q.w; q.y /= q.w; q.z /= q.w; q.w = 1.0f;

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

x/z=nx sin(θ/2)/cos(θ/2)=nx tan(θ/2)

そうなると、以下の式はθを求めていることがわかります
float angleX = 2.f * Mathf.Rad2Deg * Mathf.Atan (q.x);

要は、クォータニオンを頑張ってオイラー角に変換しようとしているわけです。

transformからはeularAngleでオイラー角を持ってこれるけど、
Quaternion からは eularAngle がなぜかないので自力計算するしかないので求めている感じでしょう。

X軸回転は制限があるけどY軸回転に制限がない、というのは
クォータニオンにはX軸Y軸という概念がないので、苦手な部類になります

そこで、角度制限とは何か、というのを再定義する必要があります
角度制限というのは首振りの上下に対して制限を設け、真上を経由して逆向きにならないようにする措置です
もしそれが出来ると上下が逆転した状態で後ろを向いてしまい、操作が困難になるからです

逆向きになるのが悪い、ということは変換後の上方向のベクトルが
上方向に対して90度以上の角度になっていることです。
これを、水平0度方向に戻す必要があります

これ以降、デバッグしてないので、ちゃんと動くかわからないです
多分こんな感じになるかと

var nup = q * Vector3.up; var angle = Vector3.Angle(Vector3.up, nup); if (angle > 80f){ var revese = Quaternion.SetFromToRotation(nup, Vector3.up); var yzero = q * reverse; // 水平0度を示すQuaternion var limitq = Quaternion.Slerp(yzero, q, 80 / angle); // 80度に角度制限したQuaternion }

投稿2019/08/22 17:27

izmktr

総合スコア2856

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/08/23 02:44 編集

ご回答ありがとうございます。 teratail側のバグらしく、小数の桁が2.0f → 2.fの消えてしまっていたので、 無理矢理2.0 fのようにスペースを打って、表示するように質問のコードを修正しました。 ・質問1。  すみません、確認させていただきたいのですが、   Atan(tanθ)とすると、θが求まるということですか? ・質問2。 >x/z=nx sin(θ/2)/cos(θ/2)=nx tan(θ/2) こちら、 x/w=nx sin(θ/2)/cos(θ/2)=nx tan(θ/2) の書き間違いだったりしますか? ・質問3。 float angleX = 2.0 f * Mathf.Rad2Deg * Mathf.Atan (q.x); ここで、2.0fを掛けている理由ですが、θ/2だからでしょうか? ・質問4。 あとは、 q.x /= q.w; としたとき、そのバランスを保つために、 下記の処理を行っていると思うのですが、 これはどういった考えで、このような処理となるのでしょうか? q.y /= q.w; q.z /= q.w; q.w = 1.0f;
izmktr

2019/08/23 09:36

1. 概ねそうです 逆関数で調べてください 2. 書き間違いです 3. そうです 4. クォータニオン全体に1/q.wを掛けています q.wは必ず1.0になります このあと回転行列を作る時に補正されるという理屈なのでしょうが、行儀のいい方法とは言えません
退会済みユーザー

退会済みユーザー

2019/08/23 11:48

ご回答ありがとうございます。 4.に関して質問させていただきたいです。 >このあと回転行列を作る時に補正されるという理屈なのでしょうが、行儀のいい方法とは言えません ということを理解できていなくての質問になってしまうのですが (今回のコードでは回転行列を作ってないですよね?)、 クォータニオン全体に1/q.wを掛けているから、q.wは必ず1.0になるということでしょうか? それとも、クォータニオン全体に何を掛けてもq.wは必ず1.0になるということですか? また、上記どちらの場合でも、q.wは必ず1.0になることに関して、クォータニオンに関する説明サイトなどがあれば教えていただけませんか?
izmktr

2019/08/23 14:04

単純に、q.w * (1/q.w)=1 を意味しています このクォータニオンは正規化されていないため、行儀が悪いと書いています 正規化されていない、という部分がわかっていれば、回転行列云々の部分は大して重要でもないので忘れてください
退会済みユーザー

退会済みユーザー

2019/08/23 15:55

ご回答ありがとうございます。 勉強になりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問