59 double EclSolar::atan23 (
double y,
double x)
64 if ((x == 0) && (y == 0)) result = 0;
65 else result = atan2 (y, x);
70 void EclSolar::esinit()
73 eb_start_called =
false;
74 eb_moonph_called =
false;
77 eb_local_called =
false;
98 eb_lastdlt = eb_del_tdut;
106 void EclSolar::DefTime ()
113 jd = 40587.0 + tt/86400.0;
115 caldat(jd, hh, mm, ss, hr);
124 if (eb_del_auto) eb_del_tdut =
DefTdUt(eb_year);
134 eb_start_called =
false;
135 eb_moonph_called =
false;
136 eb_local_called =
false;
137 eb_lunactive =
false;
140 if (eb_del_auto) eb_del_tdut =
DefTdUt(eb_year);
151 if (!eb_moonph_called) moonph();
153 if (eb_lunecl)
return eb_numecl;
156 for (j=0; j<eb_numecl; j++)
158 if (eb_phase[j] > 0) k++;
166 if (lecl) eb_lunecl =
true;
167 else eb_lunecl =
false;
168 eb_start_called =
false;
169 eb_local_called =
false;
175 if (s < 0.01) eb_cstep = 0.01;
191 eb_del_tdut = d + 32.184;
199 eb_del_tdut =
DefTdUt(eb_year);
212 eb_local_called =
false;
222 if (!eb_local_called) getLocalDetails(wbuf);
238 if (!eb_local_called) getLocalDetails(wbuf);
243 if(eb_lccnt == 0)
return 0;
248 for (j=0; j<eb_nphase; j++)
250 if ((k==0) && (eb_spp[j] > 3))
252 mjd_start = eb_spt[j];
253 mjd_stop = eb_ept[j];
258 if(mjd_start < eb_lcb1) mjd_start = eb_lcb1;
259 if(mjd_start > eb_lce1) k = 0;
260 if(mjd_stop > eb_lce1) mjd_stop = eb_lce1;
261 if(mjd_stop < eb_lcb1) k = 0;
263 eb_ltotb = mjd_start;
269 mjd_start = eb_ltotb;
290 if (eb_lunactive)
return 0;
292 k = getLocalVisibility(mjdmax, magmax);
311 if (!eb_start_called) eclStart();
316 if (!eb_lunactive)
return 0;
318 if (eb_nphase <= 0)
return 0;
321 for (j=0; j<eb_nphase; j++)
325 mjd_start = eb_spt[j];
341 if (!eb_start_called) eclStart();
346 if (eb_nphase <= 0)
return 0;
352 for (j=0; j<eb_nphase; j++)
354 if ((k==0) && (eb_spp[j] == 3))
356 mjd_start = eb_spt[j];
364 for (j=0; j<eb_nphase; j++)
366 if ((k==0) && (eb_spp[j] == 1))
368 mjd_start = eb_spt[j];
386 if (!eb_start_called) eclStart();
391 if (eb_nphase <= 0)
return 0;
397 for (j=0; j<eb_nphase; j++)
399 if ((k==0) && (eb_spp[j] > 3))
401 mjd_start = eb_spt[j];
409 for (j=0; j<eb_nphase; j++)
411 if ((k==0) && (eb_spp[j] > 1))
413 mjd_start = eb_spt[j];
431 jd =
ddd(hour, min, sec) - eb_tzone;
432 jd =
mjd(day, month, year, jd);
445 caldat((mjd + eb_tzone/24.0), day, month, year, magn);
446 dms (magn,hour,min,sec);
447 if (sec>30.0) min++;;
467 if (!eb_moonph_called) moonph();
469 sprintf(wbuf,
"Solar Eclipses for %4i UTC +%4.1f", eb_year, eb_tzone);
472 for (j=0; j<eb_numecl; j++)
474 sprintf(dts,
"%1i : ", kecl);
476 dtmstr((eb_eclmjd[j] + eb_tzone/24.0),dts);
483 case 1: strcat(outbuf,
"\t Partial Sun");
484 sprintf(magbuf,
" (magnitude:%5.2f)",eb_magnitude[j]);
485 strcat(outbuf,magbuf);
488 case 2: strcat(outbuf,
"\t non-central Annular Sun");
490 case 4: strcat(outbuf,
"\t Annular Sun");
493 case 3: strcat(outbuf,
"\t non-central Total Sun");
495 case 5: strcat(outbuf,
"\t Total Sun");
498 case 6: strcat(outbuf,
"\t Annular/Total Sun");
502 case -2: strcat(outbuf,
"\t Penumbral Moon");
503 sprintf(magbuf,
" (magnitude:%5.2f)",eb_magnitude[j]);
504 strcat(outbuf,magbuf);
507 case -3: strcat(outbuf,
"\t Partial Moon");
508 sprintf(magbuf,
" (magnitude:%5.2f)",eb_magnitude[j]);
509 strcat(outbuf,magbuf);
512 case -4: strcat(outbuf,
"\t Total Moon");
513 sprintf(magbuf,
" (magnitude:%5.2f)",eb_magnitude[j]);
514 strcat(outbuf,magbuf);
518 if ((p > 0) || eb_lunecl)
521 strcat (wbuf, outbuf);
528 int &hour,
int &min,
double &sec,
double &tzone,
double &magn)
554 if (!eb_moonph_called) moonph();
561 if ((k < 1) && (k > eb_numecl))
return 0;
564 if (nls && (!eb_lunecl))
568 for(j=0; j<eb_numecl; j++)
573 if (kecl == k) p = j;
583 caldat((eb_eclmjd[j] + eb_tzone/24.0), day, month, yr, magn);
584 dms (magn,hour,min,sec);
585 if (sec>30.0) min++;;
592 magn = eb_magnitude[j];
608 if (!eb_moonph_called) moonph();
610 if (k < 1) k = eb_eclselect;
611 if ((k < 1) && (k > eb_numecl))
return 0;
615 sprintf(jtxt,
"%2i :", (j+1));
616 sprintf(dts,
"%5i ", eb_year);
618 dtmstr((eb_eclmjd[j]+eb_tzone/24.0),dts);
625 case 1: strcat(jtxt,
" Par.Sun");
627 case 2: strcat(jtxt,
" non-centr.Ann.Sun");
629 case 4: strcat(jtxt,
" Ann.Sun");
631 case 3: strcat(jtxt,
" non-centr.Tot.Sun");
633 case 5: strcat(jtxt,
" Tot.Sun");
635 case 6: strcat(jtxt,
" Ann/Tot.");
639 case -2: strcat(jtxt,
" Pen.Moon");
641 case -3: strcat(jtxt,
" Par.Moon");
643 case -4: strcat(jtxt,
" Tot.Moon");
657 if (!eb_moonph_called) moonph();
661 eb_lunactive =
false;
663 for (j=0; j<eb_numecl; j++)
665 if ((eb_phase[j] > 0) || eb_lunecl)
670 eb_eclselect = j + 1;
671 if (eb_phase[j] < 0) eb_lunactive =
true;
675 eb_start_called =
false;
683 if (!eb_moonph_called) moonph();
684 eb_start_called =
false;
686 k = eb_eclselect + 1;
704 eb_lunactive =
false;
708 for (j=es; j<eb_numecl; j++)
710 if ((k == 0) && (eb_phase[j] > 0)) k = j + 1;
731 if (!eb_moonph_called) moonph();
732 eb_start_called =
false;
734 k = eb_eclselect - 1;
750 eb_lunactive =
false;
756 if ((es == 0) && (eb_phase[j] > 0)) es = j + 1;
759 if(es > 0) eb_eclselect = es;
760 else putEclSelect(0);
785 double mjd, dpn1, dpn2, pan1, pan2;
786 double mag, m1, m2, s, ps;
795 if (pa > 1.0) eb_penangle = 1.0;
796 if (pa < 0) eb_penangle = 1.0;
801 if (!eb_start_called) eclStart();
806 mjd = eb_eclmjd[eb_eclselect-1];
807 eclp.
umbra (mjd, eb_del_tdut, ubm, ube, dpn1, pan1);
808 eclp.
penumd (mjd, eb_del_tdut, ubm, ube, dpn2, pan2);
812 eb_penangle = fabs(pa);
813 if(eb_penangle > 1.0) eb_penangle = 1.0;
814 eb_penangle = 1.0 - eb_penangle * (1.0 + dpn1 / dpn2);
816 else eb_penangle = 1.0;
824 mjd = eb_eclmjd[eb_eclselect-1];
825 eclp.
umbra (mjd, eb_del_tdut, ubm, ube, dpn1, pan1);
826 eclp.
penumd (mjd, eb_del_tdut, ubm, ube, dpn2, pan2);
829 if (ps > 1.0) ps = 1.0;
833 mag = double(j) * 0.1;
834 s = sunObscure(dpn2, dpn1, mag);
842 mag = (m2 + m1) * 0.5;
843 s = sunObscure(dpn2, dpn1, mag);
844 if (s > ps) m2 =
mag;
850 eb_penangle = fabs(mag);
851 if(eb_penangle > 1.0) eb_penangle = 1.0;
852 eb_penangle = 1.0 - eb_penangle * (1.0 + dpn1 / dpn2);
854 else eb_penangle = 1.0;
865 void EclSolar::GetMonth (
int mm,
char* mchr)
873 case 1 : strcpy(mchr,
"JAN");
break;
874 case 2 : strcpy(mchr,
"FEB");
break;
875 case 3 : strcpy(mchr,
"MAR");
break;
876 case 4 : strcpy(mchr,
"APR");
break;
877 case 5 : strcpy(mchr,
"MAY");
break;
878 case 6 : strcpy(mchr,
"JUN");
break;
879 case 7 : strcpy(mchr,
"JUL");
break;
880 case 8 : strcpy(mchr,
"AUG");
break;
881 case 9 : strcpy(mchr,
"SEP");
break;
882 case 10 : strcpy(mchr,
"OCT");
break;
883 case 11 : strcpy(mchr,
"NOV");
break;
884 case 12 : strcpy(mchr,
"DEC");
break;
885 default: strcpy(mchr,
"ERR");
889 double EclSolar::phmjd (
double yearf,
double phase,
double tdut,
890 int& eph,
double& ejd,
double& emag)
915 double tt, jd, k, m, p, f;
921 k = floor ((yearf - 1900.0) * 12.3685) + phase;
923 jd = 166.56 + (132.87 - 0.009173*tt)*tt;
924 jd = 15020.25933 + 29.53058868*k
925 + (0.0001178 - 0.000000155*tt)*tt*tt
926 + 0.00033 * sin (
degrad*jd);
931 m =
degrad * (359.2242 + 29.10535608*k
932 - (0.0000333 - 0.00000347*tt)*tt*tt);
934 p =
degrad * (306.0253 + 385.81691808*k
935 + (0.0107306 + 0.00001236*tt)*tt*tt);
937 f = 2.0 *
degrad * (21.2964 + 390.67050646*k
938 - (0.0016528 - 0.00000239*tt)*tt*tt);
940 if ((phase == 0) || (phase == 0.5))
942 k = (0.1734 - 0.000393*tt) * sin (m)
943 + 0.0021 * sin (2.0 * m)
945 + 0.0161 * sin (2.0 * p)
946 - 0.0004 * sin (3.0 * p)
948 - 0.0051 * sin (m + p)
949 - 0.0074 * sin (m - p)
950 + 0.0004 * sin (f + m)
951 - 0.0004 * sin (f - m)
952 - 0.0006 * sin (f + p)
953 + 0.0010 * sin (f - p)
954 + 0.0005 * sin (m + 2.0*p);
958 if (fabs(sin(f)) <= 0.36)
960 ejd = (0.1734 - 0.000393*tt) * sin(m)
961 + 0.0021 * sin(2.0*m)
963 + 0.0161 * sin(2.0*p)
966 - 0.0104 * sin(2.0*f);
969 s = 5.19595 - 0.0048*cos(m) + 0.0020*cos(2.0*m) - 0.3283*cos(p)
970 - 0.0060*cos(m+p) + 0.0041*cos(m-p);
972 c = 0.2070*sin(m) + 0.0024*sin(2.0*m) - 0.0390*sin(p)
973 + 0.0115*sin(2.0*p) - 0.0073*sin(m+p)
974 - 0.0067*sin(m-p) + 0.0117*sin(2.0*f);
976 gam = s*sin(f) + c*cos(f);
977 u = 0.0059 + 0.0046*cos(m) - 0.0182*cos(p)
978 + 0.0004*cos(2.0*p) - 0.0005*cos(m+p);
982 if (fabs(gam) <= (1.5432+u))
984 if (fabs(gam) < 0.9972)
990 if (u > 0.0047) eph = 4;
993 if (u < (0.00464*cos(asin(gam)))) eph = 6;
1001 if (fabs(gam) < (0.9972+fabs(u)))
1003 eph = eclp.solar(ejd,tdut,s,c);
1007 emag = (1.5432 + u - fabs(gam)) / (0.5460 + 2.0*u);
1012 for (
int j=0; j < 288; j++)
1014 tt = ejd - 0.2 + double(j)*u;
1015 tst = eclp.solar(tt,tdut,s,c);
1016 if (tst > 0) eph = tst;
1025 c = (1.5572 + u - fabs(gam)) / 0.5450;
1028 s = (1.0129 - u - fabs(gam)) / 0.5450;
1032 if (emag > 1) eph = -2;
1038 if (emag > 1) eph = -4;
1046 if ((phase == 0.25) || (phase == 0.75))
1048 k = (0.1721 - 0.0004*tt) * sin (m)
1049 + 0.0021 * sin (2.0 * m)
1051 + 0.0089 * sin (2.0 * p)
1052 - 0.0004 * sin (3.0 * p)
1054 - 0.0119 * sin (m + p)
1055 - 0.0047 * sin (m - p)
1056 + 0.0003 * sin (f + m)
1057 - 0.0004 * sin (f - m)
1058 - 0.0006 * sin (f + p)
1059 + 0.0021 * sin (f - p)
1060 + 0.0003 * sin (m + 2.0*p)
1061 + 0.0004 * sin (m - 2.0*p)
1062 - 0.0003 * sin (2.0*m + p);
1065 k += 0.0028 - 0.0004*cos(m) + 0.0003*cos(p);
1069 k += -0.0028 + 0.0004*cos(m) - 0.0003*cos(p);
1078 void EclSolar::ckphase (
double minmjd,
double maxmjd,
double yr,
1079 double deltdut,
int &mp,
PMJD p,
double phase)
1089 double td, ejd, emag;
1092 td = phmjd (yr, phase, deltdut*86400.0, eph, ejd, emag);
1098 if ((td >= minmjd) && (td <= maxmjd) && (mp <
MAXLUN))
1107 if (p[mp-1] < (td - 0.1))
1122 if ((td >= minmjd)&&(td <= maxmjd)&&(eb_numecl<
GBL_ECLBUF))
1127 eb_magnitude[0] = emag;
1133 for (j=0; j<eb_numecl; j++)
1135 if (fabs(eb_eclmjd[j]- td) < 0.01) eph = 0;
1141 eb_magnitude[j] = emag;
1150 void EclSolar::dtmstr(
double jdmoon,
char *dts)
1154 int dd, mm, yy, deg, mnt;
1159 caldat(jdmoon, dd, mm, yy, hh);
1160 dms (hh,deg,mnt,sec);
1161 if (sec>30.0) {mnt++;};
1169 GetMonth (mm, mchr);
1174 sprintf(&dts[4],
"%2i %2i:%02i", dd, deg, mnt);
1180 void EclSolar::moonph()
1182 int mp0, mp25, mp5, mp75;
1183 PMJD p0, p25, p5, p75;
1184 int day, month, year, j;
1185 double yr, yx, hour, deltdut;
1186 double minmjd, maxmjd;
1187 double glatsv, glongsv, gheightsv, lat, lng;
1190 eb_moonph_called =
true;
1194 deltdut = eb_del_tdut / 86400.0;
1196 eb_lasttz = eb_tzone;
1197 eb_lastdlt = eb_del_tdut;
1211 minmjd =
mjd(day, month, year, hour);
1215 maxmjd =
mjd(day, month, year, hour);
1226 ckphase(minmjd,maxmjd,yr,deltdut, mp0, p0, 0.0);
1227 ckphase(minmjd,maxmjd,yr,deltdut, mp25, p25, 0.25);
1228 ckphase(minmjd,maxmjd,yr,deltdut, mp5, p5, 0.5);
1229 ckphase(minmjd,maxmjd,yr,deltdut, mp75, p75, 0.75);
1233 for (j=0; j<eb_numecl; j++)
1235 if( (eb_phase[j] == 1) && (eb_magnitude[j] > 0.98))
1238 glongsv = eb_geolong;
1239 gheightsv = eb_geoheight;
1241 eb_start_called =
false;
1242 eb_local_called =
false;
1244 getMaxPos (lat, lng);
1249 getLocalDetails(wbuf);
1251 if ((eb_spp[0] == 2) || (eb_spp[1] == 2)) eb_phase[j] = 2;
1252 if ((eb_spp[0] == 3) || (eb_spp[1] == 3)) eb_phase[j] = 3;
1255 eb_geolong = glongsv;
1256 eb_geoheight = gheightsv;
1257 eb_start_called =
false;
1258 eb_local_called =
false;
1267 double EclSolar::getlocmag(
double jd,
double ep2,
double phi,
double lamda,
1268 double height,
Vec3 rs,
Vec3 rm,
int& totflg)
1281 const double ds = 218.245445;
1282 const double dm = 0.544986;
1284 double dsun, dmoon, asep;
1287 gm =
GeoPos(jd, ep2, phi, lamda, height);
1292 s =
EquHor(jd, ep2, phi, lamda, gs);
1301 gs =
HorEqu(jd, ep2, phi, lamda, s);
1304 s =
EquHor(jd, ep2, phi, lamda, gm);
1312 gm =
HorEqu(jd, ep2, phi, lamda, s);
1315 dsun = atan(0.5*ds/
abs(gs));
1316 dmoon = atan(0.5*dm/
abs(gm));
1320 asep = fabs(
dot(gs, gm));
1321 if (asep > 1.0) asep = 1.0;
1325 if ((dsun+dmoon) > asep)
1327 if (fabs(dsun-dmoon) > asep) totflg = 1;
1328 asep = fabs(dsun + dmoon - asep) / (2.0 * dsun);
1337 void EclSolar::eclStart()
1349 int nump, eflg, pcur, pold, maxp, i, j, npflg, p;
1350 double jd, step, jd2, jdf, d1, d2;
1351 double azim, elev, dist, phi, lamda;
1356 if (!eb_moonph_called)
1362 eb_local_called =
false;
1363 eb_start_called =
true;
1376 jd = eb_eclmjd[j] - 0.5;
1378 step = eb_cstep / (24.0*60.0);
1382 if (eb_lunactive) pcur = eclp.
lunar(jd, eb_del_tdut);
1383 else pcur = eclp.
solar (jd, eb_del_tdut,d1, d2);
1391 eb_spp[nump] = pcur;
1396 jd2 = jd - 1.0/86400.0;
1397 for (i=0; i<60; i++)
1399 if (eb_lunactive) pcur = eclp.
lunar(jd, eb_del_tdut);
1400 else pcur = eclp.
solar (jd2, eb_del_tdut,d1, d2);
1402 if (pcur == pold) eb_spt[nump] = jd2;
1404 jd2 = jd2 - 1.0/86400.0;
1410 else if (eclstarted && (pcur < pold))
1414 jd2 = jd - 1.0/86400.0;
1415 for (i=0; i<60; i++)
1417 if (eb_lunactive) pcur = eclp.
lunar(jd, eb_del_tdut);
1418 else pcur = eclp.
solar (jd2, eb_del_tdut,d1, d2);
1419 if (pcur == pold) jd = jd2;
1421 jd2 = jd2 - 1.0/86400.0;
1428 if (pcur > eb_spp[nump-2]) npflg = 0;
1433 if (nump >= 0) eb_ept[nump] = jd;
1436 if (pcur < eb_spp[nump-1])
1442 if (nump <= 0) eflg = 1;
1447 if (jd > jdf) eflg = 1;
1449 }
while (eflg != 1);
1453 calcMaxPos(phi, lamda);
1455 if ((eb_lunactive ==
false) && (p > 3))
1457 eb_jdmaxps = eb_eclmjd[j];
1458 jd = eb_eclmjd[j] - 600.0/86400.0;
1459 phi = eb_cmxlat *
degrad;
1460 lamda = eb_cmxlng *
degrad;
1461 for (i=0; i<1200; i++)
1464 pcur = eclp.
solar (jd, eb_del_tdut,d1, d2);
1468 AppPos (jd, eclp.
GetEp2(), d1, d2, 0.0, 1, gx, azim, elev, dist);
1470 if (elev > eb_maxelv)
1480 eb_maxelv = elev /
degrad;
1481 eb_cmxlat = phi /
degrad;
1482 eb_cmxlng = lamda /
degrad;
1483 if (eb_cmxlng < 0) eb_cmxlng += 360.0;
1486 eb_jdstart = eb_spt[0];
1487 eb_jdstop = eb_ept[0];
1492 void EclSolar::calcMaxPos(
double &lat,
double &lng)
1512 p = eclp.
lunar(t, eb_del_tdut);
1519 if (lng > mp2) lng -= mp2;
1520 if (lng < -
M_PI) lng += mp2;
1521 if (lng >
M_PI) lng -= mp2;
1522 if (fabs(lat) < 1.53589) lat = atan(1.00674*tan(lat));
1525 if (lng < 0) lng += 360.0;
1530 else p = eclp.
solar(t,eb_del_tdut,lat,lng);
1541 eclp.
maxpos(t,eb_del_tdut,eb_cmxlat,eb_cmxlng);
1546 if (eb_cmxlng < 0) eb_cmxlng += 360.0;
1555 if (!eb_start_called) eclStart();
1561 double EclSolar::sunObscure(
double l1,
double l2,
double mag)
1566 double s, a, b, c, m;
1568 m = l1 - mag * (l1 + l2);
1569 s = (l1 - l2) / (l1 + l2);
1570 c = (l1*l1 + l2*l2 - 2*m*m) / (l1*l1 - l2*l2);
1572 b = (l1*l2 + m*m) / (m*(l1+l2));
1575 s = (s*s*a + b) - s * sin(c);
1591 double phi, lamda, d1, d2, jd, jd2;
1595 if (!eb_start_called) eclStart();
1599 eb_finished2 =
true;
1610 kp = eclp.
solar(jd, eb_del_tdut, phi, lamda);
1612 while ((kp < 4) && (jd < eb_jdstop))
1614 jd += double(eb_cstep) / (24.0*60.0);
1616 kp = eclp.
solar(jd, eb_del_tdut, phi, lamda);
1620 for (i=0; i<60; i++)
1622 jd2 = jd2 - 1.0/86400.0;
1623 kp2 = eclp.
solar (jd2, eb_del_tdut,d1, d2);
1632 eb_finished2 =
false;
1637 if (eb_finished2)
return 0;
1639 jd = eb_lastjd + double(eb_cstep) / (24.0*60.0);
1643 eb_finished2 =
true;
1647 kp = eclp.
solar(jd, eb_del_tdut, phi, lamda);
1652 for (i=0; i<60; i++)
1655 kp = eclp.
solar (jd, eb_del_tdut, phi, lamda);
1667 if (lamda < 0.0) lamda += 360.0;
1668 if (lamda > 360.0) lamda -= 360.0;
1681 void EclSolar::InitBound()
1699 double dpn1, dpn2, pan1, pan2, s0;
1700 Vec3 shmv, u2m, u2e;
1704 if (!eb_start_called) eclStart();
1705 if (eb_lunactive)
return;
1708 eclp.
penumd (eb_jdstart, eb_del_tdut, eb_ubm, eb_ube, dpn1, pan1);
1711 eclp.
penumd (eb_jdstop, eb_del_tdut, u2m, u2e, dpn2, pan2);
1716 if (eb_penamode == 0)
1718 dpn1 *= eb_penangle;
1719 pan1 *= eb_penangle;
1720 dpn2 *= eb_penangle;
1721 pan2 *= eb_penangle;
1724 if (eb_penamode > 0)
1726 s0 = eb_penangle * tan(pan1);
1730 dpn1 = dpn1 * s0 / pan1;
1733 s0 = eb_penangle * tan(pan2);
1737 dpn2 = dpn2 * s0 / pan2;
1744 if (pan1 != 0) dpn1 = dpn1 / pan1;
1745 else dpn1 = 1.2 *
abs(eb_ubm);
1747 if (pan2 != 0) dpn2 = dpn2 / pan2;
1751 s0 = -
dot(eb_ubm, eb_ube);
1752 ax1 = eb_ubm + s0 * eb_ube;
1753 eb_ubm = eb_ubm + (s0 - dpn1) * eb_ube;
1754 s0 = -
dot(u2m, u2e);
1755 ax2 = u2m + s0 * u2e;
1756 u2m = u2m + (s0 - dpn2) * u2e;
1763 eb_udm = u2m - eb_ubm;
1764 eb_lbe = eb_ube - pan1 * shmv;
1765 eb_ube = eb_ube + pan1 * shmv;
1766 eb_ude = u2e + pan2 * shmv;
1767 eb_lde = u2e - pan2 * shmv;
1768 eb_ube =
vnorm(eb_ube);
1769 eb_lbe =
vnorm(eb_lbe);
1770 eb_ude =
vnorm(eb_ude);
1771 eb_lde =
vnorm(eb_lde);
1772 eb_lde = eb_lde - eb_lbe;
1773 eb_ude = eb_ude - eb_ube;
1776 dpn1 = eb_jdstop - eb_jdstart;
1777 if (dpn1 == 0) dpn1 = 1.0;
1778 else dpn1 = 1.0 / dpn1;
1797 const double flat = 0.996633;
1799 double s0, s, r0, r2, dlt, t;
1817 t = eb_lastjd + double(eb_cstep) / (24.0*60.0);
1829 vrm = eb_ubm + (t - eb_jdstart) * eb_udm;
1830 if (north) vre = eb_ube + (t - eb_jdstart) * eb_ude;
1831 else vre = eb_lbe + (t - eb_jdstart) * eb_lde;
1834 s0 = -
dot(vrm, vre);
1836 dlt = s0*s0 + 1.0 - r2;
1839 if (r0 > 0) r0 = sqrt (r0);
1845 if (dlt > 0) dlt = sqrt(dlt);
1848 vrm = vrm + s * vre;
1852 lng = vre[1] -
lsidtim(t,0,0)*0.261799387799;
1854 if (lng < 0.0) lng += 2.0*
M_PI;
1855 lat = sqrt(vrm[0]*vrm[0] + vrm[1]*vrm[1])*0.993305615;
1856 lat = atan23(vrm[2],lat);
1860 if (lng < 0.0) lng += 360.0;
1861 if (lng > 360.0) lng -= 360.0;
1874 void EclSolar::InRSBound()
1895 if (!eb_start_called) eclStart();
1898 eclp.
penumd (eb_jdstart, eb_del_tdut, eb_ubm, eb_ube, eb_dpb, pan);
1901 eclp.
penumd (eb_jdstop, eb_del_tdut, u2m, u2e, eb_dpd, pan);
1904 eb_udm = u2m - eb_ubm;
1905 eb_ude = u2e - eb_ube;
1906 eb_dpd = eb_dpd - eb_dpb;
1910 pan = eb_jdstop - eb_jdstart;
1911 if (pan == 0) pan = 1.0;
1912 else pan = 1.0 / pan;
1918 int EclSolar::iscrs(
double vrc0,
double vrc1,
double dpn,
1919 double& vrx0,
double& vrx1,
double& vrx20,
double& vrx21)
1936 double a, b, c, f1, f2, f3, f4;
1941 if (f1 < 1.0e-60) rtn = 0;
1944 f2 = 1.0 - dpn*dpn + f1 + vrc1*vrc1;
1945 f3 = f2 / (2.0*vrc0);
1947 a = 1.0 + vrc1*vrc1 / f1;
1949 c = f2*f2 / (4.0*f1) - 1.0;
1950 if (fabs(a) < 1.0e-60) rtn = 0;
1953 vrx21 = -0.5 * b / a; ;
1954 vrx0 = vrx21*vrx21 - c / a;
1955 if (vrx0 < 0) rtn = 0;
1959 vrx1 = vrx21 + vrx0;
1960 vrx21 = vrx21 - vrx0;
1961 vrx0 = f3 + f4*vrx1;
1962 vrx20 = f3 + f4*vrx21;
1986 const double flat = 0.996633;
1988 double s0, r0, dpn, t;
1989 Vec3 vrm, vre, vrc, vrx, vrx2;
2005 t = eb_jdstart + 1.0/86400.0;
2007 eb_finished =
false;
2011 t = eb_lastjd + double(eb_cstep) / (24.0*60.0);
2025 t = eb_jdstop - 1.0/86400.0;
2031 vrm = eb_ubm + (t - eb_jdstart) * eb_udm;
2032 vre = eb_ube + (t - eb_jdstart) * eb_ude;
2034 dpn = eb_dpb + (t - eb_jdstart) * eb_dpd;
2044 s0 = -
dot(vrm, vre);
2045 vrc = vrm + s0 * vre;
2048 vrc =
mxvct(m1, vrc);
2056 if ((r0 > fabs(1.0 - dpn)) && (r0 < fabs(1.0 + dpn)))
2059 if (iscrs(vrc[0],vrc[1], dpn, vrx[0],vrx[1], vrx2[0],vrx2[1])) lat1 = 0;
2062 if (iscrs(vrc[1],vrc[0], dpn, vrx[1],vrx[0], vrx2[1],vrx2[0])) lat1 = 0;
2070 vrx =
mxvct(m2, vrx);
2074 lng1 = vre[1] -
lsidtim(t,0,0)*0.261799387799;
2077 if (lng1 < (-
M_PI)) lng1 += 2.0*
M_PI;
2078 lat1 = sqrt(vrx[0]*vrx[0] + vrx[1]*vrx[1])*0.993305615;
2079 lat1 = atan23(vrx[2],lat1);
2086 vrx2 =
mxvct(m2, vrx2);
2090 lng2 = vre[1] -
lsidtim(t,0,0)*0.261799387799;
2092 if (lng2 < (-
M_PI)) lng2 += 2.0*
M_PI;
2093 lat2 = sqrt(vrx2[0]*vrx2[0] + vrx2[1]*vrx2[1])*0.993305615;
2094 lat2 = atan23(vrx2[2],lat2);
2104 double EclSolar::DegFDms (
double h)
2113 dms (hh,deg,mm,sec);
2125 t = double(mm)/100.0;
2129 if (h < 0) hh = -hh;
2134 int EclSolar::localStart(
int j,
double *spt,
double *ept,
int *spp,
2148 int nump, eflg, pcur, pold, maxp, i, npflg;
2150 double jd, step, jdf, d1, d2, elrise;
2151 double azim, elev, dist, phi, lamda;
2165 phi = eb_geolat *
M_PI / 180.0;
2166 lamda = eb_geolong *
M_PI / 180.0;
2167 jd = eb_eclmjd[j] - 0.5;
2169 step = 1.0/(24.0*60.0);
2171 eb_ltote = jd - 1.0;
2177 pcur = eclp.
lunar (jd, eb_del_tdut);
2184 pcur = eclp.
solar (jd, eb_del_tdut,d1, d2);
2193 AppPos (jd, eclp.
GetEp2(), phi, lamda, eb_geoheight, 1, gx,
2195 if ((p > 0) && (elev >= elrise))
2197 magecl = getlocmag(jd, eclp.
GetEp2(), phi, lamda, eb_geoheight,
2199 if (magecl > eb_maxps)
2208 if ((eb_lccnt == 0) && (pcur != 0))
2210 if ((elev >= elrise) && (magecl > 0))
2218 if ((elev < elrise) || (pcur == 0) || (magecl == 0))
2224 if ((eb_lccnt == 2) && (pcur != 0))
2226 if ((elev >= elrise) && (magecl > 0))
2234 if ((elev < elrise) || (pcur == 0) || (magecl == 0))
2253 else if (pcur < pold)
2258 if (pcur > spp[nump-2]) npflg = 0;
2263 if (nump >= 0) ept[nump] = jd;
2266 if (pcur < spp[nump-1])
2272 if (nump <= 0) eflg = 1;
2278 if (jd > jdf) eflg = 1;
2280 }
while (eflg != 1);
2285 for (i=0; i<maxp; i++)
2291 case 1: strcpy(outb,
"penumbral ");
2293 case 2: strcpy(outb,
"tot.penumb ");
2295 case 3: strcpy(outb,
"partial ");
2297 case 4: strcpy(outb,
"totality ");
2305 case 1: strcpy(outb,
"partial ");
2307 case 2: strcpy(outb,
"n-centr.Ann ");
2309 case 3: strcpy(outb,
"n-centr.Tot ");
2311 case 4: strcpy(outb,
"annularity ");
2313 case 5: strcpy(outb,
"totality ");
2320 strcat(otxt,
"\tbegins ");
2321 dtmstr((spt[i]+eb_tzone/24.0),dts);
2324 strcat(otxt,
"\tends ");
2325 dtmstr((ept[i]+eb_tzone/24.0),dts);
2332 if (eb_lccnt == 1) eb_lce1 = ept[0];
2333 if (eb_lccnt == 3) eb_lce2 = ept[0];
2338 jd = eb_jdmaxps - 16.0/(24.0*60.0);
2339 eb_ltote = jd + 32.0/(24.0*60.0);
2344 eclp.
solar (jd, eb_del_tdut,d1, d2);
2346 AppPos (jd, eclp.
GetEp2(), phi, lamda, eb_geoheight, 1, gx,
2350 magecl = getlocmag(jd, eclp.
GetEp2(), phi, lamda, eb_geoheight,
2352 if (magecl > eb_maxps)
2364 if (jd > eb_ltote) eflg = 1;
2374 eclp.
solar (jd, eb_del_tdut,d1, d2);
2376 AppPos (jd, eclp.
GetEp2(), phi, lamda, eb_geoheight, 1, gx,
2378 if (elev < elrise) eflg = 1;
2379 magecl = getlocmag(jd, eclp.
GetEp2(), phi, lamda, eb_geoheight,
2381 if (magecl > eb_maxps)
2387 if (i == 0) eflg = 1;
2388 if (jd > eb_ltote) eflg = 1;
2393 else eb_ltote = eb_ltotb - 1.0;
2405 int j, p, i, ecloutbn;
2406 int dd, mm, yy, deg, mnt;
2410 double spt[4], ept[4];
2415 if (!eb_start_called) eclStart();
2416 eb_local_called =
true;
2422 sprintf(otxt,
"+++ Timezone: %g +++ TT - UTC: %g (sec) +++ Year: %5i +++\n\n", eb_tzone, eb_del_tdut, eb_year);
2425 case 1: strcpy(outb,
"\t\tPartial Eclipse of the Sun");
2427 case 2: strcpy(outb,
"\t\tNon-Central Annular Eclipse of the Sun");
2429 case 3: strcpy(outb,
"\t\tNon-Central Total Eclipse of the Sun");
2431 case 4: strcpy(outb,
"\t\tAnnular Eclipse of the Sun");
2433 case 5: strcpy(outb,
"\t\tTotal Eclipse of the Sun");
2435 case 6: strcpy(outb,
"\t\tAnnular/Total Solar Eclipse");
2439 case -2: strcpy(outb,
"\t\tPenumbral Eclipse of the Moon");
2441 case -3: strcpy(outb,
"\t\tPartial eclipse of the Moon");
2443 case -4: strcpy(outb,
"\t\tTotal eclipse of the Moon");
2448 sprintf(outb,
"\n\nMaximum Eclipse at ");
2450 dtmstr((eb_eclmjd[j]+eb_tzone/24.0),dts);
2455 sprintf(outb,
" with magnitude:%5.2f",eb_magnitude[j]);
2460 nump = localStart(j, spt, ept, spp, p, otxt);
2461 if ((p < 4) || (nump < 1)) ecloutbn = 5;
2467 for (i=0; i<nump; i++)
2468 if ((spt[i] < jd) && (spp[i] > 3)) jd = spt[i];
2469 caldat(jd, dd, mm, yy, hh);
2470 dms (hh,deg,mnt,sec);
2473 mnt = i* int(eb_cstep);
2474 hh =
ddd (deg, mnt, sec);
2475 jd =
mjd (dd, mm, yy, hh);
2477 for (i=0; i<nump; i++)
2478 if ((ept[i] > jdf) && (spp[i] > 3)) jdf = ept[i];
2480 jd += eb_cstep / (24.0*60.0);
2484 strcat(otxt,
"\n\n\nLocal Circumstances for ");
2487 sprintf(outb,
"\nLat: %g Long: %g height: %g m\n\n",
2488 jd, jdf, eb_geoheight);
2494 sprintf(outb,
"Eclipse visible from ");
2495 dtmstr((eb_lcb1+eb_tzone/24.0),dts);
2499 strcat(outb,
" to ");
2500 dtmstr((eb_lce1+eb_tzone/24.0),dts);
2506 strcpy(outb,
"\n\tand from ");
2507 dtmstr((eb_lcb2+eb_tzone/24.0),dts);
2511 strcat(outb,
" to ");
2512 dtmstr((eb_lce2+eb_tzone/24.0),dts);
2517 else sprintf(outb,
"Eclipse not visible");
2522 if ((p > 0) && (eb_lccnt > 0))
2524 sprintf(outb,
"\nMaximum Eclipse at ");
2526 dtmstr((eb_jdmaxps+eb_tzone/24.0),dts);
2529 sprintf(outb,
" with magnitude %6.3f", eb_maxps);
2531 sprintf(outb,
" elev:%4.1f", 180.0*eb_maxelv/
M_PI);
2533 if (eb_ltotb <= eb_ltote)
2535 if ((p % 2) == 0) strcpy(outb,
"\nannularity from");
2536 else strcpy(outb,
"\ntotality from");
2537 if ((p == 1) || (p == 6))
2538 strcpy(outb,
"\ntotality/annularity from");
2540 caldat((eb_ltotb+eb_tzone/24.0), dd, mm, yy, hh);
2541 caldat((eb_ltote+eb_tzone/24.0), dd, mm, yy, jd);
2544 jdf = (eb_ltote - eb_ltotb) * 86400.0;
2545 sprintf(outb,
"%8.4f to%8.4f del.t:%3.0f sec \n",hh,jd, jdf);
2555 double EclSolar::navCourse (
double lat1,
double lng1,
double lat2,
double lng2)
2560 double lt1, ln1, lt2, ln2, cd, an;
2567 cd = sin(lt1)*sin(lt2) + cos(lt1)*cos(lt2)*cos(ln2 - ln1);
2569 an = cos(lt1) * sin(an);
2571 if (an == 0)
return 0;
2573 cd = (sin(lt2) - sin(lt1)*cd) / an;
2576 if (sin(ln2 - ln1) < 0) an = -an;
2581 void EclSolar::navNewPos (
double d,
double an,
double lat1,
double lng1,
double &lat2,
double &lng2)
2588 double cd, sd, lt1, ag;
2597 sd = cd * sin(lt1) + sin(d) * cos(lt1) * cos(ag);
2600 lng2 = cos(lt1) * cos(lat2);
2609 lng2 = (cd - sin(lt1) * sd) / lng2;
2612 if (ag > 0) lng2 = lng1 + lng2;
2613 else lng2 = lng1 -lng2;
2614 if(lng2 > 360.0) lng2 -= 360.0;
2615 if(lng2 < 0) lng2 += 360.0;
2637 double lt1, ln1, lt2, ln2, an;
2640 if (!eb_start_called) eclStart();
2649 if (eb_lunactive)
return 0;
2654 k = eclPltCentral(
true, lt1, ln1);
2657 else k = eclPltCentral(
false, lt1, ln1);
2660 if (k <= 3)
return k;
2662 k = eclPltCentral(
false, lt2, ln2);
2667 eb_lastjd -= 2.0 * eb_cstep / (24.0*60.0);
2668 k = eclPltCentral(
false, lt2, ln2);
2673 if (k <= 3)
return k;
2675 eclp.
solar(t, eb_del_tdut, lat1, lng1);
2679 an = navCourse (lt1, ln1, lt2, ln2);
2682 eclp.
duration(t, eb_del_tdut, dpn1);
2683 dpn1 = (dpn1 / 111.1) * 0.0174533;
2685 navNewPos(dpn1, an, lt1, ln1, lat1, lng1);
2689 navNewPos(dpn1, an, lt1, ln1, lat2, lng2);
2717 const double flat = 0.996633;
2719 int j, k1, k2, kmiss;
2720 double dpn1, pan1, s0, dlt, dta, ag;
2721 double s, r0, r2, dt1, dt2;
2728 if (numpts < 2)
return;
2730 for (j=0; j<numpts; j++)
2736 if (!eb_start_called) eclStart();
2737 if (eb_lunactive)
return;
2739 if (umbra && (eb_phase[eb_eclselect-1] < 1))
return;
2742 if(umbra) eclp.
umbra (mjd, eb_del_tdut, ubm, ube, dpn1, pan1);
2743 else eclp.
penumd (mjd, eb_del_tdut, ubm, ube, dpn1, pan1);
2749 if (eb_penamode == 0)
2751 dpn1 *= eb_penangle;
2752 pan1 *= eb_penangle;
2755 if (eb_penamode > 0)
2757 s0 = eb_penangle * tan(pan1);
2761 dpn1 = dpn1 * s0 / pan1;
2769 if (pan1 < 0.0000174533)
return;
2772 s0 = -
dot(ubm, ube);
2773 ubm = ubm + (s0 - dpn1) * ube;
2780 ax1 =
vnorm(ax2) * pan1;
2784 mx2 =
yrot(ax2[2]) * mx1;
2787 ax2 =
mxvct(mx2,ax1);
2790 dta = 2.0*
M_PI / double(numpts);
2792 for (j=0; j<numpts; j++)
2794 ag = double(j) * dta;
2796 ax1 =
mxvct(mx2,ax2);
2797 ax1 =
mxvct(mx1, ax1);
2805 s0 = -
dot(vrm, vre);
2807 dlt = s0*s0 + 1.0 - r2;
2810 if (r0 > 0) r0 = sqrt (r0);
2816 if (dlt > 0) dlt = sqrt(dlt);
2819 vrm = vrm + s * vre;
2823 lng[j] = vre[1] -
lsidtim(mjd,0,0)*0.261799387799;
2824 if (lng[j] > 2*
M_PI) lng[j] -= 2.0*
M_PI;
2825 if (lng[j] < 0.0) lng[j] += 2.0*
M_PI;
2826 lat[j] = sqrt(vrm[0]*vrm[0] + vrm[1]*vrm[1])*0.993305615;
2827 lat[j] = atan23(vrm[2],lat[j]);
2831 if (lng[j] < 0.0) lng[j] += 360.0;
2832 if (lng[j] > 360.0) lng[j] -= 360.0;
2844 for (j=0; j<numpts; j++)
2854 if ((kmiss < 2) || (kmiss >= (numpts -1)))
return;
2856 dt1 = double(k1) * dta;
2857 dt2 = double(k2) * dta;
2860 if (k1 < 0) k1 = numpts - 1;
2861 if (k2 >= (numpts-1)) k2 = 0;
2862 dta = 2.0*
M_PI / double(numpts*20);
2864 for (j=1; j<20; j++)
2866 ag = dt1 - double(j) * dta;
2868 ax1 =
mxvct(mx2,ax2);
2869 ax1 =
mxvct(mx1, ax1);
2877 s0 = -
dot(vrm, vre);
2879 dlt = s0*s0 + 1.0 - r2;
2882 if (r0 > 0) r0 = sqrt (r0);
2888 if (dlt > 0) dlt = sqrt(dlt);
2891 vrm = vrm + s * vre;
2895 lng[k1] = vre[1] -
lsidtim(mjd,0,0)*0.261799387799;
2896 if (lng[k1] > 2*
M_PI) lng[k1] -= 2.0*
M_PI;
2897 if (lng[k1] < 0.0) lng[k1] += 2.0*
M_PI;
2898 lat[k1] = sqrt(vrm[0]*vrm[0] + vrm[1]*vrm[1])*0.993305615;
2899 lat[k1] = atan23(vrm[2],lat[k1]);
2903 if (lng[k1] < 0.0) lng[k1] += 360.0;
2904 if (lng[k1] > 360.0) lng[k1] -= 360.0;
2909 for (j=1; j<20; j++)
2911 ag = dt2 + double(j) * dta;
2913 ax1 =
mxvct(mx2,ax2);
2914 ax1 =
mxvct(mx1, ax1);
2922 s0 = -
dot(vrm, vre);
2924 dlt = s0*s0 + 1.0 - r2;
2927 if (r0 > 0) r0 = sqrt (r0);
2933 if (dlt > 0) dlt = sqrt(dlt);
2936 vrm = vrm + s * vre;
2940 lng[k2] = vre[1] -
lsidtim(mjd,0,0)*0.261799387799;
2941 if (lng[k2] > 2*
M_PI) lng[k2] -= 2.0*
M_PI;
2942 if (lng[k2] < 0.0) lng[k2] += 2.0*
M_PI;
2943 lat[k2] = sqrt(vrm[0]*vrm[0] + vrm[1]*vrm[1])*0.993305615;
2944 lat[k2] = atan23(vrm[2],lat[k2]);
2948 if (lng[k2] < 0.0) lng[k2] += 360.0;
2949 if (lng[k2] > 360.0) lng[k2] -= 360.0;
double Refract(double h, double p, double t)
void putEclSelect(int es)
Vec3 GeoPos(double jd, double ep2, double lat, double lng, double ht)
double duration(double jd, double tdut, double &width)
void setLunarEcl(bool lecl)
void setDeltaTAI_UTC(double d)
int getLocalTotal(double &mjd_start, double &mjd_stop)
void getShadowCone(double mjd, bool umbra, int numpts, double *lat, double *lng)
void getEclYearInfo(char *wbuf)
void setLocalPos(double lat, double lng, double hgt)
int GRSBound(bool firstc, double &lat1, double &lng1, double &lat2, double &lng2)
int solar(double jd, double tdut, double &phi, double &lamda)
double ddd(int d, int m, double s)
void setCurrentMJD(int year, int month, int day, int hour, int min, double sec)
double lsidtim(double jd, double lambda, double ep2)
Vec3 HorEqu(double jd, double ep2, double lat, double lng, Vec3 r)
void getLocalDetails(char *otxt)
int lunar(double jd, double tdut)
int getTotal(double &mjd_start, double &mjd_stop)
int eclPltCentral(bool firstc, double &lat, double &lng)
void setPenumbraAngle(double pa, int mode)
Vec3 carpol(const Vec3 &c)
Vec3 vnorm(const Vec3 &c)
void maxpos(double jd, double tdut, double &phi, double &lamda)
int centralBound(bool firstc, double &lat1, double &lng1, double &lat2, double &lng2)
void getDatefromMJD(double mjd, int &year, int &month, int &day, int &hour, int &min, double &sec) const
int GNSBound(bool firstc, bool north, double &lat, double &lng)
int getLocalVisibility(double &mjd_start, double &mjd_stop)
void getMaxPos(double &lat, double &lng)
void caldat(double mjd, int &day, int &month, int &year, double &hour)
double abs(const Vec3 &c)
int getPenumbra(double &mjd_start, double &mjd_stop)
Mat3 mxtrn(const Mat3 &m1)
int getEclTxt(int j, char *jtxt)
void AppPos(double jd, double ep2, double lat, double lng, double ht, int solsys, Vec3 r, double &azim, double &elev, double &dist)
void setStepWidth(double s)
void dms(double dd, int &d, int &m, double &s)
double mjd(int day, int month, int year, double hour)
void setTimezone(double d)
void penumd(double jd, double tdut, Vec3 &vrm, Vec3 &ves, double &dpn, double &pang)
int getPartial(double &mjd_start, double &mjd_stop)
int getLocalMax(double &mjdmax, double &magmax, double &elmax)
Vec3 EquHor(double jd, double ep2, double lat, double lng, Vec3 r)
double getLastMJD() const
double dot(const Vec3 &c1, const Vec3 &c2)
void umbra(double jd, double tdut, Vec3 &vrm, Vec3 &ves, double &dpn, double &pang)
Vec3 polcar(const Vec3 &c)
Vec3 mxvct(const Mat3 &m1, Vec3 &v1)