~kennylevinsen/wlsunset

416713129f652e2191e53c5b8018995251e7bad0 — Kenny Levinsen 15 days ago 29a20ce
WIP
4 files changed, 130 insertions(+), 27 deletions(-)

M color_math.c
M main.c
M meson.build
A testcalc.c
M color_math.c => color_math.c +20 -20
@@ 45,32 45,32 @@ void calc_sun(struct tm *tm, double longitude, double latitude, struct sun *sun)
		0.002697 * cos(3*year_rad) +
		0.00148 * sin(3*year_rad);

	double threshold = fabs(latitude) + fabs(degrees(decl));

	if (SOLAR_HORIZON + SOLAR_START_TWILIGHT > threshold) {
		double ha = degrees(acos(
			cos(radians(SOLAR_HORIZON + SOLAR_START_TWILIGHT)) / (cos(radians(latitude)) * cos(decl)) -
			tan(radians(latitude)) * tan(decl)));
		sun->dawn = (720 - 4 * (longitude + fabs(ha)) - eqtime) * 60;
		sun->dusk = (720 - 4 * (longitude - fabs(ha)) - eqtime) * 60;
		fprintf(stderr, "TWILIGHT OKAY: %ld, %ld, %lf\n", sun->dawn, sun->dusk,
			cos(radians(SOLAR_HORIZON + SOLAR_START_TWILIGHT)) / (cos(radians(latitude)) * cos(decl)) -
			tan(radians(latitude)) * tan(decl));
	double latitude_rad = radians(latitude);

	double latdecl_cos = cos(latitude_rad) * cos(decl);
	double latdecl_tan = tan(latitude_rad) * tan(decl);

	double twilight_cos = cos(radians(SOLAR_HORIZON + SOLAR_START_TWILIGHT)) / latdecl_cos - latdecl_tan;
	double daylight_cos = cos(radians(SOLAR_HORIZON + SOLAR_END_TWILIGHT)) / latdecl_cos - latdecl_tan;

	double twilight_ha = degrees(acos(twilight_cos));
	double daylight_ha = degrees(acos(daylight_cos));

	fprintf(stderr, "twilight: cos %lf, ha %lf, daylight: cos %lf, ha %lf\n",
			twilight_cos, twilight_ha, daylight_cos, daylight_ha);

	if (!isnan(twilight_ha)) {
			sun->dawn = (720 - 4 * (longitude + fabs(twilight_ha)) - eqtime) * 60;
		sun->dusk = (720 - 4 * (longitude - fabs(twilight_ha)) - eqtime) * 60;
	} else {
		sun->dawn = -1;
		sun->dusk = -1;
		sun->condition = sign(latitude) != sign(decl) ? MIDNIGHT_SUN : POLAR_NIGHT;
	}

	if (SOLAR_HORIZON + SOLAR_END_TWILIGHT > threshold) {
		double ha = degrees(acos(
			cos(radians(SOLAR_HORIZON + SOLAR_END_TWILIGHT)) / (cos(radians(latitude)) * cos(decl)) -
			tan(radians(latitude)) * tan(decl)));
		sun->sunrise = (720 - 4 * (longitude + fabs(ha)) - eqtime) * 60;
		sun->sunset = (720 - 4 * (longitude - fabs(ha)) - eqtime) * 60;
		fprintf(stderr, "DAY OKAY: %ld, %ld, %lf\n", sun->sunrise, sun->sunset,
			cos(radians(SOLAR_HORIZON + SOLAR_END_TWILIGHT)) / (cos(radians(latitude)) * cos(decl)) -
			tan(radians(latitude)) * tan(decl));
	if (!isnan(daylight_ha)) {
		sun->sunrise = (720 - 4 * (longitude + fabs(daylight_ha)) - eqtime) * 60;
		sun->sunset = (720 - 4 * (longitude - fabs(daylight_ha)) - eqtime) * 60;
	} else {
		sun->sunrise = -1;
		sun->sunset = -1;

M main.c => main.c +14 -7
@@ 19,29 19,36 @@
#define SPEEDRUN
#if defined(SPEEDRUN)
#include <sys/wait.h>
static time_t start = 0;
static time_t start = 0, offset = 0;
static void init_time(time_t *tloc) {
	(void)tloc;
	tzset();
	struct timespec realtime;
	clock_gettime(CLOCK_REALTIME, &realtime);
	start = realtime.tv_sec;
	offset = realtime.tv_sec;

	char *startstr = getenv("SPEEDRUN_START");
	if (startstr != NULL) {
		start = atol(startstr);
	} else {
		start = offset;
	}
}
static time_t get_time_sec(time_t *tloc) {
	(void)tloc;
	struct timespec realtime;
	clock_gettime(CLOCK_REALTIME, &realtime);
	time_t now = start + ((realtime.tv_sec - start) * 1000 + realtime.tv_nsec / 1000000);

	time_t now = start + ((realtime.tv_sec - offset) * 1000 + realtime.tv_nsec / 1000000);
	struct tm tm;
	localtime_r(&now, &tm);
	fprintf(stderr, "time in termina: %02d:%02d:%02d\n", tm.tm_hour, tm.tm_min, tm.tm_sec);
	fprintf(stderr, "time in termina: %02d:%02d:%02d, %d/%d/%d\n", tm.tm_hour, tm.tm_min, tm.tm_sec,
			tm.tm_mday, tm.tm_mon+1, tm.tm_year + 1900);
	return now;
}
static int set_timer(timer_t timer, time_t deadline) {
	time_t diff = deadline - start;
	time_t diff = deadline - offset;
	struct itimerspec timerspec = {{0}, {0}};
	timerspec.it_value.tv_sec = start + diff / 1000;
	timerspec.it_value.tv_sec = offset + diff / 1000;
	timerspec.it_value.tv_nsec = (diff % 1000) * 1000000;
	return timer_settime(timer, TIMER_ABSTIME, &timerspec, NULL);
}

M meson.build => meson.build +6 -0
@@ 53,3 53,9 @@ executable(
	dependencies: [protocols_dep, m, rt],
	install: true
)
executable(
	'testcalc',
	['testcalc.c', 'color_math.c'],
	dependencies: [m, rt],
	install: true
)

A testcalc.c => testcalc.c +90 -0
@@ 0,0 1,90 @@
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>

#include "color_math.h"

static const char *sun_condition_str[] = {
	"normal",
	"midnight sun",
	"polar night",
	NULL,
};

static void print_trajectory(struct sun *sun, time_t day) {
	fprintf(stderr, "calculated sun trajectory:");

	struct tm tm;
	if (sun->dawn >= day) {
		localtime_r(&sun->dawn, &tm);
		fprintf(stderr, " dawn %0d:%02d,", tm.tm_hour, tm.tm_min);
	} else {
		fprintf(stderr, " dawn N/A,");
	}

	if (sun->sunrise >= day) {
		localtime_r(&sun->sunrise, &tm);
		fprintf(stderr, " sunrise %0d:%02d,", tm.tm_hour, tm.tm_min);
	} else {
		fprintf(stderr, " sunrise N/A,");
	}

	if (sun->sunset >= day) {
		localtime_r(&sun->sunset, &tm);
		fprintf(stderr, " sunset %0d:%02d,", tm.tm_hour, tm.tm_min);
	} else {
		fprintf(stderr, " sunset N/A,");
	}

	if (sun->dusk >= day) {
		localtime_r(&sun->dusk, &tm);
		fprintf(stderr, " dusk %0d:%02d,", tm.tm_hour, tm.tm_min);
	} else {
		fprintf(stderr, " dusk N/A,");
	}

	fprintf(stderr, " condition: %s\n", sun_condition_str[sun->condition]);
}

int main(int argc, char *argv[]) {
	double latitude = 0, longitude = 0;
	time_t now = time(NULL);
	int opt;
	while ((opt = getopt(argc, argv, "hn:l:L:")) != -1) {
		switch (opt) {
			case 'n':
				now = strtol(optarg, NULL, 10);
				break;
			case 'l':
				latitude = strtod(optarg, NULL);
				break;
			case 'L':
				longitude = strtod(optarg, NULL);
				break;
			case 'h':
			default:
				return opt == 'h' ? EXIT_SUCCESS : EXIT_FAILURE;
		}
	}

	struct tm tm;
	localtime_r(&now, &tm);
	fprintf(stderr, "time in termina: %02d:%02d:%02d, %d/%d/%d\n", tm.tm_hour, tm.tm_min, tm.tm_sec,
			tm.tm_mday, tm.tm_mon+1, tm.tm_year + 1900);

	struct sun sun = { 0 };
	time_t day = now - (now % 86400);
	gmtime_r(&day, &tm);
	calc_sun(&tm, longitude, latitude, &sun);
	
	sun.dawn += day;
	sun.sunrise += day;
	sun.sunset += day;
	sun.dusk += day;

	print_trajectory(&sun, day);
	return EXIT_SUCCESS;
}