Exemple #1
0
/*
 * Given vectors a and b, compute the angle between them in degrees
 */
double Lgm_VectorAngle(Lgm_Vector *a, Lgm_Vector *b) {
  double ang;
  Lgm_Vector  u, v;
  u = *a;
  v = *b;
  Lgm_NormalizeVector(&u);
  Lgm_NormalizeVector(&v);
  ang = acos(Lgm_DotProduct(&u, &v));
  return (ang*DegPerRad);
}
Exemple #2
0
/**
 *  \brief
 *      Compute the curl of B and it's parallel and perpendicular components at a given point.
 *
 *  \details
 *      Computes \f$ \nabla\times B \f$, \f$ (\nabla\times B)_\parallel \f$, and \f$ (\nabla\times B)_\perp \f$.
 *
 *
 *      \param[in]      u0          Position (in GSM) to use.
 *      \param[out]     CurlB       The computed curl of B at position u0.
 *      \param[out]     CurlB_para  The computed parallel component of curl of B at position u0.
 *      \param[out]     CurlB_perp  The computed perpendicular component of curl of B at position u0.
 *      \param[in]      DerivScheme Derivative scheme to use (can be one of LGM_DERIV_SIX_POINT, LGM_DERIV_FOUR_POINT, or LGM_DERIV_TWO_POINT).
 *      \param[in]      h           The delta (in Re) to use for grid spacing in the derivative scheme.
 *      \param[in,out]  m           A properly initialized and configured Lgm_MagModelInfo structure.
 *
 *
 *      \author         Mike Henderson
 *      \date           2011
 *
 */
void Lgm_CurlB2( Lgm_Vector *u0, Lgm_Vector *CurlB, Lgm_Vector *CurlB_para, Lgm_Vector *CurlB_perp, int DerivScheme, double h, Lgm_MagModelInfo *m ) {

    double      g;
    Lgm_Vector  Bvec;


    Lgm_CurlB( u0, CurlB, DerivScheme, h, m );


    m->Bfield( u0, &Bvec, m );
    Lgm_NormalizeVector( &Bvec );

    // Compute parallel component of CurlB
    g = Lgm_DotProduct( &Bvec, CurlB );
    *CurlB_para = *CurlB;
    Lgm_ScaleVector( CurlB_para, g );


    // Compute perpendicular component of CurlB (CurlB_perp = CurlB - CurlB_para)
    Lgm_VecSub( CurlB_perp, CurlB, CurlB_para );


    return;

}
Exemple #3
0
/**
 *  \brief
 *      Compute the gradient of B and it's parallel and perpendicular components at a given point.
 *
 *  \details
 *      Computes \f$ \nabla B \f$, \f$ (\nabla B)_\parallel \f$, and \f$ (\nabla B)_\perp \f$.
 *
 *
 *      \param[in]      u0          Position (in GSM) to use.
 *      \param[out]     GradB       The computed curl of B at position u0.
 *      \param[out]     GradB_para  The computed parallel component of curl of B at position u0.
 *      \param[out]     GradB_perp  The computed perpendicular component of curl of B at position u0.
 *      \param[in]      DerivScheme Derivative scheme to use (can be one of LGM_DERIV_SIX_POINT, LGM_DERIV_FOUR_POINT, or LGM_DERIV_TWO_POINT).
 *      \param[in]      h           The delta (in Re) to use for grid spacing in the derivative scheme.
 *      \param[in,out]  m           A properly initialized and configured Lgm_MagModelInfo structure.
 *
 *
 *      \author         Mike Henderson
 *      \date           2011
 *
 */
void Lgm_GradB2( Lgm_Vector *u0, Lgm_Vector *GradB, Lgm_Vector *GradB_para, Lgm_Vector *GradB_perp, int DerivScheme, double h, Lgm_MagModelInfo *m ) {

    double      g;
    Lgm_Vector  Bvec;


    Lgm_GradB( u0, GradB, DerivScheme, h, m );


    m->Bfield( u0, &Bvec, m );
    Lgm_NormalizeVector( &Bvec );

    // Compute parallel component of GradB
    g = Lgm_DotProduct( &Bvec, GradB );
    *GradB_para = *GradB;
    Lgm_ScaleVector( GradB_para, g );


    // Compute perpendicular component of GradB (GradB_perp = GradB - GradB_para)
    Lgm_VecSub( GradB_perp, GradB, GradB_para );


    return;

}
Exemple #4
0
int main(){


  Lgm_Vector      a, b, z1, z2;
    Lgm_SlerpInfo   s;
    double          alpha;

    a.x = 1.0; a.y = 1.0; a.z = 1.0;
    b.x = 0.0; b.y = -1.0; b.z = 1.0;

    Lgm_NormalizeVector( &a );
    Lgm_NormalizeVector( &b );

    Lgm_InitSlerp( &a, &b, &s );
    

    alpha = 0.1;
    Lgm_Slerp( &a, &b, &z1, alpha, &s );

    printf("Results of slerping:\n");
    Lgm_PrintVector(&a);
    Lgm_PrintVector(&b);
    Lgm_PrintVector(&z1);

    z2.x = (1.0-alpha)*a.x + alpha*b.x;
    z2.y = (1.0-alpha)*a.y + alpha*b.y;
    z2.z = (1.0-alpha)*a.z + alpha*b.z;
    Lgm_NormalizeVector( &z2 );

    printf("Results of interpolating components (and re-normalizing):\n");
    Lgm_PrintVector(&a);
    Lgm_PrintVector(&b);
    Lgm_PrintVector(&z2);

    Lgm_VecSub(&a, &z1, &z2); 
    printf("\nThey are different by:\n");
    Lgm_PrintVector(&a);

    return(0);


}
Exemple #5
0
/*
 *  This routinem determines the angle and axis of rotation implied
 *  by a (normalized) quaternion.
 *
 *  Input:
 *      Q[4]  -- four element array containing Qx, Qy, Qz, Qw
 *
 *  Output:
 *
 *      Angle -- angle (in degrees) of rotation.
 *      u     -- unit vector of rotation axis.
 *
 *
 */
void Lgm_QuatToAxisAngle( double *Q, double *Angle, Lgm_Vector *u ) {

    double  Aover2, SinAover2, SinAover2_inv;


    /*
     * Force normalization of Q
     */
    Lgm_NormalizeQuat( Q );

    if ( (1.0-fabs(Q[3])) < 1e-8 ) {

        /*
         *  Rotation angle is close to zero
         *  (Its either A/2 = 0 (i.e. A = 0) or
         *  A/2 = 180 (i.e. A = 360))
         *  Rotation axis is arbitrary
         */
        *Angle = 0.0;
        u->x = 0.0;
        u->y = 0.0;
        u->z = 1.0;

    } else {

        /*
         *  Determine Angle/2
         */
        Aover2 = acos( Q[3] );
        *Angle = 2.0*Aover2*DegPerRad;

        /* 
         * Compute 1.0/sin(Angle/2)
         */
        SinAover2 = sqrt( 1.0 - Q[3]*Q[3] );
        SinAover2_inv = 1.0/SinAover2;

        /*
         *  Compute components of rotation axis
         */
        u->x = Q[0]*SinAover2;
        u->y = Q[1]*SinAover2;
        u->z = Q[2]*SinAover2;
        Lgm_NormalizeVector( u );


    }



}
Exemple #6
0
/*
 * Take exp() of a purely imaginary quaternion.
 */
void Lgm_QuatExp( double Q[4], double expQ[4] ) {

    double     Theta, SinTheta, CosTheta;
    Lgm_Vector u;

    u.x = Q[0];
    u.y = Q[1];
    u.z = Q[2];
    Theta = Lgm_NormalizeVector( &u );
    SinTheta = sin( Theta );
    CosTheta = cos( Theta );

    expQ[0] = SinTheta*u.x;
    expQ[1] = SinTheta*u.y;
    expQ[2] = SinTheta*u.z;
    expQ[3] = CosTheta;

}
Exemple #7
0
/* 
 * makes the given vector have a magnitude of mag
 */
void Lgm_ForceMagnitude(Lgm_Vector *a, double mag) {
    Lgm_NormalizeVector(a);
    Lgm_ScaleVector(a, mag);
}
void ComputeZPSTransMatrix( Lgm_Vector *Rgeo, long int Date, double UT, double Agsm_to_ins[3][3], double Ains_to_gsm[3][3], double Qins_to_gsm[4], double Qgsm_to_ins[4] ) {

    double  Glon, Alpha, A, B, ca, sa, sum;
    Lgm_Vector  Xgeo, Ygeo, Zgeo, Xgsm, Ygsm, Zgsm;
    Lgm_Vector  Ngeo, Egeo, Ngsm, Egsm;
    Lgm_Vector  Xsc_geo,Ysc_geo, Zsc_geo;
    Lgm_Vector  Xsc_gsm,Ysc_gsm, Zsc_gsm;
    double  Agsm_to_sc[3][3], Asc_to_gsm[3][3], Asc_to_r3[3][3], Ar3_to_sc[3][3], Asc_to_dom[3][3], Adom_to_sc[3][3];  
    Lgm_Vector  X1, Y1, Z1;
    Lgm_Vector  X2, Y2, Z2;
    Lgm_Vector  X3, Y3, Z3;
    Lgm_Vector  X4, Y4, Z4;
    int     i, j, k;
    Lgm_CTrans  c;
    Lgm_Vector Xins, Yins, Zins, Xsc, Ysc, Zsc;
    Lgm_Vector Xins_new, Yins_new, Zins_new;
    double  Q1[4], Q2[4], Q3[4], QQ[4], QT1[4];



    Glon = atan2( Rgeo->y, Rgeo->x );



    /*
     *  Compute transformation matrix from dome coords to GSM
     *  Assume spacecraft is located at Rgeo.
     */
    
    
    /*
     * Nadir in GEO coords.
     */
    Ngeo.x = -Rgeo->x;
    Ngeo.y = -Rgeo->y;
    Ngeo.z = -Rgeo->z;
    Lgm_NormalizeVector( &Ngeo );
    

    
    /*
     *   East in GEO coords. Since, r = {cos(phi), sin(phi)}
     *   east direction will be dr/dphi which is;
     *
     *      east = {-sin(phi), cos(phi)}
     *  
     *   note that phi is just glon in GEO coords.
     *  
     */
    Egeo.x = -1.0*sin(Glon);
    Egeo.y = cos(Glon);
    Egeo.z = 0.0;


    /*
     * North in GEO coords.
     */
    Zgeo.x = 0.0;
    Zgeo.y = 0.0;
    Zgeo.z = 1.0;




    /*
     *  Define S/C coords as:
     *   X: East
     *   Y: South
     *   Z: Nadir
     */
    Xsc_geo = Egeo;
    Ysc_geo.x = -Zgeo.x; Ysc_geo.y = -Zgeo.y; Ysc_geo.z = -Zgeo.z;
    Zsc_geo = Ngeo;


    /*
     *  Convert to GSM
     */
    Lgm_Set_Coord_Transforms( Date, UT, &c );
    Lgm_Convert_Coords( &Xsc_geo, &Xsc_gsm, GEO_TO_GSM, &c );
    Lgm_Convert_Coords( &Ysc_geo, &Ysc_gsm, GEO_TO_GSM, &c );
    Lgm_Convert_Coords( &Zsc_geo, &Zsc_gsm, GEO_TO_GSM, &c );

Xsc_gsm = Xsc_geo;
Ysc_gsm = Ysc_geo;
Zsc_gsm = Zsc_geo;


    /*
     *  Construct Transformation Matrix from GSM to S/C
     */
    Agsm_to_sc[0][0] = Xsc_gsm.x, Agsm_to_sc[1][0] =  Xsc_gsm.y, Agsm_to_sc[2][0] = Xsc_gsm.z;
    Agsm_to_sc[0][1] = Ysc_gsm.x, Agsm_to_sc[1][1] =  Ysc_gsm.y, Agsm_to_sc[2][1] = Ysc_gsm.z;
    Agsm_to_sc[0][2] = Zsc_gsm.x, Agsm_to_sc[1][2] =  Zsc_gsm.y, Agsm_to_sc[2][2] = Zsc_gsm.z;

    Asc_to_gsm[0][0] = Xsc_gsm.x, Asc_to_gsm[1][0] =  Ysc_gsm.x, Asc_to_gsm[2][0] = Zsc_gsm.x;
    Asc_to_gsm[0][1] = Xsc_gsm.y, Asc_to_gsm[1][1] =  Ysc_gsm.y, Asc_to_gsm[2][1] = Zsc_gsm.y;
    Asc_to_gsm[0][2] = Xsc_gsm.z, Asc_to_gsm[1][2] =  Ysc_gsm.z, Asc_to_gsm[2][2] = Zsc_gsm.z;
printf("             ( %5g %5g %5g )\n", Asc_to_gsm[0][0],  Asc_to_gsm[1][0], Asc_to_gsm[2][0] );
printf("Asc_to_gsm = ( %5g %5g %5g )\n", Asc_to_gsm[0][1],  Asc_to_gsm[1][1], Asc_to_gsm[2][1] );
printf("             ( %5g %5g %5g )\n", Asc_to_gsm[0][2],  Asc_to_gsm[1][2], Asc_to_gsm[2][2] );




    /*
     *  Now construct trans matrix between S/C and INSTRUMENT
     *
     *  Lets define the instrument coord system to be as follows:
     *     Yins: parallel to instrument cylindrical symmetry axis.
     *     Zins: parallel to FOV of 
     */


    /*
     *  Here is the prescription to orient ZPS:
     *
     *      1. Start with Yins parallel to Ysc and Zins parallel to Zsc
     *      2. Rotate by -29 deg. about Zsc
     *      3. Then rotate by +45.5 deg. about Yins
     *      4. Then roate by +30.0 deg. about Zins
     * 
     * The easiest way to do this is to use Quaternions
     * 
     */
    
    // Step 1
    Xins = Xsc_gsm;
    Yins = Ysc_gsm;
    Zins = Zsc_gsm;

    // Step2
    //Lgm_AxisAngleToQuat( &Zins, -29.0, Q1 );
    Lgm_AxisAngleToQuat( &Zins, 0.0, Q1 );
    Lgm_QuatRotateVector( Q1, &Xins, &Xins_new ); Xins = Xins_new;
    Lgm_QuatRotateVector( Q1, &Yins, &Yins_new ); Yins = Yins_new;
    Lgm_QuatRotateVector( Q1, &Zins, &Zins_new ); Zins = Zins_new;

    // Step3
    //Lgm_AxisAngleToQuat( &Yins, 45.5, Q2 );
    Lgm_AxisAngleToQuat( &Yins, 0.0, Q2 );
    Lgm_QuatRotateVector( Q2, &Xins, &Xins_new ); Xins = Xins_new;
    Lgm_QuatRotateVector( Q2, &Yins, &Yins_new ); Yins = Yins_new;
    Lgm_QuatRotateVector( Q2, &Zins, &Zins_new ); Zins = Zins_new;
    
    // Step4
    //Lgm_AxisAngleToQuat( &Zins, 30.0, Q3 );
    Lgm_AxisAngleToQuat( &Zins, 0.0, Q3 );
    Lgm_QuatRotateVector( Q3, &Xins, &Xins_new ); Xins = Xins_new;
    Lgm_QuatRotateVector( Q3, &Yins, &Yins_new ); Yins = Yins_new;
    Lgm_QuatRotateVector( Q3, &Zins, &Zins_new ); Zins = Zins_new;

    /*
     *  Now, Xins, Yins, Zins will be oriented in their final positions.
     *  We can construct the sc -> ins trans matrix in one of two wyas now.
     *      1. combine all of the quats and then convert Q->matrix
     *  or  2. use the final unit vectors to manually construct the matri.
     *  Try both...
     */

    Lgm_QuatCombineQuats( Q1, Q2, QT1 );
    Lgm_QuatCombineQuats( QT1, Q3, QQ );
    for (i=0; i<4; i++) Qins_to_gsm[i] = QQ[i];

    Lgm_Quat_To_Matrix( QQ, Ains_to_gsm );

    for (i=0; i<3; ++i){ 
        for (j=0; j<3; ++j){ 
            Agsm_to_ins[i][j] = Ains_to_gsm[j][i];
        }
    }
    Lgm_MatrixToQuat( Agsm_to_ins, Qgsm_to_ins );

Lgm_MatrixToQuat( Agsm_to_sc, Qgsm_to_ins );
Lgm_MatrixToQuat( Asc_to_gsm, Qins_to_gsm );
}
Exemple #9
0
int main(void) {
  Lgm_Vector *v, *v2;
  double Lat, Lon, r, ang;
  double Arr[3];

  printf("Make a Vector:\n");
  v = Lgm_CreateVector(1,2,3);
  Lgm_PrintVector(v);

  printf("Normalize it:\n");
  Lgm_NormalizeVector(v);
  Lgm_PrintVector(v);

  printf("Force it to have a magnitude:\n");
  Lgm_ForceMagnitude(v, 2);
  Lgm_PrintVector(v);

  printf("Set its value:\n");
  Lgm_SetVecVal(v, 3);
  Lgm_PrintVector(v);

  printf("Set its elements:\n");
  Lgm_SetVecElements(v, 1,2,3);
  Lgm_PrintVector(v);

  printf("Change it to spherical:\n");
  Lgm_CartToSphCoords(v, &Lat, &Lon, &r);
  printf("Lat:%lf Lon:%lf r:%lf\n", Lat, Lon, r);

  printf("And back to Cart:\n");
  Lgm_SphToCartCoords(Lat, Lon, r, v );
  Lgm_PrintVector(v);

  printf("Make it an array:\n");
  Lgm_VecToArr(v, Arr);
  printf("Arr[0]:%lf Arr[1]:%lf Arr[2]:%lf\n", Arr[0], Arr[1], Arr[2]);

  printf("Edit the array and make it a vector:\n");
  Arr[0] = -1;
  Lgm_ArrToVec(Arr, v);
  Lgm_PrintVector(v);

  printf("Divide it by a scalar:\n");
  Lgm_VecDivideScalar(v, 2);
  Lgm_PrintVector(v);

  printf("Multiply by a scalar:\n");
  Lgm_VecMultiplyScalar(v, 2);
  Lgm_PrintVector(v);

  printf("Make a new vector and get the angle between them:\n");
  v2 = Lgm_CreateVector(1,0,0);
  Lgm_SetVecElements(v, 0, 1, 0);
  ang = Lgm_VectorAngle(v, v2);
  printf("Angle:%lf\n", ang);

  printf("Make a new vector and get the angle between them:\n");
  Lgm_SetVecElements(v, 0, 1, 0);
  Lgm_SetVecElements(v2, 0, 1, 0);
  ang = Lgm_VectorAngle(v, v2);
  printf("Angle:%lf\n", ang);

  Lgm_FreeVector(v);
  Lgm_FreeVector(v2);
  return(0);
}