Ejemplo n.º 1
0
/** @brief Find next direction changing of object
**
** This function tries to find when and where a planet in direct or
** retrograde motion goes retrograde or direct (respectively).
**
** @attention If step is set to 0, use a predefined step (recommended); it must
** be inferior to the planet's minimum retrogradation time.
**
** @remarks If dayspan is set to 0, the search is not limited in time.
** Otherwise, the function may return 1 when time limit has been reached.
** Flag must include SEFLG_SPEED, and SEFLG_NOGDEFL to avoid bad surprises;
** alternatively use true positions.
**
** @see swh_min_retro_time()
**
** @param planet Planet number (SE_*, etc)
** @param jdstart Julian day number, when search is starting
** @param step Number of days used in the dichotomic search process
** @param backw Search before jdstart [1], or after [0] (boolean)
** @param dayspan Limit search to a certain time, expressed in days
** @param flag Calculation flags, see swisseph docs
** @param jdret Julian day number found
** @param posret Planet's positions found
** @param err Buffer for error, declared as char[256]
** @return 0 on success, 1 if time limit reached, -1 on error
*/
int swh_next_retro(int planet, double jdstart, double step, int backw,
    double dayspan, int flag, double *jdret, double *posret, char *err)
{
    int res, direct[3];
    double jdstop = 0; /* dummy assign */
    direct[2] = 0; /* dummy assign */
    /* set limit */
    dayspan = fabs(dayspan);
    if (dayspan)
    {
        jdstop = (backw) ? jdstart-dayspan : jdstart+dayspan;
        direct[2] = (backw) ? 0 : 1;
    }
    /* find step if 0 */
    if (step == 0)
    {
        step = swh_min_retro_time(planet, err);
        if (step < 0) { return -1; } /* never retro */
    } else { step = fabs(step); }
    /* find current direction */
    res = swe_calc_ut(jdstart, planet, flag, posret, err);
    if (res < 0) { return -1; }
    direct[1] = direct[0] = (posret[3] > 0) ? 1 : 0;
    /* step till direction changes */
    *jdret = jdstart;
    while (step > swh_precision)
    {
        *jdret = (backw) ? *jdret-step : *jdret+step;
        res = swe_calc_ut(*jdret, planet, flag, posret, err);
        if (res < 0) { return -1; }
        direct[0] = (posret[3] > 0) ? 1 : 0;
        if (direct[0] != direct[1]) /* invert step */
        {
            if (dayspan && backw == direct[2])
            {
                if (direct[2]) { if (*jdret > jdstop) return 1; }
                else { if (*jdret < jdstop) return 1; }
            }
            step = step/2;
            backw = (backw) ? 0 : 1;
            direct[1] = direct[0];
        }
        else if (dayspan && backw != direct[2])
        {
            if (direct[2]) { if (*jdret > jdstop) return 1; }
            else { if (*jdret < jdstop) return 1; }
        }
    }
    return 0;
}
Ejemplo n.º 2
0
		double SweWrapper::body_pos(body b, double julian_day)
		{
			/*
			 target address for 6 position values: longitude, latitude, distance, long. speed, lat. speed, dist. speed
			*/
			static double coords[6];

			static char swe_error_msg[AS_MAXCH];
			static long calc_flag = 0;

			int swe_body = static_cast<int>(body_to_swe_body(b));
						
			long swe_result = swe_calc_ut(julian_day, swe_body, calc_flag, coords, swe_error_msg);

			if(calc_flag != swe_result) {

				throw runtime_error{ (string("Swiss ephemeris error: '") + swe_error_msg + "'\n").c_str() };
			}

			if(b == body::earth || b == body::snode) {

				coords[0] += 180.;
				if(coords[0] > 360.) coords[0] -= 360.;
			}

			// return ecliptic longitude of the body (in degrees [0..365), counting from the vernal equinox of the date as 0 degrees)
			return coords[0];
		}
Ejemplo n.º 3
0
/** @brief Get an estimation of when a planet is gone past a fixed point
**
** Get Julian day number and positions when a celestial object is gone past
** a fixed point expressed in longitude degrees. This is not meant to be
** precise at all. Mainly used in swephelp search routines.
**
** @attention Same warning as in swh_next_retro.
**
** @remarks If step is set to 0, use a predefined step (recommended).
**
** @param planet Planet number (SE_*, etc)
** @param fixedpt Fixed pointed targeted [0;360[
** @param jdstart Julian day number, when search is starting
** @param step Number of days used in the dichotomic search process
** @param backw Search before jdstart [1], or after [0] (boolean)
** @param flag Calculation flags, see swisseph docs
** @param jdret Julian day number found
** @param posret Planet's positions found
** @param err Buffer for errors, declared as char[256]
** @return 0 on success, -1 on error
*/
int swh_go_past(int planet, double fixedpt, double jdstart, double step,
    int backw, int flag, double *jdret, double *posret, char *err)
{
    int res;
    double testjd, difdegn[2], difdeg2n[2];
    /* find step if 0 */
    if (step == 0)
    {
        step = swh_min_retro_time(planet, err);
        if (step < 0) { step = 10; } /* never retro, use default step */
    } else { step = fabs(step); }
    /* get start position */
    res = swe_calc_ut(jdstart, planet, flag, posret, err);
    if (res < 0) { return -1; }
    /* get difference between start pt and fixed pt */
    difdegn[1] = swe_difdegn(posret[0], fixedpt);
    difdeg2n[1] = swe_difdeg2n(posret[0], fixedpt);
    *jdret = jdstart;
    while (1)
    {
        *jdret = (backw) ? *jdret-step : *jdret+step;
        res = swe_calc_ut(*jdret, planet, flag, posret, err);
        if (res < 0) { return -1; }
        if (posret[3] < 0)
        {
            res = swh_next_retro(planet, *jdret, step, (backw) ? 0 : 1,
                0, flag, &testjd, posret, err);
            if (res < 0) { return -1; }
        }
        else { testjd = *jdret; }
        difdegn[0] = swe_difdegn(posret[0], fixedpt);
        difdeg2n[0] = swe_difdeg2n(posret[0], fixedpt);
        if (ISPOSITIVE(difdeg2n[1]) != ISPOSITIVE(difdeg2n[0])
            && fabs(difdegn[1]-difdegn[0]) > 180)
        {
            *jdret = testjd;
            return 0;
        }
        difdegn[1] = difdegn[0];
        difdeg2n[1] = difdeg2n[0];
    }
}
Ejemplo n.º 4
0
/** @brief Get number of years difference between two julian days
**
** One exact "astrological" year can be considered as one solar return.
** Then is it varying with the type of zodiac in use.
**
** @param jd1 First Julian day
** @param jd2 Second Julian day
** @param flag Calculation flag
** @param years Result, declared as double
** @param err Buffer for errors, declared as char[256]
** @return 0 on success, else -1
**/
int swh_years_diff(double jd1, double jd2, int flag, double *years, char *err)
{
    double pos1[6], pos2[6], dec;
    double corr = 2 * swh_precision;
    int res;
    res = swe_calc_ut(jd1, SE_SUN, flag, pos1, err);
    if (res < 0) { return -1; }
    res = swe_calc_ut(jd2, SE_SUN, flag, pos2, err);
    if (res < 0) { return -1; }
    *years = 0;
    if (jd1 < jd2) /* forward search */
    {
        dec = swe_difdegn(pos2[0], pos1[0]) / 360.0;
        while (1)
        {
            res = swh_next_aspect(SE_SUN, 0, pos1[0], jd1+corr, 120, 0, 0,
                flag, &jd1, pos2, err);
            if (res < 0) { return -1; }
            if (jd1+corr < jd2) { *years += 1; }
            else { break; }
        }
        *years += dec;
    }
    else if (jd1 > jd2) /* backward search */
    {
        dec = swe_difdegn(pos1[0], pos2[0]) / 360.0;
        while (1)
        {
            res = swh_next_aspect(SE_SUN, 0, pos1[0], jd1-corr, 120, 1, 0,
                flag, &jd1, pos2, err);
            if (res < 0) { return -1; }
            if (jd1-corr > jd2) { *years -= 1; }
            else { break; }
        }
        *years -= dec;
    }
    /* else equal julian days */
    return 0;
}
Ejemplo n.º 5
0
static PyObject* astrology_swe_calc_ut(PyObject *self, PyObject *args)
{
	double tjd_ut;
	int ipl;
	int iflag;

	if (!PyArg_ParseTuple(args, "dii", &tjd_ut, &ipl, &iflag))
		return NULL;

	double xx[6];
	char serr[AS_MAXCH];
	int ret = swe_calc_ut(tjd_ut, ipl, iflag, xx, serr);

	return Py_BuildValue("(l)(dddddd)(s)", ret, xx[0], xx[1], xx[2], xx[3], xx[4], xx[5], serr);
}
Ejemplo n.º 6
0
Archivo: swe4r.c Proyecto: aakara/swe4r
/*
 * Calculation of planets, moon, asteroids, lunar nodes, apogees, fictitious bodies
 * http://www.astro.com/swisseph/swephprg.htm#_Toc283735419
	long swe_calc_ut(
		double tjd_ut,	// Julian day number, Universal Time
		int ipl,		// planet number
		long iflag,		// flag bits
		double *xx,  	// target address for 6 position values: longitude, latitude, distance, long.speed, lat.speed, dist.speed
		char *serr		// 256 bytes for error string
	);
 */
static VALUE t_swe_calc_ut(VALUE self, VALUE julian_ut, VALUE body, VALUE iflag) {
	double results[6];
	char serr[AS_MAXCH];
	VALUE arr = rb_ary_new();
	int id_push = rb_intern("push");
	int i=0;
	
	if ( swe_calc_ut(NUM2DBL(julian_ut), NUM2INT(body), NUM2LONG(iflag), results,  serr) < 0 )
		rb_raise (rb_eRuntimeError, serr);
	
	for ( i = 0; i < 6; i++)
		rb_funcall(arr, id_push, 1, rb_float_new(results[i]));
	
	return arr;
}
Ejemplo n.º 7
0
/** @brief Find next aspect to a house cusp
**
** Get Julian day number and positions, and houses cusps, when a
** celestial object makes longitudinal aspect to a house cusp.
**
** @attention Here, step may not be too high, or 0. Setting it to 0.2 is enough.
**
** @remarks If star != "", the planet is ignored.
**
** @see For risings, settings, meridian transits, see swe_rise_trans.
**
** @param planet Planet number (SE_*, etc)
** @param star Fixed star
** @param aspect Aspect, in degrees [0;360[
** @param cusp House cusp number [1;12], or [1;36] for Gauquelin sectors
** @param jdstart Julian day number, when search is starting
** @param lat Latitude, in degrees (north is positive)
** @param lon Longitude, in degrees (east is positive)
** @param hsys House system, see swisseph docs
** @param step Number of days used in the dichotomic search process
** @param backw Search before jdstart [1], or after [0] (boolean)
** @param flag Calculation flags, see swisseph docs
** @param jdret Julian day number found
** @param posret Planet (or fixed star) positions found
** @param cuspsret House cusps positions found
** @param ascmcret Asc-Mc-etc found, see swisseph docs
** @param err Buffer for errors, declared as char[256]
** @return 0 on success, -1 on error
*/
int swh_next_aspect_cusp(int planet, char *star, double aspect, int cusp,
    double jdstart, double lat, double lon, int hsys, double step, int backw,
    int flag, double *jdret, double *posret, double *cuspsret, double *ascmcret,
    char *err)
{
    int res, starflag;
    double diff[4];
    char starbuf[41];
    aspect = swe_degnorm(aspect);
    step = fabs(step);
    if (step == 0) { step = 0.2; }
    /* get start position */
    if (strcmp("", star) != 0)
    {
        strcpy(starbuf, star); /* only first time */
        res = swe_fixstar_ut(starbuf, jdstart, flag, posret, err);
        if (res < 0) { return -1; }
        starflag = 1;
    }
    else
    {
        res = swe_calc_ut(jdstart, planet, flag, posret, err);
        if (res < 0) { return -1; }
        starflag = 0;
    }
    res = swe_houses_ex(jdstart, flag, lat, lon, hsys, cuspsret, ascmcret);
    if (res < 0) { return -1; }
    /* compare */
    diff[1] = swe_difdeg2n(posret[0], cuspsret[cusp] + aspect);
    diff[3] = swe_difdegn(posret[0], cuspsret[cusp] + aspect);
    *jdret = jdstart;
    while (step > swh_precision)
    {
        *jdret = (backw) ? *jdret-step : *jdret+step;
        /* get positions */
        if (starflag)
        {
            res = swe_fixstar_ut(starbuf, *jdret, flag, posret, err);
            if (res < 0) { return -1; }
        }
        else
        {
            res = swe_calc_ut(*jdret, planet, flag, posret, err);
            if (res < 0) { return -1; }
        }
        res = swe_houses_ex(*jdret, flag, lat, lon, hsys, cuspsret, ascmcret);
        if (res < 0) { return -1; }
        /* compare */
        diff[0] = swe_difdeg2n(posret[0], cuspsret[cusp] + aspect);
        diff[2] = swe_difdegn(posret[0], cuspsret[cusp] + aspect);
        if (ISPOSITIVE(diff[1]) != ISPOSITIVE(diff[0])
            && fabs(diff[3]-diff[2]) > 180)
        {
            backw = (backw) ? 0 : 1;
            step = step/2;
        }
        diff[1] = diff[0];
        diff[3] = diff[2];
    }
    return 0;
}
Ejemplo n.º 8
0
/** @brief Find next aspect between two moving objects
**
** Get Julian day number and positions when a celestial object makes a
** longitudinal aspect to another moving object.
**
** @attention Here, step may not be set to 0. If you estimate that the aspect
** is to occur in a very long time, you better set it to a high value, for
** faster results. In doubt, set it to 10.
**
** @remarks If star != "", the other planet is ignored.
** If dayspan is set to 0, the search is not limited in time.
** Otherwise, the function may return 1 when time limit has been reached.
**
** @param planet Planet number (SE_*, etc)
** @param aspect Aspect, in degrees [0;360[
** @param other Other planet number
** @param star Fixed star
** @param jdstart Julian day number, when search is starting
** @param step Number of days used in the dichotomic search process
** @param backw Search before jdstart [1], or after [0] (boolean)
** @param dayspan Limit search to a certain time, expressed in days
** @param flag Calculation flags, see swisseph docs
** @param jdret Julian day number found
** @param posret0 Planet's positions found
** @param posret1 Other planet (or star) positions found
** @param err Buffer for errors, declared as char[256]
** @return 0 on success, 1 if time limit reached, -1 on error
*/
int swh_next_aspect_with(int planet, double aspect, int other, char *star,
    double jdstart, double step, int backw, double dayspan, int flag,
    double *jdret, double *posret0, double *posret1, char *err)
{
    int res, starflag, direct = 0; /* dummy assign */
    double jdstop = 0, diff[4]; /* dummy assign */
    char starbuf[41];
    aspect = swe_degnorm(aspect);
    step = fabs(step);
    if (step == 0) { step = 10; }
    dayspan = fabs(dayspan);
    if (dayspan)
    {
        jdstop = (backw) ? jdstart-dayspan : jdstart+dayspan;
        direct = (backw) ? 0 : 1;
    }
    /* get planets positions */
    res = swe_calc_ut(jdstart, planet, flag, posret0, err);
    if (res < 0) { return -1; }
    if (strcmp("", star) != 0)
    {
        strcpy(starbuf, star); /* only first time */
        res = swe_fixstar_ut(starbuf, jdstart, flag, posret1, err);
        if (res < 0) { return -1; }
        starflag = 1;
    }
    else
    {
        res = swe_calc_ut(jdstart, other, flag, posret1, err);
        if (res < 0) { return -1; }
        starflag = 0;
    }
    /* compare */
    diff[1] = swe_difdeg2n(posret0[0], posret1[0] + aspect);
    diff[3] = swe_difdegn(posret0[0], posret1[0] + aspect);
    *jdret = jdstart;
    while (step > swh_precision)
    {
        *jdret = (backw) ? *jdret-step : *jdret+step;
        /* get planets positions */
        res = swe_calc_ut(*jdret, planet, flag, posret0, err);
        if (res < 0) { return -1; }
        if (starflag)
        {
            res = swe_fixstar_ut(starbuf, *jdret, flag, posret1, err);
            if (res < 0) { return -1; }
        }
        else
        {
            res = swe_calc_ut(*jdret, other, flag, posret1, err);
            if (res < 0) { return -1; }
        }
        /* compare */
        diff[0] = swe_difdeg2n(posret0[0], posret1[0] + aspect);
        diff[2] = swe_difdegn(posret0[0], posret1[0] + aspect);
        if (ISPOSITIVE(diff[1]) != ISPOSITIVE(diff[0])
            && fabs(diff[3]-diff[2]) > 180) /* invert step */
        {
            if (dayspan && backw == direct)
            {
                if (direct) { if (*jdret > jdstop) return 1; }
                else { if (*jdret < jdstop) return 1; }
            }
            backw = (backw) ? 0 : 1;
            step = step/2;
        }
        else if (dayspan && backw != direct)
        {
            if (direct) { if (*jdret > jdstop) return 1; }
            else { if (*jdret < jdstop) return 1; }
        }
        diff[1] = diff[0];
        diff[3] = diff[2];
    }
    return 0;
}
Ejemplo n.º 9
0
int swh_saturn_4_stars( const double jd, const int flag, double* ret, char* err )
{
    char starbuf[50];
    double xx[6];
    double* stars[2] = {0,0}; /* dummy assign */
    double midp, dist0, dist1, dist2;
    int i;

    /* Get bodies positions */
    i = swe_calc_ut( jd, SE_SATURN, flag, xx, err );
    if ( i < 0 )
        return -1;
    ret[0] = xx[0];

    strcpy( starbuf, "Aldebaran" );
    i = swe_fixstar_ut( starbuf, jd, flag, xx, err );
    if ( i < 0 )
        return -1;
    ret[1] = xx[0];

    strcpy( starbuf, "Regulus" );
    i = swe_fixstar_ut( starbuf, jd, flag, xx, err );
    if ( i < 0 )
        return -1;
    ret[2] = xx[0];

    strcpy( starbuf, "Antares" );
    i = swe_fixstar_ut( starbuf, jd, flag, xx, err );
    if ( i < 0 )
        return -1;
    ret[3] = xx[0];

    strcpy( starbuf, "Fomalhaut" );
    i = swe_fixstar_ut( starbuf, jd, flag, xx, err );
    if ( i < 0 )
        return -1;
    ret[4] = xx[0];

    /* Find nearest stars from Saturn */
    if ( ret[0] <= ret[1] || ret[0] > ret[4] )
    {
        stars[0] = &ret[4];
        stars[1] = &ret[1];
    }
    else if ( ret[0] <= ret[2] )
    {
        stars[0] = &ret[1];
        stars[1] = &ret[2];
    }
    else if ( ret[0] <= ret[3] )
    {
        stars[0] = &ret[2];
        stars[1] = &ret[3];
    }
    else if ( ret[0] <= ret[4] )
    {
        stars[0] = &ret[3];
        stars[1] = &ret[4];
    }

    /* Find midpoint between stars */
    midp = swe_deg_midp( *stars[0], *stars[1] );

    /* Find distance Saturn/midpoint */
    dist0 = fabs( swe_difdeg2n( ret[0], midp ) );

    /* Find which star is closer from saturn and calculate the index */
    dist1 = fabs( swe_difdeg2n( ret[0], *stars[0] ) );
    dist2 = fabs( swe_difdeg2n( ret[0], *stars[1] ) );

    if ( dist1 <= dist2 ) /* first is closer */
        ret[5] = dist0 / ( fabs( swe_difdeg2n( midp, *stars[0] ) ) / 100.0 );
    else /* second is closer */
        ret[5] = dist0 / ( fabs( swe_difdeg2n( midp, *stars[1] ) ) / 100.0 );
    return 0;
}