1
\$\begingroup\$

I want to know the values of x, y, z satisfying the following.

float ax = 30;
float ay = 40;
float az = 50;

var rotation1 = Quaternion.Euler(ax, ay, az).eulerAngles;
var quaternion = Quaternion.identity;
quaternion = Quaternion.AngleAxis(x, Vector3.right) * quaternion;
quaternion = Quaternion.AngleAxis(y, Vector3.up) * quaternion;
quaternion = Quaternion.AngleAxis(z, Vector3.forward) * quaternion;
var rotation2 = quaternion.eulerAngles;

Assert.AreApproximatelyEqual(rotation1, rotation2);

ax, ay, az can be arbitrary value. Unity's operation between quaternion and euler angle (Vector3) seems to rotate by Z axis first, so I think x, y, z won't be equal to ax, ay, az.

How can I derive x, y, z?

New contributor
jeiea is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

I managed to write the code I need with the reference.

public static Vector3 ToXyz(Quaternion q) {
  var angles = new Vector3();

  // roll / x
  double sinr_cosp = 2 * (q.w * q.x + q.y * q.z);
  double cosr_cosp = 1 - 2 * (q.x * q.x + q.y * q.y);
  angles.x = (float)Math.Atan2(sinr_cosp, cosr_cosp);

  // pitch / y
  float sinp = 2 * (q.w * q.y - q.z * q.x);
  if (Math.Abs(sinp) >= 1) {
    angles.y = (float)((sinp < 0 ? -1 : 1) * Math.PI / 2);
  } else {
    angles.y = (float)Math.Asin(sinp);
  }

  // yaw / z
  double siny_cosp = 2 * (q.w * q.z + q.x * q.y);
  double cosy_cosp = 1 - 2 * (q.y * q.y + q.z * q.z);
  angles.z = (float)Math.Atan2(siny_cosp, cosy_cosp);

  return angles * 180 / (float)Math.PI;
}
New contributor
jeiea is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .