### Re: [Numpy-discussion] composing Euler rotation matrices

On Wed, 1 Feb 2017 09:42:15 +, Matthew Brettwrote: > Hi, > On Wed, Feb 1, 2017 at 8:28 AM, Robert McLeod wrote: >> Instead of trying to decipher what someone wrote on a Wikipedia, why >> don't you look at a working piece of source code? >> e.g. >> https://github.com/3dem/relion/blob/master/src/euler.cpp > Also - have a look at https://pypi.python.org/pypi/transforms3d - and > in particular you might get some use from symbolic versions of the > transformations, e.g. here : > https://github.com/matthew-brett/transforms3d/blob/master/transforms3d/derivations/eulerangles.py > It's really easy to mix up the conventions, as I'm sure you know - see > http://matthew-brett.github.io/transforms3d/reference/transforms3d.euler.html Thank you very much for providing this package. It looks like this is exactly what I was trying to do (learn). The symbolic versions really help show what is going on in the derivations sub-package by showing how each of the 9 matrix elements are found. I'll try to hack it to use active rotations. -- Seb ___ NumPy-Discussion mailing list NumPy-Discussion@scipy.org https://mail.scipy.org/mailman/listinfo/numpy-discussion

### Re: [Numpy-discussion] composing Euler rotation matrices

[off topic] Nothing good ever comes from using Euler matrices. All the cool kids a using quaternions these days. They're (in some ways) simpler, can be interpolated easily, don't suffer from gimbal lock (discontinuity), and are not confused about which axis rotation is applied first (for Euler you much decide whether you want to apply x.y.z or z.y.x). They'd be a good addition to numpy. On Wed, Feb 1, 2017 at 1:42 AM, Matthew Brettwrote: > Hi, > > On Wed, Feb 1, 2017 at 8:28 AM, Robert McLeod > wrote: > > Instead of trying to decipher what someone wrote on a Wikipedia, why > don't > > you look at a working piece of source code? > > > > e.g. > > > > https://github.com/3dem/relion/blob/master/src/euler.cpp > > Also - have a look at https://pypi.python.org/pypi/transforms3d - and > in particular you might get some use from symbolic versions of the > transformations, e.g. here : > https://github.com/matthew-brett/transforms3d/blob/master/transforms3d/ > derivations/eulerangles.py > > It's really easy to mix up the conventions, as I'm sure you know - see > http://matthew-brett.github.io/transforms3d/reference/ > transforms3d.euler.html > > Cheers, > > Matthew > ___ > NumPy-Discussion mailing list > NumPy-Discussion@scipy.org > https://mail.scipy.org/mailman/listinfo/numpy-discussion > ___ NumPy-Discussion mailing list NumPy-Discussion@scipy.org https://mail.scipy.org/mailman/listinfo/numpy-discussion

### Re: [Numpy-discussion] composing Euler rotation matrices

Hi, On Wed, Feb 1, 2017 at 8:28 AM, Robert McLeodwrote: > Instead of trying to decipher what someone wrote on a Wikipedia, why don't > you look at a working piece of source code? > > e.g. > > https://github.com/3dem/relion/blob/master/src/euler.cpp Also - have a look at https://pypi.python.org/pypi/transforms3d - and in particular you might get some use from symbolic versions of the transformations, e.g. here : https://github.com/matthew-brett/transforms3d/blob/master/transforms3d/derivations/eulerangles.py It's really easy to mix up the conventions, as I'm sure you know - see http://matthew-brett.github.io/transforms3d/reference/transforms3d.euler.html Cheers, Matthew ___ NumPy-Discussion mailing list NumPy-Discussion@scipy.org https://mail.scipy.org/mailman/listinfo/numpy-discussion

### Re: [Numpy-discussion] composing Euler rotation matrices

Instead of trying to decipher what someone wrote on a Wikipedia, why don't you look at a working piece of source code? e.g. https://github.com/3dem/relion/blob/master/src/euler.cpp Robert On Wed, Feb 1, 2017 at 4:27 AM, Sebwrote: > On Tue, 31 Jan 2017 21:23:55 -0500, > Joseph Fox-Rabinovitz wrote: > > > Could you show what you are doing to get the statement "However, I > > cannot reproduce this matrix via composition; i.e. by multiplying the > > underlying rotation matrices.". I would guess something involving the > > `*` operator instead of `@`, but guessing probably won't help you > > solve your issue. > > Sure, although composition is not something I can take credit for, as > it's a well-described operation for generating linear transformations. > It is the matrix multiplication of two or more transformation matrices. > In the case of Euler transformations, it's matrices specifying rotations > around 3 orthogonal axes by 3 given angles. I'm using `numpy.dot' to > perform matrix multiplication on 2D arrays representing matrices. > > However, it's not obvious from the link I provided what particular > rotation matrices are multiplied and in what order (i.e. what > composition) is used to arrive at the Z1Y2X3 rotation matrix shown. > Perhaps I'm not understanding the conventions used therein. This is one > of my attempts at reproducing that rotation matrix via composition: > > --- ->--- > import numpy as np > > angles = np.radians(np.array([30, 20, 10])) > > def z1y2x3(alpha, beta, gamma): > """Z1Y2X3 rotation matrix given Euler angles""" > return np.array([[np.cos(alpha) * np.cos(beta), > np.cos(alpha) * np.sin(beta) * np.sin(gamma) - > np.cos(gamma) * np.sin(alpha), > np.sin(alpha) * np.sin(gamma) + > np.cos(alpha) * np.cos(gamma) * np.sin(beta)], > [np.cos(beta) * np.sin(alpha), > np.cos(alpha) * np.cos(gamma) + > np.sin(alpha) * np.sin(beta) * np.sin(gamma), > np.cos(gamma) * np.sin(alpha) * np.sin(beta) - > np.cos(alpha) * np.sin(gamma)], > [-np.sin(beta), np.cos(beta) * np.sin(gamma), > np.cos(beta) * np.cos(gamma)]]) > > euler_mat = z1y2x3(angles[0], angles[1], angles[2]) > > ## Now via composition > > def rotation_matrix(theta, axis, active=False): > """Generate rotation matrix for a given axis > > Parameters > -- > > theta: numeric, optional > The angle (degrees) by which to perform the rotation. Default is > 0, which means return the coordinates of the vector in the rotated > coordinate system, when rotate_vectors=False. > axis: int, optional > Axis around which to perform the rotation (x=0; y=1; z=2) > active: bool, optional > Whether to return active transformation matrix. > > Returns > --- > numpy.ndarray > 3x3 rotation matrix > """ > theta = np.radians(theta) > if axis == 0: > R_theta = np.array([[1, 0, 0], > [0, np.cos(theta), -np.sin(theta)], > [0, np.sin(theta), np.cos(theta)]]) > elif axis == 1: > R_theta = np.array([[np.cos(theta), 0, np.sin(theta)], > [0, 1, 0], > [-np.sin(theta), 0, np.cos(theta)]]) > else: > R_theta = np.array([[np.cos(theta), -np.sin(theta), 0], > [np.sin(theta), np.cos(theta), 0], > [0, 0, 1]]) > if active: > R_theta = np.transpose(R_theta) > return R_theta > > ## The rotations are given as active > xmat = rotation_matrix(angles[2], 0, active=True) > ymat = rotation_matrix(angles[1], 1, active=True) > zmat = rotation_matrix(angles[0], 2, active=True) > ## The operation seems to imply this composition > euler_comp_mat = np.dot(xmat, np.dot(ymat, zmat)) > --- ->--- > > I believe the matrices `euler_mat' and `euler_comp_mat' should be the > same, but they aren't, so it's unclear to me what particular composition > is meant to produce the matrix specified by this Z1Y2X3 transformation. > What am I missing? > > -- > Seb > > ___ > NumPy-Discussion mailing list > NumPy-Discussion@scipy.org > https://mail.scipy.org/mailman/listinfo/numpy-discussion > -- Robert McLeod, Ph.D. Center for Cellular Imaging and Nano Analytics (C-CINA) Biozentrum der Universität Basel Mattenstrasse 26, 4058 Basel Work: +41.061.387.3225 robert.mcl...@unibas.ch robert.mcl...@bsse.ethz.ch robbmcl...@gmail.com ___ NumPy-Discussion mailing

### Re: [Numpy-discussion] composing Euler rotation matrices

On Tue, 31 Jan 2017 21:23:55 -0500, Joseph Fox-Rabinovitzwrote: > Could you show what you are doing to get the statement "However, I > cannot reproduce this matrix via composition; i.e. by multiplying the > underlying rotation matrices.". I would guess something involving the > `*` operator instead of `@`, but guessing probably won't help you > solve your issue. Sure, although composition is not something I can take credit for, as it's a well-described operation for generating linear transformations. It is the matrix multiplication of two or more transformation matrices. In the case of Euler transformations, it's matrices specifying rotations around 3 orthogonal axes by 3 given angles. I'm using `numpy.dot' to perform matrix multiplication on 2D arrays representing matrices. However, it's not obvious from the link I provided what particular rotation matrices are multiplied and in what order (i.e. what composition) is used to arrive at the Z1Y2X3 rotation matrix shown. Perhaps I'm not understanding the conventions used therein. This is one of my attempts at reproducing that rotation matrix via composition: --- --- import numpy as np angles = np.radians(np.array([30, 20, 10])) def z1y2x3(alpha, beta, gamma): """Z1Y2X3 rotation matrix given Euler angles""" return np.array([[np.cos(alpha) * np.cos(beta), np.cos(alpha) * np.sin(beta) * np.sin(gamma) - np.cos(gamma) * np.sin(alpha), np.sin(alpha) * np.sin(gamma) + np.cos(alpha) * np.cos(gamma) * np.sin(beta)], [np.cos(beta) * np.sin(alpha), np.cos(alpha) * np.cos(gamma) + np.sin(alpha) * np.sin(beta) * np.sin(gamma), np.cos(gamma) * np.sin(alpha) * np.sin(beta) - np.cos(alpha) * np.sin(gamma)], [-np.sin(beta), np.cos(beta) * np.sin(gamma), np.cos(beta) * np.cos(gamma)]]) euler_mat = z1y2x3(angles[0], angles[1], angles[2]) ## Now via composition def rotation_matrix(theta, axis, active=False): """Generate rotation matrix for a given axis Parameters -- theta: numeric, optional The angle (degrees) by which to perform the rotation. Default is 0, which means return the coordinates of the vector in the rotated coordinate system, when rotate_vectors=False. axis: int, optional Axis around which to perform the rotation (x=0; y=1; z=2) active: bool, optional Whether to return active transformation matrix. Returns --- numpy.ndarray 3x3 rotation matrix """ theta = np.radians(theta) if axis == 0: R_theta = np.array([[1, 0, 0], [0, np.cos(theta), -np.sin(theta)], [0, np.sin(theta), np.cos(theta)]]) elif axis == 1: R_theta = np.array([[np.cos(theta), 0, np.sin(theta)], [0, 1, 0], [-np.sin(theta), 0, np.cos(theta)]]) else: R_theta = np.array([[np.cos(theta), -np.sin(theta), 0], [np.sin(theta), np.cos(theta), 0], [0, 0, 1]]) if active: R_theta = np.transpose(R_theta) return R_theta ## The rotations are given as active xmat = rotation_matrix(angles[2], 0, active=True) ymat = rotation_matrix(angles[1], 1, active=True) zmat = rotation_matrix(angles[0], 2, active=True) ## The operation seems to imply this composition euler_comp_mat = np.dot(xmat, np.dot(ymat, zmat)) --- --- I believe the matrices `euler_mat' and `euler_comp_mat' should be the same, but they aren't, so it's unclear to me what particular composition is meant to produce the matrix specified by this Z1Y2X3 transformation. What am I missing? -- Seb ___ NumPy-Discussion mailing list NumPy-Discussion@scipy.org https://mail.scipy.org/mailman/listinfo/numpy-discussion

### Re: [Numpy-discussion] composing Euler rotation matrices

Could you show what you are doing to get the statement "However, I cannot reproduce this matrix via composition; i.e. by multiplying the underlying rotation matrices.". I would guess something involving the `*` operator instead of `@`, but guessing probably won't help you solve your issue. -Joe On Tue, Jan 31, 2017 at 7:56 PM, Sebwrote: > Hello, > > I'm trying to compose Euler rotation matrices shown in > https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix. For > example, The Z1Y2X3 Tait-Bryan rotation shown in the table can be > represented in Numpy using the function: > > def z1y2x3(alpha, beta, gamma): > """Rotation matrix given Euler angles""" > return np.array([[np.cos(alpha) * np.cos(beta), > np.cos(alpha) * np.sin(beta) * np.sin(gamma) - > np.cos(gamma) * np.sin(alpha), > np.sin(alpha) * np.sin(gamma) + > np.cos(alpha) * np.cos(gamma) * np.sin(beta)], > [np.cos(beta) * np.sin(alpha), > np.cos(alpha) * np.cos(gamma) + > np.sin(alpha) * np.sin(beta) * np.sin(gamma), > np.cos(gamma) * np.sin(alpha) * np.sin(beta) - > np.cos(alpha) * np.sin(gamma)], > [-np.sin(beta), np.cos(beta) * np.sin(gamma), > np.cos(beta) * np.cos(gamma)]]) > > which given alpha, beta, gamma as: > > angles = np.radians(np.array([30, 20, 10])) > > returns the following matrix: > > In [31]: z1y2x3(angles[0], angles[1], angles[2]) > Out[31]: > > array([[ 0.81379768, -0.44096961, 0.37852231], >[ 0.46984631, 0.88256412, 0.01802831], >[-0.34202014, 0.16317591, 0.92541658]]) > > If I understand correctly, one should be able to compose this matrix by > multiplying the rotation matrices that it is made of. However, I cannot > reproduce this matrix via composition; i.e. by multiplying the > underlying rotation matrices. Any tips would be appreciated. > > -- > Seb > > ___ > NumPy-Discussion mailing list > NumPy-Discussion@scipy.org > https://mail.scipy.org/mailman/listinfo/numpy-discussion > ___ NumPy-Discussion mailing list NumPy-Discussion@scipy.org https://mail.scipy.org/mailman/listinfo/numpy-discussion