Beispiel #1
0
int fill_planet_data( PLANET_DATA *pdata, const int planet_no, const double jd,
                  const double observer_lat, const double observer_lon,
                  const char *vsop_data)
{
   double loc_sidereal_time = green_sidereal_time( jd) + observer_lon;
   double t_centuries = (jd - J2000) / 36525.;
   double obliquity = mean_obliquity( t_centuries);
   double loc[3];

   pdata->jd = jd;
   if( planet_no == 10)         /* get lunar data,  not VSOP */
      {
      double fund[N_FUND];

      lunar_fundamentals( vsop_data, t_centuries, fund);
      lunar_lon_and_dist( vsop_data, fund, &pdata->ecliptic_lon, &pdata->r, 0L);
      pdata->ecliptic_lon *= pi / 180.;
      pdata->ecliptic_lat = lunar_lat( vsop_data, fund, 0L) * pi / 180.;
      }
   else
      {
                  /* What we _really_ want is the location of the sun as */
                  /* seen from the earth.  VSOP gives us the opposite,   */
                  /* i.e.,  where the _earth_ is as seen from the _sun_. */
                  /* To evade this,  we add PI to the longitude and      */
                  /* negate the latitude.                                */
      pdata->ecliptic_lon =
               calc_vsop_loc( vsop_data, planet_no, 0, t_centuries, 0.) + pi;
      pdata->ecliptic_lat =
                  -calc_vsop_loc( vsop_data, planet_no, 1, t_centuries, 0.);
      pdata->r   = calc_vsop_loc( vsop_data, planet_no, 2, t_centuries, 0.);
      }


   polar3_to_cartesian( loc, pdata->ecliptic_lon, pdata->ecliptic_lat);
   memcpy( pdata->ecliptic_loc, loc, 3 * sizeof( double));

                  /* At this point,  loc is a unit vector in ecliptic */
                  /* coords of date.  Rotate it by 'obliquity' to get */
                  /* a vector in equatorial coords of date: */

   rotate_vector( loc, obliquity, 0);
   memcpy( pdata->equatorial_loc, loc, 3 * sizeof( double));

               /* The following two rotations take us from a vector in */
               /* equatorial coords of date to an alt/az vector: */
   rotate_vector( loc, -loc_sidereal_time, 2);
/* printf( "LST: %lf\n", fmod( loc_sidereal_time * 180. / pi, 360.)); */
   pdata->hour_angle = atan2( loc[1], loc[0]);
   rotate_vector( loc, observer_lat - pi / 2., 1);
   memcpy( pdata->altaz_loc, loc, 3 * sizeof( double));
   return( 0);
}
Beispiel #2
0
int main( const int argc, const char **argv)
{
   const double j2000 = 2451545.;    /* 1.5 Jan 2000 = JD 2451545 */
   int i, julian = 0, verbose = 0, chinese_calendar = 0;
   double t, t_centuries, t_cen2, t_cen3, t_cen4, t0, ut_time;
   double m, mp, f, e, max_date = 4000. * 365.25 + j2000;
   double lunar, dist, fund[N_FUND], rate = 29.5306, t_final;
   char buff[80];
   long long_to_write;
   double k;
   FILE *log_file = NULL, *vsop_file, *data_file = NULL;
   char *vsop_tbuff, FAR *vsop_data;
   time_t curr_time = time( NULL);

   vsop_file = fopen( "vsop.bin", "rb");
   if( !vsop_file)
      {
      printf( "Couldn't open vsop.bin");
      return( -1);
      }
   vsop_tbuff = (char *)malloc( VSOP_CHUNK);
   vsop_data = (char *)malloc( VSOP_CHUNK * 22U);
   for( i = 0; i < 22; i++)
      {
      if( !fread( vsop_tbuff, VSOP_CHUNK, 1, vsop_file))
         {
         printf( "Couldn't read VSOP data\n");
         return( -2);
         }
      FMEMCPY( vsop_data + (unsigned)i * VSOP_CHUNK, vsop_tbuff, VSOP_CHUNK);
      }
   fclose( vsop_file);
   free( vsop_tbuff);

   for( i = 0; i < argc; i++)
      if( argv[i][0] == '-')
         switch( argv[i][1])
            {
            case 'j': case 'J':
               julian = 1;
               break;
            case 'c': case 'C':
               chinese_calendar = 1;
               break;
            case 'v': case 'V':
               verbose = 1;
               break;
            case 'l': case 'L':
               log_file = fopen( argv[i] + 2, "wb");
               break;
            case 'd': case 'D':
               data_file = fopen( argv[i] + 2, "wb");
               break;
            case 'm': case 'M':
               max_date = (atof( argv[i] + 2) - 2000.) * 365.25 + j2000;
               break;
            default:
               break;
            }
   t0 = t = j2000 + 365.25 * (atof( argv[1]) - 2000.);
   k = floor( (atof( argv[1]) - 2000.) * 12.3685);
   if( data_file)
      {
      long_to_write = (long)k;
      fwrite( &long_to_write, 1, sizeof( long), data_file);
      }
   t_final = max_date - 1.;
   while( t_final < max_date)
      for( i = 0; i < 4; i++)
         {
         double t2, dlon_1, dlon_2, phase_angle, solar_lon, time_lag;
         static const char *phase_name[4] = {
                  "New moon ",
                  "1st qtr. ",
                  "Full moon",
                  "last qtr." };

         t_centuries = k / 1236.85;       /* first approx */
         t = 2451550.09765 + 29.530588853 * k
               + (1.337e-4 - 1.5e-7 * t_centuries) * t_centuries * t_centuries;
         t_centuries = (t - j2000) / 36525.;
         t_cen2 = t_centuries * t_centuries;
         t_cen3 = t_cen2 * t_centuries;
         t_cen4 = t_cen3 * t_centuries;
         m = 2.5534 + 29.10535669 * k
                    -  2.18e-5 * t_cen2
                    -  1.1e-7 * t_cen3;
         mp = 201.5643 + 385.81693528 * k
                       +    .0107438 * t_cen2
                       +   1.239e-5 * t_cen3
                       -   5.8e-8 * t_cen4;
         f = 160.7108 + 390.67050274 * k
                      -   1.6541e-3 * t_cen2
                      -   2.27e-6 * t_cen3
                      +   1.1e-8 * t_cen4;
         m *= PI / 180.;
         f *= PI / 180.;
         mp *= PI / 180.;
         e = 1. - .002516 * t_centuries - 7.4e-6 * t_cen2;
         switch( i)
            {
            case NEW_MOON:
               t +=   -.40720 * sin( mp)
                      +.17241 * sin( m) * e
                      +.01608 * sin( mp + mp)
                      +.01039 * sin( f + f)
                      +.00739 * sin( mp - m) * e
                      -.00514 * sin(  mp + m) * e
                      +.00208 * sin( m + m) * e * e
                      -.00111 * sin( mp - f - f);
               break;
            case FIRST_QUARTER:
            case LAST_QUARTER:
               t +=   -.62801 * sin( mp)
                      +.17172 * sin( m) *  e
                      -.01183 * sin( mp + m) * e
                      +.00862 * sin( mp + mp)
                      +.00804 * sin( f + f)
                      +.00454 * sin( mp - m) * e
                      +.00204 * sin( m + m) * e * e
                      -.00180 * sin( mp - f - f);
               t += ((i == FIRST_QUARTER) ? .00306 : -.00306);
               break;
            case FULL_MOON:
               t +=   -.40614 * sin( mp)
                      +.17302 * sin( m) * e
                      +.01614 * sin( mp + mp)
                      +.01043 * sin( f + f)
                      +.00734 * sin( mp - m) * e
                      -.00515 * sin(  mp + m) * e
                      +.00209 * sin( m + m) * e * e
                      -.00111 * sin( mp - f - f);
               break;
            default:
               break;
            }
         phase_angle = (double)i * 90.;
         t_centuries = (t - j2000) / 36525.;
         time_lag = approx_solar_dist( t_centuries) / SPEED_OF_LIGHT;
         time_lag /= 86400. * 36525.;
         lunar_fundamentals( vsop_data, t_centuries, fund);
         lunar_lon_and_dist( vsop_data, fund, &lunar, &dist, 0L);
         solar_lon = calc_vsop_loc( vsop_data, 3, 0, t_centuries - time_lag, 0.);
         solar_lon = solar_lon * 180. / PI - 180.;
         dlon_1 = lunar - solar_lon - phase_angle;
         while( dlon_1 < -180.) dlon_1 += 360.;
         while( dlon_1 >  180.) dlon_1 -= 360.;
         if( verbose)
            {
            full_ctime( buff, t, julian);
            printf( "   first  time is %s;  lon diff %lf\n", buff, dlon_1);
            }

         t2 = t - rate * dlon_1 / 360.;
         t_centuries = (t2 - j2000) / 36525.;
         lunar_fundamentals( vsop_data, t_centuries, fund);
         lunar_lon_and_dist( vsop_data, fund, &lunar, &dist, 0L);
         solar_lon = calc_vsop_loc( vsop_data, 3, 0, t_centuries - time_lag, 0.);
         solar_lon = solar_lon * 180. / PI - 180.;
         dlon_2 = lunar - solar_lon - phase_angle;
         while( dlon_2 < -180.) dlon_2 += 360.;
         while( dlon_2 >  180.) dlon_2 -= 360.;
         if( verbose)
            {
            full_ctime( buff, t2, julian);
            printf( "   second time is %s;  lon diff %lf\n", buff, dlon_2);
            }
         t_final = (t * dlon_2 - t2 * dlon_1) / (dlon_2 - dlon_1);
         ut_time = t_final - td_minus_ut( t_final) / 86400.;
         full_ctime( buff, ut_time, julian);
         if( log_file)
            {
            if( chinese_calendar)
               fprintf( log_file, "%7ld    %s\n",
                                (long)floor( ut_time - 1. / 6.), buff);
            else
               fprintf( log_file, "%s: %s\n", phase_name[i], buff);
            }
         buff[17] = '\0';        /* trim the seconds */
         if( !chinese_calendar)
            {
            printf( "%s  ", buff);
            if( i == 3)
               printf( "\n");
            }
         if( data_file)
            {
            double diff = t_final - ( 2451550.09765 + 29.530588853 * k);

            diff *= 86400.;
            if( verbose)
               printf( "Time diff %lf\n", diff);
            long_to_write = (long)diff;
            fwrite( &long_to_write, 1, sizeof( long), data_file);
            }
         if( chinese_calendar)
            {
            k++;
            i = 4;
            }
         else        /* just moving to next _phase_ */
            k += .25;
         if( curr_time != time( NULL))
            {
            curr_time = time( NULL);
            printf( "JD %.3lf (%.3lf)\r", t_final,
                     (t_final - j2000) / 365.25 + 2000.);
            }
         }

   if( chinese_calendar)
      while( t0 < max_date)
         {
         double t_centuries, time_lag, delta_t = 1.;
         double solar_lon;
         const double thirty_deg = PI / 6.;
         long solar_month = 0L, year;

         while( fabs( delta_t) > .00001)  /* resolution a little better than 1s */
            {
            t_centuries = (t0 - j2000) / 36525.;
            time_lag = approx_solar_dist( t_centuries) / SPEED_OF_LIGHT;
            time_lag /= 86400. * 36525.;
            solar_lon = calc_vsop_loc( vsop_data, 3, 0, t_centuries - time_lag, 0.);
            solar_month = (long)floor( solar_lon / thirty_deg + .5);
            solar_lon -= (double)solar_month * thirty_deg;
            delta_t = solar_lon * 365.25 / (2. * PI);
            t0 -= delta_t;
            if( verbose)
               printf( "delta_t: %.5lf   JD %.5lf\n", delta_t, t0);
            }
         solar_month = (solar_month + 7) % 12;  /* flip around to winter sol */
         year = (long)
                  floor( (t0 - (double)solar_month * 30.5 - 100.) / 365.25);
         year -= 2074L;
         ut_time = t0 - td_minus_ut( t0) / 86400.;
         full_ctime( buff, ut_time, julian);
         if( log_file)
            fprintf( log_file, "%7ld z  %s  %2ld %5ld\n",
                          (long)floor( ut_time - 1. / 6.),
                          buff, solar_month + 1, year);
         if( curr_time != time( NULL))
            {
            curr_time = time( NULL);
            printf( "%7ld z  %s   %2ld %5ld: %.3lf\n",
                          (long)floor( ut_time - 1. / 6.),
                          buff, solar_month + 1, year,
                          (ut_time - j2000) / 365.25 + 2000.);
            }
         t0 += 365.25 / 12.;
         }
   fclose( data_file);
   fclose( log_file);
   return( 0);
}
Beispiel #3
0
int find_events( int sat_no, double t1, double t2, int viewpoint, EVENT *e)
{
   double t, lon_j, lat_j, rad_j, lon_e, lat_e, rad_e;
   double loc[9], tloc[18], *tptr, step, delta_lat, prev_delta_lat;
   double tc, lon_s, lat_s, rad_s, prev_delta = 0., delta;
   int i, rval = 0;

   t = t1;
   step = 10. / speeds[sat_no - 1];
   while( t < t2)
      {
      tc = (t - 2451545.) / 36525.;     /* re-cvt to julian centuries */

      lon_j = calc_vsop_loc( vsop_data, 5, 0, tc, 0.);
      lat_j = calc_vsop_loc( vsop_data, 5, 1, tc, 0.);
      rad_j = calc_vsop_loc( vsop_data, 5, 2, tc, 0.);

      lon_e = calc_vsop_loc( vsop_data, 3, 0, tc, 0.);
      lat_e = calc_vsop_loc( vsop_data, 3, 1, tc, 0.);
      rad_e = calc_vsop_loc( vsop_data, 3, 2, tc, 0.);

      loc[0] = rad_j * cos( lat_j) * cos( lon_j);
      loc[1] = rad_j * cos( lat_j) * sin( lon_j);
      loc[2] = rad_j * sin( lat_j);

      loc[6] = rad_e * cos( lat_e) * cos( lon_e);
      loc[7] = rad_e * cos( lat_e) * sin( lon_e);
      loc[8] = rad_e * sin( lat_e);

      calc_jsat_loc( t, tloc, 1 << (sat_no - 1), 0L);
      tptr = tloc + (sat_no - 1) * 3;
      loc[3] = loc[0] + tptr[0] * AU_PER_JRAD;
      loc[4] = loc[1] + tptr[1] * AU_PER_JRAD;
      loc[5] = loc[2] + tptr[2] * AU_PER_JRAD;

      if( viewpoint)
         {
         for( i = 0; i < 9; i++)
            loc[i] -= loc[6 + i % 3];
         lon_j = atan2( loc[1], loc[0]);
         lat_j = atan( loc[2] / sqrt( loc[0] * loc[0] + loc[1] * loc[1]));
         }
      rad_s = sqrt( loc[3] * loc[3] + loc[4] * loc[4] + loc[5] * loc[5]);
      lon_s = atan2( loc[4], loc[3]);
      while( lon_s - lon_j > PI)
         lon_s -= PI + PI;
      while( lon_s - lon_j <-PI)
         lon_s += PI + PI;
      lat_s = asin( loc[5] / rad_s);
      delta = (lon_s - lon_j) * rad_s / AU_PER_JRAD;
      delta_lat = (lat_s - lat_j) * rad_s / AU_PER_JRAD;
      delta_lat *= 1.071374;     /* stretch for jup's oblateness */
      if( delta * prev_delta < 0.)     /* zero crossed */
         {
         double t_crossing, diff, a, b, c, dx, dy, dist = 0.;

         dx = prev_delta - delta;
         dy = prev_delta_lat - delta_lat;
         a = dx * dx + dy * dy;              /* quadratic for intercept */
         b = 2. * (dx * delta + dy * delta_lat);
         c = delta_lat * delta_lat + delta * delta - 1.;
         diff = b * b - 4. * a * c;
         t_crossing = t + b * step / (2. * a);
         t = t_crossing + (180. / speeds[sat_no - 1]) * .9;
         if( diff > 0.)       /* if real solution, ie, sat doesn't miss */
            {
            diff = sqrt( diff) * step / (2. * a);
            diff = fabs( diff);
            for( i = 0; i < 3; i++)
               dist += (loc[i + 6] - loc[i]) * (loc[i + 6] - loc[i]);
            t_crossing += sqrt( dist) / AU_PER_DAY;
            e[0].t = t_crossing - diff;
            e[0].sat = sat_no;
            e[0].event_type = (prev_delta > 0.);
            if( !viewpoint)
               e[0].event_type |= FROM_SUN;
            e[1].t = t_crossing + diff;
            e[1].sat = sat_no;
            e[1].event_type = e[0].event_type;
            e[0].event_type |= EVENT_START;
            if( !quiet)
               {
               show_event( stdout, e);
               show_event( stdout, e + 1);
               }
            e += 2;
            rval += 2;
            }
         delta = 0.;
         }
      prev_delta = delta;
      prev_delta_lat = delta_lat;
      t += step;
      }
   return( rval);
}