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 > ®olithVelocityVector ) { // 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 ]; }