rsspice 0.1.0

Pure Rust port of the SPICE Toolkit for space geometry
Documentation
//
// GENERATED FILE
//

use super::*;
use crate::SpiceContext;
use f2rust_std::*;

struct SaveVars {
    INDEXS: StackArray<i32, 5>,
}

impl SaveInit for SaveVars {
    fn new() -> Self {
        let mut INDEXS = StackArray::<i32, 5>::new(1..=5);

        {
            use f2rust_std::data::Val;

            let mut clist = [Val::I(3), Val::I(1), Val::I(2), Val::I(3), Val::I(1)].into_iter();
            INDEXS
                .iter_mut()
                .for_each(|n| *n = clist.next().unwrap().into_i32());

            debug_assert!(clist.next().is_none(), "DATA not fully initialised");
        }

        Self { INDEXS }
    }
}

/// Generate a rotation matrix
///
/// Calculate the 3x3 rotation matrix generated by a rotation
/// of a specified angle about a specified axis. This rotation
/// is thought of as rotating the coordinate system.
///
/// # Brief I/O
///
/// ```text
///  VARIABLE  I/O  DESCRIPTION
///  --------  ---  --------------------------------------------------
///  ANGLE      I   Angle of rotation (radians).
///  IAXIS      I   Axis of rotation (X=1, Y=2, Z=3).
///  MOUT       O   Resulting rotation matrix [ANGLE]
///                                                 IAXIS
/// ```
///
/// # Detailed Input
///
/// ```text
///  ANGLE    is the angle, given in radians, through which the
///           rotation is performed.
///
///  IAXIS    is the index of the axis of rotation. The X, Y, and Z
///           axes have indices 1, 2 and 3 respectively.
/// ```
///
/// # Detailed Output
///
/// ```text
///  MOUT     is the rotation matrix which describes the rotation of
///           a reference frame through ANGLE radians about the axis
///           whose index is IAXIS.
/// ```
///
/// # Exceptions
///
/// ```text
///  Error free.
///
///  1)  If the axis index is not in the range 1 to 3, it will be
///      treated the same as that integer 1, 2, or 3 that is congruent
///      to it mod 3.
/// ```
///
/// # Particulars
///
/// ```text
///  A rotation about the first, i.e. x-axis, is described by
///
///     .-                            -.
///     |  1        0           0      |
///     |  0   cos(theta)  sin(theta)  |
///     |  0  -sin(theta)  cos(theta)  |
///     `-                            -'
///
///  A rotation about the second, i.e. y-axis, is described by
///
///     .-                            -.
///     |  cos(theta)  0  -sin(theta)  |
///     |      0       1        0      |
///     |  sin(theta)  0   cos(theta)  |
///     `-                            -'
///
///  A rotation about the third, i.e. z-axis, is described by
///
///     .-                            -.
///     |  cos(theta)  sin(theta)  0   |
///     | -sin(theta)  cos(theta)  0   |
///     |       0          0       1   |
///     `-                            -'
///
///  ROTATE decides which form is appropriate according to the value
///  of IAXIS.
/// ```
///
/// # Examples
///
/// ```text
///  If ROTATE is called from a FORTRAN program as follows:
///
///        CALL ROTATE (PI/4, 3, MOUT)
///
///  then MOUT will be given by
///
///               | SQRT(2)/2   SQRT(2)/2   0  |
///        MOUT = |-SQRT(2)/2   SQRT(2)/2   0  |
///               |     0           0       1  |
/// ```
///
/// # Author and Institution
///
/// ```text
///  J. Diaz del Rio    (ODC Space)
///  W.M. Owen          (JPL)
///  W.L. Taber         (JPL)
/// ```
///
/// # Version
///
/// ```text
/// -    SPICELIB Version 1.1.0, 25-MAY-2021 (JDR)
///
///         Added IMPLICIT NONE statement.
///
///         Edited the header to comply with NAIF standard.
///
/// -    SPICELIB Version 1.0.1, 10-MAR-1992 (WLT)
///
///         Comment section for permuted index source lines was added
///         following the header.
///
/// -    SPICELIB Version 1.0.0, 31-JAN-1990 (WMO) (WLT)
/// ```
///
/// # Revisions
///
/// ```text
/// -    Beta Version 1.1.0, 03-JAN-1989 (WLT)
///
///      Upgrade the routine to work with negative axis indexes. Also take
///      care of the funky way the indices (other than the input) were
///      obtained via the MOD function. It works but isn't as clear
///      (or fast) as just reading the axes from data.
/// ```
pub fn rotate(ctx: &mut SpiceContext, angle: f64, iaxis: i32, mout: &mut [[f64; 3]; 3]) {
    ROTATE(angle, iaxis, mout.as_flattened_mut(), ctx.raw_context());
}

//$Procedure ROTATE ( Generate a rotation matrix )
pub fn ROTATE(ANGLE: f64, IAXIS: i32, MOUT: &mut [f64], ctx: &mut Context) {
    let save = ctx.get_vars::<SaveVars>();
    let save = &mut *save.borrow_mut();

    let mut MOUT = DummyArrayMut2D::new(MOUT, 1..=3, 1..=3);
    let mut S: f64 = 0.0;
    let mut C: f64 = 0.0;
    let mut TEMP: i32 = 0;
    let mut I1: i32 = 0;
    let mut I2: i32 = 0;
    let mut I3: i32 = 0;

    //
    //

    //
    // Get the sine and cosine of ANGLE
    //
    S = f64::sin(ANGLE);
    C = f64::cos(ANGLE);
    //
    // Get indices for axes. The first index is for the axis of rotation.
    // The next two axes follow in right hand order (XYZ).  First get the
    // non-negative value of IAXIS mod 3 .
    //
    TEMP = intrinsics::MOD((intrinsics::MOD(IAXIS, 3) + 3), 3);

    I1 = save.INDEXS[(TEMP + 1)];
    I2 = save.INDEXS[(TEMP + 2)];
    I3 = save.INDEXS[(TEMP + 3)];

    //
    // Construct the rotation matrix
    //
    MOUT[[I1, I1]] = 1.0;
    MOUT[[I2, I1]] = 0.0;
    MOUT[[I3, I1]] = 0.0;
    MOUT[[I1, I2]] = 0.0;
    MOUT[[I2, I2]] = C;
    MOUT[[I3, I2]] = -S;
    MOUT[[I1, I3]] = 0.0;
    MOUT[[I2, I3]] = S;
    MOUT[[I3, I3]] = C;
    //
}