Differences between revisions 9 and 10
Revision 9 as of 2008-09-05 20:59:53
Size: 3578
Comment:
Revision 10 as of 2008-09-05 21:08:10
Size: 4968
Comment:
Deletions are marked like this. Additions are marked like this.
Line 19: Line 19:
= The Transforms object in Python = = The Transform object in Python =
Line 85: Line 85:

== 2D degenerance ==

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"

{{{#!python
t = Transform()
t.set_rotation({"type":"2d","alpha":32})
twod_rot = t.get_rotation("2d")
s = Transform(twod_rot) # works fine

}}}

== Setting/getting 2D translation ==

The interface is more or less identical to the 3D case

{{{#!python
t = Transform()
t.set_trans(1,2) # method 1
t.set_trans(Vec2f(1,2)) # method 2
t.set_trans([1,2]) # method 3 - the tuple is converted to a Vec2f automatically
v = t.get_trans()
s = Transform("dx":v[0],"dy") # set translation as part of construction
}}}


== Setting/getting parameters ==

For getting the parameters in 2D form there is the get_params_2d function

{{{#!python
t = Transform()
t.set_params({"type":"2d","alpha":10,"scale":2.0,"mirror":True,"dx":3.4,"dy":0.0}) # no special interface required for 2D, use the same as 3D
d = t.get_params_2d() # no euler type required because there is only one ("2d")
s = Transform(d) # s is the same as t
}}}

TableOfContents

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 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 Transformobject 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 these approaches the 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 option x-mirroring operation which identity, except in the case of x mirroring where the (0,0) entry is -1, $$R$$ is a $$3x3$$ rotation matrix and $$\mathbf{t}=(dx,dy,dz)^T$$ is a post translation. In this approach a 3D point $$\mathbf{p}=(x,y,z)^T$$ as represented in homogeneous coordinates as a 4D vector $$\mathbf{p}_{hc}=(x,y,z,1)^T$$ and is multiplied by the matrix $$M$$ to produce the result of applying the transformation

$$ Tr \mathbf{p}_{hc} = ( (sMR\mathbf{p} +  M\mathbf{t})^T, 1 )^T $$

In this way the result of applying a Transform is a rotation followed by a scaling, followed by a translation and then finally the x mirroring operation is (optionally) applied.

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,"dx":3.4}) # construction using a dictionary
   3 s = Transform(t) # copy construction - s is precisely the same as t

Setting/getting rotations

   1 t = Transform()
   2 t.set_rotation({"type":"spider","phi":32,"theta":12,"psi":-100})
   3 spider_rot = t.get_rotation("spider")
   4 eman_rot = t.get_rotation("eman")
   5 s = Transform(eman_rot) # works fine

Setting/getting scale

   1 t = Transform()
   2 t.set_scale(2.0)
   3 scale = t.get_scale()
   4 s = Transform({"scale":scale}) # set scale as part of construction

Setting/getting mirror

   1 t = Transform()
   2 t.set_mirror(2.0)
   3 mirror = t.get_mirror()
   4 s = Transform({"mirror":mirror}) # set mirror as part of construction

Setting/getting translation

   1 t = Transform()
   2 t.set_trans(1,2,3) # method 1
   3 t.set_trans(Vec3f(1,2,3)) # method 2
   4 t.set_trans([1,2,3]) # method 3 - the tuple is converted to a Vec3f automatically
   5 v = t.get_trans()
   6 s = Transform("dx":v[0],"dy":v[1],"dz":v[2]) # set translation as part of construction

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,"dx":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

2D degenerance

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"

   1 t = Transform()
   2 t.set_rotation({"type":"2d","alpha":32})
   3 twod_rot = t.get_rotation("2d")
   4 s = Transform(twod_rot) # works fine

Setting/getting 2D translation

The interface is more or less identical to the 3D case

   1 t = Transform()
   2 t.set_trans(1,2) # method 1
   3 t.set_trans(Vec2f(1,2)) # method 2
   4 t.set_trans([1,2]) # method 3 - the tuple is converted to a Vec2f automatically
   5 v = t.get_trans()
   6 s = Transform("dx":v[0],"dy") # set translation as part of construction

Setting/getting parameters

For getting the parameters in 2D form there is the get_params_2d function

   1 t = Transform()
   2 t.set_params({"type":"2d","alpha":10,"scale":2.0,"mirror":True,"dx":3.4,"dy":0.0}) # no special interface required for 2D, use the same as 3D
   3 d = t.get_params_2d() # no euler type required because there is only one ("2d")
   4 s = Transform(d) # s is the same as t

EMAN2/TransformInPython (last edited 2023-09-29 12:51:26 by SteveLudtke)