Example #1
0
Vector3 getZUnitVector( )
{
    Vector3 zUnitVector( 3 );

    // Set components of unit-vector.
    zUnitVector[ 0 ] = 0.0;
    zUnitVector[ 1 ] = 0.0;
    zUnitVector[ 2 ] = 1.0;

    return zUnitVector;
}
/*!
 * This sub-routine computes the velocity vector, given a magnitude, a unit normal vector from the
 * point on the surface where the regolith is lofted from, and the two conic angles which describe
 * the velocity vector's direction relative to the normal vector. A backwards approach is used
 * to go from the velocity vector in the final rotated intermediate frame back to the body fixed
 * frame. More details are given in the thesis report and author's personal notes.
 *
 */
void computeRegolithVelocityVector( std::vector< double > regolithPositionVector,
                                    const double velocityMagnitude,
                                    const double coneAngleAzimuth,
                                    const double coneAngleDeclination,
                                    std::vector< double > &unitNormalVector,
                                    std::vector< double > &regolithVelocityVector )
{
    // form the velocity vector, assuming that the intermediate frame's z-axis, on the surface of
    // the asteroid, is along the final velocity vector
    regolithVelocityVector[ 0 ] = 0.0;
    regolithVelocityVector[ 1 ] = 0.0;
    regolithVelocityVector[ 2 ] = velocityMagnitude;

    // get the rotatin matrix to go from the rotated intermediate frame back to the initial
    // frame where the z-axis was along the normal axis and the x-axis was pointing towards north
    // direction
    std::vector< std::vector< double > > zBasicRotationMatrix
            { { std::cos( coneAngleAzimuth ), std::sin( coneAngleAzimuth ), 0.0 },
              { -std::sin( coneAngleAzimuth ), std::cos( coneAngleAzimuth ), 0.0 },
              { 0.0, 0.0, 1.0 } };

    std::vector< std::vector< double > > yBasicRotationMatrix
            { { std::cos( coneAngleDeclination ), 0.0, -std::sin( coneAngleDeclination ) },
              { 0.0, 1.0, 0.0 },
              { std::sin( coneAngleDeclination ), 0.0, std::cos( coneAngleDeclination ) } };

    std::vector< std::vector< double > > nonTransposedRotationMatrix( 3, std::vector< double > ( 3 ) );

    matrixMultiplication( yBasicRotationMatrix,
                          zBasicRotationMatrix,
                          nonTransposedRotationMatrix,
                          3,
                          3,
                          3,
                          3 );

    std::vector< std::vector< double > > intermediateFrameRotationMatrix( 3, std::vector< double > ( 3 ) );

    matrixTranspose( nonTransposedRotationMatrix, intermediateFrameRotationMatrix );

    std::vector< std::vector< double > > rotatedIntermediateFrameVelocityVector
                { { regolithVelocityVector[ 0 ] },
                  { regolithVelocityVector[ 1 ] },
                  { regolithVelocityVector[ 2 ] } };

    std::vector< std::vector< double > > intermediateFrameVelocityVector( 3, std::vector< double > ( 1 ) );

    matrixMultiplication( intermediateFrameRotationMatrix,
                          rotatedIntermediateFrameVelocityVector,
                          intermediateFrameVelocityVector,
                          3,
                          3,
                          3,
                          1 );

    // now obtain the basis vectors for the intermediate frame expressed in the
    // body fixed frame coordinates
    std::vector< double > xUnitVector( 3 );
    std::vector< double > yUnitVector( 3 );
    std::vector< double > zUnitVector( 3 );

    zUnitVector = unitNormalVector;

    std::vector< double > bodyFrameZUnitVector { 0.0, 0.0, 1.0 };

    // get the intermediate RTN frame at the surface point
    std::vector< double > unitR = normalize( regolithPositionVector );

    std::vector< double > unitT = normalize( crossProduct( unitR, bodyFrameZUnitVector ) );

    // get the x basis vector, pointing to north
    xUnitVector = normalize( crossProduct( unitT, zUnitVector ) );

    // get the y basis vector
    yUnitVector = normalize( crossProduct( zUnitVector, xUnitVector ) );

    std::vector< double > zPrincipalAxisBodyFrame { 0.0, 0.0, 1.0 };
    std::vector< double > zNegativePrincipalAxisBodyFrame { 0.0, 0.0, -1.0 };

    // check if the position vector is along the poles
    const double positionDotPrincipalZ
            = dotProduct( normalize( regolithPositionVector ), zPrincipalAxisBodyFrame );
    const double positionDotNegativePrincipalZ
            = dotProduct( normalize( regolithPositionVector ), zNegativePrincipalAxisBodyFrame );
    if( positionDotPrincipalZ == 1.0 )
    {
        // the position vector is pointing to the poles, hence x basis vector pointing to the north
        // direction wouldn't work
        xUnitVector = { 1.0, 0.0, 0.0 };
        yUnitVector = { 0.0, 1.0, 0.0 };
    }
    else if( positionDotNegativePrincipalZ == 1.0 )
    {
        xUnitVector = { -1.0, 0.0, 0.0 };
        yUnitVector = { 0.0, 1.0, 0.0 };
    }

    // put the basis vectors in a 3x3 matrix
    std::vector< std::vector< double > > intermediateFrameBasisMatrix
            { { xUnitVector[ 0 ], yUnitVector[ 0 ], zUnitVector[ 0 ] },
              { xUnitVector[ 1 ], yUnitVector[ 1 ], zUnitVector[ 1 ] },
              { xUnitVector[ 2 ], yUnitVector[ 2 ], zUnitVector[ 2 ] } };

    std::vector< std::vector< double > > bodyFrameVelocityVector( 3, std::vector< double >( 1 ) );

    matrixMultiplication( intermediateFrameBasisMatrix,
                          intermediateFrameVelocityVector,
                          bodyFrameVelocityVector,
                          3,
                          3,
                          3,
                          1 );

    // return the final regolith velocity vector, expressed in body frame coordinates
    regolithVelocityVector[ 0 ] = bodyFrameVelocityVector[ 0 ][ 0 ];
    regolithVelocityVector[ 1 ] = bodyFrameVelocityVector[ 1 ][ 0 ];
    regolithVelocityVector[ 2 ] = bodyFrameVelocityVector[ 2 ][ 0 ];
}