User Tools

Site Tools


eman2:transforminpython

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
eman2:transforminpython [2025/06/19 19:56] – created steveludtkeeman2:transforminpython [2025/07/06 03:39] (current) steveludtke
Line 1: Line 1:
-====== The center of the image ======+====== Transforms in Python ====== 
 + 
 +===== The center of the image =====
 ---- ----
-The center of the image for purposes of rotations is different for odd and even sized images. For even images, the center is at (nx/2,ny/2) where the first pixel is at (0,0). For odd sized images, the center is at ((nx-1)/2,(ny-1)/2). The same concept extends to 3-D.+The center of the image for purposes of rotations is different for odd and even sized images. For even images, the center is at $(nx/2,ny/2)where the first pixel is at $(0,0)$. For odd sized images, the center is at $((nx-1)/2,(ny-1)/2)$. The same concept extends to 3-D.
  
 {{attachment:center1.png}} {{attachment:center2.png}} {{attachment:center1.png}} {{attachment:center2.png}}
  
-====== What is a Transform? ======+===== What is a Transform? =====
 ---- ----
-We use the [[http://blake.bcm.edu/doxygen/classEMAN_1_1Transform.html|Transform]] class for storing/managing Euler angles,translations, scales and x mirroring. At any time a Transform object <code>Tr</code> defines a group of 4 transformations of a rigid body that are applied in a specific order, namely+We use the [[http://blake.bcm.edu/doxygen/classEMAN_1_1Transform.html|Transform]] class for storing/managing Euler angles,translations, scales and x mirroring. At any time a Transform object $\mathrm{Tr}$ defines a group of 4 transformations of a rigid body that are applied in a specific order, namely
  
-<code> Tr = M T S R </code>+$$\mathrm{Tr= M T S R$$
  
-Where <code>M</code> is a mirroring operation about the x-axis, <code>T</code> is a translation, <code>S</code> is a uniform, positive, non zero scaling operation and <code>R</code> is a rotation. The Transform object stores these transformations internally in a 3x4 matrix.+Where $Mis a mirroring operation about the x-axis, $Tis a translation, $Sis a uniform, positive, non zero scaling operation and $Ris a rotation. The Transform object stores these transformations internally in a 3x4 matrix.
  
-====== Supported Rotation Conventions ======+===== Supported Rotation Conventions =====
 ---- ----
 ||Convention ||Angle Names ||Matrices || ||Convention ||Angle Names ||Matrices ||
-||EMAN ||az, alt, phi (Z,X,Z') ||<code> [[cos phi,sin phi0],[-sin phi,cos phi,0],[0,0,1]] [[1,0,0],[0cos al, sin al],[0-sin al, cos al]] [[cos az,sin az0],[-sin az,cos az,0],[0,0,1]] </code> || +||EMAN ||az, alt, phi (Z,X,Z') ||$\begin{bmatrix}\cos phi&\sin phi0\\-\sin phi&\cos phi&0\\0&0&1\end{bmatrix}$ $\begin{bmatrix}1&0&0\\0& \cos alt& \sin alt\\0-\sin alt& \cos alt\end{bmatrix}$ $\begin{bmatrix}\cos az&\sin az0\\-\sin az&\cos az&0\\0&0&1\end{bmatrix}$ || 
-||Imagic ||gamma, beta, alpha ||<code> [[cos gamma,sin gamma0],[-sin gamma,cos gamma,0],[0,0,1]] [[1,0,0],[0cos betasin beta],[0-sin betacos beta]] [[cos alpha,sin alpha0],[-sin alpha,cos alpha,0],[0,0,1]] </code> || +||Imagic ||gamma, beta, alpha ||$\begin{bmatrix}\cos gamma&\sin gamma0\\-\sin gamma&\cos gamma&0\\0&0&1\end{bmatrix}$ $\begin{bmatrix}1&0&0\\0& \cos beta& \sin beta\\0-\sin beta& \cos beta\end{bmatrix}$ $\begin{bmatrix}\cos alpha&\sin alpha0\\-\sin alpha&\cos alpha&0\\0&0&1\end{bmatrix}$ || 
-||Spider ||psi, theta, phi ||<code> [[cos psi,sin psi0],[-sin psi,cos psi,0],[0,0,1]] [[cos theta,0,sin theta],[010],[-sin theta0cos theta]] [[cos phi,sin phi0],[-sin phi,cos phi,0],[0,0,1]] </code> || +||Spider ||psi, theta, phi ||$\begin{bmatrix}\cos psi&\sin psi0\\-\sin psi&\cos psi&0\\0&0&1\end{bmatrix}$ $\begin{bmatrix}\cos theta&0&\sin theta\\010\\-\sin theta0& \cos theta\end{bmatrix}$ $\begin{bmatrix}\cos phi&\sin phi0\\-\sin phi&\cos phi&0\\0&0&1\end{bmatrix}$ || 
-||MRC ||phi, theta, omega ||<code> [[cos phi,sin phi0],[-sin phi,cos phi,0],[0,0,1]] [[cos theta,0,sin theta],[010],[-sin theta0cos theta]] [[cos omega,sin omega0],[-sin omega,cos omega,0],[0,0,1]] </code> || +||MRC ||phi, theta, omega ||$\begin{bmatrix}\cos phi&\sin phi0\\-\sin phi&\cos phi&0\\0&0&1\end{bmatrix}$ $\begin{bmatrix}\cos theta&0&\sin theta\\010\\-\sin theta0& \cos theta\end{bmatrix}$ $\begin{bmatrix}\cos omega&\sin omega0\\-\sin omega&\cos omega&0\\0&0&1\end{bmatrix}$ || 
-||XYZ ||z, y, x ||<code> [[cos z,sin z0],[-sin zcos z,0],[0,0,1]] [[cos y,0,sin y],[010],[-sin y0cos y]] [[1,0,0],[0cos xsin x],[0-sin xcos x]] </code> || +||XYZ ||z, y, x ||$\begin{bmatrix}\cos z&\sin z0\\-\sin z& \cos z&0\\0&0&1\end{bmatrix}$ $\begin{bmatrix}\cos y&0&\sin y\\010\\-\sin y0& \cos y\end{bmatrix}$ $\begin{bmatrix}1&0&0\\0& \cos x& \sin x\\0-\sin x& \cos x\end{bmatrix}$ || 
-||spin ||Omega, n1, n2, n3 ||Quaternion rotation by  Omega  degrees about the vector [n1,n2\,n3] || +||spin ||Omega, n1, n2, n3 ||Quaternion rotation by  Omega  degrees about the vector $[n1,n2,n3]|| 
-||sgirot ||q, n1, n2, n3 ||Quaternion rotation by q degrees about the vector [n1,n2\,n3] || +||sgirot ||q, n1, n2, n3 ||Quaternion rotation by q degrees about the vector $[n1,n2,n3]|| 
-||quaternion ||e0, e1, e2, e3 ||Literal quaternion rotation using  q = e0 + e1\mathbf{i} + e2\mathbf{j} + e2\mathbf{k}  ||+||quaternion ||e0, e1, e2, e3 ||Literal quaternion rotation using  $q = e0 + e1\mathbf{i} + e2\mathbf{j} + e2\mathbf{k} ||
 ||2d||alpha||Rotation in 2-D only, for 3-D objects this is a rotation about Z|| ||2d||alpha||Rotation in 2-D only, for 3-D objects this is a rotation about Z||
  
  
-====== The Transform object in Python ======+===== The Transform object in Python =====
 ---- ----
-===== Constructing a Transform =====+==== Constructing a Transform ====
 There a four ways to construct a Transform object in Python There a four ways to construct a Transform object in Python
  
-<code>#!python+<code python>
 t = Transform() # default constructor, t is the identity t = Transform() # default constructor, t is the identity
 t = Transform({"type":"eman","az":10,"alt":150,"scale":2.0,"mirror":True,"tx":3.4}) # construction using a dictionary t = Transform({"type":"eman","az":10,"alt":150,"scale":2.0,"mirror":True,"tx":3.4}) # construction using a dictionary
Line 44: Line 46:
 For example: For example:
  
-<code>#!python+<code python>
 t = Tranform({"type":"spin"}) t = Tranform({"type":"spin"})
 t = Tranform({"type":"quaternion"}) t = Tranform({"type":"quaternion"})
Line 51: Line 53:
 </code> </code>
  
-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 ==== 
- +<code python>
-===== Setting/getting rotations ===== +
-<code>#!python+
 t = Transform() t = Transform()
 t.set_rotation({"type":"spider","phi":32,"theta":12,"psi":-100}) t.set_rotation({"type":"spider","phi":32,"theta":12,"psi":-100})
Line 67: Line 67:
 You can supply ANY rotation CONVENTION as a string to get the rotation in the corresponding convention, irrespective of the "type" you set for the transform. For example, from an 'eman' type Transform,  You can supply ANY rotation CONVENTION as a string to get the rotation in the corresponding convention, irrespective of the "type" you set for the transform. For example, from an 'eman' type Transform, 
  
-<code>#!python+<code python>
 t = Transform({'type':'eman'}) t = Transform({'type':'eman'})
 </code> </code>
Line 73: Line 73:
 You can still get the rotation in other conventions: You can still get the rotation in other conventions:
  
-<code>#!python+<code python>
 t.get_rotation('spin') gives {'Omega': 0.0, 'n1': 0.0, 'n2': 0.0, 'n3': 0.0, 'type': 'spin'} t.get_rotation('spin') gives {'Omega': 0.0, 'n1': 0.0, 'n2': 0.0, 'n3': 0.0, 'type': 'spin'}
 t.get_rotation('quaternion') gives  {'e0': 1.0, 'e1': 0.0, 'e2': 0.0, 'e3': 0.0, 'type': 'quaternion'} t.get_rotation('quaternion') gives  {'e0': 1.0, 'e1': 0.0, 'e2': 0.0, 'e3': 0.0, 'type': 'quaternion'}
 </code> </code>
  
-===== Setting/getting scale ===== +==== Setting/getting scale ==== 
-<code>#!python+<code python>
 t = Transform() t = Transform()
 t.set_scale(2.0) t.set_scale(2.0)
Line 85: Line 85:
 s = Transform({"scale":scale}) # set scale as part of construction s = Transform({"scale":scale}) # set scale as part of construction
 </code> </code>
-===== Setting/getting mirror ===== +==== Setting/getting mirror ==== 
-<code>#!python+<code python>
 t = Transform() t = Transform()
 #  Can be set using integers #  Can be set using integers
Line 96: Line 96:
 s = Transform({"mirror":mirror}) # set mirror as part of construction s = Transform({"mirror":mirror}) # set mirror as part of construction
 </code> </code>
-===== Setting/getting translation ===== +==== Setting/getting translation ==== 
-<code>#!python+<code python>
 t = Transform() t = Transform()
 t.set_trans(1,2,3) # method 1 t.set_trans(1,2,3) # method 1
Line 105: Line 105:
 s = Transform({"tx":v[0],"ty":v[1],"tz":v[2]}) # set translation as part of construction s = Transform({"tx":v[0],"ty":v[1],"tz":v[2]}) # set translation as part of construction
 </code> </code>
-===== Setting/getting parameters =====+==== 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 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
  
-<code>#!python+<code python>
 t = Transform() t = Transform()
 t.set_params({"type":"eman","az":10,"alt":150,"scale":2.0,"mirror":True,"tx":3.4}) t.set_params({"type":"eman","az":10,"alt":150,"scale":2.0,"mirror":True,"tx":3.4})
Line 118: Line 118:
 s = Transform(d) # s is the same as t s = Transform(d) # s is the same as t
 </code> </code>
-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 ===== +==== A Transform multiplied by a Vec3f ==== 
-The transformation of a 3D vector <code>$$ v = (v_x,v_y,v_z)^T $$</code> by a Transform is defined as+The transformation of a 3D vector $$ v = (v_x,v_y,v_z)^T $$ by a Transform is defined as
  
-<code>$$ Tr \mathbf{v}  = [sMR,M\mathbf{t}] (v_x,v_y,v_z,1)^T = sMR\mathbf{v}+ M\mathbf{t}  $$</code>+$$ Tr \mathbf{v}  = [sMR,M\mathbf{t}] (v_x,v_y,v_z,1)^T = sMR\mathbf{v}+ M\mathbf{t}  $$
  
 This can be done in Python using the following This can be done in Python using the following
  
-<code>#!python+<code python>
 t = Transform() t = Transform()
 t.set_params({"type":"eman","az":10,"alt":150,"scale":2.0,"mirror":True,"tx":3.4}) t.set_params({"type":"eman","az":10,"alt":150,"scale":2.0,"mirror":True,"tx":3.4})
Line 134: Line 133:
 v_transformed = t.transform(v) # can also do it this way if you prefer v_transformed = t.transform(v) # can also do it this way if you prefer
 </code> </code>
-===== Transforming a 3D image =====+==== Transforming a 3D image ====
 Transforming a 3D image is achieved using a single function call Transforming a 3D image is achieved using a single function call
  
-<code>#!python+<code python>
 t = Transform() t = Transform()
 t.set_params({"type":"eman","az":10,"alt":150,"scale":2.0,"mirror":True,"tx":3.4}) t.set_params({"type":"eman","az":10,"alt":150,"scale":2.0,"mirror":True,"tx":3.4})
Line 146: Line 145:
 You can alternatively use the EMData processing framework, for example: You can alternatively use the EMData processing framework, for example:
  
-<code>#!python+<code python>
 t = Transform() t = Transform()
 t.set_params({"type":"eman","az":10,"alt":150,"scale":2.0,"mirror":True,"tx":3.4}) t.set_params({"type":"eman","az":10,"alt":150,"scale":2.0,"mirror":True,"tx":3.4})
Line 155: Line 154:
 In fact <code>e.transform(t)</code> actually calls <code>e.process_inplace("xform",{"transform":t})</code> internally on the C++ side. In fact <code>e.transform(t)</code> actually calls <code>e.process_inplace("xform",{"transform":t})</code> internally on the C++ side.
  
-====== 2D degenerate use of the Transform object in Python ======+===== 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. 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 =====+==== Setting/getting 2D rotations ====
 Use the "2d" euler type, and the angle is specified using "alpha" Use the "2d" euler type, and the angle is specified using "alpha"
  
-<code>#!python+<code python>
 t = Transform() t = Transform()
 t.set_rotation({"type":"2d","alpha":32}) t.set_rotation({"type":"2d","alpha":32})
Line 168: Line 167:
 s = Transform(a) # works fine s = Transform(a) # works fine
 </code> </code>
-===== Setting/getting 2D translation =====+==== Setting/getting 2D translation ====
 The interface is more or less identical to the 3D case The interface is more or less identical to the 3D case
  
-<code>#!python+<code python>
 t = Transform() t = Transform()
 t.set_trans(1,2) # method 1 t.set_trans(1,2) # method 1
Line 178: Line 177:
 s = Transform("tx":v[0],"ty",v[1]) # set translation as part of construction s = Transform("tx":v[0],"ty",v[1]) # set translation as part of construction
 </code> </code>
-===== Setting/getting 2D parameters =====+==== Setting/getting 2D parameters ====
 For getting the parameters in 2D form use the following For getting the parameters in 2D form use the following
  
-<code>#!python+<code python>
 t = Transform() t = Transform()
 t.set_params({"type":"2d","alpha":10,"scale":2.0,"mirror":True,"tx":3.4,"ty":0.0}) # no special interface required for 2D, use the same as 3D t.set_params({"type":"2d","alpha":10,"scale":2.0,"mirror":True,"tx":3.4,"ty":0.0}) # no special interface required for 2D, use the same as 3D
Line 187: Line 186:
 s = Transform(d) # s is the same as t s = Transform(d) # s is the same as t
 </code> </code>
-===== A Transform multiplied by a Vec2f ===== +==== A Transform multiplied by a Vec2f ==== 
-The transformation of a 2D vector <code>$$ v_{2D} = (v_x,v_y)^T $$</code> by a Transform is equivalent to setting the z component of 3D vector to 0. If <code>$$ v = (v_x,v_y,0)^T $$</code>  then the 2D transformation is equivalent to the following,+The transformation of a 2D vector $$ v_{2D} = (v_x,v_y)^T $$ by a Transform is equivalent to setting the z component of 3D vector to 0. If $$ v = (v_x,v_y,0)^T $$  then the 2D transformation is equivalent to the following,
  
-<code>$$ Tr \mathbf{v_{2D}}  = [sMR,M\mathbf{t}] (v_x,v_y,0,1)^T = sMR\mathbf{v}+ M\mathbf{t}  $$</code>+$$ Tr \mathbf{v_{2D}}  = [sMR,M\mathbf{t}] (v_x,v_y,0,1)^T = sMR\mathbf{v}+ M\mathbf{t}  $$
  
 and the z component is ignored. Note that the internal implementation is efficient. 2D vector transformation can be done in Python using the following and the z component is ignored. Note that the internal implementation is efficient. 2D vector transformation can be done in Python using the following
  
-<code>#!python+<code python>
 t = Transform() t = Transform()
 t.set_params({"type":"2d","alpha":10,"scale":2.0,"mirror":True,"tx":3.4}) t.set_params({"type":"2d","alpha":10,"scale":2.0,"mirror":True,"tx":3.4})
Line 201: Line 200:
 v_transformed = t.transform(v) # can also do it this way if you prefer v_transformed = t.transform(v) # can also do it this way if you prefer
 </code> </code>
-===== Transforming a 2D image =====+==== Transforming a 2D image ====
 Transforming a 2D image is achieved using a single function call Transforming a 2D image is achieved using a single function call
  
-<code>#!python+<code python>
 t = Transform() t = Transform()
 t.set_params({"type":"2d","alpha":10,"scale":2.0,"mirror":True,"tx":3.4}) t.set_params({"type":"2d","alpha":10,"scale":2.0,"mirror":True,"tx":3.4})
Line 212: Line 211:
 You can alternatively use the EMData processing framework, for example: You can alternatively use the EMData processing framework, for example:
  
-<code>#!python+<code python>
 t = Transform() t = Transform()
 t.set_params({"type":"2d","alpha":10,"scale":2.0,"mirror":True,"tx":3.4}) t.set_params({"type":"2d","alpha":10,"scale":2.0,"mirror":True,"tx":3.4})
Line 222: Line 221:
 Note that if you try to transform a 2D image using a Transform that contains 3D rotations or translations you will get an error: Note that if you try to transform a 2D image using a Transform that contains 3D rotations or translations you will get an error:
  
-<code>#!python+<code python>
 t = Transform({"type":"eman","alt":22}) # 3D rotation t = Transform({"type":"eman","alt":22}) # 3D rotation
 a = test_image() # 2D a = test_image() # 2D
Line 229: Line 228:
 a.transform(t) # ERROR is thrown a.transform(t) # ERROR is thrown
 </code> </code>
-<<Anchor(dict_const)>> 
  
-====== A more in depth look at the dictionary constructor ======+===== 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 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
  
-<code>#!python+<code python>
 t = Transform({"type":"eman","az":10,"alt":150,"phi":20,"scale":2.0,"mirror":True,"tx":3.4,"ty":3,"tz":2}) t = Transform({"type":"eman","az":10,"alt":150,"phi":20,"scale":2.0,"mirror":True,"tx":3.4,"ty":3,"tz":2})
 t = Transform({"type":"spider","phi":10,"theta":150,"psi":20,"scale":2.0,"mirror":True,"tx":3.4,"ty":3,"tz":2}) t = Transform({"type":"spider","phi":10,"theta":150,"psi":20,"scale":2.0,"mirror":True,"tx":3.4,"ty":3,"tz":2})
Line 241: Line 239:
 If any of the angles or not specified they are implicitly set to 0 If any of the angles or not specified they are implicitly set to 0
  
-<code>#!python+<code python>
 t = Transform({"type":"spider","phi":10,"scale":2.0,"mirror":True,"tx":3.4,"ty":3,"tz":2}) # spider theta and psi are both 0 t = Transform({"type":"spider","phi":10,"scale":2.0,"mirror":True,"tx":3.4,"ty":3,"tz":2}) # spider theta and psi are both 0
 t = Transform({"type":"spider","scale":2.0,"mirror":True,"tx":3.4,"ty":3,"tz":2}) # spider phi, theta and psi are all 0 t = Transform({"type":"spider","scale":2.0,"mirror":True,"tx":3.4,"ty":3,"tz":2}) # spider phi, theta and psi are all 0
Line 247: Line 245:
 If no euler type is specified then the rotation matrix is the identity If no euler type is specified then the rotation matrix is the identity
  
-<code>#!python+<code python>
 t = Transform({"scale":2.0,"mirror":True,"tx":3.4,"ty":3,"tz":2}) # Rotation matrix is the identity t = Transform({"scale":2.0,"mirror":True,"tx":3.4,"ty":3,"tz":2}) # Rotation matrix is the identity
 </code> </code>
 Similarly if any of the translation parameters are not specified they are implicitly set to 0 Similarly if any of the translation parameters are not specified they are implicitly set to 0
  
-<code>#!python+<code python>
 t = Transform({"scale":2.0,"mirror":True,"tx":3.4,"ty":3}) # tz is 0 t = Transform({"scale":2.0,"mirror":True,"tx":3.4,"ty":3}) # tz is 0
 t = Transform({"scale":2.0,"mirror":True}) # tx,ty and tz are all 0 t = Transform({"scale":2.0,"mirror":True}) # tx,ty and tz are all 0
Line 258: Line 256:
 If scale is not specified it is by default 1.0, similarly if mirror is not specified it is be default False If scale is not specified it is by default 1.0, similarly if mirror is not specified it is be default False
  
-<code>#!python+<code python>
 t = Transform({"tx":3.4,"ty":3,"tz":3}) # scale is 1.0, mirror is False t = Transform({"tx":3.4,"ty":3,"tz":3}) # scale is 1.0, mirror is False
 </code> </code>
-<<Anchor(set_params)>> 
  
-====== A more in depth look at set_params ======+===== A more in depth look at set_params =====
 ---- ----
 Constructing a Transform with some dictionary is the same as calling set_params on a Transform that is the identity. Constructing a Transform with some dictionary is the same as calling set_params on a Transform that is the identity.
  
-<code>#!python+<code python>
 d = {"type":"eman","az":10,"alt":150,"phi":20,"scale":2.0,"mirror":True,"tx":3.4,"ty":3,"tz":2} d = {"type":"eman","az":10,"alt":150,"phi":20,"scale":2.0,"mirror":True,"tx":3.4,"ty":3,"tz":2}
 t = Transform(d) # t is initialized as the identity and then set_params(d) is called internally t = Transform(d) # t is initialized as the identity and then set_params(d) is called internally
Line 275: Line 272:
 The main difference between calling set_params explicitly on a Transform as opposed to constructing a Tranform with a dictionary lies in the fact that the construction method first sets the Transform object to the identity before calling set_params. So 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... The main difference between calling set_params explicitly on a Transform as opposed to constructing a Tranform with a dictionary lies in the fact that the construction method first sets the Transform object to the identity before calling set_params. So 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 ===== +==== If unspecified, old parameters are retained ==== 
-<code>#!python+<code python>
 t = Transform({"type":"eman","az":10,"alt":150,"phi":20,"scale":2.0,"mirror":True,"tx":3.4,"ty":3,"tz":2}) t = Transform({"type":"eman","az":10,"alt":150,"phi":20,"scale":2.0,"mirror":True,"tx":3.4,"ty":3,"tz":2})
 d = {"tx":23,"ty":23,"tz":12} d = {"tx":23,"ty":23,"tz":12}
 t.set_params(d) # t still has the same rotation, scale and mirror but it has an updated translation t.set_params(d) # t still has the same rotation, scale and mirror but it has an updated translation
 </code> </code>
-===== For rotation and translation, setting one is equivalent to setting them all ===== +==== For rotation and translation, setting one is equivalent to setting them all ==== 
-<code>#!python+<code python>
 t = Transform({"tx":3.4,"ty":3,"tz":2}) t = Transform({"tx":3.4,"ty":3,"tz":2})
 d = {"tx":23} d = {"tx":23}
eman2/transforminpython.1750362982.txt.gz · Last modified: by steveludtke