diff --git a/swe-glib/src/gswe-moment.c b/swe-glib/src/gswe-moment.c index 1b83a2a..91d8bdf 100644 --- a/swe-glib/src/gswe-moment.c +++ b/swe-glib/src/gswe-moment.c @@ -1,9 +1,12 @@ #include "swe-glib.h" #include "gswe-types.h" #include "gswe-moment.h" +#include "swe-glib-private.h" #include "../../swe/src/swephexp.h" +#define SYNODIC 29.53058867 + #define GSWE_MOMENT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), GSWE_TYPE_MOMENT, GsweMomentPrivate)) /** @@ -27,6 +30,8 @@ struct _GsweMomentPrivate { guint points_revision; GHashTable *element_points; GHashTable *quality_points; + guint moon_phase_revision; + GsweMoonPhaseData moon_phase; }; enum { @@ -94,6 +99,7 @@ gswe_moment_init(GsweMoment *moment) moment->priv->quality_points = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, NULL); moment->priv->house_revision = 0; moment->priv->points_revision = 0; + moment->priv->moon_phase_revision = 0; moment->priv->revision = 1; } @@ -527,3 +533,51 @@ gswe_moment_get_quality_points(GsweMoment *moment, GsweQuality quality) return point; } +GsweMoonPhaseData * +gswe_moment_get_moon_phase(GsweMoment *moment) +{ + gdouble difference, + phase_percent; + + if (moment->priv->moon_phase_revision == moment->priv->revision) { + return &(moment->priv->moon_phase); + } + + difference = (gswe_timestamp_get_julian_day(moment->priv->timestamp) - gswe_timestamp_get_julian_day(gswe_full_moon_base_date)); + phase_percent = fmod((difference * 100) / SYNODIC, 100); + + if (phase_percent < 0) { + phase_percent += 100.0; + } + + if ((phase_percent < 0) || (phase_percent > 100)) { + g_error("Error during Moon phase calculation!"); + } + + moment->priv->moon_phase.illumination = (50.0 - fabs(phase_percent - 50.0)) * 2; + + if (phase_percent == 0) { + moment->priv->moon_phase.phase = GSWE_MOON_PHASE_NEW; + } else if (phase_percent < 25) { + moment->priv->moon_phase.phase = GSWE_MOON_PHASE_WAXING_CRESCENT; + } else if (phase_percent == 25) { + moment->priv->moon_phase.phase = GSWE_MOON_PHASE_WAXING_HALF; + } else if (phase_percent < 50) { + moment->priv->moon_phase.phase = GSWE_MOON_PHASE_WAXING_GIBBOUS; + } else if (phase_percent == 50) { + moment->priv->moon_phase.phase = GSWE_MOON_PHASE_FULL; + } else if (phase_percent < 75) { + moment->priv->moon_phase.phase = GSWE_MOON_PHASE_WANING_GIBBOUS; + } else if (phase_percent == 75) { + moment->priv->moon_phase.phase = GSWE_MOON_PHASE_WANING_HALF; + } else if (phase_percent < 100) { + moment->priv->moon_phase.phase = GSWE_MOON_PHASE_WANING_CRESCENT; + } else { + moment->priv->moon_phase.phase = GSWE_MOON_PHASE_DARK; + } + + moment->priv->moon_phase_revision = moment->priv->revision; + + return &(moment->priv->moon_phase); +} + diff --git a/swe-glib/src/gswe-moment.h b/swe-glib/src/gswe-moment.h index 97ae484..e17d043 100644 --- a/swe-glib/src/gswe-moment.h +++ b/swe-glib/src/gswe-moment.h @@ -60,6 +60,11 @@ typedef struct { guint revision; } GswePlanetData; +typedef struct { + GsweMoonPhase phase; + gdouble illumination; +} GsweMoonPhaseData; + struct _GsweMoment { /* Parent instance structure */ GObject parent_instance; @@ -96,6 +101,7 @@ GList *gswe_moment_get_planets(GsweMoment *moment); GswePlanetData *gswe_moment_get_planet(GsweMoment *moment, GswePlanet planet); guint gswe_moment_get_element_points(GsweMoment *moment, GsweElement element); guint gswe_moment_get_quality_points(GsweMoment *moment, GsweQuality quality); +GsweMoonPhaseData *gswe_moment_get_moon_phase(GsweMoment *moment); #endif /* __GSWE_MOMENT_H__ */ diff --git a/swe-glib/src/gswe-types.h b/swe-glib/src/gswe-types.h index 1f58fec..149a999 100644 --- a/swe-glib/src/gswe-types.h +++ b/swe-glib/src/gswe-types.h @@ -81,6 +81,18 @@ typedef enum { GSWE_HOUSE_SISTEM_EQUAL } GsweHouseSystem; +typedef enum { + GSWE_MOON_PHASE_NEW, + GSWE_MOON_PHASE_WAXING_CRESCENT, + GSWE_MOON_PHASE_WAXING_HALF, + GSWE_MOON_PHASE_WAXING_GIBBOUS, + GSWE_MOON_PHASE_FULL, + GSWE_MOON_PHASE_WANING_GIBBOUS, + GSWE_MOON_PHASE_WANING_HALF, + GSWE_MOON_PHASE_WANING_CRESCENT, + GSWE_MOON_PHASE_DARK +} GsweMoonPhase; + /** * GswePlanetInfo: * @planet: the planet ID diff --git a/swe-glib/src/swe-glib-private.h b/swe-glib/src/swe-glib-private.h index 30ce07d..e794918 100644 --- a/swe-glib/src/swe-glib-private.h +++ b/swe-glib/src/swe-glib-private.h @@ -1,7 +1,10 @@ #ifdef __SWE_GLIB_BUILDING__ #ifndef __SWE_GLIB_PRIVATE_H__ +#include "gswe-timestamp.h" + extern gchar *gswe_ephe_path; +extern GsweTimestamp *gswe_full_moon_base_date; #endif /* __SWE_GLIB_PRIVATE_H__ */ #else /* not defined __SWE_GLIB_BUILDING__ */ diff --git a/swe-glib/src/swe-glib.c b/swe-glib/src/swe-glib.c index 320b3b2..0f15bfa 100644 --- a/swe-glib/src/swe-glib.c +++ b/swe-glib/src/swe-glib.c @@ -10,6 +10,7 @@ gchar *gswe_ephe_path = NULL; GHashTable *gswe_planet_info_table; GHashTable *gswe_sign_info_table; GHashTable *gswe_house_system_info_table; +GsweTimestamp *gswe_full_moon_base_date; #define ADD_PLANET(ht, v, i, s, r, n, o, h, dom1, dom2, exi1, exi2, exa, fal) (v) = g_new0(GswePlanetInfo, 1); \ (v)->planet = (i); \ @@ -122,6 +123,8 @@ gswe_init(gchar *sweph_path) ADD_HOUSE_SYSTEM(gswe_house_system_info_table, house_system_info, GSWE_HOUSE_SYSTEM_KOCH, 'K', _("Koch")); ADD_HOUSE_SYSTEM(gswe_house_system_info_table, house_system_info, GSWE_HOUSE_SISTEM_EQUAL, 'E', _("Equal")); + gswe_full_moon_base_date = gswe_timestamp_new_from_gregorian_full(2005, 5, 8, 3, 48, 0, 0, 0.0); + gswe_ephe_path = g_strdup(sweph_path); swe_set_ephe_path(sweph_path); gswe_initialized = TRUE;