void format_result(const char *format, struct object_details *result) { char buffer[128]; char *local_format = strdup(format); int i; struct ln_hms ra; /* convert results */ ln_deg_to_hms(result->equ.ra, &ra); ln_get_hrz_from_equ(&result->equ, &result->obs, result->jd, &result->hrz); result->azidir = ln_hrz_to_nswe(&result->hrz); result->hrz.az = ln_range_degrees(result->hrz.az + 180); result->hrz.alt = ln_range_degrees(result->hrz.alt); struct specifiers specifiers[] = { {"%J", &result->jd, DOUBLE}, {"§r", &result->equ.ra, DOUBLE}, {"§d", &result->equ.dec, DOUBLE}, {"§a", &result->hrz.az, DOUBLE}, {"§h", &result->hrz.alt, DOUBLE}, {"§d", &result->diameter, DOUBLE}, {"§e", &result->distance, DOUBLE}, {"§t", &result->tz, INTEGER}, {"§A", &result->obs.lat, DOUBLE}, {"§O", &result->obs.lng, DOUBLE}, {"§s", (void *) result->azidir, STRING}, {"§§", "§", STRING}, {0} }; for (i = 0; specifiers[i].token; i++) { if (strstr(local_format, specifiers[i].token) != NULL) { switch (specifiers[i].format) { case DOUBLE: snprintf(buffer, sizeof(buffer), "%." PRECISION "f", * (double *) specifiers[i].data); break; case STRING: snprintf(buffer, sizeof(buffer), "%s", (char *) specifiers[i].data); break; case INTEGER: snprintf(buffer, sizeof(buffer), "%d", * (int *) specifiers[i].data); break; } local_format = strreplace(local_format, specifiers[i].token, buffer); } } strfjd(buffer, sizeof(buffer), local_format, result->jd, result->tz); printf("%s\n", buffer); free(local_format); }
void MainWindow::setSunCurrentHeading(const QDateTime &dateTime) { struct ln_equ_posn equ; struct ln_lnlat_posn observer; struct ln_hrz_posn hpos; double JD; observer.lat = ui->latEdit->text().toFloat(); observer.lng = ui->lngEdit->text().toFloat(); ln_date novaDate; novaDate.years = dateTime.date().year(); novaDate.months = dateTime.date().month(); novaDate.days = dateTime.date().day(); novaDate.hours = dateTime.time().hour(); novaDate.minutes = dateTime.time().minute(); novaDate.seconds = dateTime.time().second(); JD = ln_get_julian_day(&novaDate); /* ra, dec */ ln_get_solar_equ_coords (JD, &equ); ln_get_hrz_from_equ(&equ, &observer, JD, &hpos); double a = ln_range_degrees(hpos.az - 180); sunHeading->setHeading(a); mc->updateRequestNew(); }
void MainWindow::setSunVectors(ln_zonedate* date, ln_lnlat_posn* observer, Vector* vector) { struct ln_equ_posn equ; struct ln_hrz_posn hpos; double JD; ln_date lnDate; lnDate.years = date->years; lnDate.months = date->months; lnDate.days = date->days; lnDate.hours = date->hours; lnDate.minutes = date->minutes; lnDate.seconds = date->seconds; JD = ln_get_julian_day(&lnDate); /* ra, dec */ ln_get_solar_equ_coords (JD, &equ); ln_get_hrz_from_equ(&equ, observer, JD, &hpos); double a = ln_range_degrees(hpos.az - 180); vector->setHeading(a); }
/* convert degrees to hh:mm:ss */ void ln_deg_to_hms (double degrees, struct ln_hms * hms) { double dtemp; degrees = ln_range_degrees (degrees); /* divide degrees by 15 to get the hours */ dtemp = degrees / 15.0; hms->hours = (unsigned short)dtemp; /* multiply remainder by 60 to get minutes */ dtemp = 60*(dtemp - hms->hours); hms->minutes = (unsigned short)dtemp; /* multiply remainder by 60 to get seconds */ hms->seconds = 60*(dtemp - hms->minutes); /* catch any overflows */ if (hms->seconds > 59) { hms->seconds = 0; hms->minutes ++; } if (hms->minutes > 59) { hms->minutes = 0; hms->hours ++; } }
/*! \fn double ln_get_ell_body_elong (double JD, struct ln_ell_orbit * orbit); * \param JD Julian day * \param orbit Orbital parameters * \return Elongation to the Sun. * * Calculate the bodies elongation to the Sun.. */ double ln_get_ell_body_elong (double JD, struct ln_ell_orbit * orbit) { double r,R,d; double t; double elong; double E,M; /* time since perihelion */ t = JD - orbit->JD; /* get mean anomaly */ if (orbit->n == 0) orbit->n = ln_get_ell_mean_motion (orbit->a); M = ln_get_ell_mean_anomaly (orbit->n, t); /* get eccentric anomaly */ E = ln_solve_kepler (orbit->e, M); /* get radius vector */ r = ln_get_ell_radius_vector (orbit->a, orbit->e, E); /* get solar and Earth-Sun distances */ R = ln_get_earth_solar_dist (JD); d = ln_get_ell_body_solar_dist (JD, orbit); elong = (R * R + d * d - r * r) / ( 2.0 * R * d ); return ln_range_degrees (ln_rad_to_deg (acos (elong))); }
/*! * \fn void ln_get_ell_body_equ_coords (double JD, struct ln_ell_orbit * orbit, struct ln_equ_posn * posn) * \param JD Julian Day. * \param orbit Orbital parameters. * \param posn Pointer to hold asteroid position. * * Calculate a bodies equatorial coordinates for the given julian day. */ void ln_get_ell_body_equ_coords (double JD, struct ln_ell_orbit * orbit, struct ln_equ_posn * posn) { struct ln_rect_posn body_rect_posn, sol_rect_posn; double dist, t; double x,y,z; /* get solar and body rect coords */ ln_get_ell_helio_rect_posn (orbit, JD, &body_rect_posn); ln_get_solar_geo_coords (JD, &sol_rect_posn); /* calc distance and light time */ dist = ln_get_rect_distance (&body_rect_posn, &sol_rect_posn); t = ln_get_light_time (dist); /* repeat calculation with new time (i.e. JD - t) */ ln_get_ell_helio_rect_posn (orbit, JD - t, &body_rect_posn); /* calc equ coords equ 33.10 */ x = sol_rect_posn.X + body_rect_posn.X; y = sol_rect_posn.Y + body_rect_posn.Y; z = sol_rect_posn.Z + body_rect_posn.Z; posn->ra = ln_range_degrees(ln_rad_to_deg(atan2 (y,x))); posn->dec = ln_rad_to_deg(asin (z / sqrt (x * x + y * y + z * z))); }
/* equ 30.1 */ double ln_get_ell_true_anomaly (double e, double E) { double v; E = ln_deg_to_rad (E); v = sqrt ((1.0 + e) / (1.0 - e)) * tan (E / 2.0); v = 2.0 * atan (v); v = ln_range_degrees (ln_rad_to_deg (v)); return v; }
/* equ 30.1 */ double ln_get_par_true_anomaly (double q, double t) { double v; double s; s = ln_solve_barker (q,t); v = 2.0 * atan (s); return ln_range_degrees(ln_rad_to_deg(v)); }
void normalizeRaDec (double &ra, double &dec) { if (dec < -90) { dec = -180 - dec; ra = ra - 180; } else if (dec > 90) { dec = 180 - dec; ra = ra - 180; } ra = ln_range_degrees (ra); }
/* Equ 20.2, 20.4 pg 126 */ void ln_get_equ_prec2 (struct ln_equ_posn * mean_position, double fromJD, double toJD, struct ln_equ_posn * position) { long double t, t2, t3, A, B, C, zeta, eta, theta, ra, dec, mean_ra, mean_dec, T, T2; /* change original ra and dec to radians */ mean_ra = ln_deg_to_rad (mean_position->ra); mean_dec = ln_deg_to_rad (mean_position->dec); /* calc t, T, zeta, eta and theta Equ 20.2 */ T = ((long double) (fromJD - JD2000)) / 36525.0; T *= 1.0 / 3600.0; t = ((long double) (toJD - fromJD)) / 36525.0; t *= 1.0 / 3600.0; T2 = T * T; t2 = t * t; t3 = t2 *t; zeta = (2306.2181 + 1.39656 * T - 0.000139 * T2) * t + (0.30188 - 0.000344 * T) * t2 + 0.017998 * t3; eta = (2306.2181 + 1.39656 * T - 0.000139 * T2) * t + (1.09468 + 0.000066 * T) * t2 + 0.018203 * t3; theta = (2004.3109 - 0.85330 * T - 0.000217 * T2) * t - (0.42665 + 0.000217 * T) * t2 - 0.041833 * t3; zeta = ln_deg_to_rad (zeta); eta = ln_deg_to_rad (eta); theta = ln_deg_to_rad (theta); /* calc A,B,C equ 20.4 */ A = cosl (mean_dec) * sinl (mean_ra + zeta); B = cosl (theta) * cosl (mean_dec) * cosl (mean_ra + zeta) - sinl (theta) * sinl (mean_dec); C = sinl (theta) * cosl (mean_dec) * cosl (mean_ra + zeta) + cosl (theta) * sinl (mean_dec); ra = atan2l (A,B) + eta; /* check for object near celestial pole */ if (mean_dec > (0.4 * M_PI) || mean_dec < (-0.4 * M_PI)) { /* close to pole */ dec = acosl (sqrt(A * A + B * B)); if (mean_dec < 0.) dec *= -1; /* 0 <= acos() <= PI */ } else { /* not close to pole */ dec = asinl (C); } /* change to degrees */ position->ra = ln_range_degrees (ln_rad_to_deg (ra)); position->dec = ln_rad_to_deg (dec); }
double ln_get_mean_sidereal_time (double JD) { long double sidereal; long double T; T = (JD - 2451545.0) / 36525.0; /* calc mean angle */ sidereal = 280.46061837 + (360.98564736629 * (JD - 2451545.0)) + (0.000387933 * T * T) - (T * T * T / 38710000.0); /* add a convenient multiple of 360 degrees */ sidereal = ln_range_degrees (sidereal); /* change to hours */ sidereal *= 24.0 / 360.0; return sidereal; }
/*! \fn double ln_get_par_body_elong (double JD, struct ln_par_orbit * orbit); * \param JD Julian day * \param orbit Orbital parameters * \return Elongation to the Sun. * * Calculate the bodies elongation to the Sun.. */ double ln_get_par_body_elong (double JD, struct ln_par_orbit * orbit) { double r,R,d; double t; double elong; /* time since perihelion */ t = JD - orbit->JD; /* get radius vector */ r = ln_get_par_radius_vector (orbit->q, t); /* get solar and Earth-Sun distances */ R = ln_get_earth_solar_dist (JD); d = ln_get_par_body_solar_dist (JD, orbit); elong = (R * R + d * d - r * r) / ( 2.0 * R * d ); return ln_range_degrees (ln_rad_to_deg (acos (elong))); }
/*! \fn double ln_get_par_body_phase_angle (double JD, struct ln_par_orbit * orbit); * \param JD Julian day * \param orbit Orbital parameters * \return Phase angle. * * Calculate the phase angle of the body. The angle Sun - body - Earth. */ double ln_get_par_body_phase_angle (double JD, struct ln_par_orbit * orbit) { double r,R,d; double t; double phase; /* time since perihelion */ t = JD - orbit->JD; /* get radius vector */ r = ln_get_par_radius_vector (orbit->q, t); /* get solar and Earth-Sun distances */ R = ln_get_earth_solar_dist (JD); d = ln_get_par_body_solar_dist (JD, orbit); phase = (r * r + d * d - R * R) / ( 2.0 * r * d ); return ln_range_degrees (ln_rad_to_deg (acos (phase))); }
/* Equ 20.3, 20.4 pg 126 */ void ln_get_equ_prec (struct ln_equ_posn * mean_position, double JD, struct ln_equ_posn * position) { long double t, t2, t3, A, B, C, zeta, eta, theta, ra, dec, mean_ra, mean_dec; /* change original ra and dec to radians */ mean_ra = ln_deg_to_rad (mean_position->ra); mean_dec = ln_deg_to_rad (mean_position->dec); /* calc t, zeta, eta and theta for J2000.0 Equ 20.3 */ t = (JD - JD2000) / 36525.0; t *= 1.0 / 3600.0; t2 = t * t; t3 = t2 *t; zeta = 2306.2181 * t + 0.30188 * t2 + 0.017998 * t3; eta = 2306.2181 * t + 1.09468 * t2 + 0.041833 * t3; theta = 2004.3109 * t - 0.42665 * t2 - 0.041833 * t3; zeta = ln_deg_to_rad (zeta); eta = ln_deg_to_rad (eta); theta = ln_deg_to_rad (theta); /* calc A,B,C equ 20.4 */ A = cosl (mean_dec) * sinl (mean_ra + zeta); B = cosl (theta) * cosl (mean_dec) * cosl (mean_ra + zeta) - sinl (theta) * sinl (mean_dec); C = sinl (theta) * cosl (mean_dec) * cosl (mean_ra + zeta) + cosl (theta) * sinl (mean_dec); ra = atan2l (A,B) + eta; /* check for object near celestial pole */ if (mean_dec > (0.4 * M_PI) || mean_dec < (-0.4 * M_PI)) { /* close to pole */ dec = acosl (sqrt(A * A + B * B)); if (mean_dec < 0.) dec *= -1; /* 0 <= acos() <= PI */ } else { /* not close to pole */ dec = asinl (C); } /* change to degrees */ position->ra = ln_range_degrees (ln_rad_to_deg (ra)); position->dec = ln_rad_to_deg (dec); }
/*! \fn double ln_get_heliocentric_time_diff (double JD, struct ln_equ_posn * object) * \param JD Julian day * \param object Pointer to object (RA, DEC) for which heliocentric correction will be caculated * * \return Heliocentric correction in fraction of day * * Calculate heliocentric corection for object at given coordinates and on given * date. */ double ln_get_heliocentric_time_diff (double JD, struct ln_equ_posn *object) { double theta, ra, dec, c_dec, obliq; struct ln_nutation nutation; struct ln_helio_posn earth; ln_get_nutation (JD, &nutation); ln_get_earth_helio_coords (JD, &earth); theta = ln_deg_to_rad (ln_range_degrees (earth.L + 180)); ra = ln_deg_to_rad (object->ra); dec = ln_deg_to_rad (object->dec); c_dec = cos (dec); obliq = ln_deg_to_rad (nutation.ecliptic); /* L.Binnendijk Properties of Double Stars, Philadelphia, University of Pennselvania Press, pp. 228-232, 1960 */ return -0.0057755 * earth.R * ( cos (theta) * cos (ra) * c_dec + sin (theta) * (sin (obliq) * sin (dec) + cos (obliq) * c_dec * sin (ra))); }
/*! \fn double ln_get_ell_body_phase_angle (double JD, struct ln_ell_orbit * orbit); * \param JD Julian day * \param orbit Orbital parameters * \return Phase angle. * * Calculate the phase angle of the body. The angle Sun - body - Earth. */ double ln_get_ell_body_phase_angle (double JD, struct ln_ell_orbit * orbit) { double r,R,d; double E,M; double phase; /* get mean anomaly */ if (orbit->n == 0) orbit->n = ln_get_ell_mean_motion (orbit->a); M = ln_get_ell_mean_anomaly (orbit->n, JD - orbit->JD); /* get eccentric anomaly */ E = ln_solve_kepler (orbit->e, M); /* get radius vector */ r = ln_get_ell_radius_vector (orbit->a, orbit->e, E); /* get solar and Earth distances */ R = ln_get_ell_body_earth_dist (JD, orbit); d = ln_get_ell_body_solar_dist (JD, orbit); phase = (r * r + d * d - R * R) / ( 2.0 * r * d ); return ln_range_degrees(acos (ln_deg_to_rad (phase))); }
int ln_get_body_rst_horizon_offset (double JD, struct ln_lnlat_posn *observer, void (*get_equ_body_coords) (double,struct ln_equ_posn *), double horizon, struct ln_rst_time *rst, double ut_offset) { int jd; double T, O, JD_UT, H0, H1; double Hat, Har, Has, altr, alts; double mt, mr, ms, mst, msr, mss, nt, nr, ns; struct ln_equ_posn sol1, sol2, sol3, post, posr, poss; double dmt, dmr, dms; int ret, i; /* dynamical time diff */ T = ln_get_dynamical_time_diff (JD); if (isnan (ut_offset)) { JD_UT = JD; } else { jd = (int)JD; JD_UT = jd + ut_offset; } /* convert local sidereal time into degrees for 0h of UT on day JD */ JD_UT = JD; O = ln_get_apparent_sidereal_time (JD_UT); O *= 15.0; /* get body coords for JD_UT -1, JD_UT and JD_UT + 1 */ get_equ_body_coords (JD_UT - 1.0, &sol1); get_equ_body_coords (JD_UT, &sol2); get_equ_body_coords (JD_UT + 1.0, &sol3); /* equ 15.1 */ H0 = (sin (ln_deg_to_rad (horizon)) - sin (ln_deg_to_rad (observer->lat)) * sin (ln_deg_to_rad (sol2.dec))); H1 = (cos (ln_deg_to_rad (observer->lat)) * cos (ln_deg_to_rad (sol2.dec))); H1 = H0 / H1; ret = check_coords (observer, H1, horizon, &sol2); if (ret) return ret; H0 = acos (H1); H0 = ln_rad_to_deg (H0); /* correct ra values for interpolation - put them to the same side of circle */ if ((sol1.ra - sol2.ra) > 180.0) sol2.ra += 360; if ((sol2.ra - sol3.ra) > 180.0) sol3.ra += 360; if ((sol3.ra - sol2.ra) > 180.0) sol3.ra -= 360; if ((sol2.ra - sol1.ra) > 180.0) sol3.ra -= 360; /* equ 15.2 */ mt = (sol2.ra - observer->lng - O) / 360.0; mr = mt - H0 / 360.0; ms = mt + H0 / 360.0; for (i = 0; i < 3; i++) { /* put in correct range */ if (mt > 1.0) mt--; else if (mt < 0) mt++; if (mr > 1.0) mr--; else if (mr < 0) mr++; if (ms > 1.0) ms--; else if (ms < 0) ms++; /* find sidereal time at Greenwich, in degrees, for each m */ mst = O + 360.985647 * mt; msr = O + 360.985647 * mr; mss = O + 360.985647 * ms; nt = mt + T / 86400.0; nr = mr + T / 86400.0; ns = ms + T / 86400.0; /* interpolate ra and dec for each m, except for transit dec (dec2) */ posr.ra = ln_interpolate3 (nr, sol1.ra, sol2.ra, sol3.ra); posr.dec = ln_interpolate3 (nr, sol1.dec, sol2.dec, sol3.dec); post.ra = ln_interpolate3 (nt, sol1.ra, sol2.ra, sol3.ra); poss.ra = ln_interpolate3 (ns, sol1.ra, sol2.ra, sol3.ra); poss.dec = ln_interpolate3 (ns, sol1.dec, sol2.dec, sol3.dec); /* find local hour angle */ Hat = mst + observer->lng - post.ra; Har = msr + observer->lng - posr.ra; Has = mss + observer->lng - poss.ra; /* find altitude for rise and set */ altr = sin (ln_deg_to_rad (observer->lat)) * sin (ln_deg_to_rad (posr.dec)) + cos (ln_deg_to_rad (observer->lat)) * cos (ln_deg_to_rad (posr.dec)) * cos (ln_deg_to_rad (Har)); alts = sin (ln_deg_to_rad (observer->lat)) * sin (ln_deg_to_rad (poss.dec)) + cos (ln_deg_to_rad (observer->lat)) * cos (ln_deg_to_rad (poss.dec)) * cos (ln_deg_to_rad (Has)); /* must be in degrees */ altr = ln_rad_to_deg (altr); alts = ln_rad_to_deg (alts); /* corrections for m */ ln_range_degrees (Hat); if (Hat > 180.0) Hat -= 360; dmt = -(Hat / 360.0); dmr = (altr - horizon) / (360 * cos (ln_deg_to_rad (posr.dec)) * cos (ln_deg_to_rad (observer->lat)) * sin (ln_deg_to_rad (Har))); dms = (alts - horizon) / (360 * cos (ln_deg_to_rad (poss.dec)) * cos (ln_deg_to_rad (observer->lat)) * sin (ln_deg_to_rad (Has))); /* add corrections and change to JD */ mt += dmt; mr += dmr; ms += dms; if (mt <= 1 && mt >= 0 && mr <= 1 && mr >= 0 && ms <= 1 && ms >= 0) break; } rst->rise = JD_UT + mr; rst->transit = JD_UT + mt; rst->set = JD_UT + ms; /* not circumpolar */ return 0; }
void MainWindow::setSunRiseAndSetVectors(const QDateTime &dateTime) { struct ln_equ_posn equ; struct ln_rst_time rst; struct ln_zonedate rise, set, transit; struct ln_lnlat_posn observer; struct ln_hrz_posn hpos; double JD; observer.lat = ui->latEdit->text().toFloat(); observer.lng = ui->lngEdit->text().toFloat(); ln_date date; date.years = dateTime.date().year(); date.months = dateTime.date().month(); date.days = dateTime.date().day(); date.hours = dateTime.time().hour(); date.minutes = dateTime.time().minute(); date.seconds = dateTime.time().second(); JD = ln_get_julian_day(&date); /* ra, dec */ ln_get_solar_equ_coords (JD, &equ); ln_get_hrz_from_equ(&equ, &observer, JD, &hpos); double a = ln_range_degrees(hpos.az - 180); QString s; s.sprintf("Azimut: %0.3f", a); ui->listWidget->addItem(s); s.sprintf("Evaluation: %0.3f", hpos.alt); ui->listWidget->addItem(s); /* rise, set and transit */ if (ln_get_solar_rst (JD, &observer, &rst) == 1) { ui->listWidget->addItem(QString("Zirkumpolar")); } else { ln_get_local_date (rst.rise, &rise); ln_get_local_date (rst.transit, &transit); ln_get_local_date (rst.set, &set); s.sprintf("Aufgang: %02d:%02d:%02d", rise.hours, rise.minutes, (int)rise.seconds); ui->listWidget->addItem(s); s.sprintf("Transit: %02d:%02d:%02d", transit.hours, transit.minutes, (int)transit.seconds); ui->listWidget->addItem(s); s.sprintf("Untergang: %02d:%02d:%02d", set.hours, set.minutes, (int)set.seconds); ui->listWidget->addItem(s); } //sunHeading->setVisible(false); setSunVectors(&rise, &observer, sunRise); setSunVectors(&set, &observer, sunSet); mc->setView(QPointF(observer.lng, observer.lat)); //overlay->addGeometry(); }
int ln_get_object_rst_horizon_offset (double JD, struct ln_lnlat_posn * observer, struct ln_equ_posn * object, long double horizon, struct ln_rst_time * rst, double ut_offset) { int jd; long double O, JD_UT, H0, H1; double Hat, Har, Has, altr, alts; double mt, mr, ms, mst, msr, mss; double dmt, dmr, dms; int ret, i; if (isnan (ut_offset)) { JD_UT = JD; } else { /* convert local sidereal time into degrees for 0h of UT on day JD */ jd = (int)JD; JD_UT = jd + ut_offset; } O = ln_get_apparent_sidereal_time (JD_UT); O *= 15.0; /* equ 15.1 */ H0 = (sin (ln_deg_to_rad (horizon)) - sin (ln_deg_to_rad (observer->lat)) * sin (ln_deg_to_rad (object->dec))); H1 = (cos (ln_deg_to_rad (observer->lat)) * cos (ln_deg_to_rad (object->dec))); H1 = H0 / H1; ret = check_coords (observer, H1, horizon, object); if (ret) return ret; H0 = acos (H1); H0 = ln_rad_to_deg (H0); /* equ 15.2 */ mt = (object->ra - observer->lng - O) / 360.0; mr = mt - H0 / 360.0; ms = mt + H0 / 360.0; for (i = 0; i < 3; i++) { /* put in correct range */ if (mt > 1.0) mt--; else if (mt < 0) mt++; if (mr > 1.0) mr--; else if (mr < 0) mr++; if (ms > 1.0) ms--; else if (ms < 0) ms++; /* find sidereal time at Greenwich, in degrees, for each m */ mst = O + 360.985647 * mt; msr = O + 360.985647 * mr; mss = O + 360.985647 * ms; /* find local hour angle */ Hat = mst + observer->lng - object->ra; Har = msr + observer->lng - object->ra; Has = mss + observer->lng - object->ra; /* find altitude for rise and set */ altr = sin (ln_deg_to_rad (observer->lat)) * sin (ln_deg_to_rad (object->dec)) + cos (ln_deg_to_rad (observer->lat)) * cos (ln_deg_to_rad (object->dec)) * cos (ln_deg_to_rad (Har)); alts = sin (ln_deg_to_rad (observer->lat)) * sin (ln_deg_to_rad (object->dec)) + cos (ln_deg_to_rad (observer->lat)) * cos (ln_deg_to_rad (object->dec)) * cos (ln_deg_to_rad (Has)); /* must be in degrees */ altr = ln_rad_to_deg (altr); alts = ln_rad_to_deg (alts); /* corrections for m */ ln_range_degrees (Hat); if (Hat > 180.0) Hat -= 360; dmt = -(Hat / 360.0); dmr = (altr - horizon) / (360 * cos (ln_deg_to_rad (object->dec)) * cos (ln_deg_to_rad (observer->lat)) * sin (ln_deg_to_rad (Har))); dms = (alts - horizon) / (360 * cos (ln_deg_to_rad (object->dec)) * cos (ln_deg_to_rad (observer->lat)) * sin (ln_deg_to_rad (Has))); /* add corrections and change to JD */ mt += dmt; mr += dmr; ms += dms; if (mt <= 1 && mt >= 0 && mr <= 1 && mr >= 0 && ms <= 1 && ms >= 0) break; } rst->rise = JD_UT + mr; rst->transit = JD_UT + mt; rst->set = JD_UT + ms; /* not circumpolar */ return 0; }