[3ae31e9] | 1 | /*
|
---|
| 2 | ============================================================================
|
---|
| 3 | sun.c -- calculate sunrise, sunset, and position of the sun
|
---|
| 4 | Version 5 -- 1989-01-12 -- Robert Bond / D.N. Lynx Crowe
|
---|
| 5 |
|
---|
| 6 | sun <options>
|
---|
| 7 |
|
---|
| 8 | options: -t hh:mm:ss time (default is current system time)
|
---|
| 9 | -d mm/dd/yy date (default is current system date)
|
---|
| 10 | -a lat decimal latitude (default = 45.5333)
|
---|
| 11 | -o lon decimal longitude (default = 122.8333)
|
---|
| 12 | -z tz timezone (default = 8, pst)
|
---|
| 13 | -p show position of sun (azimuth)
|
---|
| 14 |
|
---|
| 15 | All output is to standard io.
|
---|
| 16 |
|
---|
| 17 | Compile with cc -O -o sun -lm
|
---|
| 18 |
|
---|
| 19 | Define BSD for BSD4.2 systems. System V assumed otherwise.
|
---|
| 20 | This selects between <sys/time.h> and <time.h> below.
|
---|
| 21 |
|
---|
| 22 | Note that the latitude, longitude, time zone correction and
|
---|
| 23 | time zone string are all defaulted in the global variable section.
|
---|
| 24 | The default is for Oakland, CA.
|
---|
| 25 |
|
---|
| 26 | Most of the code in this program is adapted from algorithms
|
---|
| 27 | presented in "Practical Astronomy With Your Calculator" by
|
---|
| 28 | Peter Duffet-Smith.
|
---|
| 29 |
|
---|
| 30 | The GST and ALT-AZIMUTH algorithms are from Sky and Telescope,
|
---|
| 31 | June, 1984 by Roger W. Sinnott
|
---|
| 32 |
|
---|
| 33 | Original author: Robert Bond - Beaverton, Oregon.
|
---|
| 34 | Mods by: D.N. Lynx Crowe - Oakland, California.
|
---|
| 35 | ============================================================================
|
---|
| 36 | */
|
---|
| 37 |
|
---|
| 38 | #include "stdio.h"
|
---|
| 39 | #include "math.h"
|
---|
| 40 | #include "types.h"
|
---|
| 41 |
|
---|
| 42 | #ifdef BSD
|
---|
| 43 | #include <sys/time.h>
|
---|
| 44 | #else
|
---|
| 45 | #include "time.h"
|
---|
| 46 | #endif
|
---|
| 47 |
|
---|
| 48 | #ifndef PI
|
---|
| 49 | #define PI 3.141592654
|
---|
| 50 | #endif
|
---|
| 51 |
|
---|
| 52 | #define EPOCH 1980
|
---|
| 53 | #define JDE 2444238.5 /* Julian date of EPOCH */
|
---|
| 54 |
|
---|
| 55 | double dtor();
|
---|
| 56 | double adj360();
|
---|
| 57 | double adj24();
|
---|
| 58 | double julian_date();
|
---|
| 59 | double hms_to_dh();
|
---|
| 60 | double solar_lon();
|
---|
| 61 | double acos_deg();
|
---|
| 62 | double asin_deg();
|
---|
| 63 | double atan_q_deg();
|
---|
| 64 | double atan_deg();
|
---|
| 65 | double sin_deg();
|
---|
| 66 | double cos_deg();
|
---|
| 67 | double tan_deg();
|
---|
| 68 | double gmst();
|
---|
| 69 |
|
---|
| 70 | int th;
|
---|
| 71 | int tm;
|
---|
| 72 | int ts;
|
---|
| 73 | int mo;
|
---|
| 74 | int day;
|
---|
| 75 | int yr;
|
---|
| 76 | int popt = 0;
|
---|
| 77 |
|
---|
| 78 | int tz=8; /* Default time zone */
|
---|
| 79 | char *tzs = "(PST)"; /* Default time zone string */
|
---|
| 80 | char *dtzs = "(PDT)"; /* Default daylight savings time string */
|
---|
| 81 |
|
---|
| 82 | /* double lat = 45.5333; /* Default latitude (Beaverton Ore.) */
|
---|
| 83 | /* double lon = 122.8333; /* Default Longitude (Degrees west) */
|
---|
| 84 |
|
---|
| 85 | double lat = 37.75; /* Default latitude (Oakland, CA) */
|
---|
| 86 | double lon = 122.25; /* Default longitude (degrees west) */
|
---|
| 87 |
|
---|
| 88 | /* |
---|
| 89 |
|
---|
| 90 | */
|
---|
| 91 |
|
---|
| 92 | main(argc,argv)
|
---|
| 93 | int argc;
|
---|
| 94 | char *argv[];
|
---|
| 95 | {
|
---|
| 96 | double ed, jd;
|
---|
| 97 | double alpha1, delta1, alpha2, delta2, st1r, st1s, st2r, st2s;
|
---|
| 98 | double a1r, a1s, a2r, a2s, dt, dh, x, y;
|
---|
| 99 | double trise, tset, ar, as, alpha, delta, tri, da;
|
---|
| 100 | double lambda1, lambda2;
|
---|
| 101 | double alt, az, gst, m1;
|
---|
| 102 | double hsm, ratio;
|
---|
| 103 | time_t sec_1970;
|
---|
| 104 | int h, m;
|
---|
| 105 | struct tm *pt;
|
---|
| 106 |
|
---|
| 107 | sec_1970 = time((time_t *)0);
|
---|
| 108 | pt = localtime(&sec_1970);
|
---|
| 109 |
|
---|
| 110 | th = pt->tm_hour;
|
---|
| 111 | tm = pt->tm_min;
|
---|
| 112 | ts = pt->tm_sec;
|
---|
| 113 | yr = pt->tm_year + 1900;
|
---|
| 114 | mo = pt->tm_mon + 1;
|
---|
| 115 | day = pt->tm_mday;
|
---|
| 116 |
|
---|
| 117 | if (pt->tm_isdst) { /* convert tz to daylight savings time */
|
---|
| 118 |
|
---|
| 119 | tz--;
|
---|
| 120 | tzs = dtzs;
|
---|
| 121 | }
|
---|
| 122 |
|
---|
| 123 | initopts(argc,argv);
|
---|
| 124 |
|
---|
| 125 | printf("On %04d-%02d-%02d at %02d:%02d:%02d\n",
|
---|
| 126 | yr, mo, day, th, tm, ts);
|
---|
| 127 |
|
---|
| 128 | jd = julian_date(mo,day,yr);
|
---|
| 129 | ed = jd - JDE;
|
---|
| 130 |
|
---|
| 131 | lambda1 = solar_lon(ed);
|
---|
| 132 | lambda2 = solar_lon(ed + 1.0);
|
---|
| 133 |
|
---|
| 134 | lon_to_eq(lambda1, &alpha1, &delta1);
|
---|
| 135 | lon_to_eq(lambda2, &alpha2, &delta2);
|
---|
| 136 |
|
---|
| 137 | rise_set(alpha1, delta1, &st1r, &st1s, &a1r, &a1s);
|
---|
| 138 | rise_set(alpha2, delta2, &st2r, &st2s, &a2r, &a2s);
|
---|
| 139 |
|
---|
| 140 | m1 = adj24(gmst(jd - 0.5, 0.5 + tz / 24.0) - lon / 15); /* lst midnight */
|
---|
| 141 | hsm = adj24(st1r - m1);
|
---|
| 142 | ratio = hsm / 24.07;
|
---|
| 143 |
|
---|
| 144 | if (fabs(st2r - st1r) > 1.0) {
|
---|
| 145 |
|
---|
| 146 | st2r += 24.0;
|
---|
| 147 | }
|
---|
| 148 |
|
---|
| 149 | trise = adj24((1.0 - ratio) * st1r + ratio * st2r);
|
---|
| 150 |
|
---|
| 151 | hsm = adj24(st1s - m1);
|
---|
| 152 | ratio = hsm / 24.07;
|
---|
| 153 |
|
---|
| 154 | if (fabs(st2s - st1s) > 1.0) {
|
---|
| 155 |
|
---|
| 156 | st2s += 24.0;
|
---|
| 157 | }
|
---|
| 158 |
|
---|
| 159 | tset = adj24((1.0 - ratio) * st1s + ratio * st2s);
|
---|
| 160 |
|
---|
| 161 | ar = a1r * 360.0 / (360.0 + a1r - a2r);
|
---|
| 162 | as = a1s * 360.0 / (360.0 + a1s - a2s);
|
---|
| 163 |
|
---|
| 164 | delta = (delta1 + delta2) / 2.0;
|
---|
| 165 | tri = acos_deg(sin_deg(lat)/cos_deg(delta));
|
---|
| 166 |
|
---|
| 167 | x = 0.835608; /* correction for refraction, parallax, size of sun */
|
---|
| 168 | y = asin_deg(sin_deg(x)/sin_deg(tri));
|
---|
| 169 | da = asin_deg(tan_deg(x)/tan_deg(tri));
|
---|
| 170 | dt = 240.0 * y / cos_deg(delta) / 3600;
|
---|
| 171 |
|
---|
| 172 | lst_to_hm(trise - dt, jd, &h, &m);
|
---|
| 173 | printf("Sunrise: %2d:%02d ", h, m);
|
---|
| 174 |
|
---|
| 175 | if (popt) {
|
---|
| 176 |
|
---|
| 177 | dh_to_hm(ar - da, &h, &m);
|
---|
| 178 | printf("Azimuth: %2d deg %02d min \n", h, m);
|
---|
| 179 | }
|
---|
| 180 |
|
---|
| 181 | lst_to_hm(tset + dt, jd, &h, &m);
|
---|
| 182 | printf("Sunset: %2d:%02d ", h, m);
|
---|
| 183 |
|
---|
| 184 | if (popt) {
|
---|
| 185 |
|
---|
| 186 | dh_to_hm(as + da, &h, &m);
|
---|
| 187 | printf("Azimuth: %2d deg %02d min \n", h, m);
|
---|
| 188 |
|
---|
| 189 | } else
|
---|
| 190 | printf("%s \n",tzs);
|
---|
| 191 |
|
---|
| 192 | if (popt) {
|
---|
| 193 |
|
---|
| 194 | if (alpha1 < alpha2)
|
---|
| 195 | alpha = (alpha1 + alpha2) / 2.0;
|
---|
| 196 | else
|
---|
| 197 | alpha = (alpha1 + 24.0 + alpha2) / 2.0;
|
---|
| 198 |
|
---|
| 199 | if (alpha > 24.0)
|
---|
| 200 | alpha -= 24.0;
|
---|
| 201 |
|
---|
| 202 | dh = (hms_to_dh(th, tm, ts) + tz) / 24.0;
|
---|
| 203 |
|
---|
| 204 | if (dh > 0.5) {
|
---|
| 205 |
|
---|
| 206 | dh -= 0.5;
|
---|
| 207 | jd += 0.5;
|
---|
| 208 |
|
---|
| 209 | } else {
|
---|
| 210 |
|
---|
| 211 | dh += 0.5;
|
---|
| 212 | jd -= 0.5;
|
---|
| 213 | }
|
---|
| 214 |
|
---|
| 215 | gst = gmst(jd, dh);
|
---|
| 216 |
|
---|
| 217 | eq_to_altaz(alpha, delta, gst, &alt, &az);
|
---|
| 218 |
|
---|
| 219 | printf("The sun is at ");
|
---|
| 220 | dh_to_hm(alt, &h, &m);
|
---|
| 221 | printf("Altitude: %2d deg %02d min", h, m);
|
---|
| 222 | dh_to_hm(az, &h, &m);
|
---|
| 223 | printf(" Azimuth: %2d deg %02d min. \n", h, m);
|
---|
| 224 | }
|
---|
| 225 | }
|
---|
| 226 |
|
---|
| 227 | /* |
---|
| 228 |
|
---|
| 229 | */
|
---|
| 230 |
|
---|
| 231 | double
|
---|
| 232 | dtor(deg)
|
---|
| 233 | double deg;
|
---|
| 234 | {
|
---|
| 235 | return (deg * PI / 180.0);
|
---|
| 236 | }
|
---|
| 237 |
|
---|
| 238 | double
|
---|
| 239 | rtod(deg)
|
---|
| 240 | double deg;
|
---|
| 241 | {
|
---|
| 242 | return (deg * 180.0 / PI);
|
---|
| 243 | }
|
---|
| 244 |
|
---|
| 245 |
|
---|
| 246 | double
|
---|
| 247 | adj360(deg)
|
---|
| 248 | double deg;
|
---|
| 249 | {
|
---|
| 250 | while (deg < 0.0)
|
---|
| 251 | deg += 360.0;
|
---|
| 252 |
|
---|
| 253 | while (deg > 360.0)
|
---|
| 254 | deg -= 360.0;
|
---|
| 255 |
|
---|
| 256 | return(deg);
|
---|
| 257 | }
|
---|
| 258 |
|
---|
| 259 | double
|
---|
| 260 | adj24(hrs)
|
---|
| 261 | double hrs;
|
---|
| 262 | {
|
---|
| 263 | while (hrs < 0.0)
|
---|
| 264 | hrs += 24.0;
|
---|
| 265 |
|
---|
| 266 | while (hrs > 24.0)
|
---|
| 267 | hrs -= 24.0;
|
---|
| 268 |
|
---|
| 269 | return(hrs);
|
---|
| 270 | }
|
---|
| 271 |
|
---|
| 272 | /* |
---|
| 273 |
|
---|
| 274 | */
|
---|
| 275 |
|
---|
| 276 | initopts(argc,argv)
|
---|
| 277 | int argc;
|
---|
| 278 | char *argv[];
|
---|
| 279 | {
|
---|
| 280 | int ai;
|
---|
| 281 | char *ca;
|
---|
| 282 | char *str;
|
---|
| 283 |
|
---|
| 284 | while (--argc) {
|
---|
| 285 |
|
---|
| 286 | if ((*++argv)[0] == '-') {
|
---|
| 287 |
|
---|
| 288 | ca = *argv;
|
---|
| 289 |
|
---|
| 290 | for(ai = 1; ca[ai] != '\0'; ai++)
|
---|
| 291 | switch (ca[ai]) {
|
---|
| 292 |
|
---|
| 293 | case 'p':
|
---|
| 294 | popt++;
|
---|
| 295 | break;
|
---|
| 296 |
|
---|
| 297 | case 'a':
|
---|
| 298 | str = *++argv;
|
---|
| 299 |
|
---|
| 300 | if (sscanf(str, "%lf", &lat) != 1)
|
---|
| 301 | usage();
|
---|
| 302 |
|
---|
| 303 | argc--;
|
---|
| 304 | break;
|
---|
| 305 |
|
---|
| 306 | case 'o':
|
---|
| 307 | str = *++argv;
|
---|
| 308 |
|
---|
| 309 | if (sscanf(str, "%lf", &lon) != 1)
|
---|
| 310 | usage();
|
---|
| 311 |
|
---|
| 312 | argc--;
|
---|
| 313 | break;
|
---|
| 314 |
|
---|
| 315 | case 'z':
|
---|
| 316 | str = *++argv;
|
---|
| 317 |
|
---|
| 318 | if (sscanf(str, "%d", &tz) != 1)
|
---|
| 319 | usage();
|
---|
| 320 |
|
---|
| 321 | tzs = " ";
|
---|
| 322 | argc--;
|
---|
| 323 | break;
|
---|
| 324 |
|
---|
| 325 | case 't':
|
---|
| 326 | str = *++argv;
|
---|
| 327 |
|
---|
| 328 | if (sscanf(str, "%d:%d:%d", &th, &tm, &ts) != 3)
|
---|
| 329 | usage();
|
---|
| 330 |
|
---|
| 331 | argc--;
|
---|
| 332 | break;
|
---|
| 333 |
|
---|
| 334 | case 'd':
|
---|
| 335 | str = *++argv;
|
---|
| 336 |
|
---|
| 337 | if (sscanf(str, "%d/%d/%d", &mo, &day, &yr) != 3)
|
---|
| 338 | usage();
|
---|
| 339 |
|
---|
| 340 | argc--;
|
---|
| 341 | break;
|
---|
| 342 |
|
---|
| 343 | default:
|
---|
| 344 | usage();
|
---|
| 345 | }
|
---|
| 346 |
|
---|
| 347 | } else
|
---|
| 348 | usage();
|
---|
| 349 | }
|
---|
| 350 | }
|
---|
| 351 |
|
---|
| 352 | /* |
---|
| 353 |
|
---|
| 354 | */
|
---|
| 355 |
|
---|
| 356 | usage()
|
---|
| 357 | {
|
---|
| 358 | printf("Usage: sun [-p] [-t h:m:s] [-d m/d/y] [-a lat] [-o lon] [-z tz]\n");
|
---|
| 359 |
|
---|
| 360 | printf("-p\t\tshow position of sun (azimuth)\n");
|
---|
| 361 | printf("-t hh:mm:ss\ttime (default is current system time)\n");
|
---|
| 362 | printf("-d mm/dd/yy\tdate (default is current system date)\n");
|
---|
| 363 | printf("-a lat\t\tdecimal latitude (default = 37.75)\n");
|
---|
| 364 | printf("-o lon\t\tdecimal longitude (default = 122.25) \n");
|
---|
| 365 | printf("-z tz\t\ttimezone (default = 8, pst)\n");
|
---|
| 366 | printf("\nDefaults are for Oakland, CA\n");
|
---|
| 367 | exit(1);
|
---|
| 368 | }
|
---|
| 369 |
|
---|
| 370 | /* |
---|
| 371 |
|
---|
| 372 | */
|
---|
| 373 |
|
---|
| 374 | double
|
---|
| 375 | julian_date(m, d, y)
|
---|
| 376 | {
|
---|
| 377 | int a, b;
|
---|
| 378 | double jd;
|
---|
| 379 |
|
---|
| 380 | if (m == 1 || m == 2) {
|
---|
| 381 |
|
---|
| 382 | --y;
|
---|
| 383 | m += 12;
|
---|
| 384 | }
|
---|
| 385 |
|
---|
| 386 | if (y < 1583) {
|
---|
| 387 |
|
---|
| 388 | printf("Can't handle dates before 1583 \n");
|
---|
| 389 | exit(1);
|
---|
| 390 | }
|
---|
| 391 |
|
---|
| 392 | a = y/100;
|
---|
| 393 | b = 2 - a + a/4;
|
---|
| 394 | b += (int)((double)y * 365.25);
|
---|
| 395 | b += (int)(30.6001 * ((double)m + 1.0));
|
---|
| 396 | jd = (double)d + (double)b + 1720994.5;
|
---|
| 397 | return(jd);
|
---|
| 398 | }
|
---|
| 399 |
|
---|
| 400 | double
|
---|
| 401 | hms_to_dh(h, m, s)
|
---|
| 402 | {
|
---|
| 403 | double rv;
|
---|
| 404 |
|
---|
| 405 | rv = h + m / 60.0 + s / 3600.0;
|
---|
| 406 | return rv;
|
---|
| 407 | }
|
---|
| 408 |
|
---|
| 409 | /* |
---|
| 410 |
|
---|
| 411 | */
|
---|
| 412 |
|
---|
| 413 | double
|
---|
| 414 | solar_lon(ed)
|
---|
| 415 | double ed;
|
---|
| 416 | {
|
---|
| 417 | double n, m, e, ect, errt, v;
|
---|
| 418 |
|
---|
| 419 | n = 360.0 * ed / 365.2422;
|
---|
| 420 | n = adj360(n);
|
---|
| 421 | m = n + 278.83354 - 282.596403;
|
---|
| 422 | m = adj360(m);
|
---|
| 423 | m = dtor(m);
|
---|
| 424 | e = m; ect = 0.016718;
|
---|
| 425 |
|
---|
| 426 | while ((errt = e - ect * sin(e) - m) > 0.0000001)
|
---|
| 427 | e = e - errt / (1 - ect * cos(e));
|
---|
| 428 |
|
---|
| 429 | v = 2 * atan(1.0168601 * tan(e/2));
|
---|
| 430 | v = adj360(v * 180.0 / PI + 282.596403);
|
---|
| 431 | return(v);
|
---|
| 432 | }
|
---|
| 433 |
|
---|
| 434 | /* |
---|
| 435 |
|
---|
| 436 | */
|
---|
| 437 |
|
---|
| 438 | double
|
---|
| 439 | acos_deg(x)
|
---|
| 440 | double x;
|
---|
| 441 | {
|
---|
| 442 | return rtod(acos(x));
|
---|
| 443 | }
|
---|
| 444 |
|
---|
| 445 | double
|
---|
| 446 | asin_deg(x)
|
---|
| 447 | double x;
|
---|
| 448 | {
|
---|
| 449 | return rtod(asin(x));
|
---|
| 450 | }
|
---|
| 451 |
|
---|
| 452 | double
|
---|
| 453 | atan_q_deg(y,x)
|
---|
| 454 | double y,x;
|
---|
| 455 | {
|
---|
| 456 | double rv;
|
---|
| 457 |
|
---|
| 458 | if (y == 0)
|
---|
| 459 | rv = 0;
|
---|
| 460 | else if (x == 0)
|
---|
| 461 | rv = y>0 ? 90.0 : -90.0;
|
---|
| 462 | else
|
---|
| 463 | rv = atan_deg(y/x);
|
---|
| 464 |
|
---|
| 465 | if (x<0)
|
---|
| 466 | return rv+180.0;
|
---|
| 467 |
|
---|
| 468 | if (y<0)
|
---|
| 469 | return rv+360.0;
|
---|
| 470 |
|
---|
| 471 | return(rv);
|
---|
| 472 | }
|
---|
| 473 |
|
---|
| 474 | /* |
---|
| 475 |
|
---|
| 476 | */
|
---|
| 477 |
|
---|
| 478 | double
|
---|
| 479 | atan_deg(x)
|
---|
| 480 | double x;
|
---|
| 481 | {
|
---|
| 482 | return rtod(atan(x));
|
---|
| 483 | }
|
---|
| 484 |
|
---|
| 485 | double
|
---|
| 486 | sin_deg(x)
|
---|
| 487 | double x;
|
---|
| 488 | {
|
---|
| 489 | return sin(dtor(x));
|
---|
| 490 | }
|
---|
| 491 |
|
---|
| 492 | double
|
---|
| 493 | cos_deg(x)
|
---|
| 494 | double x;
|
---|
| 495 | {
|
---|
| 496 | return cos(dtor(x));
|
---|
| 497 | }
|
---|
| 498 |
|
---|
| 499 | double
|
---|
| 500 | tan_deg(x)
|
---|
| 501 | double x;
|
---|
| 502 | {
|
---|
| 503 | return tan(dtor(x));
|
---|
| 504 | }
|
---|
| 505 |
|
---|
| 506 | /* |
---|
| 507 |
|
---|
| 508 | */
|
---|
| 509 |
|
---|
| 510 | lon_to_eq(lambda, alpha, delta)
|
---|
| 511 | double lambda;
|
---|
| 512 | double *alpha;
|
---|
| 513 | double *delta;
|
---|
| 514 | {
|
---|
| 515 | double tlam,epsilon;
|
---|
| 516 |
|
---|
| 517 | tlam = dtor(lambda);
|
---|
| 518 | epsilon = dtor((double)23.441884);
|
---|
| 519 | *alpha = atan_q_deg((sin(tlam))*cos(epsilon),cos(tlam)) / 15.0;
|
---|
| 520 | *delta = asin_deg(sin(epsilon)*sin(tlam));
|
---|
| 521 | }
|
---|
| 522 |
|
---|
| 523 | rise_set(alpha, delta, lstr, lsts, ar, as)
|
---|
| 524 | double alpha, delta, *lstr, *lsts, *ar, *as;
|
---|
| 525 | {
|
---|
| 526 | double tar;
|
---|
| 527 | double h;
|
---|
| 528 |
|
---|
| 529 | tar = sin_deg(delta)/cos_deg(lat);
|
---|
| 530 |
|
---|
| 531 | if (tar < -1.0 || tar > 1.0) {
|
---|
| 532 |
|
---|
| 533 | printf("The object is circumpolar \n");
|
---|
| 534 | exit (1);
|
---|
| 535 | }
|
---|
| 536 |
|
---|
| 537 | *ar = acos_deg(tar);
|
---|
| 538 | *as = 360.0 - *ar;
|
---|
| 539 |
|
---|
| 540 | h = acos_deg(-tan_deg(lat) * tan_deg(delta)) / 15.0;
|
---|
| 541 | *lstr = 24.0 + alpha - h;
|
---|
| 542 |
|
---|
| 543 | if (*lstr > 24.0)
|
---|
| 544 | *lstr -= 24.0;
|
---|
| 545 |
|
---|
| 546 | *lsts = alpha + h;
|
---|
| 547 |
|
---|
| 548 | if (*lsts > 24.0)
|
---|
| 549 | *lsts -= 24.0;
|
---|
| 550 | }
|
---|
| 551 |
|
---|
| 552 | /* |
---|
| 553 |
|
---|
| 554 | */
|
---|
| 555 |
|
---|
| 556 | lst_to_hm(lst, jd, h, m)
|
---|
| 557 | double lst, jd;
|
---|
| 558 | int *h, *m;
|
---|
| 559 | {
|
---|
| 560 | double ed, gst, jzjd, t, r, b, t0, gmt;
|
---|
| 561 |
|
---|
| 562 | gst = lst + lon / 15.0;
|
---|
| 563 |
|
---|
| 564 | if (gst > 24.0)
|
---|
| 565 | gst -= 24.0;
|
---|
| 566 |
|
---|
| 567 | jzjd = julian_date(1,0,yr);
|
---|
| 568 | ed = jd-jzjd;
|
---|
| 569 | t = (jzjd -2415020.0)/36525.0;
|
---|
| 570 | r = 6.6460656+2400.05126*t+2.58E-05*t*t;
|
---|
| 571 | b = 24-(r-24*(yr-1900));
|
---|
| 572 | t0 = ed * 0.0657098 - b;
|
---|
| 573 |
|
---|
| 574 | if (t0 < 0.0)
|
---|
| 575 | t0 += 24;
|
---|
| 576 |
|
---|
| 577 | gmt = gst-t0;
|
---|
| 578 |
|
---|
| 579 | if (gmt<0)
|
---|
| 580 | gmt += 24.0;
|
---|
| 581 |
|
---|
| 582 | gmt = gmt * 0.99727 - tz;;
|
---|
| 583 |
|
---|
| 584 | if (gmt < 0)
|
---|
| 585 | gmt +=24.0;
|
---|
| 586 |
|
---|
| 587 | dh_to_hm(gmt, h, m);
|
---|
| 588 | }
|
---|
| 589 |
|
---|
| 590 | /* |
---|
| 591 |
|
---|
| 592 | */
|
---|
| 593 |
|
---|
| 594 | dh_to_hm(dh, h, m)
|
---|
| 595 | double dh;
|
---|
| 596 | int *h, *m;
|
---|
| 597 | {
|
---|
| 598 | double tempsec;
|
---|
| 599 |
|
---|
| 600 | *h = dh;
|
---|
| 601 | *m = (dh - *h) * 60;
|
---|
| 602 | tempsec = (dh - *h) * 60 - *m;
|
---|
| 603 | tempsec = tempsec * 60 + 0.5;
|
---|
| 604 |
|
---|
| 605 | if (tempsec > 30)
|
---|
| 606 | (*m)++;
|
---|
| 607 |
|
---|
| 608 | if (*m == 60) {
|
---|
| 609 |
|
---|
| 610 | *m = 0;
|
---|
| 611 | (*h)++;
|
---|
| 612 | }
|
---|
| 613 | }
|
---|
| 614 |
|
---|
| 615 | /* |
---|
| 616 |
|
---|
| 617 | */
|
---|
| 618 |
|
---|
| 619 | eq_to_altaz(r, d, t, alt, az)
|
---|
| 620 | double r, d, t;
|
---|
| 621 | double *alt, *az;
|
---|
| 622 | {
|
---|
| 623 | double p = 3.14159265;
|
---|
| 624 | double r1 = p / 180.0;
|
---|
| 625 | double b = lat * r1;
|
---|
| 626 | double l = (360 - lon) * r1;
|
---|
| 627 | double t5, s1, c1, c2, s2, a, h;
|
---|
| 628 |
|
---|
| 629 | r = r * 15.0 * r1;
|
---|
| 630 | d = d * r1;
|
---|
| 631 | t = t * 15.0 * r1;
|
---|
| 632 | t5 = t - r + l;
|
---|
| 633 | s1 = sin(b) * sin(d) + cos(b) * cos(d) * cos(t5);
|
---|
| 634 | c1 = 1 - s1 * s1;
|
---|
| 635 |
|
---|
| 636 | if (c1 > 0) {
|
---|
| 637 |
|
---|
| 638 | c1 = sqrt(c1);
|
---|
| 639 | h = atan(s1 / c1);
|
---|
| 640 |
|
---|
| 641 | } else {
|
---|
| 642 |
|
---|
| 643 | h = (s1 / fabs(s1)) * (p / 2.0);
|
---|
| 644 | }
|
---|
| 645 |
|
---|
| 646 | c2 = cos(b) * sin(d) - sin(b) * cos(d) * cos(t5);
|
---|
| 647 | s2 = -cos(d) * sin(t5);
|
---|
| 648 |
|
---|
| 649 | if (c2 == 0)
|
---|
| 650 | a = (s2/fabs(s2)) * (p/2);
|
---|
| 651 | else {
|
---|
| 652 |
|
---|
| 653 | a = atan(s2/c2);
|
---|
| 654 |
|
---|
| 655 | if (c2 < 0)
|
---|
| 656 | a=a+p;
|
---|
| 657 | }
|
---|
| 658 |
|
---|
| 659 | if (a<0)
|
---|
| 660 | a=a+2*p;
|
---|
| 661 |
|
---|
| 662 | *alt = h / r1;
|
---|
| 663 | *az = a / r1;
|
---|
| 664 | }
|
---|
| 665 |
|
---|
| 666 | /* |
---|
| 667 |
|
---|
| 668 | */
|
---|
| 669 |
|
---|
| 670 | double
|
---|
| 671 | gmst(j, f)
|
---|
| 672 | double j,f;
|
---|
| 673 | {
|
---|
| 674 | double d, j0, t, t1, t2, s;
|
---|
| 675 |
|
---|
| 676 | d = j - 2451545.0;
|
---|
| 677 | t = d / 36525.0;
|
---|
| 678 | t1 = floor(t);
|
---|
| 679 | j0 = t1 * 36525.0 + 2451545.0;
|
---|
| 680 | t2 = (j - j0 + 0.5)/36525.0;
|
---|
| 681 | s = 24110.54841 + 184.812866 * t1;
|
---|
| 682 | s += 8640184.812866 * t2;
|
---|
| 683 | s += 0.093104 * t * t;
|
---|
| 684 | s -= 0.0000062 * t * t * t;
|
---|
| 685 | s /= 86400.0;
|
---|
| 686 | s -= floor(s);
|
---|
| 687 | s = 24 * (s + (f - 0.5) * 1.002737909);
|
---|
| 688 |
|
---|
| 689 | if (s < 0)
|
---|
| 690 | s += 24.0;
|
---|
| 691 |
|
---|
| 692 | if (s > 24.0)
|
---|
| 693 | s -= 24.0;
|
---|
| 694 |
|
---|
| 695 | return(s);
|
---|
| 696 | }
|
---|