Index: AUTHORS =================================================================== --- AUTHORS (revision 4038) +++ AUTHORS (working copy) @@ -1,4 +1,5 @@ Benedikt Meurer Jasper Huijsmans Masse Nicolas -Nick Schermer \ No newline at end of file +Nick Schermer +kilo aka Gabor Kmetyko \ No newline at end of file Index: ChangeLog =================================================================== --- ChangeLog (revision 4038) +++ ChangeLog (working copy) @@ -1,3 +1,7 @@ +2008-03-12 kilo aka Gabor Kmetyko + + * Added moonrise/moonset data to summary window. + 2007-11-18 Nick Schermer * Post release bump, 0.6.3svn Index: panel-plugin/weather-summary.h =================================================================== --- panel-plugin/weather-summary.h (revision 4038) +++ panel-plugin/weather-summary.h (working copy) @@ -1,7 +1,7 @@ /* $Id$ * * Copyright (c) 2003-2007 Xfce Development Team - * + * * 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 2 of the License, or @@ -23,6 +23,7 @@ G_BEGIN_DECLS GtkWidget * create_summary_window (xml_weather * data, units unit); +void get_moon_data(gdouble lat, gdouble lon, gchar *buf1, gchar *buf2, gint size); G_END_DECLS #endif Index: panel-plugin/MoonRise.h =================================================================== --- panel-plugin/MoonRise.h (revision 0) +++ panel-plugin/MoonRise.h (revision 0) @@ -0,0 +1,32 @@ +#ifndef MOON_RISE_H +#define MOON_RISE_H 1 +/* MoonRise.h + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + * + * Original (C) Mike Henderson . + * + * I've converted Mike Henderson's original file to glib types. + * + * (C) 1999-2003 josh buhl + * + */ + +#include "CalcEphem.h" + +void MoonRise(CTrans * c, gdouble * UTRise, gdouble * UTSet); + +#endif /* !MOON_RISE_H */ Index: panel-plugin/weather-data.c =================================================================== --- panel-plugin/weather-data.c (revision 4038) +++ panel-plugin/weather-data.c (working copy) @@ -257,6 +257,12 @@ case SUNS: str = data->suns; break; + case LAT: + str = data->lat; + break; + case LON: + str = data->lon; + break; } return CHK_NULL (str); Index: panel-plugin/Moon.c =================================================================== --- panel-plugin/Moon.c (revision 0) +++ panel-plugin/Moon.c (revision 0) @@ -0,0 +1,485 @@ +/* Moon.c + * + * Calculates Moon's position according to Brown's Lunar Theory... + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + * + * Original (C) Mike Henderson . + * + * I've converted Mike Henderson's original file to glib types, + * removed unused variables, and piped the whole thing through indent. + * + * (C) 1999-2003 josh buhl + * + */ + +#include +#include "Moon.h" + +#define DegPerRad 57.29577951308232087680 +#define RadPerDeg 0.01745329251994329576 + +gdouble TwoPi = 6.283185308; +gdouble ARC = 206264.81; +gdouble DLAM, DLAMS; +gdouble DS; +gdouble GAM1C; +gdouble SINPI; +gdouble N; +gdouble CO[14][5], SI[14][5]; + + +static gdouble +sine(gdouble phi) +{ + return (sin(TwoPi * frac(phi))); +} + + +gdouble +frac(gdouble x) +{ + x -= (gint) x; + return ((x < 0) ? x + 1.0 : x); +} + + +static void +addthe(gdouble C1, gdouble S1, gdouble C2, gdouble S2, gdouble * C, + gdouble * S) +{ + *C = C1 * C2 - S1 * S2; + *S = S1 * C2 + C1 * S2; +} + + +static void +term(gint P, gint Q, gint R, gint S, gdouble * X, gdouble * Y) +{ + gdouble XX, YY; + gint k, I[5]; + + I[1] = P, I[2] = Q, I[3] = R, I[4] = S, XX = 1.0, YY = 0.0; + for (k = 1; k <= 4; ++k) { + if (I[k] != 0.0) { + addthe(XX, YY, CO[6 + I[k]][k], SI[6 + I[k]][k], + &XX, &YY); + } + } + *X = XX; + *Y = YY; +} + + +static void +addsol(gdouble COEFFL, gdouble COEFFS, gdouble COEFFG, gdouble COEFFP, + gint P, gint Q, gint R, gint S) +{ + gdouble X, Y; + + term(P, Q, R, S, &X, &Y); + DLAM += COEFFL * Y; + DS += COEFFS * Y; + GAM1C += COEFFG * X; + SINPI += COEFFP * X; +} + + +static void +addn(gdouble COEFFN, gint P, gint Q, gint R, gint S) +{ + gdouble X, Y; + + term(P, Q, R, S, &X, &Y); + N += COEFFN * Y; +} + + +gdouble +Moon(gdouble T, gdouble * LAMBDA, gdouble * BETA, gdouble * R, gdouble * AGE) +{ + gdouble T2; + gdouble S1, S2, S3, S4, S5, S6, S7; + gdouble DL0, DL, DD, DGAM, DLS, DF; + gdouble L0, L, LS, F, D; + gdouble ARG, FAC; + gint MAX, i, j; + gdouble S; + + ARG = 0.0, FAC = 0.0, MAX = 0; + + T2 = T * T; + DLAM = 0.0, DS = 0.0, GAM1C = 0.0; + SINPI = 3422.7000; + + /* + * Long Periodic variations + */ + S1 = sine(0.19833 + 0.05611 * T); + S2 = sine(0.27869 + 0.04508 * T); + S3 = sine(0.16827 - 0.36903 * T); + S4 = sine(0.34734 - 5.37261 * T); + S5 = sine(0.10498 - 5.37899 * T); + S6 = sine(0.42681 - 0.41855 * T); + S7 = sine(0.14943 - 5.37511 * T); + DL0 = + 0.84 * S1 + 0.31 * S2 + 14.27 * S3 + 7.26 * S4 + 0.28 * S5 + + 0.24 * S6; + DL = + 2.94 * S1 + 0.31 * S2 + 14.27 * S3 + 9.34 * S4 + 1.12 * S5 + + 0.83 * S6; + DLS = -6.40 * S1 - 1.89 * S6; + DF = + 0.21 * S1 + 0.31 * S2 + 14.27 * S3 - 88.70 * S4 - 15.30 * S5 + + 0.24 * S6 - 1.86 * S7; + DD = DL0 - DLS; + DGAM = -3332e-9 * sine(0.59734 - 5.37261 * T) + - 539e-9 * sine(0.35498 - 5.37899 * T) + - 64e-9 * sine(0.39943 - 5.37511 * T); + + + + L0 = + TwoPi * frac(0.60643382 + 1336.85522467 * T - + 0.00000313 * T2) + DL0 / ARC; + L = + TwoPi * frac(0.37489701 + 1325.55240982 * T + + 0.00002565 * T2) + DL / ARC; + LS = + TwoPi * frac(0.99312619 + 99.99735956 * T - 0.00000044 * T2) + + DLS / ARC; + F = + TwoPi * frac(0.25909118 + 1342.22782980 * T - + 0.00000892 * T2) + DF / ARC; + D = + TwoPi * frac(0.82736186 + 1236.85308708 * T - + 0.00000397 * T2) + DD / ARC; + + for (i = 1; i <= 4; ++i) { + switch (i) { + case 1: + ARG = L, MAX = 4, FAC = 1.000002208; + break; + case 2: + ARG = LS, MAX = 3, FAC = + 0.997504612 - 0.002495388 * T; + break; + case 3: + ARG = F, MAX = 4, FAC = + 1.000002708 + 139.978 * DGAM; + break; + case 4: + ARG = D, MAX = 6, FAC = 1.0; + break; + } + + CO[6 + 0][i] = 1.0, CO[6 + 1][i] = cos(ARG) * FAC; + SI[6 + 0][i] = 0.0, SI[6 + 1][i] = sin(ARG) * FAC; + for (j = 2; j <= MAX; ++j) + addthe(CO[6 + j - 1][i], SI[6 + j - 1][i], + CO[6 + 1][i], SI[6 + 1][i], &CO[6 + j][i], + &SI[6 + j][i]); + for (j = 1; j <= MAX; ++j) { + CO[6 - j][i] = CO[6 + j][i]; + SI[6 - j][i] = -SI[6 + j][i]; + } + + } + + + /* + * Solar1 + */ + addsol(13.902, 14.06, -0.001, 0.2607, 0, 0, 0, 4); + addsol(0.403, -4.01, +0.394, 0.0023, 0, 0, 0, 3); + addsol(2369.912, 2373.36, +0.601, 28.2333, 0, 0, 0, 2); + addsol(-125.154, -112.79, -0.725, -0.9781, 0, 0, 0, 1); + addsol(1.979, 6.98, -0.445, 0.0433, 1, 0, 0, 4); + addsol(191.953, 192.72, +0.029, 3.0861, 1, 0, 0, 2); + addsol(-8.466, -13.51, +0.455, -0.1093, 1, 0, 0, 1); + addsol(22639.500, 22609.07, +0.079, 186.5398, 1, 0, 0, 0); + addsol(18.609, 3.59, -0.094, 0.0118, 1, 0, 0, -1); + addsol(-4586.465, -4578.13, -0.077, 34.3117, 1, 0, 0, -2); + addsol(+3.215, 5.44, +0.192, -0.0386, 1, 0, 0, -3); + addsol(-38.428, -38.64, +0.001, 0.6008, 1, 0, 0, -4); + addsol(-0.393, -1.43, -0.092, 0.0086, 1, 0, 0, -6); + addsol(-0.289, -1.59, +0.123, -0.0053, 0, 1, 0, 4); + addsol(-24.420, -25.10, +0.040, -0.3000, 0, 1, 0, 2); + addsol(18.023, 17.93, +0.007, 0.1494, 0, 1, 0, 1); + addsol(-668.146, -126.98, -1.302, -0.3997, 0, 1, 0, 0); + addsol(0.560, 0.32, -0.001, -0.0037, 0, 1, 0, -1); + addsol(-165.145, -165.06, +0.054, 1.9178, 0, 1, 0, -2); + addsol(-1.877, -6.46, -0.416, 0.0339, 0, 1, 0, -4); + addsol(0.213, 1.02, -0.074, 0.0054, 2, 0, 0, 4); + addsol(14.387, 14.78, -0.017, 0.2833, 2, 0, 0, 2); + addsol(-0.586, -1.20, +0.054, -0.0100, 2, 0, 0, 1); + addsol(769.016, 767.96, +0.107, 10.1657, 2, 0, 0, 0); + addsol(+1.750, 2.01, -0.018, 0.0155, 2, 0, 0, -1); + addsol(-211.656, -152.53, +5.679, -0.3039, 2, 0, 0, -2); + addsol(+1.225, 0.91, -0.030, -0.0088, 2, 0, 0, -3); + addsol(-30.773, -34.07, -0.308, 0.3722, 2, 0, 0, -4); + addsol(-0.570, -1.40, -0.074, 0.0109, 2, 0, 0, -6); + addsol(-2.921, -11.75, +0.787, -0.0484, 1, 1, 0, 2); + addsol(+1.267, 1.52, -0.022, 0.0164, 1, 1, 0, 1); + addsol(-109.673, -115.18, +0.461, -0.9490, 1, 1, 0, 0); + addsol(-205.962, -182.36, +2.056, +1.4437, 1, 1, 0, -2); + addsol(0.233, 0.36, 0.012, -0.0025, 1, 1, 0, -3); + addsol(-4.391, -9.66, -0.471, 0.0673, 1, 1, 0, -4); + + + /* + * Solar2 + */ + addsol(0.283, 1.53, -0.111, +0.0060, 1, -1, 0, +4); + addsol(14.577, 31.70, -1.540, +0.2302, 1, -1, 0, 2); + addsol(147.687, 138.76, +0.679, +1.1528, 1, -1, 0, 0); + addsol(-1.089, 0.55, +0.021, 0.0, 1, -1, 0, -1); + addsol(28.475, 23.59, -0.443, -0.2257, 1, -1, 0, -2); + addsol(-0.276, -0.38, -0.006, -0.0036, 1, -1, 0, -3); + addsol(0.636, 2.27, +0.146, -0.0102, 1, -1, 0, -4); + addsol(-0.189, -1.68, +0.131, -0.0028, 0, 2, 0, 2); + addsol(-7.486, -0.66, -0.037, -0.0086, 0, 2, 0, 0); + addsol(-8.096, -16.35, -0.740, 0.0918, 0, 2, 0, -2); + addsol(-5.741, -0.04, 0.0, -0.0009, 0, 0, 2, 2); + addsol(0.255, 0.0, 0.0, 0.0, 0, 0, 2, 1); + addsol(-411.608, -0.20, 0.0, -0.0124, 0, 0, 2, 0); + addsol(0.584, 0.84, 0.0, +0.0071, 0, 0, 2, -1); + addsol(-55.173, -52.14, 0.0, -0.1052, 0, 0, 2, -2); + addsol(0.254, 0.25, 0.0, -0.0017, 0, 0, 2, -3); + addsol(+0.025, -1.67, 0.0, +0.0031, 0, 0, 2, -4); + addsol(1.060, 2.96, -0.166, 0.0243, 3, 0, 0, +2); + addsol(36.124, 50.64, -1.300, 0.6215, 3, 0, 0, 0); + addsol(-13.193, -16.40, +0.258, -0.1187, 3, 0, 0, -2); + addsol(-1.187, -0.74, +0.042, 0.0074, 3, 0, 0, -4); + addsol(-0.293, -0.31, -0.002, 0.0046, 3, 0, 0, -6); + addsol(-0.290, -1.45, +0.116, -0.0051, 2, 1, 0, 2); + addsol(-7.649, -10.56, +0.259, -0.1038, 2, 1, 0, 0); + addsol(-8.627, -7.59, +0.078, -0.0192, 2, 1, 0, -2); + addsol(-2.740, -2.54, +0.022, 0.0324, 2, 1, 0, -4); + addsol(1.181, 3.32, -0.212, 0.0213, 2, -1, 0, +2); + addsol(9.703, 11.67, -0.151, 0.1268, 2, -1, 0, 0); + addsol(-0.352, -0.37, +0.001, -0.0028, 2, -1, 0, -1); + addsol(-2.494, -1.17, -0.003, -0.0017, 2, -1, 0, -2); + addsol(0.360, 0.20, -0.012, -0.0043, 2, -1, 0, -4); + addsol(-1.167, -1.25, +0.008, -0.0106, 1, 2, 0, 0); + addsol(-7.412, -6.12, +0.117, 0.0484, 1, 2, 0, -2); + addsol(-0.311, -0.65, -0.032, 0.0044, 1, 2, 0, -4); + addsol(+0.757, 1.82, -0.105, 0.0112, 1, -2, 0, 2); + addsol(+2.580, 2.32, +0.027, 0.0196, 1, -2, 0, 0); + addsol(+2.533, 2.40, -0.014, -0.0212, 1, -2, 0, -2); + addsol(-0.344, -0.57, -0.025, +0.0036, 0, 3, 0, -2); + addsol(-0.992, -0.02, 0.0, 0.0, 1, 0, 2, 2); + addsol(-45.099, -0.02, 0.0, -0.0010, 1, 0, 2, 0); + addsol(-0.179, -9.52, 0.0, -0.0833, 1, 0, 2, -2); + addsol(-0.301, -0.33, 0.0, 0.0014, 1, 0, 2, -4); + addsol(-6.382, -3.37, 0.0, -0.0481, 1, 0, -2, 2); + addsol(39.528, 85.13, 0.0, -0.7136, 1, 0, -2, 0); + addsol(9.366, 0.71, 0.0, -0.0112, 1, 0, -2, -2); + addsol(0.202, 0.02, 0.0, 0.0, 1, 0, -2, -4); + + /* + * Solar3 + */ + addsol(0.415, 0.10, 0.0, 0.0013, 0, 1, 2, 0); + addsol(-2.152, -2.26, 0.0, -0.0066, 0, 1, 2, -2); + addsol(-1.440, -1.30, 0.0, +0.0014, 0, 1, -2, 2); + addsol(0.384, -0.04, 0.0, 0.0, 0, 1, -2, -2); + addsol(+1.938, +3.60, -0.145, +0.0401, 4, 0, 0, 0); + addsol(-0.952, -1.58, +0.052, -0.0130, 4, 0, 0, -2); + addsol(-0.551, -0.94, +0.032, -0.0097, 3, 1, 0, 0); + addsol(-0.482, -0.57, +0.005, -0.0045, 3, 1, 0, -2); + addsol(0.681, 0.96, -0.026, 0.0115, 3, -1, 0, 0); + addsol(-0.297, -0.27, 0.002, -0.0009, 2, 2, 0, -2); + addsol(0.254, +0.21, -0.003, 0.0, 2, -2, 0, -2); + addsol(-0.250, -0.22, 0.004, 0.0014, 1, 3, 0, -2); + addsol(-3.996, 0.0, 0.0, +0.0004, 2, 0, 2, 0); + addsol(0.557, -0.75, 0.0, -0.0090, 2, 0, 2, -2); + addsol(-0.459, -0.38, 0.0, -0.0053, 2, 0, -2, 2); + addsol(-1.298, 0.74, 0.0, +0.0004, 2, 0, -2, 0); + addsol(0.538, 1.14, 0.0, -0.0141, 2, 0, -2, -2); + addsol(0.263, 0.02, 0.0, 0.0, 1, 1, 2, 0); + addsol(0.426, +0.07, 0.0, -0.0006, 1, 1, -2, -2); + addsol(-0.304, +0.03, 0.0, +0.0003, 1, -1, 2, 0); + addsol(-0.372, -0.19, 0.0, -0.0027, 1, -1, -2, 2); + addsol(+0.418, 0.0, 0.0, 0.0, 0, 0, 4, 0); + addsol(-0.330, -0.04, 0.0, 0.0, 3, 0, 2, 0); + + N = 0.0; + addn(-526.069, 0, 0, 1, -2); + addn(-3.352, 0, 0, 1, -4); + addn(+44.297, +1, 0, 1, -2); + addn(-6.000, +1, 0, 1, -4); + addn(+20.599, -1, 0, 1, 0); + addn(-30.598, -1, 0, 1, -2); + addn(-24.649, -2, 0, 1, 0); + addn(-2.000, -2, 0, 1, -2); + addn(-22.571, 0, +1, 1, -2); + addn(+10.985, 0, -1, 1, -2); + + DLAM += + +0.82 * sine(0.7736 - 62.5512 * T) + 0.31 * sine(0.0466 - + 125.1025 * T) + + 0.35 * sine(0.5785 - 25.1042 * T) + 0.66 * sine(0.4591 + + 1335.8075 * + T) + + 0.64 * sine(0.3130 - 91.5680 * T) + 1.14 * sine(0.1480 + + 1331.2898 * T) + + 0.21 * sine(0.5918 + 1056.5859 * T) + 0.44 * sine(0.5784 + + 1322.8595 * + T) + + 0.24 * sine(0.2275 - 5.7374 * T) + 0.28 * sine(0.2965 + + 2.6929 * T) + + 0.33 * sine(0.3132 + 6.3368 * T); + + + *LAMBDA = 360.0 * frac((L0 + DLAM / ARC) / TwoPi); + + S = F + DS / ARC; + FAC = 1.000002708 + 139.978 * DGAM; + *BETA = + (FAC * (18518.511 + 1.189 + GAM1C) * sin(S) - + 6.24 * sin(3 * S) + N) / 3600.0; + + SINPI *= 0.999953253; + *R = ARC / SINPI; + + + DLAMS = 6893.0 * sin(LS) + 72.0 * sin(2.0 * LS); + + *AGE = 29.530589 * frac((D + (DLAM - DLAMS) / ARC) / TwoPi); +/* +printf("Diff = %f\n", 360.0*frac((D+(DLAM-DLAMS)/ARC)/TwoPi)); +*/ + + /* + * Return the phase. + */ +/* + return( 0.5*(1.0 - cos(D+(DLAM-DLAMS)/ARC)) ); +*/ + return (*AGE / 29.530589); + + + +} + +#define R 0.61803399 +#define C 0.38196601 + +gdouble +NewMoon(gdouble ax, gdouble bx, gdouble cx) +{ + gdouble f1, f2, x0, x1, x2, x3; + gdouble L, B, Rad, AGE, tol = 1e-7; + + x0 = ax; + x3 = cx; + if (fabs(cx - bx) > fabs(bx - ax)) { + x1 = bx; + x2 = bx + C * (cx - bx); + } else { + x2 = bx; + x1 = bx - C * (bx - ax); + } + f1 = Moon(x1, &L, &B, &Rad, &AGE); + f2 = Moon(x2, &L, &B, &Rad, &AGE); + while (fabs(x3 - x0) > tol * (fabs(x1) + fabs(x2))) { + if (f2 < f1) { + x0 = x1; + x1 = x2; + + x2 = R * x1 + C * x3; + f1 = f2; + f2 = Moon(x2, &L, &B, &Rad, &AGE); + } else { + x3 = x2; + x2 = x1; + + x1 = R * x2 + C * x0; + f2 = f1; + f1 = Moon(x1, &L, &B, &Rad, &AGE); + } + } + if (f1 < f2) { + return (x1); + } else { + return (x2); + } +} + +/* + * MINI_MOON: low precision lunar coordinates (approx. 5'/1') + * T : time in Julian centuries since J2000 + * ( T=(JD-2451545)/36525 ) + * RA : right ascension (in h; equinox of date) + * DEC: declination (in deg; equinox of date) + * + */ +gint +MiniMoon(gdouble T, gdouble * RA, gdouble * DEC) +{ + gdouble L0, L, LS, F, D, H, S, N, DL, CB, L_MOON, B_MOON, V, W, X, + Y, Z, RHO; + gdouble frac(), cosEPS, sinEPS, P2, ARC; + + + cosEPS = 0.91748; + sinEPS = 0.39778; + P2 = 6.283185307; + ARC = 206264.8062; + + + /* + * mean elements of lunar orbit + */ + L0 = frac(0.606433 + 1336.855225 * T); /* mean longitude Moon (in rev) */ + L = P2 * frac(0.374897 + 1325.552410 * T); /* mean anomaly of the Moon */ + LS = P2 * frac(0.993133 + 99.997361 * T); /* mean anomaly of the Sun */ + D = P2 * frac(0.827361 + 1236.853086 * T); /* diff. longitude Moon-Sun */ + F = P2 * frac(0.259086 + 1342.227825 * T); /* mean argument of latitude */ + DL = + +22640.0 * sin(L) - 4586.0 * sin(L - 2.0 * D) + + 2370.0 * sin(2.0 * D) + 769.0 * sin(2.0 * L) + - 668.0 * sin(LS) - 412.0 * sin(2.0 * F) - + 212.0 * sin(2.0 * L - 2.0 * D) - 206.0 * sin(L + LS - 2.0 * D) + + 192.0 * sin(L + 2.0 * D) - 165.0 * sin(LS - 2.0 * D) - + 125.0 * sin(D) - 110.0 * sin(L + LS) + + 148.0 * sin(L - LS) - 55.0 * sin(2.0 * F - 2.0 * D); + S = F + (DL + 412.0 * sin(2.0 * F) + 541.0 * sin(LS)) / ARC; + H = F - 2.0 * D; + N = + -526.0 * sin(H) + 44.0 * sin(L + H) - 31.0 * sin(-L + H) - + 23.0 * sin(LS + H) + + 11.0 * sin(-LS + H) - 25.0 * sin(-2.0 * L + F) + + 21.0 * sin(-L + F); + L_MOON = P2 * frac(L0 + DL / 1296e3); /* in rad */ + B_MOON = (18520.0 * sin(S) + N) / ARC; /* in rad */ + + /* equatorial coordinates */ + CB = cos(B_MOON); + X = CB * cos(L_MOON); + V = CB * sin(L_MOON); + W = sin(B_MOON); + Y = cosEPS * V - sinEPS * W; + Z = sinEPS * V + cosEPS * W; + RHO = sqrt(1.0 - Z * Z); + *DEC = (360.0 / P2) * atan2(Z, RHO); + *RA = (48.0 / P2) * atan2(Y, X + RHO); + if (*RA < 0.0) + *RA += 24.0; + + return (0); +} Index: panel-plugin/weather-data.h =================================================================== --- panel-plugin/weather-data.h (revision 4038) +++ panel-plugin/weather-data.h (working copy) @@ -1,7 +1,7 @@ /* $Id$ * * Copyright (c) 2003-2007 Xfce Development Team - * + * * 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 2 of the License, or @@ -72,7 +72,9 @@ { DNAM = 0x0201, SUNR = 0x0202, - SUNS = 0x0203 + SUNS = 0x0203, + LAT = 0x0204, + LON = 0x0205 } datas_loc; Index: panel-plugin/weather-parsers.c =================================================================== --- panel-plugin/weather-parsers.c (revision 4038) +++ panel-plugin/weather-parsers.c (working copy) @@ -1,7 +1,7 @@ /* $Id$ * * Copyright (c) 2003-2007 Xfce Development Team - * + * * 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 2 of the License, or @@ -93,6 +93,10 @@ ret->sunr = DATA (cur_node); else if (NODE_IS_TYPE (cur_node, "suns")) ret->suns = DATA (cur_node); + else if (NODE_IS_TYPE (cur_node, "lat")) + ret->lat = DATA (cur_node); + else if (NODE_IS_TYPE (cur_node, "lon")) + ret->lon = DATA (cur_node); } return ret; @@ -363,6 +367,8 @@ g_free (data->dnam); g_free (data->sunr); g_free (data->suns); + g_free (data->lat); + g_free (data->lon); panel_slice_free (xml_loc, data); } Index: panel-plugin/Moon.h =================================================================== --- panel-plugin/Moon.h (revision 0) +++ panel-plugin/Moon.h (revision 0) @@ -0,0 +1,38 @@ +#ifndef MOON_H +#define MOON_H 1 +/* + * Moon.h + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + * + * Original (C) Mike Henderson . + * + * I've converted Mike Henderson's original file to glib types, + * removed unused variables, and piped the whole thing through indent. + * + * (C) 1999-2003 josh buhl + * + */ + +#include + +gdouble Moon(gdouble T, gdouble * LAMBDA, gdouble * BETA, gdouble * R, + gdouble * AGE); +gdouble frac(gdouble x); +gdouble NewMoon(gdouble ax, gdouble bx, gdouble cx); +gint MiniMoon(gdouble T, gdouble * RA, gdouble * DEC); + +#endif /* !MOON_H */ Index: panel-plugin/weather-parsers.h =================================================================== --- panel-plugin/weather-parsers.h (revision 4038) +++ panel-plugin/weather-parsers.h (working copy) @@ -1,7 +1,7 @@ /* $Id$ * * Copyright (c) 2003-2007 Xfce Development Team - * + * * 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 2 of the License, or @@ -33,6 +33,8 @@ gchar *dnam; gchar *sunr; gchar *suns; + gchar *lat; + gchar *lon; } xml_loc; Index: panel-plugin/CalcEphem.c =================================================================== --- panel-plugin/CalcEphem.c (revision 0) +++ panel-plugin/CalcEphem.c (revision 0) @@ -0,0 +1,390 @@ +/* CalcEphem.c + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + * + * Original (C) Mike Henderson . + * + * I've converted to glib types, removed unused variables and functions, + * piped the whole thing through indent, and added small stuff. + * + * (C) 1999-2004 Josh Buhl + * + */ +#ifdef HAVE_CONFIG_H +#include +#include +#endif + +#include "CalcEphem.h" +#include "Moon.h" + + +static gdouble +kepler(gdouble M, gdouble e) +{ + gint n = 0; + gdouble E, Eold, eps = 1.0e-8; + + E = M + e * sin(M); + do { + Eold = E; + E = Eold + (M - Eold + e * sin(Eold)) + / (1.0 - e * cos(Eold)); + ++n; + } while ((fabs(E - Eold) > eps) && (n < 100)); + return (E); +} + +static gint +DayofYear(gint year, gint month, gint day) +{ + gdouble jd(); + return ((gint) (jd(year, month, day, 0.0) - jd(year, 1, 0, 0.0))); +} + + +static gint +DayofWeek(gint year, gint month, gint day, gchar dowstr[]) +{ + gdouble JD, A, Afrac, jd(); + gint n, iA; + + JD = jd(year, month, day, 0.0); + A = (JD + 1.5) / 7.0; + iA = (gint) A; + Afrac = A - (gdouble) iA; + n = (gint) (Afrac * 7.0 + 0.5); + switch (n) { + case 0: + strcpy(dowstr, "Sunday"); + break; + case 1: + strcpy(dowstr, "Monday"); + break; + case 2: + strcpy(dowstr, "Tuesday"); + break; + case 3: + strcpy(dowstr, "Wednesday"); + break; + case 4: + strcpy(dowstr, "Thursday"); + break; + case 5: + strcpy(dowstr, "Friday"); + break; + case 6: + strcpy(dowstr, "Saturday"); + break; + } + return (n); +} + +/* + * Compute the Julian Day number for the given date. + * Julian Date is the number of days since noon of Jan 1 4713 B.C. + */ +gdouble +jd(gint ny, gint nm, gint nd, gdouble UT) +{ + gdouble A, B, C, D, JD, day; + + day = nd + UT / 24.0; + + if ((nm == 1) || (nm == 2)) { + ny = ny - 1; + nm = nm + 12; + } + + if (((gdouble) ny + nm / 12.0 + day / 365.25) >= + (1582.0 + 10.0 / 12.0 + 15.0 / 365.25)) { + A = ((gint) (ny / 100.0)); + B = 2.0 - A + (gint) (A / 4.0); + } else { + B = 0.0; + } + + if (ny < 0.0) { + C = (gint) ((365.25 * (gdouble) ny) - 0.75); + } else { + C = (gint) (365.25 * (gdouble) ny); + } + + D = (gint) (30.6001 * (gdouble) (nm + 1)); + + + JD = B + C + D + day + 1720994.5; + return (JD); +} + +gdouble +hour24(gdouble hour) +{ + gint n; + + if (hour < 0.0) { + n = (gint) (hour / 24.0) - 1; + return (hour - n * 24.0); + } else if (hour > 24.0) { + n = (gint) (hour / 24.0); + return (hour - n * 24.0); + } else { + return (hour); + } +} + +gdouble +angle2pi(gdouble angle) +{ + gint n; + gdouble a; + a = 2.0 * M_PI; + + if (angle < 0.0) { + n = (gint) (angle / a) - 1; + return (angle - n * a); + } else if (angle > a) { + n = (gint) (angle / a); + return (angle - n * a); + } else { + return (angle); + } +} + +static gdouble +angle360(gdouble angle) +{ + gint n; + + if (angle < 0.0) { + n = (gint) (angle / 360.0) - 1; + return (angle - n * 360.0); + } else if (angle > 360.0) { + n = (gint) (angle / 360.0); + return (angle - n * 360.0); + } else { + return (angle); + } +} + +void +CalcEphem(glong date, gdouble UT, CTrans * c) +{ + gint year, month, day; + gdouble TU, TU2, TU3, T0, gmst; + gdouble varep, varpi; + gdouble eccen, epsilon; + gdouble days, M, E, nu, lambnew; + gdouble r0, earth_sun_distance; + gdouble RA, DEC, RA_Moon, DEC_Moon; + gdouble TDT; + gdouble AGE; + gdouble LambdaMoon, BetaMoon, R; + gdouble Ta, Tb, Tc, frac(); + gdouble SinGlat, CosGlat, SinGlon, CosGlon, Tau, lmst, x, y, z; + gdouble SinTau, CosTau, SinDec, CosDec; + gdouble TimeNewMoon; + + c->UT = UT; + + year = (gint) (date / 10000); + month = (gint) ((date - year * 10000) / 100); + day = (gint) (date - year * 10000 - month * 100); + c->year = year; + c->month = month; + c->day = day; + + c->doy = DayofYear(year, month, day); + c->dow = DayofWeek(year, month, day, c->dowstr); + + + /* + * Compute Greenwich Mean Sidereal Time (gmst) + * The TU here is number of Julian centuries + * since 2000 January 1.5 + * From the 1996 astronomical almanac + */ + TU = (jd(year, month, day, 0.0) - 2451545.0) / 36525.0; + TU2 = TU * TU; + TU3 = TU2 * TU; + T0 = + (6.0 + 41.0 / 60.0 + 50.54841 / 3600.0) + + 8640184.812866 / 3600.0 * TU + 0.093104 / 3600.0 * TU2 - + 6.2e-6 / 3600.0 * TU3; + T0 = hour24(T0); + + c->gmst = hour24(T0 + UT * 1.002737909); + + /* convert to radians for ease later on */ + gmst = c->gmst * 15.0 * M_PI / 180.0; + + lmst = 24.0 * frac((c->gmst - c->Glon / 15.0) / 24.0); + + /* + + * Construct Transformation Matrix from GEI to GSE systems + * + * + * First compute: + * mean ecliptic longitude of sun at epoch TU (varep) + * elciptic longitude of perigee at epoch TU (varpi) + * eccentricity of orbit at epoch TU (eccen) + * + * The TU here is the number of Julian centuries since + * 1900 January 0.0 (= 2415020.0) + */ + TDT = UT + 59.0 / 3600.0; + TU = (jd(year, month, day, TDT) - 2415020.0) / 36525.0; + varep = + (279.6966778 + 36000.76892 * TU + + 0.0003025 * TU * TU) * RadPerDeg; + varpi = + (281.2208444 + 1.719175 * TU + + 0.000452778 * TU * TU) * RadPerDeg; + eccen = 0.01675104 - 0.0000418 * TU - 0.000000126 * TU * TU; + c->eccentricity = eccen; + + /* + * Compute the Obliquity of the Ecliptic at epoch TU + * The TU in this formula is the number of Julian + * centuries since epoch 2000 January 1.5 + */ + TU = (jd(year, month, day, TDT) - jd(2000, 1, 1, 12.0)) / 36525.0; + epsilon = (23.43929167 - 0.013004166 * TU - 1.6666667e-7 * TU * TU + - 5.0277777778e-7 * TU * TU * TU) * RadPerDeg; + c->epsilon = epsilon; + + /* + * Compute: + * Number of Days since epoch 1990.0 (days) + * The Mean Anomaly (M) + * The True Anomaly (nu) + * The Eccentric Anomaly via Keplers equation (E) + * + * + */ + days = jd(year, month, day, TDT) - jd(year, month, day, TDT); + M = angle2pi(2.0 * M_PI / 365.242191 * days + varep - varpi); + E = kepler(M, eccen); + nu = + 2.0 * atan(sqrt((1.0 + eccen) / (1.0 - eccen)) * tan(E / 2.0)); + lambnew = angle2pi(nu + varpi); + c->lambda_sun = lambnew; + + /* + * Compute distance from earth to the sun + */ + r0 = 1.495985e8; /* in km */ + earth_sun_distance = + r0 * (1 - eccen * eccen) / (1.0 + eccen * cos(nu)) / 6371.2; + c->earth_sun_dist = earth_sun_distance; + + /* + * Compute Right Ascension and Declination of the Sun + */ + RA = + angle360(atan2(sin(lambnew) * cos(epsilon), cos(lambnew)) * + 180.0 / M_PI); + DEC = asin(sin(epsilon) * sin(lambnew)) * 180.0 / M_PI; + c->RA_sun = RA; + c->DEC_sun = DEC; + + /* + * Compute Moon Phase and AGE Stuff. The AGE that comes out of Moon() + * is actually the Phase converted to days. Since AGE is actually defined + * to be time since last NewMoon, we need to figure out what the JD of the + * last new moon was. Thats done below.... + */ + TU = (jd(year, month, day, TDT) - 2451545.0) / 36525.0; + c->MoonPhase = Moon(TU, &LambdaMoon, &BetaMoon, &R, &AGE); + LambdaMoon *= RadPerDeg; + BetaMoon *= RadPerDeg; + + + RA_Moon = + angle360(atan2 + (sin(LambdaMoon) * cos(epsilon) - + tan(BetaMoon) * sin(epsilon), + cos(LambdaMoon)) * DegPerRad); + DEC_Moon = + asin(sin(BetaMoon) * cos(epsilon) + + cos(BetaMoon) * sin(epsilon) * sin(LambdaMoon)) * + DegPerRad; + c->RA_moon = RA_Moon; + c->DEC_moon = DEC_Moon; + + /* + * Compute Alt/Az coords + */ + Tau = (15.0 * lmst - RA_Moon) * RadPerDeg; + CosGlat = cos(c->Glat * RadPerDeg); + SinGlat = sin(c->Glat * RadPerDeg); + CosGlon = cos(c->Glon * RadPerDeg); + SinGlon = sin(c->Glon * RadPerDeg); + CosTau = cos(Tau); + SinTau = sin(Tau); + SinDec = sin(DEC_Moon * RadPerDeg); + CosDec = cos(DEC_Moon * RadPerDeg); + x = CosDec * CosTau * SinGlat - SinDec * CosGlat; + y = CosDec * SinTau; + z = CosDec * CosTau * CosGlat + SinDec * SinGlat; + c->A_moon = DegPerRad * atan2(y, x) + 180.0; + c->h_moon = DegPerRad * asin(z); + c->Visible = (c->h_moon < 0.0) ? FALSE : TRUE; + + /* + * Compute accurate AGE of the Moon + */ + Tb = TU - AGE / 36525.0; /* should be very close to minimum */ + Ta = Tb - 0.4 / 36525.0; + Tc = Tb + 0.4 / 36525.0; + c->MoonAge = (TU - NewMoon(Ta, Tb, Tc)) * 36525.0; +/* g_message("ta is %f, tb is %f, tc is %f, moonage is %f, age is %f", Ta, Tb, Tc, c->MoonAge, AGE); */ + + /* + * Compute next New Moon + */ + + /* New Moon very sensitive to initial parameters. must find correct ones. */ + +/* g_message("abs(MoonPhase) is %f, ratio is %f\n", ABS(c->MoonPhase), c->MoonAge/c->MoonPhase); */ + + /* hardcoded */ +/* TimeNewMoon = 29.530589; */ + /* estimated for non-small phases */ + TimeNewMoon = (ABS(c->MoonPhase) < 0.6) ? 29.530589 : c->MoonAge/c->MoonPhase; + Tb += TimeNewMoon/36525.0; + Ta += TimeNewMoon/36525.0; + Tc += TimeNewMoon/36525.0; + c->NewMoon = (NewMoon(Ta, Tb, Tc) - TU) * 36525.0; + +/* g_message("calculated Moonperiod is %f\n", TimeNewMoon); */ +/* g_message("ta is %f, tb is %f, tc is %f, newmoon is %f\n", Ta, Tb, Tc, c->NewMoon); */ + + /* approximate FullMoon */ + c->FullMoon = (((ABS(c->MoonPhase) < 0.5) ? 0.5 : 1.5) - c->MoonPhase) * 29.530589; + +/* g_message("fullmoon in %f days; or %f days\n", c->FullMoon, (c->NewMoon+(29.530589/2.0))); */ + + /* + * Set Earth-Moon distance (calc above w/ func Moon) + */ + c->EarthMoonDistance = R; + + + c->SinGlat = SinGlat; + c->CosGlat = CosGlat; +} Index: panel-plugin/CalcEphem.h =================================================================== --- panel-plugin/CalcEphem.h (revision 0) +++ panel-plugin/CalcEphem.h (revision 0) @@ -0,0 +1,105 @@ +#ifndef CALC_EPHEM_H +#define CALC_EPHEM_H 1 +/* CalcEphem.h + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + * + * Original (C) Mike Henderson . + * + * I've added function prototypes, a couple of data to the CTrans + * structure, converted standard data types to their glib counterparts + * (as compared to original wmMoonClock code), and piped the whole + * thing through indent. + * + * (C) 1999-2004 josh buhl + * + */ + +#include + +#include +#include + +#define DegPerRad 57.29577951308232087680 +#define RadPerDeg 0.01745329251994329576 + + +typedef struct Vector { + gdouble x; + gdouble y; + gdouble z; +} Vector; + + +typedef struct Position { + gdouble x; + gdouble y; + gdouble z; +} Position; + + +typedef struct CTrans { + gdouble UT; /* Universal Time (in decimal hours) */ + gint year; /* 2 digit year */ + gint month; /* 2 digit month of year */ + gint day; /* 2 digit day of month */ + gint doy; /* 3 digit Day Of Year */ + gint dow; /* 1 digit day of week */ + gchar dowstr[80]; /* Day of week String (e.g. "Sun") */ + gdouble gmst; /* Greenwich Mean Sidereal Time */ + gdouble eccentricity; /* Eccentricity of Earth-Sun orbit */ + gdouble epsilon; /* Obliquity of the ecliptic (in radians) */ + gdouble lambda_sun; /* Ecliptic Long. of Sun (in radians) */ + gdouble earth_sun_dist; /* Earth-Sun distance (in units of earth radii) */ + gdouble RA_sun; /* Right Ascention of Sun (in degrees) */ + gdouble DEC_sun; /* Declination of Sun (in degrees) */ + Vector Sun; /* direction of Sun in GEI system (unit vector) */ + Vector EcPole; /* direction of Ecliptic Pole in GEI system (unit vector) */ + gdouble psi; /* Geodipole tilt angle (in radians) */ + gdouble Dipole_Gcolat; /* Geographic colat of centered dipole axis (deg.) */ + gdouble Dipole_Glon; /* Geographic long. of centered dipole axis (deg.) */ + + gdouble RA_moon; /* Right Ascention of Moon (in degrees) */ + gdouble DEC_moon; /* Declination of Moon (in degrees) */ + gdouble MoonPhase; /* The Phase of the Moon (as fraction of 1) */ + gdouble MoonAge; /* Age of Moon in Days */ + gdouble NewMoon; /* time to New Moon in Days */ + gdouble FullMoon; /* time to Full Moon in Days */ + gdouble EarthMoonDistance; /* Distance between the Earth and Moon (in earth-radii) */ + gdouble Glat; /* Geographic Latitude of Observer */ + gdouble Glon; /* Geographic Longitude of Observer */ + gdouble h_moon; /* Altitude of Moon (in degrees) */ + gdouble A_moon; /* Azimuth of Moon (in degrees) */ + gboolean Visible; /* Whether or not moon is above horizon */ + + /* Additional Data for glunarclock */ + gdouble SinGlat; /* data calc. in CalcEphem, used in MoonRise */ + gdouble CosGlat; /* data calc. in CalcEphem, used in MoonRise */ + + gdouble LAT; /* Local Apparent Time (sundial time) */ + gdouble LMT; /* Local Mean Time (eqn of time corrected LAT) */ + gdouble LST; /* Local Standard Time */ + gdouble LSD; /* Local Sidereal Time */ + /* end additional data */ +} CTrans; + + +void CalcEphem(glong date, gdouble UT, CTrans * c); +gdouble jd(gint ny, gint nm, gint nd, gdouble UT); +gdouble hour24(gdouble hour); +gdouble angle2pi(gdouble angle); + +#endif /* !CALC_EPHEM_H */ Index: panel-plugin/Makefile.am =================================================================== --- panel-plugin/Makefile.am (revision 4038) +++ panel-plugin/Makefile.am (working copy) @@ -31,7 +31,13 @@ weather-summary.c \ weather-summary.h \ weather-translate.c \ - weather-translate.h + weather-translate.h \ + CalcEphem.c \ + CalcEphem.h \ + Moon.c \ + Moon.h \ + MoonRise.c \ + MoonRise.h xfce4_weather_plugin_CFLAGS = \ $(LIBXFCE4PANEL_CFLAGS) \ Index: panel-plugin/weather-summary.c =================================================================== --- panel-plugin/weather-summary.c (revision 4038) +++ panel-plugin/weather-summary.c (working copy) @@ -31,8 +31,8 @@ #include "weather-translate.h" #include "weather-icon.h" +#include "CalcEphem.h" - #define BORDER 8 #define APPEND_BTEXT(text) gtk_text_buffer_insert_with_tags(GTK_TEXT_BUFFER(buffer),\ &iter, text, -1, btag, NULL); @@ -58,7 +58,7 @@ GtkTextBuffer *buffer; GtkTextIter iter; GtkTextTag *btag; - gchar *value, *date, *wind, *sun_val, *vis; + gchar *value, *date, *wind, *sun_val, *moon_val, *vis; GtkWidget *view, *frame, *scrolled; view = gtk_text_view_new (); @@ -149,6 +149,30 @@ g_free (sun_val); APPEND_TEXT_ITEM_REAL (value); + /* Moon */ + const gint size = 64; + gchar buf_rise[size]; + gchar buf_set[size]; + /* Read Lat/Lon values from weather data */ + gdouble lat = strtod (get_data (data, LAT), NULL); + gdouble lon = strtod (get_data (data, LON), NULL); + + /* Compute moon rise/set based on lat/lon and local time */ + get_moon_data(lat, lon, buf_rise, buf_set, size); + + APPEND_BTEXT (_("\nMoon\n")); + moon_val = translate_time (buf_rise); + value = g_strdup_printf ("\t%s: %s\n", + _("Rise"), moon_val ? moon_val : buf_rise); + g_free (moon_val); + APPEND_TEXT_ITEM_REAL (value); + + moon_val = translate_time (buf_set); + value = g_strdup_printf ("\t%s: %s\n", + _("Set"), moon_val ? moon_val : buf_set); + g_free (moon_val); + APPEND_TEXT_ITEM_REAL (value); + /* Other */ APPEND_BTEXT (_("\nOther\n")); APPEND_TEXT_ITEM (_("Humidity"), HMID); @@ -414,3 +438,63 @@ return window; } + + +void +get_moon_data(gdouble lat, gdouble lon, gchar *buf1, gchar *buf2, gint size) +{ + struct tm *time_struc; /* The tm struct is defined in */ + gdouble local_std_time, univ_time, eot; + glong current_gmt, date; + gint day_of_month, month, year; + + current_gmt = time(CurrentTime);/* CurrentTime defined in */ + + time_struc = gmtime(¤t_gmt); + univ_time = time_struc->tm_hour + time_struc->tm_min / 60.0 + + time_struc->tm_sec / 3600.0; + + /* The date needs to be the date in UTC, i.e. in greenwich, so + * be sure not to call the localtime function until after date + * has been set (there's only one tm structure). */ + year = time_struc->tm_year + 1900; + month = time_struc->tm_mon + 1; + day_of_month = time_struc->tm_mday; + + date = year * 10000 + month * 100 + day_of_month; + + time_struc = localtime(¤t_gmt); + local_std_time = time_struc->tm_hour + time_struc->tm_min / 60.0 + + time_struc->tm_sec / 3600.0; + + CTrans c; + c.Glat = lat; /* North: positive, South: negative */ + c.Glon = -lon; /* BEWARE!!! East: negative, West: positive! */ + c.LST = local_std_time; + + /* Fill CTrans struct with all kinds of calculated data */ + CalcEphem(date, univ_time, &c); + + /* Get Moon rise/set time */ + gdouble rise, set; + MoonRise(&c, &rise, &set); + + /* Format time a little bit */ + if (ABS(rise) > 24.0) + g_snprintf(buf1, size, _("no rise")); + else + g_snprintf(buf1, size, "%02d:%02d:%02d", + (gint)rise, /* hour */ + (gint)((ABS(rise - (gint)rise)) * 60), /* min */ + (gint)(ABS(ABS((rise - (gint)rise) * 60) - (gint)((ABS(rise - (gint)rise)) * 60)) * 60) /* sec */ + ); + + if (ABS(set) > 24.0) + g_snprintf(buf2, size, _("no set")); + else + g_snprintf(buf2, size, "%02d:%02d:%02d", + (gint)set, /* hour */ + (gint)((ABS(set - (gint)set)) * 60), /* min */ + (gint)(ABS(ABS((set - (gint)set) * 60) - (gint)((ABS(set - (gint)set)) * 60)) * 60) /* sec */ + ); +} Index: panel-plugin/MoonRise.c =================================================================== --- panel-plugin/MoonRise.c (revision 0) +++ panel-plugin/MoonRise.c (revision 0) @@ -0,0 +1,184 @@ +/* MoonRise.c + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + * + * Original (C) Mike Henderson . + * + * I've converted Mike Henderson's original file to glib types, + * removed unused variables, and piped the whole thing through indent. + * + * (C) 1999-2003 josh buhl + * + */ + +#include "Moon.h" +#include "MoonRise.h" + +static gint +Interp(gdouble ym, gdouble y0, gdouble yp, gdouble * xe, gdouble * ye, + gdouble * z1, gdouble * z2, gint * nz) +{ + gdouble a, b, c, d, dx; + + *nz = 0; + a = 0.5 * (ym + yp) - y0; + b = 0.5 * (yp - ym); + c = y0; + *xe = -b / (2.0 * a); + *ye = (a * (*xe) + b) * (*xe) + c; + d = b * b - 4.0 * a * c; + + if (d >= 0) { + dx = 0.5 * sqrt(d) / fabs(a); + *z1 = *xe - dx; + *z2 = *xe + dx; + if (fabs(*z1) <= 1.0) + *nz += 1; + if (fabs(*z2) <= 1.0) + *nz += 1; + if (*z1 < -1.0) + *z1 = *z2; + } + + return (0); +} + + +static gdouble +SinH(CTrans * c, gdouble UT) +{ + gdouble TU, TU2, TU3, LambdaMoon, BetaMoon, R, AGE, frac(), jd(); + gdouble RA_Moon, DEC_Moon, gmst, lmst, Tau, epsilon, Moon(); + gdouble angle2pi(); + + TU = (jd(c->year, c->month, c->day, UT) - 2451545.0) / 36525.0; + + /* this is more accurate, but expensive. */ + TU2 = TU * TU; + TU3 = TU2 * TU; + Moon(TU, &LambdaMoon, &BetaMoon, &R, &AGE); + LambdaMoon *= RadPerDeg; + BetaMoon *= RadPerDeg; + epsilon = + (23.43929167 - 0.013004166 * TU - 1.6666667e-7 * TU2 - + 5.0277777778e-7 * TU3) * RadPerDeg; + RA_Moon = + angle2pi(atan2 + (sin(LambdaMoon) * cos(epsilon) - + tan(BetaMoon) * sin(epsilon), cos(LambdaMoon))); + DEC_Moon = + asin(sin(BetaMoon) * cos(epsilon) + + cos(BetaMoon) * sin(epsilon) * sin(LambdaMoon)); + + + /* This is less accurate, but computationally less expensive */ +/* MiniMoon(TU, &RA_Moon, &DEC_Moon); */ +/* RA_Moon *= 15.0*RadPerDeg; */ +/* DEC_Moon *= RadPerDeg; */ + + /* + * Compute Greenwich Mean Sidereal Time (gmst) + */ + UT = 24.0 * frac(UT / 24.0); + /* this is for the ephemeris meridian??? + gmst = 6.697374558 + 1.0027379093*UT + (8640184.812866+(0.093104-6.2e-6*TU)*TU)*TU/3600.0; + */ + gmst = + UT + 6.697374558 + (8640184.812866 + + (0.093104 - + 6.2e-6 * TU) * TU) * TU / 3600.0; + lmst = 24.0 * frac((gmst - c->Glon / 15.0) / 24.0); + + Tau = 15.0 * lmst * RadPerDeg - RA_Moon; + + return (c->SinGlat * sin(DEC_Moon) + + c->CosGlat * cos(DEC_Moon) * cos(Tau)); +} + + +void +MoonRise(CTrans * c, gdouble * UTRise, gdouble * UTSet) +{ + + gdouble UT, ym, y0, yp, SinH0; + gdouble xe, ye, z1, z2; + gint Rise, Set, nz, TimeZone; + + SinH0 = sin(8.0 / 60.0 * RadPerDeg); + + /* report rise and set times in LST. */ + /* If you want to report in GMT, set TimeZone to 0 explicitly. */ + TimeZone = c->UT - c->LST; + + UT = 1.0 + TimeZone; + *UTRise = -999.0; + *UTSet = -999.0; + Rise = Set = 0; + + ym = SinH(c, UT - 1.0) - SinH0; + + while ((UT <= 24.0 + TimeZone)) { + + y0 = SinH(c, UT) - SinH0; + yp = SinH(c, UT + 1.0) - SinH0; + + Interp(ym, y0, yp, &xe, &ye, &z1, &z2, &nz); + + switch (nz) { + + case 0: + break; + case 1: + if (ym < 0.0) { + *UTRise = UT + z1; + Rise = 1; + } else { + *UTSet = UT + z1; + Set = 1; + } + break; + case 2: + if (ye < 0.0) { + *UTRise = UT + z2; + *UTSet = UT + z1; + } else { + *UTRise = UT + z1; + *UTSet = UT + z2; + } + Rise = 1; + Set = 1; + break; + } + ym = yp; + UT += 2.0; + } + + if (Rise) { + *UTRise -= TimeZone; + *UTRise = hour24(*UTRise); + } else { + *UTRise = -999.0; + } + + if (Set) { + *UTSet -= TimeZone; + *UTSet = hour24(*UTSet); + } else { + *UTSet = -999.0; + } + + return; +}