Beispiel #1
0
/**
 * Note: timestamp = unixtimestamp (NEEDS to be 00:00:00 UT)
 *       Eastern longitude positive, Western longitude negative
 *       Northern latitude positive, Southern latitude negative
 *       The longitude value IS critical in this function!
 *       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 rise/set
 *               times, and to zero when computing start/end of
 *               twilight.
 *        *rise = where to store the rise time
 *        *set  = where to store the set  time
 *                Both times are relative to the specified altitude,
 *                and thus this function can be used to compute
 *                various twilight times, as well as rise/set times
 * Return value:  0 = sun rises/sets this day, times stored at
 *                    *trise and *tset.
 *               +1 = sun above the specified "horizon" 24 hours.
 *                    *trise set to time when the sun is at south,
 *                    minus 12 hours while *tset is set to the south
 *                    time plus 12 hours. "Day" length = 24 hours
 *               -1 = sun is below the specified "horizon" 24 hours
 *                    "Day" length = 0 hours, *trise and *tset are
 *                    both set to the time when the sun is at south.
 *
 */
int timelib_astro_rise_set_altitude(timelib_time *t_loc, double lon, double lat, double altit, int upper_limb, double *h_rise, double *h_set, timelib_sll *ts_rise, timelib_sll *ts_set, timelib_sll *ts_transit)
{
	double  d,  /* Days since 2000 Jan 0.0 (negative before) */
	sr,         /* Solar distance, astronomical units */
	sRA,        /* Sun's Right Ascension */
	sdec,       /* Sun's declination */
	sradius,    /* Sun's apparent radius */
	t,          /* Diurnal arc */
	tsouth,     /* Time when Sun is at south */
	sidtime;    /* Local sidereal time */
	timelib_time *t_utc;
	timelib_sll   timestamp, old_sse;

	int rc = 0; /* Return cde from function - usually 0 */

	/* Normalize time */
	old_sse = t_loc->sse;
	t_loc->h = 12;
	t_loc->i = t_loc->s = 0;
	timelib_update_ts(t_loc, NULL);

	/* Calculate TS belonging to UTC 00:00 of the current day */
	t_utc = timelib_time_ctor();
	t_utc->y = t_loc->y;
	t_utc->m = t_loc->m;
	t_utc->d = t_loc->d;
	t_utc->h = t_utc->i = t_utc->s = 0;
	timelib_update_ts(t_utc, NULL);

	/* Compute d of 12h local mean solar time */
	timestamp = t_loc->sse;
	d = timelib_ts_to_juliandate(timestamp) - lon/360.0;

	/* Compute local sidereal time of this moment */
	sidtime = astro_revolution(astro_GMST0(d) + 180.0 + lon);

	/* Compute Sun's RA + Decl at this moment */
	astro_sun_RA_dec( d, &sRA, &sdec, &sr );

	/* Compute time when Sun is at south - in hours UT */
	tsouth = 12.0 - astro_rev180(sidtime - sRA) / 15.0;

	/* 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 altitude altit: */
	{
		double cost;
		cost = (sind(altit) - sind(lat) * sind(sdec)) / (cosd(lat) * cosd(sdec));
		*ts_transit = t_utc->sse + (tsouth * 3600);
		if (cost >= 1.0) {
			rc = -1;
			t = 0.0;       /* Sun always below altit */

			*ts_rise = *ts_set = t_utc->sse + (tsouth * 3600);
		} else if (cost <= -1.0) {
			rc = +1;
			t = 12.0;      /* Sun always above altit */

			*ts_rise = t_loc->sse - (12 * 3600);
			*ts_set  = t_loc->sse + (12 * 3600);
		} else {
			t = acosd(cost) / 15.0;   /* The diurnal arc, hours */

			/* Store rise and set times - as Unix Timestamp */
			*ts_rise = ((tsouth - t) * 3600) + t_utc->sse;
			*ts_set  = ((tsouth + t) * 3600) + t_utc->sse;

			*h_rise = (tsouth - t);
			*h_set  = (tsouth + t);
		}
	}

	/* Kill temporary time and restore original sse */
	timelib_time_dtor(t_utc);
	t_loc->sse = old_sse;

	return rc;
}
Beispiel #2
0
int main( int argc, char *argv[] )
{
/*** first probing code, now superseded 
	float fpi = 2.0*acos(0.0);
	printf("fpi = %.12f\n", fpi);
	double dpi = 2.0*acos(0.0);
	printf("dpi = %.12f\n", dpi);
	fract16 r, s;
	r = 0.0r16;
	fract16 fr16pi = acos_fr16(r);
	float ff = fr16_to_float(fr16pi);
//Ha! This gave nonsense (but no error message) until I included all the other .h's up there apart from math.h
	printf("fr16pi as a fraction of pi/2 = %f, which *pi = %.12f\n", ff , HIPI*ff);
	
	printf("fr16pi as float = %.8f\n", fr16_to_float(fr16pi));
	s = 0.1r16;
	dpi = fr16_to_float(asin_fr16(s))*HIPI*0.5;
	printf("fr16 asin of small angle as float = %.12f\n", dpi);
	fpi = asin(0.1);
	printf("regular asin of same angle = %.12f\n", fpi);
	printf("Error %% %.8f \n", 100.0*(1.0 - dpi/(double)fpi)); 
	
	fract32 p32, q32, r32, fr32pi;
	r32 = 0.0r32;
	fr32pi = acos_fr32(r32);
	ff = fr32_to_float(fr32pi);
	printf("fr32pi as a fraction of pi/2 = %f, which *pi = %.12f\n", ff , HIPI*ff);
***/	
	
/*
	Accuracy and precision evaluation of different arithmetic operations on the Blackfin 355
	I've taken pi to 20 decimal places from the internet, 3 sources gave the same number, one differed!
	I calculate pi using a call to various forms of acos.
	I also compare calculations of the sine of a small angle (0.1 rad) by different methods with a (presumably)
	highly accurate calculation from the internet
	
	N.B. float and double are both 32-bit
	
*/	
	
	float f1, f2;
	long double dd=0.0, dd2=0.0;
	//printf("\tUsing float\n");
	f1 = 2.0*acos(0.0);
	dd2 = f1;
	dd = ldpi;//(long double)HIPI;
	f2 = (dd2-ldpi)*(long double)1000000.0/dd;
	printf("Error of 2.0*acos(0.0) in ppm = \n%.12f\n", f2);
	printf("True value of pi = \n%s\n", PISTRING);
	//printf("\tUsing long double\n");
	dd = 0.0;
	//dd2 = 2.0;
	dd2 = 2.0*acosd(dd);
	dd = HIPI;
	//Can't format printf properly to show long double, so
	f2 = (dd2-dd)*(long double)1000000.0/dd;
	printf("Error of 2.0*acosd(0.0) in ppm = \n%.12f\n", f2);
	
	//printf("Using fract32\n");
	
	 
	return 0;
}
Beispiel #3
0
///===vecfunc========== ANGLE BETWEEN A-B-C ===================///
float Angle (vec2 A, vec2 B, vec2 C) {
    vec2 Vector1 = Normalize (A-B);
    vec2 Vector2 = Normalize (C-B);
    return acosd (Vector1*Vector2);
}
Beispiel #4
0
float Angle (vec3 A, vec3 B, vec3 C) {
    vec3 Vector1 = Normalize (A-B);
    vec3 Vector2 = Normalize (C-B);
    return acosd (Vector1*Vector2);
}
Beispiel #5
0
///===vecfunc========== ANGLE BETWEEN A-0-B ===================///
float Angle (vec2 A, vec2 B) {
    return acosd (A*B);
}
Beispiel #6
0
float Angle (vec3 A, vec3 B) {
    return acosd (A*B);
}
Beispiel #7
0
int sphx2s(
  const double eul[5],
  int nphi,
  int ntheta,
  int spt,
  int sll,
  const double phi[],
  const double theta[],
  double lng[],
  double lat[])

{
  int mphi, mtheta, rowlen, rowoff;
  double cosphi, costhe, costhe3, costhe4, dlng, dphi, sinphi, sinthe,
         sinthe3, sinthe4, x, y, z;
  register int iphi, itheta;
  register const double *phip, *thetap;
  register double *latp, *lngp;

  if (ntheta > 0) {
    mphi   = nphi;
    mtheta = ntheta;
  } else {
    mphi   = 1;
    mtheta = 1;
    ntheta = nphi;
  }


  /* Check for a simple change in origin of longitude. */
  if (eul[4] == 0.0) {
    if (eul[1] == 0.0) {
      dlng = fmod(eul[0] + 180.0 - eul[2], 360.0);

      lngp = lng;
      latp = lat;
      phip   = phi;
      thetap = theta;
      for (itheta = 0; itheta < ntheta; itheta++) {
        for (iphi = 0; iphi < mphi; iphi++) {
          *lngp = *phip + dlng;
          *latp = *thetap;

          /* Normalize the celestial longitude. */
          if (eul[0] >= 0.0) {
            if (*lngp < 0.0) *lngp += 360.0;
          } else {
            if (*lngp > 0.0) *lngp -= 360.0;
          }

          if (*lngp > 360.0) {
            *lngp -= 360.0;
          } else if (*lngp < -360.0) {
            *lngp += 360.0;
          }

          lngp   += sll;
          latp   += sll;
          phip   += spt;
          thetap += spt;
        }
      }

    } else {
      dlng = fmod(eul[0] + eul[2], 360.0);

      lngp = lng;
      latp = lat;
      phip   = phi;
      thetap = theta;
      for (itheta = 0; itheta < ntheta; itheta++) {
        for (iphi = 0; iphi < mphi; iphi++) {
          *lngp = dlng - *phip;
          *latp = -(*thetap);

          /* Normalize the celestial longitude. */
          if (eul[0] >= 0.0) {
            if (*lngp < 0.0) *lngp += 360.0;
          } else {
            if (*lngp > 0.0) *lngp -= 360.0;
          }

          if (*lngp > 360.0) {
            *lngp -= 360.0;
          } else if (*lngp < -360.0) {
            *lngp += 360.0;
          }

          lngp   += sll;
          latp   += sll;
          phip   += spt;
          thetap += spt;
        }
      }
    }

    return 0;
  }


  /* Do phi dependency. */
  phip = phi;
  rowoff = 0;
  rowlen = nphi*sll;
  for (iphi = 0; iphi < nphi; iphi++, rowoff += sll, phip += spt) {
    dphi = *phip - eul[2];

    lngp = lng + rowoff;
    for (itheta = 0; itheta < mtheta; itheta++) {
      *lngp = dphi;
      lngp += rowlen;
    }
  }


  /* Do theta dependency. */
  thetap = theta;
  lngp = lng;
  latp = lat;
  for (itheta = 0; itheta < ntheta; itheta++, thetap += spt) {
    sincosd(*thetap, &sinthe, &costhe);
    costhe3 = costhe*eul[3];
    costhe4 = costhe*eul[4];
    sinthe3 = sinthe*eul[3];
    sinthe4 = sinthe*eul[4];

    for (iphi = 0; iphi < mphi; iphi++, lngp += sll, latp += sll) {
      dphi = *lngp;
      sincosd(dphi, &sinphi, &cosphi);

      /* Compute the celestial longitude. */
      x = sinthe4 - costhe3*cosphi;
      if (fabs(x) < tol) {
        /* Rearrange formula to reduce roundoff errors. */
        x = -cosd(*thetap + eul[1]) + costhe3*(1.0 - cosphi);
      }

      y = -costhe*sinphi;
      if (x != 0.0 || y != 0.0) {
        dlng = atan2d(y, x);
      } else {
        /* Change of origin of longitude. */
        if (eul[1] < 90.0) {
          dlng =  dphi + 180.0;
        } else {
          dlng = -dphi;
        }
      }
      *lngp = eul[0] + dlng;

      /* Normalize the celestial longitude. */
      if (eul[0] >= 0.0) {
        if (*lngp < 0.0) *lngp += 360.0;
      } else {
        if (*lngp > 0.0) *lngp -= 360.0;
      }

      if (*lngp > 360.0) {
        *lngp -= 360.0;
      } else if (*lngp < -360.0) {
        *lngp += 360.0;
      }

      /* Compute the celestial latitude. */
      if (fmod(dphi,180.0) == 0.0) {
        *latp = *thetap + cosphi*eul[1];
        if (*latp >  90.0) *latp =  180.0 - *latp;
        if (*latp < -90.0) *latp = -180.0 - *latp;
      } else {
        z = sinthe3 + costhe4*cosphi;
        if (fabs(z) > 0.99) {
          /* Use an alternative formula for greater accuracy. */
          *latp = copysign(acosd(sqrt(x*x+y*y)), z);
        } else {
          *latp = asind(z);
        }
      }
    }
  }

  return 0;
}
Beispiel #8
0
int sphs2x(
  const double eul[5],
  int nlng,
  int nlat,
  int sll,
  int spt,
  const double lng[],
  const double lat[],
  double phi[],
  double theta[])

{
  int mlat, mlng, rowlen, rowoff;
  double coslat, coslat3, coslat4, coslng, dlng, dphi, sinlat, sinlat3,
         sinlat4, sinlng, x, y, z;
  register int ilat, ilng;
  register const double *latp, *lngp;
  register double *phip, *thetap;

  if (nlat > 0) {
    mlng = nlng;
    mlat = nlat;
  } else {
    mlng = 1;
    mlat = 1;
    nlat = nlng;
  }


  /* Check for a simple change in origin of longitude. */
  if (eul[4] == 0.0) {
    if (eul[1] == 0.0) {
      dphi = fmod(eul[2] - 180.0 - eul[0], 360.0);

      lngp = lng;
      latp = lat;
      phip   = phi;
      thetap = theta;
      for (ilat = 0; ilat < nlat; ilat++) {
        for (ilng = 0; ilng < mlng; ilng++) {
          *phip = fmod(*lngp + dphi, 360.0);
          *thetap = *latp;

          /* Normalize the native longitude. */
          if (*phip > 180.0) {
            *phip -= 360.0;
          } else if (*phip < -180.0) {
            *phip += 360.0;
          }

          phip   += spt;
          thetap += spt;
          lngp   += sll;
          latp   += sll;
        }
      }

    } else {
      dphi = fmod(eul[2] + eul[0], 360.0);

      lngp = lng;
      latp = lat;
      phip   = phi;
      thetap = theta;
      for (ilat = 0; ilat < nlat; ilat++) {
        for (ilng = 0; ilng < mlng; ilng++) {
          *phip = fmod(dphi - *lngp, 360.0);
          *thetap = -(*latp);

          /* Normalize the native longitude. */
          if (*phip > 180.0) {
            *phip -= 360.0;
          } else if (*phip < -180.0) {
            *phip += 360.0;
          }

          phip   += spt;
          thetap += spt;
          lngp   += sll;
          latp   += sll;
        }
      }
    }

    return 0;
  }


  /* Do lng dependency. */
  lngp = lng;
  rowoff = 0;
  rowlen = nlng*spt;
  for (ilng = 0; ilng < nlng; ilng++, rowoff += spt, lngp += sll) {
    dlng = *lngp - eul[0];

    phip = phi + rowoff;
    thetap = theta;
    for (ilat = 0; ilat < mlat; ilat++) {
      *phip = dlng;
      phip += rowlen;
    }
  }


  /* Do lat dependency. */
  latp = lat;
  phip   = phi;
  thetap = theta;
  for (ilat = 0; ilat < nlat; ilat++, latp += sll) {
    sincosd(*latp, &sinlat, &coslat);
    coslat3 = coslat*eul[3];
    coslat4 = coslat*eul[4];
    sinlat3 = sinlat*eul[3];
    sinlat4 = sinlat*eul[4];

    for (ilng = 0; ilng < mlng; ilng++, phip += spt, thetap += spt) {
      dlng = *phip;
      sincosd(dlng, &sinlng, &coslng);

      /* Compute the native longitude. */
      x = sinlat4 - coslat3*coslng;
      if (fabs(x) < tol) {
        /* Rearrange formula to reduce roundoff errors. */
        x = -cosd(*latp+eul[1]) + coslat3*(1.0 - coslng);
      }

      y = -coslat*sinlng;
      if (x != 0.0 || y != 0.0) {
        dphi = atan2d(y, x);
      } else {
        /* Change of origin of longitude. */
        if (eul[1] < 90.0) {
          dphi =  dlng - 180.0;
        } else {
          dphi = -dlng;
        }
      }
      *phip = fmod(eul[2] + dphi, 360.0);

      /* Normalize the native longitude. */
      if (*phip > 180.0) {
        *phip -= 360.0;
      } else if (*phip < -180.0) {
        *phip += 360.0;
      }

      /* Compute the native latitude. */
      if (fmod(dlng,180.0) == 0.0) {
        *thetap = *latp + coslng*eul[1];
        if (*thetap >  90.0) *thetap =  180.0 - *thetap;
        if (*thetap < -90.0) *thetap = -180.0 - *thetap;
      } else {
        z = sinlat3 + coslat4*coslng;
        if (fabs(z) > 0.99) {
          /* Use an alternative formula for greater accuracy. */
          *thetap = copysign(acosd(sqrt(x*x+y*y)), z);
        } else {
          *thetap = asind(z);
        }
      }
    }
  }

  return 0;
}
Beispiel #9
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__ */
Beispiel #10
0
int __sunriset__( long year, long month, long day, double lon, double lat,
                 double altit, int upper_limb, double *trise, double *tset )
/***************************************************************************/
/* 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 critical in this function!            */
/*       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 rise/set     */
/*               times, and to zero when computing start/end of       */
/*               twilight.                                            */
/*        *rise = where to store the rise time                        */
/*        *set  = where to store the set  time                        */
/*                Both times are relative to the specified altitude,  */
/*                and thus this function can be used to comupte       */
/*                various twilight times, as well as rise/set times   */
/* Return value:  0 = sun rises/sets this day, times stored at        */
/*                    *trise and *tset.                               */
/*               +1 = sun above the specified "horizon" 24 hours.     */
/*                    *trise set to time when the sun is at south,    */
/*                    minus 12 hours while *tset is set to the south  */
/*                    time plus 12 hours. "Day" length = 24 hours     */
/*               -1 = sun is below the specified "horizon" 24 hours   */
/*                    "Day" length = 0 hours, *trise and *tset are    */
/*                    both set to the time when the sun is at south.  */
/*                                                                    */
/**********************************************************************/
{
    double  d,  /* Days since 2000 Jan 0.0 (negative before) */
    sr,         /* Solar distance, astronomical units */
    sRA,        /* Sun's Right Ascension */
    sdec,       /* Sun's declination */
    sradius,    /* Sun's apparent radius */
    t,          /* Diurnal arc */
    tsouth,     /* Time when Sun is at south */
    sidtime;    /* Local sidereal time */
    
    int rc = 0; /* Return cde from function - usually 0 */
    
    /* Compute d of 12h local mean solar time */
    d = days_since_2000_Jan_0(year,month,day) + 0.5 - lon/360.0;
    
    /* Compute local sideral time of this moment */
    sidtime = revolution( GMST0(d) + 180.0 + lon );
    
    /* Compute Sun's RA + Decl at this moment */
    sun_RA_dec( d, &sRA, &sdec, &sr );
    
    /* Compute time when Sun is at south - in hours UT */
    tsouth = 12.0 - rev180(sidtime - sRA)/15.0;
    
    /* 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) * sind(sdec) ) /
        ( cosd(lat) * cosd(sdec) );
        if ( cost >= 1.0 )
            rc = -1, t = 0.0;       /* Sun always below altit */
        else if ( cost <= -1.0 )
            rc = +1, t = 12.0;      /* Sun always above altit */
        else
            t = acosd(cost)/15.0;   /* The diurnal arc, hours */
    }
    
    /* Store rise and set times - in hours UT */
    *trise = tsouth - t;
    *tset  = tsouth + t;
    
    return rc;
}  /* __sunriset__ */
Beispiel #11
0
void astro_calculate(astro_t *ast) {
	if	(!ast->tm) {
		time_t t = time(0);
		ast->tm	= localtime(&t);
	}
/*
	if	(!ast->Lat && !ast->Lon) {
		ast->Lat	= 45.7500000000;
		ast->Lon	= 4.8333333333;
	}
*/

/*
	ast->j = ast->tm->tm_yday;
*/
	ast->JD = JD (ast->tm->tm_year+1900, ast->tm->tm_mon+1, ast->tm->tm_mday + 0.5);	// 0.5 is 12:00
	ast->j = ast->JD - 2451545.0;	// 2000.0

#if (VERSION==1)
	ast->M = 357 + 0.9856 * ast->j;
	ast->C = 1.914 * sind(ast->M) + 0.02 * sind(2*ast->M);
	ast->L = 280 + ast->C + 0.9856 * ast->j;
	ast->R = -2.465 * sind(2*ast->L) + 0.053 * sind(4*ast->L);
#endif
#if (VERSION==2)
	ast->M = 357.5291 + 0.98560028 * ast->j;
	ast->C = 1.9146 * sind(ast->M) + 0.02 * sind(2*ast->M) + 0.0003 * sind(3*ast->M);
	ast->L = 280.4665 + ast->C + 0.98564736 * ast->j;
	ast->R = -2.4680 * sind(2*ast->L) + 0.053 * sind(4*ast->L) - 0.0014 * sind(6*ast->L);
#endif

	ast->EoT = -(ast->C + ast->R) * 4;

	//	0.397777 représente le sinus de l'obliquité de l'écliptique (23.43929)
	ast->Dec = asind(0.397777 * sind(ast->L));

	//double RA = atan2d(0.9175*sind(ast->L), cosd(ast->L));

	/*
	Le Soleil se lève ou se couche quand le bord supérieur de son disque apparaît ou disparait à l'horizon.
	Du fait de la réfraction atmosphérique le centre du Soleil est alors à 50' sous l'horizon : 34' pour
	l'effet de la réfraction et 16' pour le demi-diamètre du Soleil. L'angle horaire Ho du Soleil, en degrés,
	au moment où son bord supérieur est sur l'horizon est donné par :
	*/
#define UPPER_LIMB -0.01454		// sind(50/60);
#define BUREAU_DES_LONGITUDES -0.01065	// sind(36.6/60);
#define CREPUSCULE_CIVIL -0.105
#define CREPUSCULE_NAUTIQUE -0.208
#define CREPUSCULE_ASTRONOMIQUE -0.309

	/*
	Si vous comparez aux valeurs données par le Bureau des Longitudes (IMCCE) vous constaterez qu'elles sont franchement différentes. En effet le BdL calcule les heures des lever/coucher du centre du Soleil avec une réfraction à l'horizon de 36,6'. Pour vous assurer de la justesse de vos calculs remplacez 0,01454 par 0,01065 dans l'expression de Ho.
	*/

#define Occultation UPPER_LIMB
//#define Occultation BUREAU_DES_LONGITUDES

	ast->cosHo = (Occultation - sind(ast->Dec)*sind(ast->Lat)) / (cosd(ast->Dec)*cosd(ast->Lat));

	/* Si la valeur du cosinus est supérieure à 1 il n'y a pas de lever (et pas de coucher), le Soleil est
	toujours sous l'horizon; si elle est inférieure à -1 il n'y a pas de coucher (et pas de lever), le
	Soleil est toujours au dessus de l'horizon.
	*/

	if	(ast->cosHo < -1) {
		ast->DayTime	= 1;
		return;
	}
	if	(ast->cosHo > 1) {
		ast->DayTime	= 0;
		return;
	}

	ast->Ho = acosd(ast->cosHo);

	//	Azimut
	//ast->cosAz = ( X * sind(ast->Lat) - sind(ast->Dec)) / cosd(ast->Lat);
	//ast->Az = acos(ast->cosAz);

	//	Lever
	ast->VL = 12 - ast->Ho/15;		// Heure vraie
	ast->TL = ast->VL - ast->EoT/60 - ast->Lon/15; // Heure UTC
	ast->HL = ast->TL + ast->tm->tm_gmtoff/3600; // Heure légale

	//	Coucher
	ast->VC = 12 + ast->Ho/15;	// Heure vraie;
	ast->TC = ast->VC - ast->EoT/60 - ast->Lon/15; // Heure UTC
	ast->HC = ast->TC + ast->tm->tm_gmtoff/3600; // Heure légale

	//	Epoch calculation
	struct tm tm	= *ast->tm;
	tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
	time_t hour0	= mktime(&tm);
	hour0	+= tm.tm_gmtoff;
	ast->TL_epoch	= hour0 + ast->TL*3600;
	ast->TC_epoch	= hour0 + ast->TC*3600;

	ast->h = (double)ast->tm->tm_hour + (double)ast->tm->tm_min/60.0 + (double)ast->tm->tm_sec/3600.0;

	if	((ast->h > ast->HL) && (ast->h < ast->HC)) {
		ast->DayTime	= 1;
		return;
	}
	else {
		ast->DayTime	= 0;
		return;
	}
}