Mirroring in the Transform3D object We use the [[http://blake.bcm.edu/doxygen/classEMAN_1_1Transform3D.html|Transform3D]] class for storing/managing Euler angles and translations. At any time a Transform3D ({{{$$T3D$$}}}) object defines a group of 3 transformations of a rigid body that are applied in a specific order, namely {{{$$T3D \equiv T_{post} R T_{pre}$$}}} Where {{{$$T_{pre} }}} is a pre translation, {{{$$R$$}}} is a rotation and {{{$$T_{post} }}} is a post translation. The Transform3D 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 these approaches the 4x4 transformation matrix {{{$$T3D$$}}} is constructed in this way {{{$$T3D = [[R,\mathbf{t}],[\mathbf{0}^T,1]]$$}}} Where 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 {{{$$ T3D \mathbf{p}_{hc} = ( (R\mathbf{p} + \mathbf{t})^T, 1 )^T $$}}} In this way the result of applying a Transform3D to a vector is literally a rotation followed by a translation. The Transform3D allows for both pre and post translation and stores the cumulative result internally {{{$$T3D = T_{post} R T_{pre} = [[I,\mathbf{t}_{post}],[\mathbf{0}^T,1]] [[R,\mathbf{0}],[\mathbf{0}^T,1]] [[I,\mathbf{t}_{pre}],[\mathbf{0}^T,1]] = [[R,R\mathbf{t}_{pre}+\mathbf{t}_{post}],[\mathbf{0}^T,1]]$$}}} === Support for the mirroring operation in Transform3D === See * [[EMAN2/TransformConventions/Mirroring_Mirroring_in_the_Transform3D_object]] === Constructing a Transform3D object in Python === In Python you can construct a Transform3D object in a number of ways {{{#!python from EMAN2 import Transform3D t = Transform3D() # t is the identity t = Transfrom3D(EULER_EMAN,25,45,65) # EULER_EMAN rotation convention uses the az, alt, phi t = Transform3D(EULER_SPIDER,24,44,64) # EULER_SPIDER rotation convention uses the phi, theta, psi convention t = Transform3D(25,45,65) # EULER_EMAN convention used by default, arguments are taken as az, alt, phi t = Transform3D(Vec3f(1,2,3),25,45,65,Vec3f(4,5,6)) # Specify a pre trans, followed by EULER_EMAN convention rotations az, alt, phi, followed by the post trans t = Transform3D(25,45,65,Vec3f(4,5,6)) # EULER_EMAN convention rotations az, alt, phi, followed by the post trans t = Transform3D(1,0,0,0,1,0,0,0,1) # Explicitly setting the nine members of the rotation matrix, row wise. s = Transform3D(t) # copy constructor }}} === Setting Transform3D rotations and translation attributes in Python === You can set the pre and post translations, as well as the rotations, directly from Python {{{#!python from EMAN2 import Transform3D t = Transform3D() # setting the rotations t.set_rotation(25,45,65) # EULER_EMAN convention rotations az, alt, phi t.set_rotation(EULER_SPIDER,24,44,64) # EULER_SPIDER rotation convention uses the phi, theta, psi convention t.set_rotation(EULER_EMAN, {"az":25,"alt":45,"phi":65}) # Optional dictionary style approach t.set_rotation(1,0,0,0,1,0,0,0,1) # Explicitly set the nine members of the rotation matrix, row wise. # setting translations t.set_pretrans(1,2,3)# pre translation dx, dy, dz t.set_pretrans(Vec3f(1,2,3)) # also takes Vec3f argument t.set_pretrans([1,2,3]) # also takes tuple argument t.set_posttrans(4,5,6)# post translation dx, dy, dz t.set_posttrans(Vec3f(4,5,6)) # also takes Vec3f argument t.set_posttrans([4,5,6]) # also takes tuple argument }}} === Retrieving transform3D rotations and translation attributes in Python === You can retrieve attributes using similar syntax to that employed for the setter methods {{{#!python