Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

308
Views
Updating an intrinsic rotation with an extrinsic rotation

I am trying to model a Rubik's Cube for a personal project, using Zdog for lightweight 3d graphics. Zdog uses a {x,y,z} vector to represent rotation - I believe this is essentially a Tait-Bryan angle.

To animate a rotation of the top, right, front, etc side, I attach the 9 blocks to an anchor in the center of the cube and rotate it 90 degrees in the desired direction. This works great, but when the animation is done I need to "save" the translation and rotation on the 9 blocks. Translation is relatively simple, but I'm stuck on rotation. I basically need a function like this:

function updateRotation(xyz, axis, angle) {
  // xyz is a {x,y,z} vector
  // axis is "x", "y", or "z"
  // rotation is the angle of rotation in radians
}

that would apply the axis/angle rotation in world coordinates to the xyz vector in object coordinates. Originally I just had xyz[axis] += angle, but this only works when no other axis has any rotation. I then thought I could use a lookup table, and I think that's possible as I only use quarter turns, but constructing the table turns out to be harder than I thought.

I am starting to suspect I need to translate the xyz vector to some other representation (matrix? quaternion?) and apply the rotation there, but I'm not sure where to start. The frustrating thing is that my blocks are in the right position at the end of the animation - I'm just not sure how to apply the parent transform so that I can detach them from the parent without losing the rotation.

about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

As far as I can tell, this can't be done with Euler angles alone (at least not in any easy way). My solution was to convert to quaternions, rotate, then convert back to Euler:

function updateRotation(obj, axis, rotation) {
  const {x, y, z} = obj.rotate;
  
  const q = new Quaternion()
    .rotateZ(z)
    .rotateY(y)
    .rotateX(x);
  
  const q2 = new Quaternion();
  if (axis === 'x') {
    q2.rotateX(rotation);
  } else if (axis === 'y') {
    q2.rotateY(rotation);
  } else if (axis === 'z') {
    q2.rotateZ(rotation);
  }
  
  q.multiply(q2, null);

  const e = new Euler().fromQuaternion(q);
  
  obj.rotate.x = e.x;
  obj.rotate.y = e.y;
  obj.rotate.z = e.z;
  obj.normalizeRotate();
}

This uses the Euler and Quaternion classes from math.gl.

(It turned out Zdog actually uses ZYX Euler angles as far as I could tell, hence the order of rotations when creating the first quaternion.)

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!