Ejemplo n.º 1
0
int
calculatesunlongitude30(int year, int degreeGMToffset, int *ichinesemonths)
{
	int m, d, h;
	double dec;
	double curL, prevL;
	int *pichinesemonths, *monthdays, *cumdays, i;
	int firstmonth330 = -1;

	cumdays = cumdaytab[isleap(year)];
	monthdays = mondaytab[isleap(year)];
	pichinesemonths = ichinesemonths;

	h = 0;
	sunpos(year - 1, 12, 31,
	    -24 * (degreeGMToffset / 360.0),
	    HOUR(h), MIN(h), SEC(h), 0.0, 0.0, &prevL, &dec);

	for (m = 1; m <= 12; m++) {
		for (d = 1; d <= monthdays[m]; d++) {
			for (h = 0; h < 4 * HOURSPERDAY; h++) {
				sunpos(year, m, d,
				    -24 * (degreeGMToffset / 360.0),
				    HOUR(h), MIN(h), SEC(h),
				    0.0, 0.0, &curL, &dec);
				if (curL < 180 && prevL > 180) {
					*pichinesemonths = cumdays[m] + d;
#ifdef DEBUG
printf("%04d-%02d-%02d %02d:%02d - %d %g\n",
    year, m, d, HOUR(h), MIN(h), *pichinesemonths, curL);
#endif
					    pichinesemonths++;
				} else {
					for (i = 0; i <= 360; i += 30)
						if (curL > i && prevL < i) {
							*pichinesemonths =
							    cumdays[m] + d;
#ifdef DEBUG
printf("%04d-%02d-%02d %02d:%02d - %d %g\n",
    year, m, d, HOUR(h), MIN(h), *pichinesemonths, curL);
#endif
							if (i == 330)
								firstmonth330 = *pichinesemonths;
							pichinesemonths++;
						}
				}
				prevL = curL;
			}
		}
	}
	*pichinesemonths = -1;
	return (firstmonth330);
}
Ejemplo n.º 2
0
/* find sun's circumstances now.
 */
static int
sun_cir (Now *np, Obj *op)
{
	double lsn, rsn;	/* true geoc lng of sun; dist from sn to earth*/
	double bsn;		/* true latitude beta of sun */
	double dhlong;

	sunpos (mjed, &lsn, &rsn, &bsn);/* sun's true coordinates; mean ecl. */

	op->s_sdist = 0.0;
	op->s_elong = 0.0;
	op->s_phase = 100.0;
	set_smag (op, -26.8);	/* TODO */
	dhlong = lsn-PI;	/* geo- to helio- centric */
	range (&dhlong, 2*PI);
	op->s_hlong = (float)dhlong;
	op->s_hlat = (float)(-bsn);

	/* fill sun's ra/dec, alt/az in op */
	cir_pos (np, bsn, lsn, &rsn, op);
	op->s_edist = (float)rsn;
	op->s_size = (float)(raddeg(4.65242e-3/rsn)*3600*2);

	return (0);
}
Ejemplo n.º 3
0
/* compute sky circumstances of an object in heliocentric hyperbolic orbit.
 */
static int
obj_parabolic (Now *np, Obj *op)
{
	double lsn, rsn;	/* true geoc lng of sun; dist from sn to earth*/
	double lam;    		/* geocentric ecliptic longitude */
	double bet;    		/* geocentric ecliptic latitude */
	double mag;		/* magnitude */
	double inc, om, Om;
	double lpd, psi, rp, rho;
	double dt;
	int pass;

	/* find solar ecliptical longitude and distance to sun from earth */
	sunpos (mjed, &lsn, &rsn, 0);

	/* two passes to correct lam and bet for light travel time. */
	dt = 0.0;
	for (pass = 0; pass < 2; pass++) {
	    reduce_elements (op->p_epoch, mjd-dt, degrad(op->p_inc),
		degrad(op->p_om), degrad(op->p_Om), &inc, &om, &Om);
	    comet (mjed-dt, op->p_ep, inc, om, op->p_qp, Om,
				    &lpd, &psi, &rp, &rho, &lam, &bet);
	    dt = rho*LTAU/3600.0/24.0;	/* light travel time, in days / AU */
	}

	/* fill in all of op->s_* stuff except s_size and s_mag */
	cir_sky (np, lpd, psi, rp, &rho, lam, bet, lsn, rsn, op);

	/* compute magnitude and size */
	gk_mag (op->p_g, op->p_k, rp, rho, &mag);
	set_smag (op, mag);
	op->s_size = (float)(op->p_size / rho);

	return (0);
}
Ejemplo n.º 4
0
QBitmap MapLoader::darkMask(int width, int height)
{
  time_t t;
  struct tm *tmp;
  double jt, sunra, sundec, sunrv, sunlong;
  short *wtab;

  QBitmap illuMask(width, height);
 
  // calculate the position of the sun
  t = time(NULL);
  tmp = gmtime(&t);
  jt = jtime(tmp);
  sunpos(jt,FALSE, &sunra, &sundec, &sunrv, &sunlong);

  int sec = tmp->tm_hour*60*60 + tmp->tm_min*60 + tmp->tm_sec;
  int gmt_position = width * sec / 86400; // note: greenwich is in the middle!

  // calculate the illuminated area
  wtab = new short[height];
  projillum(wtab,width,height,sundec);
 
  // draw illumination
  illuMask.fill(Qt::black);
  QPainter p;
  p.begin(&illuMask);
 
  int start, stop;
  int middle = width - gmt_position;
  for (int y=0; y<height; y++)
    if (wtab[y]>0)
      {
	start = middle - wtab[y];
	stop = middle + wtab[y];
	if (start < 0)
	  {
	    p.drawLine(0,y,stop,y);
	    p.drawLine(width+start,y,width,y);
	  }
	else
	  if (stop > width)
	    {
	      p.drawLine(start,y,width,y);
	      p.drawLine(0,y,stop-width,y);
	    }
	  else
	    p.drawLine(start,y,stop,y);
      }
  p.end();
  delete [] wtab;
  return illuMask;
}
Ejemplo n.º 5
0
/*-------------------------------------------*\
 SHCRDS.C
 Определение местных горизонтальных координат Солнца
 ВХОД:
 jd - юлианская дата
 l - долгота места наблюдения (рад)
 fi - широта места наблюдения (рад)

 Функция возвращает высоту видимого Солнца над
 горизонтом (град)
\*-------------------------------------------*/
double shcrds( double jd, double l, double fi) {
    double st;
    double alfa;
    double delta;
    double hh;
    double sh;
    double pi=3.14159265358979;
    double raddeg;

    raddeg=pi/180.0;

    st = gsidtj( jd );
    sunpos(jd, &alfa, &delta );
    hh = 2 * pi * st - l - alfa;
    sh = sin( fi ) * sin( delta ) + cos( fi ) * cos( delta ) * cos( hh );
    return( asin( sh ) / raddeg );
}
Ejemplo n.º 6
0
/* find moon's circumstances now.
 */
static int
moon_cir (Now *np, Obj *op)
{
	double lsn, rsn;	/* true geoc lng of sun; dist from sn to earth*/
	double lam;    		/* geocentric ecliptic longitude */
	double bet;    		/* geocentric ecliptic latitude */
	double edistau;		/* earth-moon dist, in au */
	double el;		/* elongation, rads east */
	double ms;		/* sun's mean anomaly */
	double md;		/* moon's mean anomaly */
	double i;

	moon (mjed, &lam, &bet, &edistau, &ms, &md);	/* mean ecliptic & EOD*/
	sunpos (mjed, &lsn, &rsn, NULL);		/* mean ecliptic & EOD*/

	op->s_hlong = (float)lam;		/* save geo in helio fields */
	op->s_hlat = (float)bet;

	/* find angular separation from sun */
	elongation (lam, bet, lsn, &el);
	op->s_elong = (float)raddeg(el);		/* want degrees */

	/* solve triangle of earth, sun, and elongation for moon-sun dist */
	op->s_sdist = (float) sqrt (edistau*edistau + rsn*rsn
						    - 2.0*edistau*rsn*cos(el));

	/* TODO: improve mag; this is based on a flat moon model. */
	i = -12.7 + 2.5*(log10(PI) - log10(PI/2*(1+1.e-6-cos(el)))) 
					+ 5*log10(edistau/.0025) /* dist */;
	set_smag (op, i);

	/* find phase -- allow for projection effects */
	i = 0.1468*sin(el)*(1 - 0.0549*sin(md))/(1 - 0.0167*sin(ms));
	op->s_phase = (float)((1+cos(PI-el-degrad(i)))/2*100);

	/* fill moon's ra/dec, alt/az in op and update for topo dist */
	cir_pos (np, bet, lam, &edistau, op);

	op->s_edist = (float)edistau;
	op->s_size = (float)(3600*2.0*raddeg(asin(MRAD/MAU/edistau)));
						/* moon angular dia, seconds */

	return (0);
}
Ejemplo n.º 7
0
static int
obj_planet (Now *np, Obj *op)
{
	double lsn, rsn;	/* true geoc lng of sun; dist from sn to earth*/
	double lpd, psi;	/* heliocentric ecliptic long and lat */
	double rp;		/* dist from sun */
	double rho;		/* dist from earth */
	double lam, bet;	/* geocentric ecliptic long and lat */
	double dia, mag;	/* angular diameter at 1 AU and magnitude */
	PLCode p;

	/* validate code and check for a few special cases */
	p = op->pl_code;
	if (p == SUN)
	    return (sun_cir (np, op));
	if (p == MOON)
	    return (moon_cir (np, op));
	if (op->pl_moon != X_PLANET)
	    return (plmoon_cir (np, op));
	if (p < 0 || p > MOON) {
	    printf ("unknown planet code: %d\n", p);
	    abort();
	}

	/* planet itself */

	/* find solar ecliptical longitude and distance to sun from earth */
	sunpos (mjed, &lsn, &rsn, 0);

	/* find helio long/lat; sun/planet and earth/planet dist; ecliptic
	 * long/lat; diameter and mag.
	 */
	plans(mjed, p, &lpd, &psi, &rp, &rho, &lam, &bet, &dia, &mag);

	/* fill in all of op->s_* stuff except s_size and s_mag */
	cir_sky (np, lpd, psi, rp, &rho, lam, bet, lsn, rsn, op);

	/* set magnitude and angular size */
	set_smag (op, mag);
	op->s_size = (float)(dia/rho);

	return (0);
}
Ejemplo n.º 8
0
/*-------------------------------------------*\
 SHCRDS.C
 Определение местных горизонтальных координат Солнца
 Более полная версия чем предыдущая.
 ВХОД:
 jd - юлианская дата
 l - долгота места наблюдения (рад)
 fi - широта места наблюдения (рад)

 Функция записывает высоту видимого Солнца над
 горизонтом (град) по адресу h, и его азимут
 по адресу a.
\*-------------------------------------------*/
void shcrds( double jd, double l, double fi, double* h, double* a ) {
    double st;
    double alfa;
    double delta;
    double hh;
    double sh;
    const double pi=3.14159265358979;
    const double raddeg=pi/180.0;
    double x;
    double y;

    st = gsidtj( jd );
    sunpos(jd, &alfa, &delta );
    hh = 2 * pi * st - l - alfa;
    x=cos(hh)*sin(fi)-tan(delta)*cos(fi);
    y=sin(hh);
    *a=atan2(y,x)/raddeg;
    sh = sin( fi ) * sin( delta ) + cos( fi ) * cos( delta ) * cos( hh );
    // переход от астрономического азимута к геодезическому
    *a += 180.;
    *h =asin(sh)/raddeg;
}
Ejemplo n.º 9
0
void sun_RA_dec( double d, double *RA, double *dec, double *r )
{
    double lon, obl_ecl, x, y, z;
    
    /* Compute Sun's ecliptical coordinates */
    sunpos( d, &lon, r );
    
    /* Compute ecliptic rectangular coordinates (z=0) */
    x = *r * cosd(lon);
    y = *r * sind(lon);
    
    /* Compute obliquity of ecliptic (inclination of Earth's axis) */
    obl_ecl = 23.4393 - 3.563E-7 * d;
    
    /* Convert to equatorial rectangular coordinates - x is uchanged */
    z = y * sind(obl_ecl);
    y = y * cosd(obl_ecl);
    
    /* Convert to spherical coordinates */
    *RA = atan2d( y, x );
    *dec = atan2d( z, sqrt(x*x + y*y) );
    
}  /* sun_RA_dec */
Ejemplo n.º 10
0
void ofApp::updateSunPosition(){
    Poco::DateTime now; //UTC
	ofLogVerbose() << "updating sun position :";
	ofLogVerbose() << now.day() << " " << now.month() << " " << now.year() << " " << now.hour() << " " << now.minute();

	cTime ctime;
	ctime.iYear = now.year();
	ctime.iMonth = now.month();
	ctime.iDay = now.day();
	ctime.dHours = now.hour(); //UTC
	ctime.dMinutes = now.minute();
	ctime.dSeconds = now.second();

	cLocation location;
	location.dLatitude = Manager.myCoordinates.getLatitude();
	location.dLongitude = Manager.myCoordinates.getLongitude();
	ofVec2f data = sunpos(ctime, location, &sunCalc);

    double angle = 15 * (ctime.dHours + ctime.dMinutes/60);  //convert time to angle
    sunCoordinates.x = ofMap(angle, 0, 360, 180, -180);      //map angle to longitude
	sunCoordinates.y =  -data.y *180/PI;	                 //inclination of earth - convert from rad to degrees and invert

	ofLogVerbose() << "sun coordinates: longitude " << sunCoordinates.x << " / latitude:" << sunCoordinates.y;
}
Ejemplo n.º 11
0
/* given a modified Julian date, mj, and a planet, p, find:
 *   lpd0: heliocentric longitude, 
 *   psi0: heliocentric latitude,
 *   rp0:  distance from the sun to the planet, 
 *   rho0: distance from the Earth to the planet,
 *         none corrected for light time, ie, they are the true values for the
 *         given instant.
 *   lam:  geocentric ecliptic longitude, 
 *   bet:  geocentric ecliptic latitude,
 *         each corrected for light time, ie, they are the apparent values as
 *	   seen from the center of the Earth for the given instant.
 *   dia:  angular diameter in arcsec at 1 AU, 
 *   mag:  visual magnitude
 *
 * all angles are in radians, all distances in AU.
 *
 * corrections for nutation and abberation must be made by the caller. The RA 
 *   and DEC calculated from the fully-corrected ecliptic coordinates are then
 *   the apparent geocentric coordinates. Further corrections can be made, if
 *   required, for atmospheric refraction and geocentric parallax.
 */
void
plans (double mj, PLCode p, double *lpd0, double *psi0, double *rp0,
double *rho0, double *lam, double *bet, double *dia, double *mag)
{
	static double lastmj = -10000;
	static double lsn, bsn, rsn;	/* geocentric coords of sun */
	static double xsn, ysn, zsn;	/* cartesian " */
	double lp, bp, rp;		/* heliocentric coords of planet */
	double xp, yp, zp, rho;		/* rect. coords and geocentric dist. */
	double dt;			/* light time */
	double *vp;			/* vis_elements[p] */
	double ci, i;			/* sun/earth angle: cos, degrees */
	int pass;

	/* get sun cartesian; needed only once at mj */
	if (mj != lastmj) {
	    sunpos (mj, &lsn, &rsn, &bsn);
	    sphcart (lsn, bsn, rsn, &xsn, &ysn, &zsn);
            lastmj = mj;
        }

	/* first find the true position of the planet at mj.
	 * then repeat a second time for a slightly different time based
	 * on the position found in the first pass to account for light-travel
	 * time.
	 */
	dt = 0.0;
	for (pass = 0; pass < 2; pass++) {
	    double ret[6];

	    /* get spherical coordinates of planet from precision routines,
	     * retarded for light time in second pass;
	     * alternative option:  vsop allows calculating rates.
	     */
	    planpos(mj - dt, p, 0.0, ret);

	    lp = ret[0];
	    bp = ret[1];
	    rp = ret[2];

	    sphcart (lp, bp, rp, &xp, &yp, &zp);
	    cartsph (xp + xsn, yp + ysn, zp + zsn, lam, bet, &rho);

	    if (pass == 0) {
		/* save heliocentric coordinates at first pass since, being
		 * true, they are NOT to be corrected for light-travel time.
		 */
		*lpd0 = lp;
		range (lpd0, 2.*PI);
		*psi0 = bp;
		*rp0 = rp;
		*rho0 = rho;
	    }

	    /* when we view a planet we see it in the position it occupied
	     * dt days ago, where rho is the distance between it and earth,
	     * in AU. use this as the new time for the next pass.
	     */
	    dt = rho * 5.7755183e-3;
	}

	vp = vis_elements[p];
	*dia = vp[0];

	/* solve plane triangle, assume sun/earth dist == 1 */
	ci = (rp*rp + rho*rho - 1)/(2*rp*rho);

	/* expl supp equation for mag */
	if (ci < -1) ci = -1;
	if (ci >  1) ci =  1;
	i = raddeg(acos(ci))/100.;
	*mag = vp[1] + 5*log10(rho*rp) + i*(vp[2] + i*(vp[3] + i*vp[4]));

	/* rings contribution if SATURN */
	if (p == SATURN) {
	    double et, st, set;
	    satrings (bp, lp, rp, lsn+PI, rsn, mj+MJD0, &et, &st);
	    set = sin(fabs(et));
	    *mag += (-2.60 + 1.25*set)*set;
	}
}
Ejemplo n.º 12
0
void
fequinoxsolstice(int year, double UTCoffset, double *equinoxdays, double *solsticedays)
{
	double dec, prevdec, L;
	int h, d, prevangle, angle;
	int found = 0;

	double decleft, decright, decmiddle;
	int dial, s;

	int *cumdays;
	cumdays = cumdaytab[isleap(year)];

	/*
	 * Find the first equinox, somewhere in March:
	 * It happens when the returned value "dec" goes from
	 * [350 ... 360> -> [0 ... 10]
	 */
	for (d = 18; d < 31; d++) {
		/* printf("Comparing day %d to %d.\n", d, d+1); */
		sunpos(year, 3, d, UTCoffset, 0, 0, 0, 0.0, 0.0, &L, &decleft);
		sunpos(year, 3, d + 1, UTCoffset, 0, 0, 0, 0.0, 0.0,
		    &L, &decright);
		/* printf("Found %g and %g.\n", decleft, decright); */
		if (SIGN(decleft) == SIGN(decright))
			continue;

		dial = SECSPERDAY;
		s = SECSPERDAY / 2;
		while (s > 0) {
			/* printf("Obtaining %d (%02d:%02d)\n",
			    dial, SHOUR(dial), SMIN(dial)); */
			sunpos(year, 3, d, UTCoffset,
			    SHOUR(dial), SMIN(dial), SSEC(dial),
			    0.0, 0.0, &L, &decmiddle);
			/* printf("Found %g\n", decmiddle); */
			if (SIGN(decleft) == SIGN(decmiddle)) {
				decleft = decmiddle;
				dial += s;
			} else {
				decright = decmiddle;
				dial -= s;
			}
			/*
			 printf("New boundaries: %g - %g\n", decleft, decright);
			*/

			s /= 2;
		}
		equinoxdays[0] = 1 + cumdays[3] + d + (dial / FSECSPERDAY);
		break;
	}

	/* Find the second equinox, somewhere in September:
	 * It happens when the returned value "dec" goes from
	 * [10 ... 0] -> <360 ... 350]
	 */
	for (d = 18; d < 31; d++) {
		/* printf("Comparing day %d to %d.\n", d, d+1); */
		sunpos(year, 9, d, UTCoffset, 0, 0, 0, 0.0, 0.0, &L, &decleft);
		sunpos(year, 9, d + 1, UTCoffset, 0, 0, 0, 0.0, 0.0,
		    &L, &decright);
		/* printf("Found %g and %g.\n", decleft, decright); */
		if (SIGN(decleft) == SIGN(decright))
			continue;

		dial = SECSPERDAY;
		s = SECSPERDAY / 2;
		while (s > 0) {
			/* printf("Obtaining %d (%02d:%02d)\n",
			    dial, SHOUR(dial), SMIN(dial)); */
			sunpos(year, 9, d, UTCoffset,
			    SHOUR(dial), SMIN(dial), SSEC(dial),
			    0.0, 0.0, &L, &decmiddle);
			/* printf("Found %g\n", decmiddle); */
			if (SIGN(decleft) == SIGN(decmiddle)) {
				decleft = decmiddle;
				dial += s;
			} else {
				decright = decmiddle;
				dial -= s;
			}
			/*
			printf("New boundaries: %g - %g\n", decleft, decright);
			*/

			s /= 2;
		}
		equinoxdays[1] = 1 + cumdays[9] + d + (dial / FSECSPERDAY);
		break;
	}

	/*
	 * Find the first solstice, somewhere in June:
	 * It happens when the returned value "dec" peaks
	 * [40 ... 45] -> [45 ... 40]
	 */
	found = 0;
	prevdec = 0;
	prevangle = 1;
	for (d = 18; d < 31; d++) {
		for (h = 0; h < 4 * HOURSPERDAY; h++) {
			sunpos(year, 6, d, UTCoffset, HOUR(h), MIN(h), SEC(h),
			    0.0, 0.0, &L, &dec);
			angle = ANGLE(prevdec, dec);
			if (prevangle != angle) {
#ifdef NOTDEF
				DEBUG2(year, 6, d, HOUR(h), MIN(h),
				    prevdec, dec, prevangle, angle);
#endif
				solsticedays[0] = 1 + cumdays[6] + d +
				    ((h / 4.0) / 24.0);
				found = 1;
				break;
			}
			prevdec = dec;
			prevangle = angle;
		}
		if (found)
			break;
	}

	/*
	 * Find the second solstice, somewhere in December:
	 * It happens when the returned value "dec" peaks
	 * [315 ... 310] -> [310 ... 315]
	 */
	found = 0;
	prevdec = 360;
	prevangle = -1;
	for (d = 18; d < 31; d++) {
		for (h = 0; h < 4 * HOURSPERDAY; h++) {
			sunpos(year, 12, d, UTCoffset, HOUR(h), MIN(h), SEC(h),
			    0.0, 0.0, &L, &dec);
			angle = ANGLE(prevdec, dec);
			if (prevangle != angle) {
#ifdef NOTDEF
				DEBUG2(year, 12, d, HOUR(h), MIN(h),
				    prevdec, dec, prevangle, angle);
#endif
				solsticedays[1] = 1 + cumdays[12] + d +
				    ((h / 4.0) / 24.0);
				found = 1;
				break;
			}
			prevdec = dec;
			prevangle = angle;
		}
		if (found)
			break;
	}

	return;
}
Ejemplo n.º 13
0
cSunCoordinates sunposf(cTime udtTime, cLocation udtLocation)
{
	cSunCoordinates ret;
	sunpos(udtTime, udtLocation, &ret);
	return ret;
}
Ejemplo n.º 14
0
/* fill equatoreal and horizontal op-> fields; stern
 *
 *    input:          lam/bet/rho geocentric mean ecliptic and equinox of day
 * 
 * algorithm at EOD:
 *   ecl_eq	--> ra/dec	geocentric mean equatoreal EOD (via mean obliq)
 *   deflect	--> ra/dec	  relativistic deflection
 *   nut_eq	--> ra/dec	geocentric true equatoreal EOD
 *   ab_eq	--> ra/dec	geocentric apparent equatoreal EOD
 *					if (PREF_GEO)  --> output
 *   ta_par	--> ra/dec	topocentric apparent equatoreal EOD
 *					if (!PREF_GEO)  --> output
 *   hadec_aa	--> alt/az	topocentric horizontal
 *   refract	--> alt/az	observed --> output
 *
 * algorithm at fixed equinox:
 *   ecl_eq	--> ra/dec	geocentric mean equatoreal EOD (via mean obliq)
 *   deflect	--> ra/dec	  relativistic deflection [for alt/az only]
 *   nut_eq	--> ra/dec	geocentric true equatoreal EOD [for aa only]
 *   ab_eq	--> ra/dec	geocentric apparent equatoreal EOD [for aa only]
 *   ta_par	--> ra/dec	topocentric apparent equatoreal EOD
 *     precess	--> ra/dec	topocentric equatoreal fixed equinox [eq only]
 *					--> output
 *   hadec_aa	--> alt/az	topocentric horizontal
 *   refract	--> alt/az	observed --> output
 */
static void
cir_pos (
Now *np,
double bet,	/* geo lat (mean ecliptic of date) */
double lam,	/* geo long (mean ecliptic of date) */
double *rho,	/* in: geocentric dist in AU; out: geo- or topocentic dist */
Obj *op)	/* object to set s_ra/dec as per equinox */
{
	double ra, dec;		/* apparent ra/dec, corrected for nut/ab */
	double tra, tdec;	/* astrometric ra/dec, no nut/ab */
	double lsn, rsn;	/* solar geocentric (mean ecliptic of date) */
	double ha_in, ha_out;	/* local hour angle before/after parallax */
	double dec_out;		/* declination after parallax */
	double dra, ddec;	/* parallax correction */
	double alt, az;		/* current alt, az */
	double lst;             /* local sidereal time */
	double rho_topo;        /* topocentric distance in earth radii */

	/* convert to equatoreal [mean equator, with mean obliquity] */
	ecl_eq (mjed, bet, lam, &ra, &dec);
	tra = ra;	/* keep mean coordinates */
	tdec = dec;

	/* precess and save astrometric coordinates */
	if (mjed != epoch)
	    precess (mjed, epoch, &tra, &tdec);
	op->s_astrora = tra;
	op->s_astrodec = tdec;

	/* get sun position */
	sunpos(mjed, &lsn, &rsn, NULL);

	/* allow for relativistic light bending near the sun.
	 * (avoid calling deflect() for the sun itself).
	 */
	if (!is_planet(op,SUN) && !is_planet(op,MOON))
	    deflect (mjed, op->s_hlong, op->s_hlat, lsn, rsn, *rho, &ra, &dec);

	/* correct ra/dec to form geocentric apparent */
	nut_eq (mjed, &ra, &dec);
	if (!is_planet(op,MOON))
	    ab_eq (mjed, lsn, &ra, &dec);
	op->s_gaera = ra;
	op->s_gaedec = dec;

	/* find parallax correction for equatoreal coords */
	now_lst (np, &lst);
	ha_in = hrrad(lst) - ra;
	rho_topo = *rho * MAU/ERAD;             /* convert to earth radii */
	ta_par (ha_in, dec, lat, elev, &rho_topo, &ha_out, &dec_out);

	/* transform into alt/az and apply refraction */
	hadec_aa (lat, ha_out, dec_out, &alt, &az);
	refract (pressure, temp, alt, &alt);
	op->s_alt = alt;
	op->s_az = az;

	/* Get parallax differences and apply to apparent or astrometric place
	 * as needed.  For the astrometric place, rotating the CORRECTIONS
	 * back from the nutated equator to the mean equator will be
	 * neglected.  This is an effect of about 0.1" at moon distance.
	 * We currently don't have an inverse nutation rotation.
	 */
	if (pref_get(PREF_EQUATORIAL) == PREF_GEO) {
	    /* no topo corrections to eq. coords */
	    dra = ddec = 0.0;
	} else {
	    dra = ha_in - ha_out;	/* ra sign is opposite of ha */
	    ddec = dec_out - dec;
	    *rho = rho_topo * ERAD/MAU; /* return topocentric distance in AU */

	    ra = ra + dra;
	    dec = dec + ddec;
	}
	range(&ra, 2*PI);
	op->s_ra = ra;
	op->s_dec = dec;
}
Ejemplo n.º 15
0
double __daylen__( long year, long month, long day, double lon, double lat,
                  double altit, int upper_limb )
/**********************************************************************/
/* Note: year,month,date = calendar date, 1801-2099 only.             */
/*       Eastern longitude positive, Western longitude negative       */
/*       Northern latitude positive, Southern latitude negative       */
/*       The longitude value is not critical. Set it to the correct   */
/*       longitude if you're picky, otherwise set to to, say, 0.0     */
/*       The latitude however IS critical - be sure to get it correct */
/*       altit = the altitude which the Sun should cross              */
/*               Set to -35/60 degrees for rise/set, -6 degrees       */
/*               for civil, -12 degrees for nautical and -18          */
/*               degrees for astronomical twilight.                   */
/*         upper_limb: non-zero -> upper limb, zero -> center         */
/*               Set to non-zero (e.g. 1) when computing day length   */
/*               and to zero when computing day+twilight length.      */
/**********************************************************************/
{
    double  d,  /* Days since 2000 Jan 0.0 (negative before) */
    obl_ecl,    /* Obliquity (inclination) of Earth's axis */
    sr,         /* Solar distance, astronomical units */
    slon,       /* True solar longitude */
    sin_sdecl,  /* Sine of Sun's declination */
    cos_sdecl,  /* Cosine of Sun's declination */
    sradius,    /* Sun's apparent radius */
    t;          /* Diurnal arc */
    
    /* Compute d of 12h local mean solar time */
    d = days_since_2000_Jan_0(year,month,day) + 0.5 - lon/360.0;
    
    /* Compute obliquity of ecliptic (inclination of Earth's axis) */
    obl_ecl = 23.4393 - 3.563E-7 * d;
    
    /* Compute Sun's position */
    sunpos( d, &slon, &sr );
    
    /* Compute sine and cosine of Sun's declination */
    sin_sdecl = sind(obl_ecl) * sind(slon);
    cos_sdecl = sqrt( 1.0 - sin_sdecl * sin_sdecl );
    
    /* Compute the Sun's apparent radius, degrees */
    sradius = 0.2666 / sr;
    
    /* Do correction to upper limb, if necessary */
    if ( upper_limb )
        altit -= sradius;
    
    /* Compute the diurnal arc that the Sun traverses to reach */
    /* the specified altitide altit: */
    {
        double cost;
        cost = ( sind(altit) - sind(lat) * sin_sdecl ) /
        ( cosd(lat) * cos_sdecl );
        if ( cost >= 1.0 )
            t = 0.0;                      /* Sun always below altit */
        else if ( cost <= -1.0 )
            t = 24.0;                     /* Sun always above altit */
        else  t = (2.0/15.0) * acosd(cost); /* The diurnal arc, hours */
    }
    return t;
}  /* __daylen__ */
Ejemplo n.º 16
0
/* compute sky circumstances of an object in heliocentric hyperbolic orbit.
 */
static int
obj_hyperbolic (Now *np, Obj *op)
{
	double lsn, rsn;	/* true geoc lng of sun; dist from sn to earth*/
	double dt;		/* light travel time to object */
	double lg;		/* helio long of earth */
	double nu;		/* true anomaly and eccentric anomaly */
	double rp=0;		/* distance from the sun */
	double lo, slo, clo;	/* angle from ascending node */
	double inc;		/* inclination */
	double psi=0;		/* heliocentric latitude */
	double spsi=0, cpsi=0;	/* trig of heliocentric latitude */
	double lpd; 		/* heliocentric longitude */
	double rho=0;		/* distance from the Earth */
	double om;		/* arg of perihelion */
	double Om;		/* long of ascending node. */
	double lam;    		/* geocentric ecliptic longitude */
	double bet;    		/* geocentric ecliptic latitude */
	double e;		/* fast eccentricity */
	double ll=0, sll, cll;	/* helio angle between object and earth */
	double mag;		/* magnitude */
	double a;		/* mean distance */
	double tp;		/* time from perihelion (days) */
	double rpd=0;
	double y;
	int pass;

	/* find solar ecliptical longitude and distance to sun from earth */
	sunpos (mjed, &lsn, &rsn, 0);

	lg = lsn + PI;
	e = op->h_e;
	a = op->h_qp/(e - 1.0);

	/* correct for light time by computing position at time mjd, then
	 *   again at mjd-dt, where
	 *   dt = time it takes light to travel earth-object distance.
	 */
	dt = 0;
	for (pass = 0; pass < 2; pass++) {

	    reduce_elements (op->h_epoch, mjd-dt, degrad(op->h_inc),
			    degrad (op->h_om), degrad (op->h_Om),
			    &inc, &om, &Om);

	    tp = mjed - dt - op->h_ep;
	    if (vrc (&nu, &rp, tp, op->h_e, op->h_qp) < 0)
		op->o_flags |= NOCIRCUM;
	    nu = degrad(nu);
	    lo = nu + om;
	    slo = sin(lo);
	    clo = cos(lo);
	    spsi = slo*sin(inc);
	    y = slo*cos(inc);
	    psi = asin(spsi);
	    lpd = atan(y/clo)+Om;
	    if (clo<0) lpd += PI;
	    range (&lpd, 2*PI);
	    cpsi = cos(psi);
	    rpd = rp*cpsi;
	    ll = lpd-lg;
	    rho = sqrt(rsn*rsn+rp*rp-2*rsn*rp*cpsi*cos(ll));

	    dt = rho*5.775518e-3;	/* light travel time, in days */
	}

	/* compute sin and cos of ll */
	sll = sin(ll);
	cll = cos(ll);

	/* find geocentric ecliptic longitude and latitude */
	if (rpd < rsn)
	    lam = atan(-1*rpd*sll/(rsn-rpd*cll))+lg+PI;
	else
	    lam = atan(rsn*sll/(rpd-rsn*cll))+lpd;
	range (&lam, 2*PI);
	bet = atan(rpd*spsi*sin(lam-lpd)/(cpsi*rsn*sll));

	/* fill in all of op->s_* stuff except s_size and s_mag */
	cir_sky (np, lpd, psi, rp, &rho, lam, bet, lsn, rsn, op);

	/* compute magnitude and size */
	gk_mag (op->h_g, op->h_k, rp, rho, &mag);
	set_smag (op, mag);
	op->s_size = (float)(op->h_size / rho);

	return (0);
}
Ejemplo n.º 17
0
/* compute sky circumstances of an object in heliocentric elliptic orbit at *np.
 */
static int
obj_elliptical (Now *np, Obj *op)
{
	double lsn, rsn;	/* true geoc lng of sun; dist from sn to earth*/
	double dt;		/* light travel time to object */
	double lg;		/* helio long of earth */
	double nu;		/* true anomaly */
	double rp=0;		/* distance from the sun */
	double lo, slo, clo;	/* angle from ascending node */
	double inc;		/* inclination */
	double psi=0;		/* heliocentric latitude */
	double spsi=0, cpsi=0;	/* trig of heliocentric latitude */
	double lpd; 		/* heliocentric longitude */
	double rho=0;		/* distance from the Earth */
	double om;		/* arg of perihelion */
	double Om;		/* long of ascending node. */
	double lam;    		/* geocentric ecliptic longitude */
	double bet;    		/* geocentric ecliptic latitude */
	double ll=0, sll, cll;	/* helio angle between object and earth */
	double mag;		/* magnitude */
	double e_n;		/* mean daily motion */
	double tp;		/* time from perihelion (days) */
	double rpd=0;
	double y;
	int pass;

	/* find location of earth from sun now */
	sunpos (mjed, &lsn, &rsn, 0);
	lg = lsn + PI;

	/* mean daily motion is derived fro mean distance */
	e_n = 0.9856076686/pow((double)op->e_a, 1.5);

	/* correct for light time by computing position at time mjd, then
	 *   again at mjd-dt, where
	 *   dt = time it takes light to travel earth-object distance.
	 */
	dt = 0;
	for (pass = 0; pass < 2; pass++) {

	    reduce_elements (op->e_epoch, mjd-dt, degrad(op->e_inc),
					degrad (op->e_om), degrad (op->e_Om),
					&inc, &om, &Om);

	    tp = mjed - dt - (op->e_cepoch - op->e_M/e_n);
	    if (vrc (&nu, &rp, tp, op->e_e, op->e_a*(1-op->e_e)) < 0)
		op->o_flags |= NOCIRCUM;
	    nu = degrad(nu);
	    lo = nu + om;
	    slo = sin(lo);
	    clo = cos(lo);
	    spsi = slo*sin(inc);
	    y = slo*cos(inc);
	    psi = asin(spsi);
	    lpd = atan(y/clo)+Om;
	    if (clo<0) lpd += PI;
	    range (&lpd, 2*PI);
	    cpsi = cos(psi);
	    rpd = rp*cpsi;
	    ll = lpd-lg;
	    rho = sqrt(rsn*rsn+rp*rp-2*rsn*rp*cpsi*cos(ll));
            printf("\nrho from sqrt(): %f\n", rho);

	    dt = rho*LTAU/3600.0/24.0;	/* light travel time, in days / AU */
	}

	/* compute sin and cos of ll */
	sll = sin(ll);
	cll = cos(ll);

	/* find geocentric ecliptic longitude and latitude */
	if (rpd < rsn)
	    lam = atan(-1*rpd*sll/(rsn-rpd*cll))+lg+PI;
	else
	    lam = atan(rsn*sll/(rpd-rsn*cll))+lpd;
	range (&lam, 2*PI);
	bet = atan(rpd*spsi*sin(lam-lpd)/(cpsi*rsn*sll));

	/* fill in all of op->s_* stuff except s_size and s_mag */
        rho;
	cir_sky (np, lpd, psi, rp, &rho, lam, bet, lsn, rsn, op);

	/* compute magnitude and size */
	if (op->e_mag.whichm == MAG_HG) {
	    /* the H and G parameters from the Astro. Almanac.
	     */
	    hg_mag (op->e_mag.m1, op->e_mag.m2, rp, rho, rsn, &mag);
	    if (op->e_size)
		op->s_size = (float)(op->e_size / rho);
	    else
		op->s_size = (float)(h_albsize (op->e_mag.m1)/rho);
	} else {
	    /* the g/k model of comets */
	    gk_mag (op->e_mag.m1, op->e_mag.m2, rp, rho, &mag);
	    op->s_size = (float)(op->e_size / rho);
	}
	set_smag (op, mag);

	return (0);
}
Ejemplo n.º 18
0
static int
obj_fixed (Now *np, Obj *op)
{
	double lsn, rsn;	/* true geoc lng of sun, dist from sn to earth*/
	double lam, bet;	/* geocentric ecliptic long and lat */
	double ha;		/* local hour angle */
	double el;		/* elongation */
	double alt, az;		/* current alt, az */
	double ra, dec;		/* ra and dec at equinox of date */
	double rpm, dpm; 	/* astrometric ra and dec with PM to now */
	double lst;

	/* on the assumption that the user will stick with their chosen display
	 * epoch for a while, we move the defining values to match and avoid
	 * precession for every call until it is changed again.
	 * N.B. only compare and store jd's to lowest precission (f_epoch).
	 * N.B. maintaining J2k ref (which is arbitrary) helps avoid accum err
	 */
	if (0 /* disabled in PyEphem */
            && epoch != EOD && epoch != op->f_epoch) {
	    double pr = op->f_RA, pd = op->f_dec, fe = epoch;
	    /* first bring back to 2k */
	    precess (op->f_epoch, J2000, &pr, &pd);
	    pr += op->f_pmRA*(J2000-op->f_epoch);
	    pd += op->f_pmdec*(J2000-op->f_epoch);
	    /* then to epoch */
	    pr += op->f_pmRA*(fe-J2000);
	    pd += op->f_pmdec*(fe-J2000);
	    precess (J2000, fe, &pr, &pd);
	    op->f_RA = pr;
	    op->f_dec = pd;
	    op->f_epoch = fe;
	}

	/* apply proper motion .. assume pm epoch reference equals equinox */
	rpm = op->f_RA + op->f_pmRA*(mjd-op->f_epoch);
	dpm = op->f_dec + op->f_pmdec*(mjd-op->f_epoch);

	/* set ra/dec to astrometric @ equinox of date */
	ra = rpm;
	dec = dpm;
	if (op->f_epoch != mjed)
	    precess (op->f_epoch, mjed, &ra, &dec);

	/* compute astrometric @ requested equinox */
	op->s_astrora = rpm;
	op->s_astrodec = dpm;
	if (op->f_epoch != epoch)
	    precess (op->f_epoch, epoch, &op->s_astrora, &op->s_astrodec);

	/* convert equatoreal ra/dec to mean geocentric ecliptic lat/long */
	eq_ecl (mjed, ra, dec, &bet, &lam);

	/* find solar ecliptical long.(mean equinox) and distance from earth */
	sunpos (mjed, &lsn, &rsn, NULL);

	/* allow for relativistic light bending near the sun */
	deflect (mjed, lam, bet, lsn, rsn, 1e10, &ra, &dec);

	/* TODO: correction for annual parallax would go here */

	/* correct EOD equatoreal for nutation/aberation to form apparent 
	 * geocentric
	 */
	nut_eq(mjed, &ra, &dec);
	ab_eq(mjed, lsn, &ra, &dec);
	op->s_gaera = ra;
	op->s_gaedec = dec;

	/* set s_ra/dec -- apparent */
	op->s_ra = ra;
	op->s_dec = dec;

	/* compute elongation from ecliptic long/lat and sun geocentric long */
	elongation (lam, bet, lsn, &el);
	el = raddeg(el);
	op->s_elong = (float)el;

	/* these are really the same fields ...
	op->s_mag = op->f_mag;
	op->s_size = op->f_size;
	*/

	/* alt, az: correct for refraction; use eod ra/dec. */
	now_lst (np, &lst);
	ha = hrrad(lst) - ra;
	hadec_aa (lat, ha, dec, &alt, &az);
	refract (pressure, temp, alt, &alt);
	op->s_alt = alt;
	op->s_az = az;

	return (0);
}