0

I have a three.js quaternion and would like to get the axis and angle representation of it. Is this possible in three.js or do I have to do this:

export function getAxisAndAngelFromQuaternion(q: Quaternion) {
  const axis = [0, 0, 0];
  const angle = 2 * Math.acos(q.w);
  if (1 - q.w * q.w < 0.000001) {
    // test to avoid divide by zero, s is always positive due to sqrt
    // if s close to zero then direction of axis not important
    axis[0] = q.x;
    axis[1] = q.y;
    axis[2] = q.z;
  } else {
    // http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/
    const s = Math.sqrt(1 - q.w * q.w);
    axis[0] = q.x / s;
    axis[1] = q.y / s;
    axis[2] = q.z / s;
  }
  return { axis: new Vector3().fromArray(axis), angle };
}
M -
  • 26,908
  • 11
  • 49
  • 81
nickponline
  • 25,354
  • 32
  • 99
  • 167
  • I think what you want is represented in three.js as an Euler (https://threejs.org/docs/#api/en/math/Euler), you can set the euler angle from quaternion with the method `setFromQuaternion` – Nephelococcygia Jun 18 '20 at 22:19
  • Three.js Quaternion only has a [.setFromAxisAngle()](https://threejs.org/docs/#api/en/math/Quaternion.setFromAxisAngle) method but it doesn't have what you want. I think your solution is pretty elegant, the only thing I'd change is instead of checking `< 0.000001`, I'd do `< Number.EPSILON`, which is the smallest fraction possible in a JS number variable. – M - Jun 18 '20 at 23:16
  • See the docs: [Vector4.setAxisAngleFromQuaternion](https://threejs.org/docs/?q=vector4#api/en/math/Vector4.setAxisAngleFromQuaternion). – WestLangley Nov 01 '21 at 20:50

1 Answers1

4

Is this in a pre-javascript code -- "export"? "q: Quaternion"?
Anyway, it's a relatively simple algorithm. A simplifying suggestion:

function getAxisAndAngelFromQuaternion(q) {
  const angle = 2 * Math.acos(q.w);
  var s;
  if (1 - q.w * q.w < 0.000001) {
    // test to avoid divide by zero, s is always positive due to sqrt
    // if s close to zero then direction of axis not important
    // http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/
    s = 1;
  } else { 
    s = Math.sqrt(1 - q.w * q.w);
  }
  return { axis: new Vector3(q.x/s, q.y/s, q.z/s), angle };
}
dcromley
  • 1,373
  • 1
  • 8
  • 23
  • 2
    `q: Quaternion` is [TypeScript](https://en.wikipedia.org/wiki/TypeScript). It's like an add-on to JavaScript where you can specify the type of the variables you use. – M - Jun 18 '20 at 23:10