What is a Transform?
We use the [http://blake.bcm.edu/eman2/doxygen_html/classEMAN_1_1Transform.html Transform] class for storing/managing Euler angles,translations, scales and x mirroring. At any time a Transform object $$Tr$$ defines a group of 4 transformations of a rigid body that are applied in a specific order, namely
$$ Tr \equiv M T S R $$
Where $$M$$ is a mirroring operation about the x-axis, $$T$$ is a translation, $$S$$ is a uniform, positive, non zero scaling operation and $$R$$ is a rotation. The Transform object stores these transformations internally in a 4x4 matrix, as is commonly the case in computer graphics applications that use homogeneous coordinate systems (i.e. OpenGL). In our approach the internal 4x4 transformation matrix is constructed in this way
$$ Tr = [[sMR,M\mathbf{t}],[\mathbf{0}^T,1]]$$
Where $$s$$ is the constant scaling factor, $$M$$ is the identity or the x-mirroring matrix, $$R$$ is a $$3x3$$ rotation matrix and $$\mathbf{t}=(tx,ty,tz)^T$$ is the translation.
The Transform object in Python
Constructing a Transform
There a three ways to construct a Transform object in Python
1 t = Transform() # default constructor, t is the identity
2 t = Transform({"type":"eman","az":10,"alt":150,"scale":2.0,"mirror":True,"tx":3.4}) # construction using a dictionary
3 p = Transform({"type":"eman","az":10,"mirror":True,"tx":3.4}) # construction using a dictionary
4 s = Transform(t) # copy construction - s is precisely the same as t
For more information on default parameters and what happens when some parameters are not set see [#dict_const a more in depth look at the dictionary constructor]
Setting/getting rotations
Setting/getting scale
Setting/getting mirror
Setting/getting translation
Setting/getting parameters
You can tell a Transform deduce any of its parameters from a dictionary. Similarly you can get the parameters of a Transform as a dictionary
1 t = Transform()
2 t.set_params({"type":"eman","az":10,"alt":150,"scale":2.0,"mirror":True,"tx":3.4})
3 d = t.get_params("eman") # must specify the euler convention
4 s = Transform(d) # s is the same as t
5 d = t.get_params("spider")
6 s = Transform(d) # s is the same as t
7 d = t.get_params("matrix")
8 s = Transform(d) # s is the same as t
For more information the behaviour of set_params see [#set_params a more in depth look at set_params ]
A Transform multiplied by a Vec3f
2D degenerate use of the Transform object in Python
The Transform object can be used as though it were a 2D transformation matrix. In this case the interface for setting/getting scale and mirror is unchanged. However setting the rotation should be done using the euler type "2d", and there are some accommodations for setting and getting 2d translations and parameters.
Setting/getting 2D rotations
Use the "2d" euler type, and the angle is specified using "alpha"
Setting/getting 2D translation
The interface is more or less identical to the 3D case
Setting/getting 2D parameters
For getting the parameters in 2D form use the following
A Transform multiplied by a Vec2f
The interface is precisely the same as the interface for
A more in depth look at the dictionary constructor
The dictionary constructor, which is equivalent to calling the default constructor followed by the set_params function, takes up to 9 parameters as exemplified in the following
If any of the angles or not specified they are implicitly set to 0
If no euler type is specified then the rotation matrix is the identity
1 t = Transform({"scale":2.0,"mirror":True,"tx":3.4,"ty":3,"tz":2}) # Rotation matrix is the identity
Similarly if any of the translation parameters are not specified they are implicitly set to 0
If scale is not specified it is by default 1.0, similarly if mirror is not specified it is be default False
1 t = Transform({"tx":3.4,"ty":3,"tz":3}) # scale is 1.0, mirror is False
A more in depth look at set_params
The transform function set_params is called in the Transform dictionary constructor
If calling the set_params function on a Transform that has already been initialized and had many things done than you should be aware of the following:
If unspecified, old parameters are retained