# Houdini's matrices and extracting trans,rot,scale

## Recommended Posts

Hi there,

I'm puzzled about the correct way to extract the translation, rotation and scale vectors from a matrix in Houdini. I can't find any examples but I thought for sure this would work:

```current_input_xform =(UT_DMatrix4&amp;)foo_node-&gt;getWorldTransform(context);
int foo2 = current_input_xform.explode(xformOrder, rot, scale, trans);
current_input_xform.getTranslates(trans);```

It appears that the translation and scale vectors return with good data, but the rotation is a whole 'nother story!

Would some kind soul please point out what I've missed?

Thanks!

--Mark

##### Share on other sites

Wooops, I meant to say:

```current_input_xform =(UT_DMatrix4&amp;)foo_node-&gt;getWorldTransform(context);

int foo2 = current_input_xform.explode(xformOrder, rot, scale, trans);
***OR***
current_input_xform.getTranslates(trans);```

I know the rotation values returned are in radians, but what happens is that when I enter various values in the object's rotation fields, and then examine them using the code I sent they often don't match. For example, here's a bunch rotation x,y,z values entered into the GUI followed by the values returned from explode():

45 0 0

rot.x: 45.0000012463633 rot.y: 0 rot.z: 0

90 0 0

rot.x: 90.00000249272661 rot.y: 0 rot.z: 0

91 0 0

rot.x: -269.000006312118 rot.y: 0 rot.z: 0

181 0 0 rot.x: -178.9999969892022 rot.y: 0 rot.z: 0

90 0 90

rot.x: 90.00000249272661 rot.y: 0 rot.z: 90.00000249272661

90 90 0

rot.x: 0 rot.y: 90.00000249272661 rot.z: -90.00000249272661

90 180 0

rot.x: 90.00000249272661 rot.y: 0 rot.z: 90.00000249272661

Freaky ....

--Mark

##### Share on other sites

I think these values are ok. The reason why you don't get integer values are those nasty roundoff errors of floating point arithmetic. And extracting the rotation values from a matrix involves quite some computations (e.g. atan, asin).

But I think you are wondering more about the fact, that feeding in a rotation of 90 90 0 leads to a rotation of 0 90 -90. This isn't an error either. The space of eulerian angles does not have a one-to-one correspondence to the space of rotations. You can always find different sets of euler angles, that describe the same orientation (and thus the same matrix). So, if you describe it mathematically: the set of euler angles is surjective to the set of rotations.

A little bit more concrete:

The transform matrix looks like this (Dependent on the rotation order):

```h: head
p: pitch
r: roll
M=Euler(h,p,r) = Rz(r)*Rx(p)*Ry(h)
(m00 m01 m02)   (cos(r)*cos(h)-sin(r)*sin(p)*sin(h)   -sin(r)*...    ... )
M=(m10 m11 m12) = (sin(r)*cos(h)+cos(r)*sin(p)*sin(h)    cos(r)*...    ... )
(m20 m21 m22)   (            -cos(p)*sin(h)               sin(p)     ... )```

In this matrix m21 is simply sin(p). In order to compute the pitch on has p = asin(m21)

Assume you have specified a rotation of 0 150 0

The pitch value of 150 degrees leads to m21=0.5 But asin(0.5) would result in 30 degrees, which is (for this one dimensional sub-problem) just as right as the "proper" solution 150 degrees.

After the pitch had been set to 30 degrees, the head and roll must be computed. They can be computed by

```h=atan2(-m20, m22)
r=atan2(-m01, m11)```

This lead to a reconstructed solution of 180 30 180. It is quite as correct as 0 150 0, because both transformations specify the same rotation.

##### Share on other sites

Hi Frank!

I had no idea the angles returned from UT_DMatrix4::explode() would return Euler angles! Thanks for the tip! I've got a bit of research to do because I don't fully understand the correct way to do the conversion; your explanation is helpful, I appreciate it, but it's not completely sinking in yet.

Could you provide an example of the conversion required to do when rotation values are returned from explode()? (Maybe it's already in your reply but I'm not seeing it).

One other problem I ran into was that my XFormOrder was incorrect! I fixed that (and it does help) but now I need to deal with the Euler conversion ... oh how I'd love to go back to school ... :-)

--Mark

##### Share on other sites

I had no idea the angles returned from UT_DMatrix4::explode() would return Euler angles!  Thanks for the tip!  I've got a bit of research to do because I don't fully understand the correct way to do the conversion; your explanation is helpful, I appreciate it, but it's not completely sinking in yet.

14599[/snapback]

Hi Mark,

Euler angles are the same angles you know and love (and love to hate ) that you use every day. It is a way of expressing an orientation through three separate rotations (or as many rotations as there are dimensions) -- one for X, another for Y, and one last one for Z. This is exactly how you represent an orientation when you enter those values in the XYZ rotation channels. Quaternions, on the other hand, use a different method for representing an orientation.

Trouble is, that these puppies are not unique! This is what Frank was explaining. There are an infinite number of representations for any given Euler orientation (if you take into account that any angle can be expressed as any one of an infinite number of multiples of 360 degrees). Add to this the fact that by the time they get encoded into a matrix, you're no longer dealing with angles, but with the sine, cosine, and tangent of these angles -- and even these are just *implicit* since all you really have by then is just a single number (per matrix cell)!

So now imagine that *you* are the explode() function. And imagine I come along and say "Hey; I've got 9 numbers here..." (the linear part -- upper 3X3 block-- of the full xform matrix) "... and I was wondering... could you tell me what numbers the user entered in those XYZ rotation channels?.... please?"

You can see the problem... :cry2:

You can try to be very smart about it and try very hard to come up with the simplest possible combination of rotations that would give you those numbers, but ultimately, it's just a "best guess" -- chances are good that they won't match what the user entered.

 Just to clarify: they *will* match the orientation, but not necessarily the individual rotations -- IOW they will be equivalent, but not necessarily *identical*[/edit]

Every one of the examples you posted (with the exception of the last one, which I imagine is a typo) are equivalent ways of expressing the *same* rotation.

In short: there's really no way to consistently get the *exact* numbers that the user entered for rotations.

Does that make any sense?

Cheers!

##### Share on other sites

Does that make any sense?

Yes, it's making more sense now (though it's not concrete quite yet).

Thanks for helping out so much (and Frank too!), I really appreciate it!!!

--Mark

## Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

×   Pasted as rich text.   Paste as plain text instead

Only 75 emoji are allowed.

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×