Error in the mathutils RotationPart() function

Scripting in Blender with Python, and working on the API

Moderators: jesterKing, stiv

Post Reply
xand
Posts: 33
Joined: Wed Oct 16, 2002 9:46 am

Error in the mathutils RotationPart() function

Post by xand »

the rotationPart() function of the class in matrix in the mathutils module gives a inexact result. the rotation matrix given is multiplied by the size of the object.
print the rotation matrix of an object with size 1, then with size 2 and finally with differents sizes along each axis, they should not be different.

i don't try other function.


+++

Warvis
Posts: 0
Joined: Wed Jul 28, 2004 12:24 am

Post by Warvis »

I think this is not really a bug:
The part that is returned by the rotationPart() method holds the values the for the overall transformation, which is rotation _and_ scaling.

The resulting rotation ist still correct (i.e. Euler rotation).
Last edited by Warvis on Wed Jul 28, 2004 8:47 am, edited 1 time in total.

ascotan
Posts: 0
Joined: Thu May 29, 2003 10:32 pm
Location: Maryland, U.S.

Post by ascotan »

I don't understand what your saying. Could you be more descriptive? Maybe an exampe would help.

Warvis
Posts: 0
Joined: Wed Jul 28, 2004 12:24 am

Post by Warvis »

Take the differently scaled objects which xand mentioned.
Their rotation matrices are different, because the rotation matrix which is returned by objmatrix.rotationPart() does not only hold information about the object's rotation, but also about the object's scaling (the this rotationpart is obivously taken directly from the orginal 4x4 object matrix).

This may not be a problem when you derive euler angles from such a (possibly scaled) rotation matrix, because the matrix rotation is still correct.
But this should be taken into account when you start doing things like:

Code: Select all

from Blender import *

Obj1=Object.Get("Cube")
Obj2=Object.Get("Cube.001")

m1 = Obj1.getMatrix()       # copy rotation from Obj1
m1rot = m1.rotationPart()   # by getting the rotationPart()

m2 = Obj2.getMatrix()       # Get Obj2 Location
m2trans = m2.translationPart()

# resize matrices for multiplication
m1rot.resize4x4()
m2trans=Mathutils.TranslationMatrix(m2trans)

m2new= m1rot * m2trans  # Obj2 will receive rotation AND scaling
Obj2.setMatrix(m2new)   # from Obj1.

Window.RedrawAll()
I think this is rather a feature and not a bug ;)

xand
Posts: 33
Joined: Wed Oct 16, 2002 9:46 am

Post by xand »

that's why i called it an error and not a bug.
you can create a pure rotation matrix or a pure scale matrix from angle and value but you can extract them.

i need to apply rotation from an object to another regadless their size.
so i must extract each part of the matrix to divided it by the corresponding size.
it would be better is the rotationpart be the pure rotation matrix.

+++

ascotan
Posts: 0
Joined: Thu May 29, 2003 10:32 pm
Location: Maryland, U.S.

Post by ascotan »

Strangly I ran the above example with 2 differently scaled cubes and found no difference. Maybe a .blend that illustrates the problem?

The rotationPart() internal matrix function is to return the tranformation of a n-dimensional matrix. It is probably named poorly. To get the rotational information from the transformation you could get it's quaternion or euler value then construct a rotation matrix based on this information.

xand
Posts: 33
Joined: Wed Oct 16, 2002 9:46 am

Post by xand »

that's what i do now but i think the result of this piece of code should be the same. but anyway, the second determination works even it seems ugly.

Code: Select all

from Blender import *
from Blender.Mathutils import *

print 'start'
ob=Object.Get('Empty')
m=ob.mat

mrot=m.rotationPart()
print mrot

mrot2=m.toEuler().toMatrix()
print mrot2

+++

Warvis
Posts: 0
Joined: Wed Jul 28, 2004 12:24 am

Post by Warvis »

ascotan wrote:Strangly I ran the above example with 2 differently scaled cubes and found no difference. Maybe a .blend that illustrates the problem?
There isn't really a problem to demonstrate: The code just shows how the rotationmatrix applies rotation and scaling to an object.
The rotationPart() internal matrix function is to return the tranformation of a n-dimensional matrix. It is probably named poorly.
That's what we're talking about:
If I understand xand correctly, rotationPart() should return a 'normalized' rotation matrix, while I think it's ok the way it is. Otherwise you would need another way to extract the 3x3 transformation from the 4x4 object matrix in the cases where you need the scaling transform.
To get the rotational information from the transformation you could get it's quaternion or euler value then construct a rotation matrix based on this information.
Hmm, why not use the quat right from the start:

Code: Select all

MyObject.toQuat().toMatrix()
instead of

Code: Select all

MyObject.rotationPart()
will return an unscaled rotation matrix.

xand
Posts: 33
Joined: Wed Oct 16, 2002 9:46 am

Post by xand »

finally, everybody arrives to the same conclusion.

the explanation in the doc ina api2.2x should indicate this particularity of the rotationPart method to avoid further confusion.


+++

ascotan
Posts: 0
Joined: Thu May 29, 2003 10:32 pm
Location: Maryland, U.S.

Post by ascotan »

Good point I think an update to the .py docs is in order. Thx for bringing this up. :)

Post Reply