Every symmetry class in this library is defined up to an orientation — an axis for transverse isotropy, a full frame for orthotropy — so the angular convention is part of the specification, not a detail. This page states the one TensND implements, read off _rot3_raw in src/tens_projection.jl and rotation_matrix and rotation_tensor4 in src/special_tens.jl.
The rotation of this page: the canonical basis at the center of the unit sphere, the rotated basis at the tip of . The sliders set the three angles and the scene turns with the mouse; how the three rotations compose is read in The three rotations.
is therefore the polar angle from and the azimuth. This is what makes the convention the natural one here: a transversely isotropic tensor is oriented by alone, so its projection is parametrized by with irrelevant, while orthotropy needs all three. The degeneracy at , where no longer affects , is why the orientation search screens axes spread over a hemisphere rather than a grid in , which would crowd them at the pole.
Spherical coordinates use the same angles in a different slot order
The predefined spherical coordinate system returns its coordinates as , not , precisely so that reproduces the canonical basis in the canonical order. See Curvilinear differential calculus.
Read from the left, is a chain of rotations, each about an axis that the previous ones have moved:
about turns into the line of nodes;
about the line of nodes tilts into , within the meridian plane of azimuth , and carries the image of to ;
about turns the pair within the plane tangent to the unit sphere at .
The rotated basis is therefore
and , the frame makes of the canonical basis, is the normalized basis of the spherical coordinates at the point (Predefined systems); the figure at the top of this page draws and dashed, in the plane tangent to the sphere. At the line of nodes is still drawn, but and then turn about the same axis and only their sum matters: the gimbal lock met again under Recovering angles from a frame.
A rotation drawn "at random" should favor no orientation: its law must be unchanged when every rotation is composed with a fixed one. On there is exactly one such probability, the Haar measure. In the angles of this page it reads
so drawing uniformly is wrong: the axis , of height , would fall near the poles as often as near the equator, where the area to fill is largest. The height must be uniform on instead (the sphere and its circumscribed cylinder have the same area between two horizontal planes), so that , where uniform angles give .
random_rotation does without angles. Unit quaternions form the sphere of , and maps them two to one onto , products to products. Multiplying by a fixed unit quaternion, on either side, is an orthogonal map of , which preserves the uniform law on ; its image on is therefore invariant under the compositions on either side, hence the Haar measure. The uniform law on is the direction of a vector of four independent standard normal numbers, whose law is invariant under every orthogonal map. Likewise random_axis normalizes three standard normal numbers.
Two consequences serve as checks. The angle of a Haar rotation, , has the density on : small rotations are rare. And the trace has mean and mean square , the moments of the character of an irreducible representation.
Coefficients. A rotation acts on the Kelvin–Mandel vector of a symmetric tensor of order 2 by an orthogonal matrix (Kelvin–Mandel representation), so a law of Kelvin–Mandel matrices invariant under all orthogonal changes of basis is invariant under rotations. The Gaussian orthogonal ensemble (symmetric, normal entries of variance on the diagonal and off it) is one; so is with of Haar law on and any law of eigenvalues, and a matrix of independent standard normal entries. rand draws generic tensors from them, and the blocks of the structured classes from their analogues of size 2 or 3. In Voigt notation the same draws would not be invariant: the change of basis is not orthogonal there.
The inverse problem, extracting from an orthonormal matrix, is angles(M, Val{3}) in src/bases.jl. It is used when a symmetry frame has been obtained as an eigenvector basis and must be reported as angles.
Two caveats, inherent to any three-angle parametrization of :
the map is not injective — and give the same ;
it degenerates at the poles (gimbal lock): at the matrix reduces to , so only the sum is determined; at only the difference is.
Neither affects the projections: the objective functions of Projection onto a symmetry class depend on the frame, not on the angles chosen to name it, so a degenerate parametrization costs at worst a redundant starting point.