Geometry helpers (pycraf.geometry)#

Introduction#

The geometry sub-package just offers some convenience functions for various geometrical calculations, e.g., in spherical coordinates.

Using pycraf.geometry#

Spherical coordinates#

One can convert between cartesian and spherical coordinates using the two functions cart_to_sphere and sphere_to_cart:

>>> from pycraf import geometry
>>> from astropy import units as u
>>> import numpy as np

>>> r, az, el = 1 * u.m, 0 * u.deg, 90 * u.deg  # z-axis
>>> geometry.sphere_to_cart(r, az, el)  
(<Quantity 0.0 m>, <Quantity 0.0 m>, <Quantity 1.0 m>)

>>> x, y, z = 200 * u.m, 1.1 * u.km, 500 * u.m
>>> geometry.cart_to_sphere(x, y, z)  
(<Quantity 1224.745 m>, <Quantity 79.69515 deg>, <Quantity 24.09484 deg>)

Note

In contrast to the often-used mathematical convention, pycraf does not work with the zenith distances but height above the horizon (i.e., elevation).

Very useful are the two functions true_angular_distance and great_circle_bearing, which allow to determine the true angular separation between two points on the sphere and the bearing of a point on the sphere w.r.t. another point:

>>> l1, b1 = 25 * u.deg, 34 * u.deg
>>> l2, b2 = 19 * u.deg, 54 * u.deg
>>> geometry.true_angular_distance(l1, b1, l2, b2)  
<Quantity 20.4425 deg>
>>> geometry.great_circle_bearing(l1, b1, l2, b2)  
<Quantity -10.1317 deg>

Warning

If you need angular distances/bearings on the Geoid with high accuracy use the Geodesics methods in the pathprof subpackage.

Rotation matrices#

Sometimes one needs to rotate quantities (e.g., antenna diagrams) in 3D space when using compatibility studies. In pycraf a few routines are provided that offer basic functionality. Rotations are easily performed using matrix algebra, where \(\vec y=R\vec x\). Rotation matrices must be orthogonal (\(R^{-1}=R^\mathrm{T}\)) and have determinant \(\det R=+1\).

Two easy ways are implemented in pycraf to construct rotation matrices. The first is via concatenation, \(R=R_z(\alpha_3)R_y(\alpha_2)R_x(\alpha_1)\), of the three basic rotation matrices:

\[\begin{split}R_x = \begin{bmatrix} 1 & 0 & 0 \\ 0 & \cos \theta & -\sin \theta \\ 0 & \sin \theta & \cos \theta \end{bmatrix}, R_y = \begin{bmatrix} \cos \theta & 0 & \sin \theta\\ 0 & 1 & 0 \\ -\sin \theta & 0 & \cos \theta \end{bmatrix}, R_z = \begin{bmatrix} \cos \theta & -\sin \theta & 0 \\ \sin \theta & \cos \theta & 0 \\ 0 & 0 & 1 \end{bmatrix}\end{split}\]

Note

One can also use other combinations of the basic rotation matrices (in total there are 24 different possibilities). Apart from the ‘xyz’ order, a common scheme is ‘zxz’, i.e., \(R=R_z(\alpha_3)R_x(\alpha_2)R_z(\alpha_1)\). The rotation angles are often called Euler angles.

Note

The right-most matrix is applied first, but since rotation matrices are associative one can just calculate the matrix multiplication (in any order) and apply the result to the target vector.

Example:

>>> R = geometry.multiply_matrices(
...     geometry.Rz(10 * u.deg),
...     geometry.Ry(-30 * u.deg),
...     geometry.Rx(-15 * u.deg),
...     )
>>> R  
array([[ 0.85286853, -0.04028776, -0.52056908],
       [ 0.15038373,  0.97372297,  0.17102137],
       [ 0.5       , -0.22414387,  0.8365163 ]])

>>> vector = (1, 4, -2) * u.m
>>> np.matmul(R, vector)  
<Quantity [ 1.73286, 3.70323,-2.06961] m>

The second approach is by specifying a rotation axis and angle and use Rodrigues’ Rotation Formula:

>>> rotax = (0.5, 0.2, -0.8) * u.m
>>> rotang = -10 * u.deg
>>> R2 = geometry.rotmat_from_rotaxis(*rotax, rotang)
>>> R2  
array([[ 0.98889169, -0.14241824, -0.04254725],
       [ 0.14568539,  0.98546118,  0.08741867],
       [ 0.02947865, -0.09264611,  0.99526263]])

It is possible to extract the Euler angles or the rotation axis/angle from a given rotation matrix, with the functions eulerangle_from_rotmat and rotaxis_from_rotmat, but keep in mind that the solution is not unique!

See Also#

Reference/API#

pycraf.geometry Package#

Contains convenience functions for geometrical calculations on the sphere.

Functions#

Rx(angle)

Construct rotation matrix about x-axis.

Ry(angle)

Construct rotation matrix about y-axis.

Rz(angle)

Construct rotation matrix about z-axis.

cart_to_sphere(x, y, z[, broadcast_arrays])

Spherical coordinates from Cartesian representation.

eulerangle_from_rotmat(R[, etype])

Cartesian rotation axis and angle from rotation matrix.

great_circle_bearing(l1, b1, l2, b2)

Great circle bearing between points (l1, b1) and (l2, b2).

multiply_matrices(*matrices)

Matrix-multiply the matrices in the given list.

rotaxis_from_rotmat(R)

Cartesian rotation axis and angle from rotation matrix.

rotmat_from_rotaxis(rotax_x, rotax_y, ...)

Construct rotation matrix from cartesian rotation axis and angle.

sphere_to_cart(r, phi, theta[, broadcast_arrays])

Spherical coordinates from Cartesian representation.

true_angular_distance(l1, b1, l2, b2)

True angular distance between points (l1, b1) and (l2, b2).