From db99d62a8f3ac1c09f4105e60f5be32ad008d3a5 Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Mon, 4 Jan 2016 21:13:38 +0100 Subject: misc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- src/blackbody.c | 145 +++++++++++++++++++++++++++------------------ src/blackbody.h | 51 ---------------- src/libred.h | 164 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/macros.h | 57 ++++++++++++++++++ src/solar.c | 180 ++++++++++++++++++++++++++------------------------------ src/solar.h | 107 --------------------------------- 6 files changed, 394 insertions(+), 310 deletions(-) delete mode 100644 src/blackbody.h create mode 100644 src/libred.h create mode 100644 src/macros.h delete mode 100644 src/solar.h (limited to 'src') diff --git a/src/blackbody.c b/src/blackbody.c index abe03a9..f45ead4 100644 --- a/src/blackbody.c +++ b/src/blackbody.c @@ -14,13 +14,47 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -#include "blackbody.h" +#include "libred.h" #include "macros.h" #include #include +/** + * The file descriptor to the colour lookup table. + */ +static int fd = -1; + + + +/** + * This function must be called, once, + * before calling `libred_get_colour`. + * + * @return 0 on success, -1 on error. + * + * @throws Any error specified for `open(3)`. + */ +int libred_init_colour(void) +{ + libred_term_colour(); + fd = open(SYSDEPRESDIR "/" PACKAGE "/10deg", O_RDONLY); + return fd < 0 ? -1 : 0; +} + + +/** + * Call this when the process will not + * longer make calls to `libred_get_colour`. + */ +void libred_term_colour(void) +{ + if (fd >= 0) + close(fd), fd = -1; +} + + /** * Convert from CIE xyY to [0, 1] sRGB. * @@ -32,23 +66,22 @@ * @param g Output parameter for the green value. * @param b Output parameter for the blue value. */ -static void -ciexyy_to_srgb(double x, double y, double Y, double *r, double *g, double *b) +static void ciexyy_to_srgb(double x, double y, double Y, double *r, double *g, double *b) { #define SRGB(C) (((C) <= 0.0031308) ? (12.92 * (C)) : ((1.0 + 0.055) * pow((C), 1.0 / 2.4) - 0.055)) - double X, Z; - - /* Convert CIE xyY to CIE XYZ. */ - X = Y * (y == 0.0 ? 0.0 : (x / y)); - Z = Y * (y == 0.0 ? 0.0 : ((1.0 - x - y) / y)); - - /* Convert CIE XYZ to [0, 1] linear RGB. (ciexyz_to_linear) */ - *r = ( 3.240450 * X) + (-1.537140 * Y) + (-0.4985320 * Z); - *g = (-0.969266 * X) + ( 1.876010 * Y) + ( 0.0415561 * Z); - *b = (0.0556434 * X) + (-0.204026 * Y) + ( 1.0572300 * Z); - - /* Convert [0, 1] linear RGB to [0, 1] sRGB. */ - SRGB(*r), SRGB(*g), SRGB(*b); + double X, Z; + + /* Convert CIE xyY to CIE XYZ. */ + X = Y * (y == 0.0 ? 0.0 : (x / y)); + Z = Y * (y == 0.0 ? 0.0 : ((1.0 - x - y) / y)); + + /* Convert CIE XYZ to [0, 1] linear RGB. (ciexyz_to_linear) */ + *r = ( 3.240450 * X) + (-1.537140 * Y) + (-0.4985320 * Z); + *g = (-0.969266 * X) + ( 1.876010 * Y) + ( 0.0415561 * Z); + *b = (0.0556434 * X) + (-0.204026 * Y) + ( 1.0572300 * Z); + + /* Convert [0, 1] linear RGB to [0, 1] sRGB. */ + SRGB(*r), SRGB(*g), SRGB(*b); } @@ -68,20 +101,18 @@ ciexyy_to_srgb(double x, double y, double Y, double *r, double *g, double *b) * @param g Output parameter for the green value. * @param b Output parameter for the blue value. */ -static void -interpolate(double x1, double y1, double x2, double y2, double temp, double *r, double *g, double *b) +static void interpolate(double x1, double y1, double x2, double y2, double temp, double *r, double *g, double *b) { - double weight = fmod(temp, (double)DELTA_TEMPERATURE) / (double)DELTA_TEMPERATURE; - double x = x1 * (1 - weight) + x2 * weight; - double y = y1 * (1 - weight) + y2 * weight; - ciexyy_to_srgb(x, y, 1.0, r, g, b); + double weight = fmod(temp, (double)DELTA_TEMPERATURE) / (double)DELTA_TEMPERATURE; + double x = x1 * (1 - weight) + x2 * weight; + double y = y1 * (1 - weight) + y2 * weight; + ciexyy_to_srgb(x, y, 1.0, r, g, b); } /** * Get the [0, 1] sRGB values of a colour temperature. * - * @param fd File descriptor for the colour table. * @param temp The desired colour temperature. * @param r Output parameter for the “red” value. * @param g Output parameter for the green value. @@ -90,41 +121,41 @@ interpolate(double x1, double y1, double x2, double y2, double temp, double *r, * * @throws 0 The file did not have the expected size. * @throws EDOM The selected temperature is below 1000 K. + * @throws Any error specified for pread(3). */ -int -get_colour(int fd, long int temp, double *r, double *g, double *b) +int libred_get_colour(long int temp, double *r, double *g, double *b) { - double values[10]; /* low:x,y,r,g,b + high:x,y,r,g,b */ - off_t offset; - double max; - - /* We do not have any values for above 40 000 K, but - * the differences will be unnoticeable, perhaps even - * unencodeable. */ - if (temp > HIGHEST_TEMPERATURE) temp = HIGHEST_TEMPERATURE; - /* Things do not glow below 1000 K. Yes, fire is hot! */ - if (temp < LOWEST_TEMPERATURE) t ((errno = EDOM)); - - /* Read table. */ - offset = ((off_t)temp - LOWEST_TEMPERATURE) / DELTA_TEMPERATURE; - offset *= (off_t)(sizeof(values) / 2); - errno = 0; xpread(fd, values, sizeof(values), offset); - - /* Get colour. */ - if (temp % DELTA_TEMPERATURE) - interpolate(values[0], values[1], values[6], values[7], (double)temp, r, g, b); - else - *r = values[2], *g = values[3], *b = values[4]; - - /* Adjust colours for use. */ - max = fmax(fmax(fabs(*r), fabs(*g)), fabs(*b)); - if (max != 0) *r /= max, *g /= max, *b /= max; - *r = *r > 0.0 ? *r : 0.0; - *g = *g > 0.0 ? *g : 0.0; - *b = *b > 0.0 ? *b : 0.0; - - return 0; -fail: - return -1; + double values[10]; /* low:x,y,r,g,b + high:x,y,r,g,b */ + off_t offset; + double max; + + /* We do not have any values for above 40 000 K, but + * the differences will be unnoticeable, perhaps even + * unencodeable. */ + if (temp > HIGHEST_TEMPERATURE) temp = HIGHEST_TEMPERATURE; + /* Things do not glow below 1000 K. Yes, fire is hot! */ + if (temp < LOWEST_TEMPERATURE) t ((errno = EDOM)); + + /* Read table. */ + offset = ((off_t)temp - LOWEST_TEMPERATURE) / DELTA_TEMPERATURE; + offset *= (off_t)(sizeof(values) / 2); + errno = 0; xpread(fd, values, sizeof(values), offset); + + /* Get colour. */ + if (temp % DELTA_TEMPERATURE) + interpolate(values[0], values[1], values[6], values[7], (double)temp, r, g, b); + else + *r = values[2], *g = values[3], *b = values[4]; + + /* Adjust colours for use. */ + max = fmax(fmax(fabs(*r), fabs(*g)), fabs(*b)); + if (max != 0) *r /= max, *g /= max, *b /= max; + *r = *r > 0.0 ? *r : 0.0; + *g = *g > 0.0 ? *g : 0.0; + *b = *b > 0.0 ? *b : 0.0; + + return 0; + fail: + return -1; } diff --git a/src/blackbody.h b/src/blackbody.h deleted file mode 100644 index 499e9b8..0000000 --- a/src/blackbody.h +++ /dev/null @@ -1,51 +0,0 @@ -/** - * Copyright © 2016 Mattias Andrée - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - - - -/** - * The highest colour temperature in the table. - */ -#define LIBRED_HIGHEST_TEMPERATURE 40000 - -/** - * The lowest colour temperature in the table. - */ -#define LIBRED_LOWEST_TEMPERATURE 1000 - -/** - * The temperature difference between the colours in the table. - */ -#define LIBRED_DELTA_TEMPERATURE 100 - - - -/** - * Get the [0, 1] sRGB values of a colour temperature. - * - * @param fd File descriptor for the colour table. - * @param temp The desired colour temperature. - * @param r Output parameter for the “red” value. - * @param g Output parameter for the green value. - * @param b Output parameter for the blue value. - * @return 0 on succeess, -1 on error. - * - * @throws 0 The file did not have the expected size. - * @throws EDOM The selected temperature is below 1000 K. - */ -int libred_get_colour(int fd, long int temp, double *r, double *g, double *b); - diff --git a/src/libred.h b/src/libred.h new file mode 100644 index 0000000..615ed04 --- /dev/null +++ b/src/libred.h @@ -0,0 +1,164 @@ +/** + * Copyright © 2016 Mattias Andrée + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef LIBRED_H +#define LIBRED_H + + + +/** + * Approximate apparent size of the Sun in degrees. + */ +#define LIBRED_SOLAR_APPARENT_RADIUS (32.0 / 60.0) + + +/** + * The Sun's elevation at sunset and sunrise, measured in degrees. + */ +#define LIBRED_SOLAR_ELEVATION_SUNSET_SUNRISE (0.0) + +/** + * The Sun's elevation at civil dusk and civil dawn, measured in degrees. + */ +#define LIBRED_SOLAR_ELEVATION_CIVIL_DUSK_DAWN (-6.0) + +/** + * The Sun's elevation at nautical dusk and nautical dawn, measured in degrees. + */ +#define LIBRED_SOLAR_ELEVATION_NAUTICAL_DUSK_DAWN (-12.0) + +/** + * The Sun's elevation at astronomical dusk and astronomical dawn, measured in degrees. + */ +#define LIBRED_SOLAR_ELEVATION_ASTRONOMICAL_DUSK_DAWN (-18.0) + + +/** + * Test whether it is twilight. + * + * @param ELEV:double The current elevation. + * @return 1 if is twilight, 0 otherwise. + */ +#define LIBRED_IS_TWILIGHT(ELEV) ((-18.0 <= (ELEV)) && ((ELEV) <= 0.0)) + +/** + * Test whether it is civil twilight. + * + * @param ELEV:double The current elevation. + * @return 1 if is civil twilight, 0 otherwise. + */ +#define LIBRED_IS_CIVIL_TWILIGHT(ELEV) ((-6.0 <= (ELEV)) && ((ELEV) <= 0.0)) + +/** + * Test whether it is nautical twilight. + * + * @param ELEV:double The current elevation. + * @return 1 if is nautical twilight, 0 otherwise. + */ +#define LIBRED_IS_NAUTICAL_TWILIGHT(ELEV) ((-12.0 <= (ELEV)) && ((ELEV) <= -6.0)) + +/** + * Test whether it is astronomical twilight. + * + * @param ELEV:double The current elevation. + * @return 1 if is astronomical twilight, 0 otherwise. + */ +#define LIBRED_IS_ASTRONOMICAL_TWILIGHT(ELEV) ((-18.0 <= (ELEV)) && ((ELEV) <= -12.0)) + + + +/** + * Calculates the Sun's elevation as apparent. + * from a geographical position. + * + * @param latitude The latitude in degrees northwards from + * the equator, negative for southwards. + * @param longitude The longitude in degrees eastwards from + * Greenwich, negative for westwards. + * @return The Sun's apparent elevation as seen, right now, + * from the specified position, measured in degrees. + * + * @throws 0 On success. + * @throws Any error specified for clock_gettime(3) on error. + */ +double libred_solar_elevation(double latitude, double longitude); + + +/** + * Exit if time the is before year 0 in J2000. + * + * @return 0 on success, -1 on error. + */ +#if defined(TIMETRAVELLER) +int libred_check_timetravel(void); +#else +# define libred_check_timetravel() 0 +#endif + + + +/** + * The highest colour temperature in the table. + */ +#define LIBRED_HIGHEST_TEMPERATURE 40000 + +/** + * The lowest colour temperature in the table. + */ +#define LIBRED_LOWEST_TEMPERATURE 1000 + +/** + * The temperature difference between the colours in the table. + */ +#define LIBRED_DELTA_TEMPERATURE 100 + + + +/** + * This function must be called, once, + * before calling `libred_get_colour`. + * + * @return 0 on success, -1 on error. + * + * @throws Any error specified for `open(3)`. + */ +int libred_init_colour(void); + +/** + * Call this when the process will not + * longer make calls to `libred_get_colour`. + */ +void libred_term_colour(void); + +/** + * Get the [0, 1] sRGB values of a colour temperature. + * + * @param temp The desired colour temperature. + * @param r Output parameter for the “red” value. + * @param g Output parameter for the green value. + * @param b Output parameter for the blue value. + * @return 0 on succeess, -1 on error. + * + * @throws 0 The file did not have the expected size. + * @throws EDOM The selected temperature is below 1000 K. + * @throws Any error specified for pread(3). + */ +int libred_get_colour(long int temp, double *r, double *g, double *b); + + + +#endif + diff --git a/src/macros.h b/src/macros.h new file mode 100644 index 0000000..c0aeabb --- /dev/null +++ b/src/macros.h @@ -0,0 +1,57 @@ +/** + * Copyright © 2016 Mattias Andrée + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include +#include +#include +#include + + + +#define try(...) do { if (!(__VA_ARGS__)) goto fail; } while (0) +#define t(...) do { if (__VA_ARGS__) goto fail; } while (0) +#define CLEANUP(...) do { int cleanup__ = errno; __VA_ARGS__; errno = cleanup__; } while (0) + +#define xstrdup(outp, ...) \ +do { \ + const char *xstrdup__ = (__VA_ARGS__); \ + if (xstrdup__) \ + try (*(outp) = strdup(xstrdup__)); \ + else \ + *(outp) = NULL; \ +} while (0) + +#define xpread(fd, buf, len, off) t (pread(fd, buf, len, off) < (ssize_t)(len)) +#define xpwrite(fd, buf, len, off) t (pwrite(fd, buf, len, off) < (ssize_t)(len)) +#define xread(fd, buf, len) t (read(fd, buf, len) < (ssize_t)(len)) +#define xwrite(fd, buf, len) t (write(fd, buf, len) < (ssize_t)(len)) + +#define xcalloc(outp, num) try (*(outp) = calloc(num, sizeof(**(outp)))) +#define xmalloc(outp, num) try (*(outp) = malloc((num) * sizeof(**(outp)))) +#define xrealloc(outp, num) \ +do { \ + size_t n__ = (num); \ + void *new__ = realloc(*(outp), n__ * sizeof(**(outp))); \ + t (n__ && !new__); \ + *(outp) = new__; \ +} while (0) + +#define SHRINK(outp, num) \ +do { \ + void *new__ = realloc(*(outp), (num) * sizeof(**(outp))); \ + if (new__) *(outp) = new__; \ +} while (0) + diff --git a/src/solar.c b/src/solar.c index 8a57507..697ecd6 100644 --- a/src/solar.c +++ b/src/solar.c @@ -13,14 +13,21 @@ * * You should have received a copy of the GNU General Public License * along with this program. If not, see . + * + * This file is a stripped down port of . */ +#include "libred.h" #include #include #include -#if !defined(CLOCK_REALTIME_COARSE) +/* Select clock. */ +#if defined(DO_NOT_USE_COARSEC_CLOCK) || !defined(CLOCK_REALTIME_COARSE) +# ifdef CLOCK_REALTIME_COARSE +# undef CLOCK_REALTIME_COARSE +# endif # define CLOCK_REALTIME_COARSE CLOCK_REALTIME #endif @@ -34,15 +41,14 @@ * @throws 0 On success. * @throws Any error specified for clock_gettime(3) on error. */ -static double -julian_centuries() +static double julian_centuries() { - struct timespec now; - double tm; - if (clock_gettime(CLOCK_REALTIME_COARSE, &now)) return 0.0; - tm = (double)(now.tv_nsec) / 1000000000.0 + (double)(now.tv_sec); - tm = (tm / 86400.0 + 2440587.5 - 2451545.0) / 36525.0; - return errno = 0, tm; + struct timespec now; + double tm; + if (clock_gettime(CLOCK_REALTIME_COARSE, &now)) return 0.0; + tm = (double)(now.tv_nsec) / 1000000000.0 + (double)(now.tv_sec); + tm = (tm / 86400.0 + 2440587.5 - 2451545.0) / 36525.0; + return errno = 0, tm; } /** @@ -51,10 +57,9 @@ julian_centuries() * @param tm The time in Julian Centuries * @return The time in Julian Days */ -static inline double -julian_centuries_to_julian_day(double tm) +static inline double julian_centuries_to_julian_day(double tm) { - return tm * 36525.0 + 2451545.0; + return tm * 36525.0 + 2451545.0; } @@ -64,10 +69,9 @@ julian_centuries_to_julian_day(double tm) * @param deg The angle in degrees. * @param The angle in radians. */ -static inline double -radians(double deg) +static inline double radians(double deg) { - return deg * (double)M_PI / 180.0; + return deg * (double)M_PI / 180.0; } /** @@ -76,10 +80,9 @@ radians(double deg) * @param rad The angle in radians. * @param The angle in degrees. */ -static inline double -degrees(double rad) +static inline double degrees(double rad) { - return rad * 180.0 / (double)M_PI; + return rad * 180.0 / (double)M_PI; } @@ -92,13 +95,12 @@ degrees(double rad) * @param hour_angle The solar hour angle, in radians. * @return The Sun's elevation, in radians. */ -static inline double -elevation_from_hour_angle(double latitude, double declination, double hour_angle) +static inline double elevation_from_hour_angle(double latitude, double declination, double hour_angle) { - double rc = cos(radians(latitude)); - rc *= cos(hour_angle) * cos(declination); - rc += sin(radians(latitude)) * sin(declination); - return asin(rc); + double rc = cos(radians(latitude)); + rc *= cos(hour_angle) * cos(declination); + rc += sin(radians(latitude)) * sin(declination); + return asin(rc); } /** @@ -107,14 +109,13 @@ elevation_from_hour_angle(double latitude, double declination, double hour_angle * @param tm The time in Julian Centuries. * @return The Sun's geometric mean longitude in radians. */ -static inline double -sun_geometric_mean_longitude(double tm) +static inline double sun_geometric_mean_longitude(double tm) { - double rc = fmod(pow(0.0003032 * tm, 2.0) + 36000.76983 * tm + 280.46646, 360.0); + double rc = fmod(pow(0.0003032 * tm, 2.0) + 36000.76983 * tm + 280.46646, 360.0); #if defined(TIMETRAVELLER) - rc = rc < 0.0 ? (rc + 360.0) : rc; + rc = rc < 0.0 ? (rc + 360.0) : rc; #endif - return radians(rc); + return radians(rc); } /** @@ -123,10 +124,9 @@ sun_geometric_mean_longitude(double tm) * @param tm The time in Julian Centuries. * @return The Sun's geometric mean anomaly in radians. */ -static inline double -sun_geometric_mean_anomaly(double tm) +static inline double sun_geometric_mean_anomaly(double tm) { - return radians(pow(-0.0001537 * tm, 2.0) + 35999.05029 * tm + 357.52911); + return radians(pow(-0.0001537 * tm, 2.0) + 35999.05029 * tm + 357.52911); } /** @@ -135,10 +135,9 @@ sun_geometric_mean_anomaly(double tm) * @param tm The time in Julian Centuries. * @return The Earth's orbit eccentricity. */ -static inline double -earth_orbit_eccentricity(double tm) +static inline double earth_orbit_eccentricity(double tm) { - return pow(-0.0000001267 * tm, 2.0) - 0.000042037 * tm + 0.016708634; + return pow(-0.0000001267 * tm, 2.0) - 0.000042037 * tm + 0.016708634; } /** @@ -148,14 +147,13 @@ earth_orbit_eccentricity(double tm) * @param tm The time in Julian Centuries. * @return The Sun's equation of the centre, in radians. */ -static inline double -sun_equation_of_centre(double tm) +static inline double sun_equation_of_centre(double tm) { - double a = sun_geometric_mean_anomaly(tm), rc; - rc = sin(1.0 * a) * (pow(-0.000014 * tm, 2.0) - 0.004817 * tm + 1.914602); - rc += sin(2.0 * a) * (-0.000101 * tm + 0.019993); - rc += sin(3.0 * a) * 0.000289; - return radians(rc); + double a = sun_geometric_mean_anomaly(tm), rc; + rc = sin(1.0 * a) * (pow(-0.000014 * tm, 2.0) - 0.004817 * tm + 1.914602); + rc += sin(2.0 * a) * (-0.000101 * tm + 0.019993); + rc += sin(3.0 * a) * 0.000289; + return radians(rc); } /** @@ -164,10 +162,9 @@ sun_equation_of_centre(double tm) * @param tm The time in Julian Centuries. * @return The longitude, in radians. */ -static inline double -sun_real_longitude(double tm) +static inline double sun_real_longitude(double tm) { - return sun_geometric_mean_longitude(tm) + sun_equation_of_centre(tm); + return sun_geometric_mean_longitude(tm) + sun_equation_of_centre(tm); } /** @@ -176,11 +173,10 @@ sun_real_longitude(double tm) * @param tm The time in Julian Centuries. * @return The longitude, in radians. */ -static inline double -sun_apparent_longitude(double tm) +static inline double sun_apparent_longitude(double tm) { - double rc = degrees(sun_real_longitude(tm)) - 0.00569; - return radians(rc - 0.00478 * sin(radians(-1934.136 * tm + 125.04))); + double rc = degrees(sun_real_longitude(tm)) - 0.00569; + return radians(rc - 0.00478 * sin(radians(-1934.136 * tm + 125.04))); } /** @@ -190,11 +186,10 @@ sun_apparent_longitude(double tm) * @param tm The time in Julian Centuries. * @return The uncorrected mean obliquity, in radians. */ -static double -mean_ecliptic_obliquity(double tm) +static double mean_ecliptic_obliquity(double tm) { - double rc = pow(0.001813 * tm, 3.0) - pow(0.00059 * tm, 2.0) - 46.815 * tm + 21.448; - return radians(23.0 + (26.0 + rc / 60.0) / 60.0); + double rc = pow(0.001813 * tm, 3.0) - pow(0.00059 * tm, 2.0) - 46.815 * tm + 21.448; + return radians(23.0 + (26.0 + rc / 60.0) / 60.0); } /** @@ -204,11 +199,10 @@ mean_ecliptic_obliquity(double tm) * @param tm The time in Julian Centuries. * @return The mean obliquity, in radians. */ -static double -corrected_mean_ecliptic_obliquity(double tm) +static double corrected_mean_ecliptic_obliquity(double tm) { - double rc = 0.00256 * cos(radians(-1934.136 * tm + 125.04)); - return radians(rc + degrees(mean_ecliptic_obliquity(tm))); + double rc = 0.00256 * cos(radians(-1934.136 * tm + 125.04)); + return radians(rc + degrees(mean_ecliptic_obliquity(tm))); } /** @@ -217,11 +211,10 @@ corrected_mean_ecliptic_obliquity(double tm) * @param tm The time in Julian Centuries. * @return The Sun's declination, in radian. */ -static inline double -solar_declination(double tm) +static inline double solar_declination(double tm) { - double rc = sin(corrected_mean_ecliptic_obliquity(tm)); - return asin(rc * sin(sun_apparent_longitude(tm))); + double rc = sin(corrected_mean_ecliptic_obliquity(tm)); + return asin(rc * sin(sun_apparent_longitude(tm))); } /** @@ -231,18 +224,17 @@ solar_declination(double tm) * @param tm The time in Julian Centuries. * @return The equation of time, in degrees. */ -static inline double -equation_of_time(double tm) +static inline double equation_of_time(double tm) { - double l = sun_geometric_mean_longitude(tm); - double e = earth_orbit_eccentricity(tm); - double m = sun_geometric_mean_anomaly(tm); - double y = pow(tan(corrected_mean_ecliptic_obliquity(tm) / 2.0), 2.0); - double rc = y * sin(2.0 * l); - rc += (4.0 * y * cos(2.0 * l) - 2.0) * e * sin(m); - rc -= pow(0.5 * y, 2.0) * sin(4.0 * l); - rc -= pow(1.25 * e, 2.0) * sin(2.0 * m); - return 4.0 * degrees(rc); + double l = sun_geometric_mean_longitude(tm); + double e = earth_orbit_eccentricity(tm); + double m = sun_geometric_mean_anomaly(tm); + double y = pow(tan(corrected_mean_ecliptic_obliquity(tm) / 2.0), 2.0); + double rc = y * sin(2.0 * l); + rc += (4.0 * y * cos(2.0 * l) - 2.0) * e * sin(m); + rc -= pow(0.5 * y, 2.0) * sin(4.0 * l); + rc -= pow(1.25 * e, 2.0) * sin(2.0 * m); + return 4.0 * degrees(rc); } /** @@ -257,14 +249,13 @@ equation_of_time(double tm) * @return The Sun's apparent elevation at the specified time as seen * from the specified position, measured in radians. */ -static inline double -solar_elevation_from_time(double tm, double latitude, double longitude) +static inline double solar_elevation_from_time(double tm, double latitude, double longitude) { - double rc = julian_centuries_to_julian_day(tm); - rc = (rc - round(rc) - 0.5) * 1440; - rc = 720.0 - rc - equation_of_time(tm); - rc = radians(rc / 4.0 - longitude); - return elevation_from_hour_angle(latitude, solar_declination(tm), rc); + double rc = julian_centuries_to_julian_day(tm); + rc = (rc - round(rc) - 0.5) * 1440; + rc = 720.0 - rc - equation_of_time(tm); + rc = radians(rc / 4.0 - longitude); + return elevation_from_hour_angle(latitude, solar_declination(tm), rc); } @@ -282,11 +273,10 @@ solar_elevation_from_time(double tm, double latitude, double longitude) * @throws 0 On success. * @throws Any error specified for clock_gettime(3) on error. */ -double -solar_elevation(double latitude, double longitude) +double libred_solar_elevation(double latitude, double longitude) { - double tm = julian_centuries(); - return errno ? -1 : degrees(solar_elevation_from_time(tm, latitude, longitude)); + double tm = julian_centuries(); + return errno ? -1 : degrees(solar_elevation_from_time(tm, latitude, longitude)); } @@ -295,18 +285,18 @@ solar_elevation(double latitude, double longitude) * * @return 0 on success, -1 on error. */ -#if defined(TIMETRAVELLER) -int -check_timetravel(void) +int libred_check_timetravel(void) { - struct timespec now; - if (clock_gettime(CLOCK_REALTIME, &now)) return -1; - if (now.tv_nsec < (time_t)946728000L) - fprintf(stderr, "We have detected that you are a time-traveller" - "(or your clock is not configured correctly.)" - "Please recompile with -DTIMETRAVELLER" - "(or correct your clock.)"), exit(1); - return 0; -} +#if !defined(TIMETRAVELLER) + struct timespec now; + if (clock_gettime(CLOCK_REALTIME, &now)) return -1; + if (now.tv_nsec < (time_t)946728000L) + fprintf(stderr, + "We have detected that you are a time-traveller" + "(or your clock is not configured correctly.)" + "Please recompile libred with -DTIMETRAVELLER" + "(or correct your clock.)"), exit(1); #endif + return 0; +} diff --git a/src/solar.h b/src/solar.h deleted file mode 100644 index 8e94cf9..0000000 --- a/src/solar.h +++ /dev/null @@ -1,107 +0,0 @@ -/** - * Copyright © 2016 Mattias Andrée - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - - -/** - * Approximate apparent size of the Sun in degrees. - */ -#define LIBRED_SOLAR_APPARENT_RADIUS (32.0 / 60.0) - - -/** - * The Sun's elevation at sunset and sunrise, measured in degrees. - */ -#define LIBRED_SOLAR_ELEVATION_SUNSET_SUNRISE (0.0) - -/** - * The Sun's elevation at civil dusk and civil dawn, measured in degrees. - */ -#define LIBRED_SOLAR_ELEVATION_CIVIL_DUSK_DAWN (-6.0) - -/** - * The Sun's elevation at nautical dusk and nautical dawn, measured in degrees. - */ -#define LIBRED_SOLAR_ELEVATION_NAUTICAL_DUSK_DAWN (-12.0) - -/** - * The Sun's elevation at astronomical dusk and astronomical dawn, measured in degrees. - */ -#define LIBRED_SOLAR_ELEVATION_ASTRONOMICAL_DUSK_DAWN (-18.0) - - -/** - * Test whether it is twilight. - * - * @param ELEV:double The current elevation. - * @return 1 if is twilight, 0 otherwise. - */ -#define LIBRED_IS_TWILIGHT(ELEV) ((-18.0 <= (ELEV)) && ((ELEV) <= 0.0)) - -/** - * Test whether it is civil twilight. - * - * @param ELEV:double The current elevation. - * @return 1 if is civil twilight, 0 otherwise. - */ -#define LIBRED_IS_CIVIL_TWILIGHT(ELEV) ((-6.0 <= (ELEV)) && ((ELEV) <= 0.0)) - -/** - * Test whether it is nautical twilight. - * - * @param ELEV:double The current elevation. - * @return 1 if is nautical twilight, 0 otherwise. - */ -#define LIBRED_IS_NAUTICAL_TWILIGHT(ELEV) ((-12.0 <= (ELEV)) && ((ELEV) <= -6.0)) - -/** - * Test whether it is astronomical twilight. - * - * @param ELEV:double The current elevation. - * @return 1 if is astronomical twilight, 0 otherwise. - */ -#define LIBRED_IS_ASTRONOMICAL_TWILIGHT(ELEV) ((-18.0 <= (ELEV)) && ((ELEV) <= -12.0)) - - - -/** - * Calculates the Sun's elevation as apparent. - * from a geographical position. - * - * @param latitude The latitude in degrees northwards from - * the equator, negative for southwards. - * @param longitude The longitude in degrees eastwards from - * Greenwich, negative for westwards. - * @return The Sun's apparent elevation as seen, right now, - * from the specified position, measured in degrees. - * - * @throws 0 On success. - * @throws Any error specified for clock_gettime(3) on error. - */ -double libred_solar_elevation(double latitude, double longitude); - - -/** - * Exit if time the is before year 0 in J2000. - * - * @return 0 on success, -1 on error. - */ -#if defined(TIMETRAVELLER) -int libred_check_timetravel(void); -#else -# define libred_check_timetravel() 0 -#endif - -- cgit v1.2.3-70-g09d2