pytd62 documentation » Technical notes

Technical notes

Setting origin and rotation of a FD element

In each FD element (except for polygons), the local origin and base vectors are defined inside .Basetrans (type: OpenTDv62.Matrix3d). OpenTDv62.Matrix3d offers several methods to set the origin and rotation, such as:

However, it is also possible to directly set the Matrix3d.entry property, which might be more convenient for rotating the element multiple times. 'Matrix3d.entry' has a 4 × 4 matrix shape, but the last row is not used for specifying the base vectors and origin. As shown in the figure below, each column corresponds to the X base vector, Y base vector, Z base vector and the origin coordinates.

In order to set the base vectors, transposed rotation matrices can be used. The equation below shows an example, how to rotate initial base vectors \((\boldsymbol{e}_{x~init},~\boldsymbol{e}_{y~init},~\boldsymbol{e}_{z~init})\) with ZYX Euler angles (which means firstly rotate around the Z axis, secondly rotate around the local Y axis and thirdly rotate around the local X axis) and acquire the new base vectors \((\boldsymbol{e}_{x~new},~\boldsymbol{e}_{y~new},~\boldsymbol{e}_{z~new})\).

$$ \left( \begin{array}{ccc} \boldsymbol{e}_{x~new}^T \\ \boldsymbol{e}_{y~new}^T \\ \boldsymbol{e}_{z~new}^T \end{array} \right) = \left( \begin{array}{ccc} 1.0 & 0.0 & 0.0 \\ 0.0 & \cos \phi & \sin \phi \\ 0.0 & -\sin \phi & \cos \phi \end{array} \right) \left( \begin{array}{ccc} \cos \theta & 0.0 & -\sin \theta \\ 0.0 & 1.0 & 0.0 \\ \sin \theta & 0.0 & \cos \theta \end{array} \right) \left( \begin{array}{ccc} \cos \psi & \sin \psi & 0.0 \\ -\sin \psi & \cos \psi & 0.0 \\ 0.0 & 0.0 & 1.0 \end{array} \right) \left( \begin{array}{ccc} \boldsymbol{e}_{x~init}^T \\ \boldsymbol{e}_{y~init}^T \\ \boldsymbol{e}_{z~init}^T \end{array} \right) $$

The acquired matrix corresponds to the 3 × 3 part of the 'Matrix3d.entry' in transposed form. As the base vectors are initially aligned to the reference coordinate, the orientation of a element can be set by the following way (rectangle as an example):

new_base = np.transpose(np.transpose(common.rotx(phi)) @ np.transpose(common.roty(theta)) @ np.transpose(common.rotz(psi)))
rectangle = td.CreateRectangle()
rectangle.BaseTrans.entry[0][0] = new_base[0,0]
rectangle.BaseTrans.entry[1][0] = new_base[1,0]
rectangle.BaseTrans.entry[2][0] = new_base[2,0]
rectangle.BaseTrans.entry[0][1] = new_base[0,1]
rectangle.BaseTrans.entry[1][1] = new_base[1,1]
rectangle.BaseTrans.entry[2][1] = new_base[2,1]
rectangle.BaseTrans.entry[0][2] = new_base[0,2]
rectangle.BaseTrans.entry[1][2] = new_base[1,2]
rectangle.BaseTrans.entry[2][2] = new_base[2,2]