How to create yzx-euler by two vectors?

i want to make quaternion or euler that beforeVector rotate to AfterVector
so, i make a function that create euler with two Vectors.
but it doesn’t work properly
What can I fix here? or Any other solution?

function getEulerYZX(prevVector, nextVector) {
  prevVector = prevVector.clone().normalize();
  nextVector = nextVector.clone().normalize();

  const yRad = Math.atan2(
    nextVector.x - prevVector.x,
    nextVector.z - prevVector.z
  ); //zx 평면 회전

  const yRotatedVector = prevVector.clone();
  yRotatedVector.z =
    prevVector.z * Math.cos(yRad) - prevVector.x * Math.sin(yRad);
  yRotatedVector.x =
    prevVector.z * Math.sin(yRad) + prevVector.x * Math.cos(yRad);

  const zRad = Math.atan2(
    nextVector.y - yRotatedVector.y,
    nextVector.x - yRotatedVector.x
  );

  const yzRotatedVector = yRotatedVector.clone();
  yzRotatedVector.x =
    yRotatedVector.x * Math.cos(zRad) - yRotatedVector.y * Math.sin(zRad);
  yzRotatedVector.y =
    yRotatedVector.x * Math.sin(zRad) + yRotatedVector.y * Math.cos(zRad);

  const xRad = Math.atan2(
    nextVector.z - yzRotatedVector.z,
    nextVector.y - yzRotatedVector.y
  );

  const yzxRotatedVector = yzRotatedVector.clone();
  yzxRotatedVector.y =
    yzRotatedVector.z * Math.cos(xRad) - yzRotatedVector.y * Math.sin(xRad);
  yzxRotatedVector.z =
    yzRotatedVector.z * Math.sin(xRad) + yzRotatedVector.y * Math.cos(xRad);

  return new THREE.Euler(xRad, yRad, zRad, "YZX");
}

If you want to create a quaternion to rotate from one vector to another, you can use setFromUnitVectors, there is also setFromEuler function available in THREE.

1 Like

thank you!

I looked through the documentation and forums with my short English skills.
I was struggling because I couldn’t find the right way.

But thanks to you, I can find a better way.

I have another question, there is a vector function that returns the angle between two vectors. Vector3.angleTo

But this [0, PI /2]
Is there any function that can return the angle between [0, 2*PI]?


just i made it

/**
 * Get the angle needed to move from the vFrom vector in the direction of the vTo vector in radians. [0, 2PI)
 *
 * vFrom and vTo are assumed to be normalized.
 * @param {THREE.Vector3} vFrom
 * @param {THREE.Vector3} vTo
 *
 * @returns {number}
 */
export function getAngleFromUnitVectors(vFrom, vTo) {
  const cosA = vFrom.dot(vTo);
  const sinA = vFrom.clone().cross(vTo).length();
  const angle = Math.atan2(cosA, sinA);
  return angle < 0 ? 2 * Math.PI - angle : angle;
}

1 Like