summaryrefslogtreecommitdiffstats
path: root/kworldwatch/sunclock.c
diff options
context:
space:
mode:
Diffstat (limited to 'kworldwatch/sunclock.c')
-rw-r--r--kworldwatch/sunclock.c164
1 files changed, 164 insertions, 0 deletions
diff --git a/kworldwatch/sunclock.c b/kworldwatch/sunclock.c
new file mode 100644
index 0000000..46058ac
--- /dev/null
+++ b/kworldwatch/sunclock.c
@@ -0,0 +1,164 @@
+/*
+ * Sun clock. X11 version by John Mackin.
+ *
+ * This program was derived from, and is still in part identical with, the
+ * Suntools Sun clock program whose author's comment appears immediately
+ * below. Please preserve both notices.
+ *
+ * The X11R3/4 version of this program was written by John Mackin, at the
+ * Basser Department of Computer Science, University of Sydney, Sydney,
+ * New South Wales, Australia; <john@cs.su.oz.AU>. This program, like
+ * the one it was derived from, is in the public domain: `Love is the
+ * law, love under will.'
+ */
+
+/*
+
+ Sun clock
+
+ Designed and implemented by John Walker in November of 1988.
+
+ Version for the Sun Workstation.
+
+ The algorithm used to calculate the position of the Sun is given in
+ Chapter 18 of:
+
+ "Astronomical Formulae for Calculators" by Jean Meeus, Third Edition,
+ Richmond: Willmann-Bell, 1985. This book can be obtained from:
+
+ Willmann-Bell
+ P.O. Box 35025
+ Richmond, VA 23235
+ USA
+ Phone: (804) 320-7016
+
+ This program was written by:
+
+ John Walker
+ Autodesk, Inc.
+ 2320 Marinship Way
+ Sausalito, CA 94965
+ USA
+ Fax: (415) 389-9418
+ Voice: (415) 332-2344 Ext. 2829
+ Usenet: {sun,well,uunet}!acad!kelvin
+ or: kelvin@acad.uu.net
+
+ modified for interactive maps by
+
+ Stephen Martin
+ Fujitsu Systems Business of Canada
+ smartin@fujitsu.ca
+
+ This program is in the public domain: "Do what thou wilt shall be the
+ whole of the law". I'd appreciate receiving any bug fixes and/or
+ enhancements, which I'll incorporate in future versions of the
+ program. Please leave the original attribution information intact so
+ that credit and blame may be properly apportioned.
+
+ Revision history:
+
+ 1.0 12/21/89 Initial version.
+ 8/24/89 Finally got around to submitting.
+
+ 1.1 8/31/94 Version with interactive map.
+ 1.2 10/12/94 Fixes for HP and Solaris, new icon bitmap
+ 1.3 11/01/94 Timezone now shown in icon
+ 1.4 03/29/98 Fixed city drawing, added icon animation
+
+*/
+
+#include "sunclock.h"
+
+void projillum(short *wtab, int xdots, int ydots, double dec);
+
+/* PROJILLUM -- Project illuminated area on the map. */
+
+void
+projillum(wtab, xdots, ydots, dec)
+short *wtab;
+int xdots, ydots;
+double dec;
+{
+ int i, ftf = 1, ilon, ilat, lilon = 0, lilat = 0, xt;
+ double m, x, y, z, th, lon, lat, s, c;
+
+ /* Clear unoccupied cells in width table */
+
+ for (i = 0; i < ydots; i++)
+ wtab[i] = -1;
+
+ /* Build transformation for declination */
+
+ s = sin(-dtr(dec));
+ c = cos(-dtr(dec));
+
+ /* Increment over a semicircle of illumination */
+
+ for (th = -(PI / 2); th <= PI / 2 + 0.001;
+ th += PI / TERMINC) {
+
+ /* Transform the point through the declination rotation. */
+
+ x = -s * sin(th);
+ y = cos(th);
+ z = c * sin(th);
+
+ /* Transform the resulting co-ordinate through the
+ map projection to obtain screen co-ordinates. */
+
+ lon = (y == 0 && x == 0) ? 0.0 : rtd(atan2(y, x));
+ lat = rtd(asin(z));
+
+ ilat = ydots - (lat + 90) * (ydots / 180.0);
+ ilon = lon * (xdots / 360.0);
+
+ if (ftf) {
+
+ /* First time. Just save start co-ordinate. */
+
+ lilon = ilon;
+ lilat = ilat;
+ ftf = 0;
+ } else {
+
+ /* Trace out the line and set the width table. */
+
+ if (lilat == ilat) {
+ wtab[(ydots - 1) - ilat] = ilon == 0 ? 1 : ilon;
+ } else {
+ m = ((double) (ilon - lilon)) / (ilat - lilat);
+ for (i = lilat; i != ilat; i += sgn(ilat - lilat)) {
+ xt = lilon + floor((m * (i - lilat)) + 0.5);
+ wtab[(ydots - 1) - i] = xt == 0 ? 1 : xt;
+ }
+ }
+ lilon = ilon;
+ lilat = ilat;
+ }
+ }
+
+ /* Now tweak the widths to generate full illumination for
+ the correct pole. */
+
+ if (dec < 0.0) {
+ ilat = ydots - 1;
+ lilat = -1;
+ } else {
+ ilat = 0;
+ lilat = 1;
+ }
+
+ for (i = ilat; i != ydots / 2; i += lilat) {
+ if (wtab[i] != -1) {
+ while (1) {
+ wtab[i] = xdots / 2;
+ if (i == ilat)
+ break;
+ i -= lilat;
+ }
+ break;
+ }
+ }
+}
+