Euler angles from two sets of N and up

   1231   5   0
User Avatar
Member
76 posts
Joined: Jan. 2015
Offline
I have two polys at some odd angle to each other. Each point on either poly has N and up vectors.
From these two sets (source and target) of N and up vectors, in vex, how do I compute the Euler
angles to transform the source poly to the target? What I have doesn't seem to work:

matrix3 m1=ident();
matrix3 m2=ident();
m1=maketransform(vector(point(0,"N",0)),vector(point(0,"up",0))); // source poly
m2=maketransform(vector(point(1,"N",0)),vector(point(1,"up",0))); // target poly
vector4 orient1=quaternion(m1);
vector4 orient2=quaternion(m2);
vector rad=quaterniontoeuler(orient2-orient1,XFORM_XYZ);
// convert to degrees etc
Edited by element33 - Dec. 13, 2023 11:47:45
User Avatar
Member
373 posts
Joined: June 2023
Offline
I feel you have some misunderstanding about what quaternions are.

Correct way to compute the rotation between two rotation matrices is like this. We assume m1 and m2 are both 4x4 matrices:

4@xform = invert(m1) * m2;
vector4 orient = quaternion(set(4@xform));
vector angleaxis = qconvert(orient);
v@axis = normalize(angleaxis);
@angle = degrees(length(angleaxis));

Or:

vector4 orient1 = quaternion(m1);
vector4 orient2 = quaternion(m2);
vector4 orient = qmultiply(orient2, qinvert(orient1)); // Note the order is reversed
vector angleaxis = qconvert(orient); 
v@axis = normalize(angleaxis);
@angle = degrees(length(angleaxis));

You can't just do orient2 - orient1. It would just substract the vector4 element by element, but quaternion rotation is a totally different beast.
Edited by kodra - Dec. 13, 2023 16:01:06
User Avatar
Member
76 posts
Joined: Jan. 2015
Offline
kodra
You can't just do orient2 - orient1. It would just substract the vector4 element by element, but quaternion rotation is a totally different beast.

Thanks, will try this.
User Avatar
Member
76 posts
Joined: Jan. 2015
Offline
kodra
4@xform = invert(m1) * m2;
vector4 orient = quaternion(set(4@xform));

I still can't get it right. Based on my original and your first snippet, I'm trying to get
the 3 Euler angles, but they don't look right. I tried other X, Y, Z combinations, but none works.

4@xform=invert(m1)*m2;
vector4 orient=quaternion(set(4@xform));
vector rad=quaterniontoeuler(orient,0);
v@rot=degrees(rad);
Edited by element33 - Dec. 14, 2023 01:09:23
User Avatar
Member
373 posts
Joined: June 2023
Offline
Check this sample file:

Attachments:
rotation_between.hiplc (82.6 KB)
Screenshot 2023-12-14 160144.png (107.0 KB)

User Avatar
Member
4715 posts
Joined: Feb. 2012
Offline
Hi,

You can also use the cracktransform function:
https://www.sidefx.com/docs/houdini/vex/functions/cracktransform.html [www.sidefx.com]

vector normal0 = normalize ( primuv ( 0, "N", @primnum, 0.5 ) );
vector normal1 = normalize ( primuv ( 1, "N", @primnum, 0.5 ) );

matrix M0 = maketransform ( normalize ( v@up ), normal0 );
matrix M1 = maketransform ( normalize ( v@opinput1_up ), normal1 );
matrix M2 = invert ( M0 ) * M1;

vector angles = cracktransform ( 0, 0, 1, 0, M2 );
v@angles = angles;

Senior FX TD @ Industrial Light & Magic
Get to the NEXT level in Houdini & VEX with Pragmatic VEX! [www.pragmatic-vfx.com]

youtube.com/@pragmaticvfx | patreon.com/animatrix | pragmaticvfx.gumroad.com
  • Quick Links