/* ** Hapgood defines a transformation between GSE and HEE in his 1992 ** paper (section 6), but this part isn't online. ** ** The gist of it is, we rotate 180 degrees about Z, and then translate ** along X. ** ** But we also need to add "R", a constant vector defined by ** ** R = [ Rsun, 0, 0 ] ** ** where ** ** r0 (1 - e^2) ** Rsun = ------------ ** 1 + e cos(v) ** ** r0 = 1.495985E8 km mean distance of the Sun from Earth. ** ** e = 0.016709 - 0.0000418T0 eccentricity of the Sun's apparent ** orbit around the Earth. ** ** w = 282.94 + 1.72 T0 longitude of perigee of that orbit ** ** v = lambda0 - w (see lambda0 above) ** ** ** Implemented by Ed Santiago, Updated by Kristi Keller */ int gse_twixt_hee(const double et, Vec v_in, Vec v_out, Direction direction) { Mat mat; double r0,e, w,v, Rsun; hapgood_matrix(180, Z, mat); /* ** Note that there's no transposition here if the direction is "back"; ** the operation works identically in both directions. */ mat_times_vec(mat, v_in, v_out); /* Translate the X axis about the earth-sun distance */ r0 = (double)1.495985e8; e = 0.016709 - 0.0000418*T0(et); w = 282.94 + 1.72*T0(et); v = lambda0(et) - w; Rsun = r0*(1-e*e)/(1.+e*cosd(v)); /* v_out[0] += (double)1.5e8; */ v_out[0] += Rsun; return 0; }
/* ** The GSE to GSEQ transformation is given by the matrix ** ** T6 = <theta, X> ** ** where theta is the angle between the Y-axes in the two systems. A full ** description can be found at ** http://www-ssc.igpp.ucla.edu/personnel/russell/papers/gct1.html/#s3.5 ** (Geophysical Coordinate Transformations, C. T. Russell 1971) */ void mat_T6(const double et, Mat mat) { Vec GSE_ES, GEI_ES, thetaD; double theta, thetaN, magThetaD; Mat matT2; /* Get Earth-Sun vector in GEI */ GSE_ES[0] = 1.0; GSE_ES[1] = 0.0; GSE_ES[2] = 0.0; /* Convert GSE --> GEI */ mat_T2(et, matT2); mat_transpose(matT2, matT2); mat_times_vec(matT2, GSE_ES, GEI_ES); /* Rotation axis of the Sun (GEI): (1.217,- 0.424, 0.897) */ thetaN = GEI_ES[0]*(-0.032) + GEI_ES[1]*(-0.112) + GEI_ES[2]*(-0.048); thetaD[0] = (-0.424)*GEI_ES[2] - 0.897*GEI_ES[1]; thetaD[1] = 0.897*GEI_ES[0] - 0.1217*GEI_ES[2]; thetaD[2] = 0.1217*GEI_ES[1] - (-0.424)*GEI_ES[0]; magThetaD = sqrt(pow(thetaD[0],2) + pow(thetaD[1], 2) + pow(thetaD[2], 2)); theta = asin(thetaN/magThetaD); /* printf("Theta: %f\n", theta); */ hapgood_matrix((theta*RADIANS_TO_DEGREES), X, mat); /* TODO: Unknown why transpose is necessary to match previous results */ mat_transpose(mat,mat); }
/* ** vec_Qe ** ** don't ask. */ void vec_Qe(double et, Vec Qe) { double lat = mag_lat(et); double lon = mag_lon(et); double cos_lat = cos(lat); double sin_lat = sin(lat); double cos_lon = cos(lon); double sin_lon = sin(lon); Mat mat_tmp, mat; Vec Qg; Qg[0] = cos_lat * cos_lon; Qg[1] = cos_lat * sin_lon; Qg[2] = sin_lat; /* printf("lat=%lf lon=%lf\n", 90.0 - lat, lon);*/ mat_T2(et, mat); mat_T1(et, mat_tmp); mat_transpose(mat_tmp, mat_tmp); mat_times_mat(mat, mat_tmp, mat); mat_times_vec(mat, Qg, Qe); }
Vec* rotate_vec_x(Vec* v, double theta) { Mat* rotate_mat = create_mat(1, 0, 0, 0, 0, cos(theta), sin(theta), 0, 0, -sin(theta), cos(theta), 0, 0, 0, 0, 0); Vec* r = mat_times_vec(rotate_mat, v); delete_mat(rotate_mat); return r; }
Vec* rotate_vec(Vec* v, Vec* u, double theta) { double c = cos(theta); double s = sin(theta); double x1 = c + u->x * u->x * (1 - c); double x2 = u->x * u->y * (1 - c) - u->z * s; double x3 = u->x * u->z * (1 - c) + u->y * s; double y1 = u->y * u->x * (1 - c) + u->z * s; double y2 = c + u->y * u->y * (1 - c); double y3 = u->y * u->z * (1 - c) - u->x * s; double z1 = u->z * u->x * (1 - c) - u->y * s; double z2 = u->z * u->y * (1 - c) + u->x * s; double z3 = c + u->z * u->z * (1 - c); Mat* rotate_mat = create_mat(x1, y1, z1, 0, x2, y2, z2, 0, x3, y3, z3, 0, 0, 0, 0, 0); Vec* r = mat_times_vec(rotate_mat, v); delete_mat(rotate_mat); return r; }
/*********************\ ** simple_rotation ** utility function used by all the "twixt" functions ********************** ** ** This is basically what all the "twixt" functions do: ** ** 1) define a rotation matrix ** 2) If doing an inverse transformation, transpose that matrix. ** 3) multiply the rotation matrix by the input vector. ** ** To save all that work in the "twixt" functions, they just call this ** function, passing us a pointer to a function that defines the matrix. */ int simple_rotation(const double et, Vec v_in, Vec v_out, Direction d, void (*m)()) { Mat mat; /* ** Call the user-specified function to get a rotation matrix. */ (m)(et, mat); /* ** To do the inverse transformation, we use the transposition of the matrix */ if (d == BACK) mat_transpose(mat, mat); /* ** Multiply the rotation matrix by the input vector, and that's it! */ mat_times_vec(mat, v_in, v_out); return 0; }