/** Wrap the input angle to keep it within 2pi radians of the * angle to compare. * * @param [in] compareAngle * @param [in] angle Angle to be wrapped if needed * @return double Wrapped angle * */ double PixelOffset::WrapAngle(double compareAngle, double angle) { double diff1 = compareAngle - angle; if ( diff1 < -1*pi_c() ){ angle -= twopi_c(); } else if (diff1 > pi_c() ) { angle += twopi_c(); } return angle; }
int main (int argc, char **argv) { double lat, lon, time; furnsh_c("/home/user/BCGIT/ASTRO/standard.tm"); for (int i=0; i< 100000; i++) { lat = pi_c()*rand()/RAND_MAX-halfpi_c(); lon = twopi_c()*rand()/RAND_MAX-pi_c(); time = 1167721200.*rand()/RAND_MAX + 946684800.; // failing badly, so testing w/ knownish values // lat = 0.611738; // lon = -1.85878; // time = 1554616800.+i; // double elev = bc_elev(lat, lon, unix2et(time), "10"); double elev = bc_elev(lat, lon, unix2et(time), "10"); printf("%f,%f,%f,%f\n", lat, lon, time, elev); } }
void recrad_c ( ConstSpiceDouble rectan[3], SpiceDouble * range, SpiceDouble * ra, SpiceDouble * dec ) /* -Brief_I/O VARIABLE I/O DESCRIPTION -------- --- -------------------------------------------------- rectan I Rectangular coordinates of a point. range O Distance of the point from the origin. ra O Right ascension in radians. dec O Declination in radians. -Detailed_Input rectan The rectangular coordinates of a point. -Detailed_Output range is the distance of the point `rectan' from the origin. The units associated with `range' are those associated with the input `rectan'. ra is the right ascension of `rectan'. This is the angular distance measured toward the east from the prime meridian to the meridian containing the input point. The direction of increasing right ascension is from the +X axis towards the +Y axis. `ra' is output in radians. The range of `ra' is [0, 2*pi]. dec is the declination of `rectan'. This is the angle from the XY plane of the ray from the origin through the point. `dec' is output in radians. The range of `dec' is [-pi/2, pi/2]. -Parameters None. -Exceptions Error free. 1) If the X and Y components of `rectan' are both zero, the right ascension is set to zero. 2) If `rectan' is the zero vector, right ascension and declination are both set to zero. -Files None. -Particulars None. -Examples The following code fragment converts right ascension and declination from the B1950 reference frame to the J2000 frame. #include "SpiceUsr.h" SpiceDouble ra; SpiceDouble dec; SpiceDouble r; SpiceDouble mtrans [ 3 ][ 3 ]; SpiceDouble v1950 [ 3 ]; SpiceDouble v2000 [ 3 ]; /. Convert RA and DEC to a 3-vector expressed in the B1950 frame. ./ radrec_c ( 1.0, ra, dec, v1950 ); /. We use the CSPICE routine pxform_c to obtain the transformation matrix for converting vectors between the B1950 and J2000 reference frames. Since both frames are inertial, the input time value we supply to pxform_c is arbitrary. We choose zero seconds past the J2000 epoch as the input value. ./ pxform_c ( "B1950", "J2000", 0.0, mtrans ); /. Transform the vector to the J2000 frame. ./ mxv_c ( mtrans, v1950, v2000 ); /. Find the RA and DEC of the J2000-relative vector. ./ recrad_c ( v2000, &r, &ra, &dec ); -Restrictions None. -Author_and_Institution N.J. Bachman (JPL) H.A. Neilan (JPL) E.D. Wright (JPL) -Literature_References None. -Version -CSPICE Version 1.1.2, 30-JUL-2003 (NJB) Various header corrections were made. -CSPICE Version 1.1.0, 22-OCT-1998 (NJB) Made input vector const. -CSPICE Version 1.0.0, 08-FEB-1998 (EDW) -Index_Entries rectangular coordinates to ra and dec rectangular to right_ascension and declination -& */ { /* Begin recrad_c */ /* Call reclat_c to perform the conversion to angular terms. */ reclat_c ( rectan, range, ra, dec ); /* Right ascension is always in the domain [0, 2Pi]. Rectan_c returns ra in the domain [ -Pi, Pi ]. If ra is negative, add 2 Pi to map the value to the correct domain */ if ( *ra < 0. ) { *ra = *ra + twopi_c(); } } /* End recrad_c */
/** Cache J2000 rotation over existing cached time range using polynomials * * This method will reload an internal cache with matrices * formed from rotation angles fit to polynomials over a time * range. * * @param function1 The first polynomial function used to * find the rotation angles * @param function2 The second polynomial function used to * find the rotation angles * @param function3 The third polynomial function used to * find the rotation angles */ void LineScanCameraRotation::ReloadCache() { NaifStatus::CheckErrors(); // Make sure caches are already loaded if(!p_cachesLoaded) { QString msg = "A LineScanCameraRotation cache has not been loaded yet"; throw IException(IException::Programmer, msg, _FILEINFO_); } // Clear existing matrices from cache p_cache.clear(); // Create polynomials fit to angles & use to reload cache Isis::PolynomialUnivariate function1(p_degree); Isis::PolynomialUnivariate function2(p_degree); Isis::PolynomialUnivariate function3(p_degree); // Get the coefficients of the polynomials already fit to the angles of rotation defining [CI] std::vector<double> coeffAng1; std::vector<double> coeffAng2; std::vector<double> coeffAng3; GetPolynomial(coeffAng1, coeffAng2, coeffAng3); // Reset linear term to center around zero -- what works best is either roll-avg & pitchavg+ or pitchavg+ & yawavg- // coeffAng1[1] -= 0.0000158661225; // coeffAng2[1] = 0.0000308433; // coeffAng3[0] = -0.001517547; if(p_pitchRate) coeffAng2[1] = p_pitchRate; if(p_yaw) coeffAng3[0] = p_yaw; // Load the functions with the coefficients function1.SetCoefficients(coeffAng1); function2.SetCoefficients(coeffAng2); function3.SetCoefficients(coeffAng3); double CI[3][3]; double IJ[3][3]; std::vector<double> rtime; SpiceRotation *prot = p_spi->bodyRotation(); std::vector<double> CJ; CJ.resize(9); for(std::vector<double>::size_type pos = 0; pos < p_cacheTime.size(); pos++) { double et = p_cacheTime.at(pos); rtime.push_back((et - GetBaseTime()) / GetTimeScale()); double angle1 = function1.Evaluate(rtime); double angle2 = function2.Evaluate(rtime); double angle3 = function3.Evaluate(rtime); rtime.clear(); // Get the first angle back into the range Naif expects [180.,180.] if(angle1 < -1 * pi_c()) { angle1 += twopi_c(); } else if(angle1 > pi_c()) { angle1 -= twopi_c(); } eul2m_c((SpiceDouble) angle3, (SpiceDouble) angle2, (SpiceDouble) angle1, p_axis3, p_axis2, p_axis1, CI); mxm_c((SpiceDouble( *)[3]) & (p_jitter->SetEphemerisTimeHPF(et))[0], CI, CI); prot->SetEphemerisTime(et); mxm_c((SpiceDouble( *)[3]) & (p_cacheIB.at(pos))[0], (SpiceDouble( *)[3]) & (prot->Matrix())[0], IJ); mxm_c(CI, IJ, (SpiceDouble( *)[3]) &CJ[0]); p_cache.push_back(CJ); // J2000 to constant frame } // Set source to cache to get updated values SetSource(SpiceRotation::Memcache); // Make sure SetEphemerisTime updates the matrix by resetting it twice (in case the first one // matches the current et. p_et is private and not available from the child class NaifStatus::CheckErrors(); SetEphemerisTime(p_cacheTime[0]); SetEphemerisTime(p_cacheTime[1]); NaifStatus::CheckErrors(); }