Exemple #1
0
Vector3 getXUnitVector( )
{
    Vector3 xUnitVector( 3 );

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

    return xUnitVector;
}
/*!
 * 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 ];
}
void computeRegolithVelocityVector2( std::vector< double > regolithPositionVector,
                                     const double velocityMagnitude,
                                     const double coneAngleAzimuth,
                                     const double coneAngleDeclination,
                                     std::vector< double > &unitNormalVector,
                                     std::vector< double > &regolithVelocityVector )
{
    // get the z basis vector of the surface frame
    std::vector< double > zUnitVector = unitNormalVector;

    std::vector< double > xUnitVector( 3 );
    std::vector< double > yUnitVector( 3 );

    // body frame principal axis Z
    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 };
    }
    else
    {
        // do the regular thing where the x basis is pointing to north
        // get the intermediate RTN frame at the surface point
        std::vector< double > unitR = normalize( regolithPositionVector );

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

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

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

    const double cosDelta = std::cos( coneAngleDeclination );
    const double sinDelta = std::sin( coneAngleDeclination );
    const double cosGamma = std::cos( coneAngleAzimuth );
    const double sinGamma = std::sin( coneAngleAzimuth );

    regolithVelocityVector[ 0 ] = velocityMagnitude * ( cosDelta * zUnitVector[ 0 ]
                                                        + sinDelta * cosGamma * xUnitVector[ 0 ]
                                                        + sinDelta * sinGamma * yUnitVector[ 0 ] );

    regolithVelocityVector[ 1 ] = velocityMagnitude * ( cosDelta * zUnitVector[ 1 ]
                                                        + sinDelta * cosGamma * xUnitVector[ 1 ]
                                                        + sinDelta * sinGamma * yUnitVector[ 1 ] );

    regolithVelocityVector[ 2 ] = velocityMagnitude * ( cosDelta * zUnitVector[ 2 ]
                                                        + sinDelta * cosGamma * xUnitVector[ 2 ]
                                                        + sinDelta * sinGamma * yUnitVector[ 2 ] );

}