Home>

### c # - [unity] tell me about the conversion of rotation information in different coordinate systems

I am always studying. I don't know what to do with Unity (rather than dealing with 3D space in general)
Since there was a point, let me ask a question.

There are different local coordinate systems A and B, and objects P and Q with the same global coordinates are children of A and B, respectively.
I want to move Q by applying rotation Y in the local coordinate system of B to the place where I moved by applying rotation X in the local coordinate system of A
thinking about. I would like to obtain a result where P and Q are in the same place in the global coordinate system.

Please tell me how to find the rotation Y.

Specific examples

・ New scene
-Create EmptyObject A in the global coordinate system. Globalrotation (also local) is (12,34,56)
-Create EmptyObject B in the global coordinate system (globalrotation (local is also) is (78,90,12)
・ EmptyObject P and Q are created in the global coordinate system globalposition (also local) is (3.4, 5.6, 7.8)
-Move P to A child and Q to B child on Hierarchy

* Each coordinate is appropriate.

Applicable source code

In the situation above,

``````Transform P = GameOjbect.Find ("P"). GetComponent&lt;Transform&gt;();
Transform Q = GameOjbect.Find ("Q"). GetComponent&lt;Transform&gt;();
P.localPosition = Quaternion.Euler (12,34,56) * P.localPosition;
Q.localPosition = ?????????????????????????? * Q.localPosition;
#as a result
P.Position == I want to match the global coordinate value with Q.Position
In this case, how can I find the above ?????????????``````
Tried

I tried various things using Quaternion.Inverse etc., but because I have little mathematical knowledge and no experience value
I didn't get the answer I wanted.

・ Points to consider when solving these problems
・ Points to be careful

If i have

etc., I would appreciate it if you could teach me.

Supplemental information (FW/tool version etc.)

Unity2018.2
C #

``````using UnityEngine;
public class PQRotator: MonoBehaviour
{
private void Start ()
{
Transform P = GameObject.Find ("P"). GetComponent<Transform>();
Transform Q = GameObject.Find ("Q"). GetComponent<Transform>();
Transform A = GameObject.Find ("A"). GetComponent<Transform>();
Transform B = GameObject.Find ("B"). GetComponent<Transform>();
A.position = Vector3.zero;
A.localScale = Vector3.one;
A.eulerAngles = new Vector3 (12, 34, 56);
// Global coordinates of P and Q in the initial state
Vector3 OG = new Vector3 (3.4f, 5.6f, 7.8f);
P.SetParent (A);
P.position = OG;
B.position = Vector3.zero;
B.localScale = Vector3.one;
B.eulerAngles = new Vector3 (78, 90, 12);
Q.SetParent (B);
Q.position = OG;
// Close the eyes for some calculation errors, and the following four coordinates should all indicate OG ... (3.4, 5.6, 7.8)
Debug.LogFormat ("P world coordinates: {0}", P.position.ToString ("F6"));
Debug.LogFormat ("A rotation * P local coordinates: {0}", (A.rotation * P.localPosition) .ToString ("F6"));
Debug.LogFormat ("Q world coordinates: {0}", Q.position.ToString ("F6"));
Debug.LogFormat ("B rotation * Q local coordinates: {0}", (B.rotation * Q.localPosition) .ToString ("F6"));
// Below, "==" in the comment should be considered to mean that the calculation error is allowed to match
// P.position == A.rotation * P.localPosition, so if you apply A reverse rotation from the left side to both sides
// Quaternion.Inverse (A.rotation) * P.Position == Quaternion.Inverse (A.rotation) * A.rotation * P.localPosition
// Because the forward and reverse rotations on the right side cancel each other and become Quaternion.identity
// Quaternion.Inverse (A.rotation) * P.position == P.localPosition
// In other words, P.localPosition == Quaternion.Inverse (A.rotation) * OG ... ①
// Also for Q, Quaternion.Inverse (B.rotation) * Q.position == Q.localPosition
// In other words, Q.localPosition == Quaternion.Inverse (B.rotation) * OG ... ②
// rotation to apply to local coordinates of P
Quaternion RP = Quaternion.Euler (12, 34, 56);
// new local coordinates of P
Vector3 NewPL = RP * P.localPosition;
// new global coordinates of P
Vector3 NewPG = A.rotation * NewPL;
// RQ is the rotation to be applied to the local coordinates of Q, NewQL is the new local coordinate obtained by applying the rotation// If the new global coordinates are NewQG, we want NewQG == NewPG
// NewQG == B.rotation * NewQL == NewPG == A.rotation * NewPL
// NewPL = RP * P.localPosition, NewQL == RQ * Q.localPosition
// B.rotation * RQ * Q.localPosition == A.rotation * RP * P.localPosition
// Now, apply B reverse rotation from the left side to both sides and delete B.rotation on the left side
// RQ * Q.localPosition == Quaternion.Inverse (B.rotation) * A.rotation * RP * P.localPosition
// Furthermore, substituting ① and ② shown above into the above formula
// RQ * Quaternion.Inverse (B.rotation) * OG == Quaternion.Inverse (B.rotation) * A.rotation * RP * Quaternion.Inverse (A.rotation) * OG
// Next, if both sides are forward rotated B from the right side and Quaternion.Inverse (B.rotation) on the left side disappears
// RQ * OG == Quaternion.Inverse (B.rotation) * A.rotation * RP * Quaternion.Inverse (A.rotation) * B.rotation * OG
// Now the Vector3 factors on both sides are both OG and can be deleted
// RQ == Quaternion.Inverse (B.rotation) * A.rotation * RP * Quaternion.Inverse (A.rotation) * B.rotation ... ③
// By the way, the above expression Quaternion.Inverse (B.rotation) * A.rotation and Quaternion.Inverse (A.rotation) * B.rotation is
// The two rotations are reverse rotations, and the rotation order is reversed, so they are in a reverse rotation relationship with each other
// So, RBiA is a combination of B reverse rotation and A forward rotation
Quaternion RBiA = Quaternion.Inverse (B.rotation) * A.rotation;
// Rotation combining A reverse rotation and B forward rotation is reverse rotation of RBiA ... Quaternion.Inverse (RBiA)
// Substituting these into ③ makes the formula clear
Quaternion RQ = RBiA * RP * Quaternion.Inverse (RBiA);
// So Q's new local coordinates are
Vector3 NewQL = RQ * Q.localPosition;
// Apply the calculated rotation and check the result
Debug.Log ("----------------");
Debug.LogFormat ("Old P local coordinates: {0}", P.localPosition.ToString ("F6"));
Debug.LogFormat ("Old P global coordinates: {0}", P.position.ToString ("F6"));
Debug.LogFormat ("P rotation applied to local coordinates: {0}", RP.eulerAngles.ToString ("F6"));
P.localPosition = RP * P.localPosition;
Debug.LogFormat ("New P local coordinates: {0}", P.localPosition.ToString ("F6"));
Debug.LogFormat ("New P global coordinates: {0}", P.position.ToString ("F6"));
Debug.Log ("----------------");
Debug.LogFormat ("Old Q local coordinates: {0}", Q.localPosition.ToString ("F6"));
Debug.LogFormat ("Old Q global coordinates: {0}", Q.position.ToString ("F6"));
Debug.LogFormat ("Rotation applied to Q local coordinates: {0}", RQ.eulerAngles.ToString ("F6"));
Q.localPosition = RQ * Q.localPosition;
Debug.LogFormat ("New Q local coordinate: {0}", Q.localPosition.ToString ("F6"));
Debug.LogFormat ("New Q global coordinates: {0}", Q.position.ToString ("F6"));
}
}``````

Are you doing well? Although there are some errors, I think they will generally agree. It looks like a math problem and is interesting.

Note that the order of multiplication of quaternion-type factors is noncommutative, so when transforming the equation, when multiplying both sides with quaternions, if the left side is from the right, the right side is also from the right, left Will it be from the left ... from the left?