@typescriptify/sweph 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +422 -0
- package/ephe/semo_18.se1 +0 -0
- package/ephe/sepl_18.se1 +0 -0
- package/originalCode/.eslintrc.json +124 -0
- package/originalCode/.gitattributes +2 -0
- package/originalCode/.github/FUNDING.yml +5 -0
- package/originalCode/.github/workflows/test.yml +35 -0
- package/originalCode/LICENSE +840 -0
- package/originalCode/README.md +91 -0
- package/originalCode/binding.gyp +41 -0
- package/originalCode/constants.js +366 -0
- package/originalCode/docs.gif +0 -0
- package/originalCode/index.d.ts +5115 -0
- package/originalCode/index.js +7 -0
- package/originalCode/index.mjs +109 -0
- package/originalCode/package.json +55 -0
- package/originalCode/src/functions/azalt.cpp +39 -0
- package/originalCode/src/functions/azalt_rev.cpp +35 -0
- package/originalCode/src/functions/calc.cpp +29 -0
- package/originalCode/src/functions/calc_pctr.cpp +31 -0
- package/originalCode/src/functions/calc_ut.cpp +29 -0
- package/originalCode/src/functions/close.cpp +6 -0
- package/originalCode/src/functions/cotrans.cpp +26 -0
- package/originalCode/src/functions/cotrans_sp.cpp +26 -0
- package/originalCode/src/functions/cs2degstr.cpp +19 -0
- package/originalCode/src/functions/cs2lonlatstr.cpp +23 -0
- package/originalCode/src/functions/cs2timestr.cpp +23 -0
- package/originalCode/src/functions/csnorm.cpp +15 -0
- package/originalCode/src/functions/csroundsec.cpp +15 -0
- package/originalCode/src/functions/d2l.cpp +15 -0
- package/originalCode/src/functions/date_conversion.cpp +30 -0
- package/originalCode/src/functions/day_of_week.cpp +15 -0
- package/originalCode/src/functions/degnorm.cpp +15 -0
- package/originalCode/src/functions/deltat.cpp +15 -0
- package/originalCode/src/functions/deltat_ex.cpp +24 -0
- package/originalCode/src/functions/difcs2n.cpp +19 -0
- package/originalCode/src/functions/difcsn.cpp +19 -0
- package/originalCode/src/functions/difdeg2n.cpp +19 -0
- package/originalCode/src/functions/difdegn.cpp +19 -0
- package/originalCode/src/functions/fixstar.cpp +32 -0
- package/originalCode/src/functions/fixstar2.cpp +32 -0
- package/originalCode/src/functions/fixstar2_mag.cpp +28 -0
- package/originalCode/src/functions/fixstar2_ut.cpp +32 -0
- package/originalCode/src/functions/fixstar_mag.cpp +28 -0
- package/originalCode/src/functions/fixstar_ut.cpp +32 -0
- package/originalCode/src/functions/gauquelin_sector.cpp +44 -0
- package/originalCode/src/functions/get_ayanamsa.cpp +15 -0
- package/originalCode/src/functions/get_ayanamsa_ex.cpp +27 -0
- package/originalCode/src/functions/get_ayanamsa_ex_ut.cpp +27 -0
- package/originalCode/src/functions/get_ayanamsa_name.cpp +19 -0
- package/originalCode/src/functions/get_ayanamsa_ut.cpp +15 -0
- package/originalCode/src/functions/get_current_file_data.cpp +28 -0
- package/originalCode/src/functions/get_library_path.cpp +8 -0
- package/originalCode/src/functions/get_orbital_elements.cpp +29 -0
- package/originalCode/src/functions/get_planet_name.cpp +19 -0
- package/originalCode/src/functions/get_tid_acc.cpp +7 -0
- package/originalCode/src/functions/heliacal_pheno_ut.cpp +52 -0
- package/originalCode/src/functions/heliacal_ut.cpp +52 -0
- package/originalCode/src/functions/helio_cross.cpp +33 -0
- package/originalCode/src/functions/helio_cross_ut.cpp +33 -0
- package/originalCode/src/functions/house_name.cpp +20 -0
- package/originalCode/src/functions/house_pos.cpp +36 -0
- package/originalCode/src/functions/houses.cpp +35 -0
- package/originalCode/src/functions/houses_armc.cpp +38 -0
- package/originalCode/src/functions/houses_armc_ex2.cpp +47 -0
- package/originalCode/src/functions/houses_ex.cpp +37 -0
- package/originalCode/src/functions/houses_ex2.cpp +46 -0
- package/originalCode/src/functions/jdet_to_utc.cpp +38 -0
- package/originalCode/src/functions/jdut1_to_utc.cpp +38 -0
- package/originalCode/src/functions/julday.cpp +25 -0
- package/originalCode/src/functions/lat_to_lmt.cpp +27 -0
- package/originalCode/src/functions/lmt_to_lat.cpp +27 -0
- package/originalCode/src/functions/lun_eclipse_how.cpp +34 -0
- package/originalCode/src/functions/lun_eclipse_when.cpp +31 -0
- package/originalCode/src/functions/lun_eclipse_when_loc.cpp +39 -0
- package/originalCode/src/functions/lun_occult_when_glob.cpp +35 -0
- package/originalCode/src/functions/lun_occult_when_loc.cpp +43 -0
- package/originalCode/src/functions/lun_occult_where.cpp +34 -0
- package/originalCode/src/functions/mooncross.cpp +26 -0
- package/originalCode/src/functions/mooncross_node.cpp +30 -0
- package/originalCode/src/functions/mooncross_node_ut.cpp +30 -0
- package/originalCode/src/functions/mooncross_ut.cpp +26 -0
- package/originalCode/src/functions/nod_aps.cpp +42 -0
- package/originalCode/src/functions/nod_aps_ut.cpp +42 -0
- package/originalCode/src/functions/orbit_max_min_true_distance.cpp +37 -0
- package/originalCode/src/functions/pheno.cpp +29 -0
- package/originalCode/src/functions/pheno_ut.cpp +29 -0
- package/originalCode/src/functions/radnorm.cpp +15 -0
- package/originalCode/src/functions/refrac.cpp +23 -0
- package/originalCode/src/functions/refrac_extended.cpp +32 -0
- package/originalCode/src/functions/revjul.cpp +33 -0
- package/originalCode/src/functions/rise_trans.cpp +44 -0
- package/originalCode/src/functions/rise_trans_true_hor.cpp +46 -0
- package/originalCode/src/functions/set_delta_t_userdef.cpp +14 -0
- package/originalCode/src/functions/set_ephe_path.cpp +14 -0
- package/originalCode/src/functions/set_jpl_file.cpp +14 -0
- package/originalCode/src/functions/set_sid_mode.cpp +20 -0
- package/originalCode/src/functions/set_tid_acc.cpp +14 -0
- package/originalCode/src/functions/set_topo.cpp +20 -0
- package/originalCode/src/functions/sidtime.cpp +15 -0
- package/originalCode/src/functions/sidtime0.cpp +21 -0
- package/originalCode/src/functions/sol_eclipse_how.cpp +34 -0
- package/originalCode/src/functions/sol_eclipse_when_glob.cpp +31 -0
- package/originalCode/src/functions/sol_eclipse_when_loc.cpp +39 -0
- package/originalCode/src/functions/sol_eclipse_where.cpp +30 -0
- package/originalCode/src/functions/solcross.cpp +26 -0
- package/originalCode/src/functions/solcross_ut.cpp +26 -0
- package/originalCode/src/functions/split_deg.cpp +35 -0
- package/originalCode/src/functions/time_equ.cpp +25 -0
- package/originalCode/src/functions/utc_time_zone.cpp +48 -0
- package/originalCode/src/functions/utc_to_jd.cpp +37 -0
- package/originalCode/src/functions/version.cpp +8 -0
- package/originalCode/src/functions/vis_limit_mag.cpp +50 -0
- package/originalCode/src/sweph.cpp +150 -0
- package/originalCode/src/sweph.h +119 -0
- package/originalCode/swisseph/swecl.c +6428 -0
- package/originalCode/swisseph/swedate.c +588 -0
- package/originalCode/swisseph/swedate.h +81 -0
- package/originalCode/swisseph/swehel.c +3511 -0
- package/originalCode/swisseph/swehouse.c +3143 -0
- package/originalCode/swisseph/swehouse.h +98 -0
- package/originalCode/swisseph/swejpl.c +958 -0
- package/originalCode/swisseph/swejpl.h +103 -0
- package/originalCode/swisseph/swemmoon.c +1930 -0
- package/originalCode/swisseph/swemplan.c +967 -0
- package/originalCode/swisseph/swemptab.h +10640 -0
- package/originalCode/swisseph/swenut2000a.h +2819 -0
- package/originalCode/swisseph/sweodef.h +326 -0
- package/originalCode/swisseph/sweph.c +8614 -0
- package/originalCode/swisseph/sweph.h +849 -0
- package/originalCode/swisseph/swephexp.h +1020 -0
- package/originalCode/swisseph/swephlib.c +4634 -0
- package/originalCode/swisseph/swephlib.h +189 -0
- package/package.json +28 -0
- package/scripts/gen-swemptab.js +177 -0
- package/scripts/gen-swenut2000a.js +106 -0
- package/src/SwissEph/README.md +268 -0
- package/src/SwissEph/UseCases/Ayanamsa.md +363 -0
- package/src/SwissEph/UseCases/AzimuthAltitude.md +408 -0
- package/src/SwissEph/UseCases/CoordinateSystems.md +337 -0
- package/src/SwissEph/UseCases/DateAndTime.md +368 -0
- package/src/SwissEph/UseCases/DeltaT.md +258 -0
- package/src/SwissEph/UseCases/EphemerisFiles.md +338 -0
- package/src/SwissEph/UseCases/FixedStars.md +300 -0
- package/src/SwissEph/UseCases/GauquelinSectors.md +304 -0
- package/src/SwissEph/UseCases/HeliacalEvents.md +396 -0
- package/src/SwissEph/UseCases/HelioCrossings.md +325 -0
- package/src/SwissEph/UseCases/HousePosition.md +254 -0
- package/src/SwissEph/UseCases/HouseSystems.md +279 -0
- package/src/SwissEph/UseCases/LunarEclipse.md +326 -0
- package/src/SwissEph/UseCases/MeridianTransit.md +279 -0
- package/src/SwissEph/UseCases/MoonCrossings.md +373 -0
- package/src/SwissEph/UseCases/NodesAndApsides.md +307 -0
- package/src/SwissEph/UseCases/Occultation.md +352 -0
- package/src/SwissEph/UseCases/OrbitalElements.md +469 -0
- package/src/SwissEph/UseCases/Phenomena.md +328 -0
- package/src/SwissEph/UseCases/PlanetPositions.md +366 -0
- package/src/SwissEph/UseCases/Planetocentric.md +278 -0
- package/src/SwissEph/UseCases/Refraction.md +314 -0
- package/src/SwissEph/UseCases/RiseAndSet.md +433 -0
- package/src/SwissEph/UseCases/SiderealTime.md +302 -0
- package/src/SwissEph/UseCases/SolarEclipse.md +379 -0
- package/src/SwissEph/UseCases/SunCrossings.md +275 -0
- package/src/SwissEph/UseCases/TopocentricCorrection.md +335 -0
- package/src/SwissEph/errors.ts +10 -0
- package/src/SwissEph/index.ts +823 -0
- package/src/SwissEph/types.ts +291 -0
- package/src/constants.ts +762 -0
- package/src/file-reader.ts +147 -0
- package/src/index.ts +10 -0
- package/src/swecl.ts +4526 -0
- package/src/swedate.ts +376 -0
- package/src/swehel.ts +1939 -0
- package/src/swehouse.ts +2167 -0
- package/src/swejpl.ts +470 -0
- package/src/swemmoon.ts +1318 -0
- package/src/swemplan.ts +585 -0
- package/src/swemptab.ts +4448 -0
- package/src/swenut2000a.ts +2763 -0
- package/src/sweph.ts +3993 -0
- package/src/swephlib.ts +2720 -0
- package/src/types.ts +490 -0
- package/tests/c-style/ayanamsa.test.ts +63 -0
- package/tests/c-style/config.test.ts +96 -0
- package/tests/c-style/crossings.test.ts +81 -0
- package/tests/c-style/date-time.test.ts +114 -0
- package/tests/c-style/eclipses.test.ts +84 -0
- package/tests/c-style/fixed-stars.test.ts +66 -0
- package/tests/c-style/heliacal.test.ts +34 -0
- package/tests/c-style/houses.test.ts +135 -0
- package/tests/c-style/math-utils.test.ts +160 -0
- package/tests/c-style/orbital.test.ts +78 -0
- package/tests/c-style/phenomena.test.ts +42 -0
- package/tests/c-style/planetocentric.test.ts +26 -0
- package/tests/c-style/planets.test.ts +117 -0
- package/tests/c-style/rise-set.test.ts +71 -0
- package/tests/helpers.ts +21 -0
- package/tests/modern/ayanamsa.test.ts +47 -0
- package/tests/modern/calc.test.ts +113 -0
- package/tests/modern/config.test.ts +46 -0
- package/tests/modern/crossings.test.ts +45 -0
- package/tests/modern/eclipses.test.ts +81 -0
- package/tests/modern/errors.test.ts +71 -0
- package/tests/modern/heliacal.test.ts +30 -0
- package/tests/modern/houses.test.ts +87 -0
- package/tests/modern/orbital.test.ts +79 -0
- package/tests/modern/phenomena.test.ts +41 -0
- package/tests/modern/rise-set.test.ts +60 -0
- package/tests/modern/statics.test.ts +99 -0
- package/tests/modern/utilities.test.ts +70 -0
- package/tsconfig.json +20 -0
package/src/swehel.ts
ADDED
|
@@ -0,0 +1,1939 @@
|
|
|
1
|
+
/*************************************************************
|
|
2
|
+
* Swiss Ephemeris — Heliacal risings and related calculations
|
|
3
|
+
* Translated from swehel.c
|
|
4
|
+
*
|
|
5
|
+
* Author: Victor Reijs
|
|
6
|
+
* Translation from VB into C by Dieter Koch
|
|
7
|
+
* Translation from C to TypeScript
|
|
8
|
+
*
|
|
9
|
+
* Copyright (c) Victor Reijs, 2008
|
|
10
|
+
* Copyright (C) 1997 - 2021 Astrodienst AG, Switzerland.
|
|
11
|
+
* All rights reserved. (AGPL)
|
|
12
|
+
*************************************************************/
|
|
13
|
+
|
|
14
|
+
import {
|
|
15
|
+
PI, DEGTORAD, RADTODEG,
|
|
16
|
+
SE_SUN, SE_MOON, SE_MERCURY, SE_VENUS, SE_MARS,
|
|
17
|
+
SE_JUPITER, SE_SATURN, SE_URANUS, SE_NEPTUNE, SE_PLUTO,
|
|
18
|
+
SE_AST_OFFSET, SE_GREG_CAL,
|
|
19
|
+
SE_CALC_RISE, SE_CALC_SET, SE_BIT_DISC_CENTER, SE_EQU2HOR,
|
|
20
|
+
SEFLG_JPLEPH, SEFLG_SWIEPH, SEFLG_MOSEPH,
|
|
21
|
+
SEFLG_EQUATORIAL, SEFLG_TOPOCTR, SEFLG_NONUT, SEFLG_TRUEPOS, SEFLG_SPEED,
|
|
22
|
+
OK, ERR, TJD_INVALID,
|
|
23
|
+
SE_HELFLAG_HIGH_PRECISION, SE_HELFLAG_OPTICAL_PARAMS,
|
|
24
|
+
SE_HELFLAG_NO_DETAILS, SE_HELFLAG_LONG_SEARCH,
|
|
25
|
+
SE_HELFLAG_SEARCH_1_PERIOD,
|
|
26
|
+
SE_HELFLAG_VISLIM_DARK, SE_HELFLAG_VISLIM_NOMOON,
|
|
27
|
+
SE_HELFLAG_VISLIM_PHOTOPIC, SE_HELFLAG_VISLIM_SCOTOPIC,
|
|
28
|
+
SE_HELFLAG_AVKIND, SE_HELFLAG_AVKIND_VR,
|
|
29
|
+
SE_HELFLAG_AVKIND_PTO, SE_HELFLAG_AVKIND_MIN7, SE_HELFLAG_AVKIND_MIN9,
|
|
30
|
+
SE_SCOTOPIC_FLAG, SE_MIXEDOPIC_FLAG,
|
|
31
|
+
SE_MORNING_FIRST, SE_EVENING_LAST, SE_EVENING_FIRST, SE_MORNING_LAST,
|
|
32
|
+
SE_ACRONYCHAL_RISING, SE_ACRONYCHAL_SETTING,
|
|
33
|
+
SEI_ECL_GEOALT_MIN, SEI_ECL_GEOALT_MAX,
|
|
34
|
+
} from './constants';
|
|
35
|
+
import { sweDegnorm } from './swephlib';
|
|
36
|
+
import { sweDeltatEx } from './swephlib';
|
|
37
|
+
import { swiPolcart } from './swephlib';
|
|
38
|
+
import { revJul } from './swedate';
|
|
39
|
+
import { sweCalc, sweCalcUt, sweFixstar, sweFixstarMag, sweSetTopo, sweGetPlanetName } from './sweph';
|
|
40
|
+
import { sweRiseTrans, sweAzalt, swePhenoUt } from './swecl';
|
|
41
|
+
import type { SweData } from './types';
|
|
42
|
+
|
|
43
|
+
/* ---- Module-level constants ---- */
|
|
44
|
+
const PLSV = 0;
|
|
45
|
+
const criticalangle = 0.0;
|
|
46
|
+
const BNIGHT = 1479.0;
|
|
47
|
+
const BNIGHT_FACTOR = 1.0;
|
|
48
|
+
const Min2Deg = 1.0 / 60.0;
|
|
49
|
+
const MaxTryHours = 4;
|
|
50
|
+
const TimeStepDefault = 1;
|
|
51
|
+
const LocalMinStep = 8;
|
|
52
|
+
|
|
53
|
+
/* time constants */
|
|
54
|
+
const D2H = 24.0;
|
|
55
|
+
const H2S = 3600.0;
|
|
56
|
+
const D2S = D2H * H2S;
|
|
57
|
+
|
|
58
|
+
/* refraction algorithm choice */
|
|
59
|
+
const REFR_SINCLAIR = 0;
|
|
60
|
+
const FormAstroRefrac = REFR_SINCLAIR;
|
|
61
|
+
const GravitySource = 2;
|
|
62
|
+
const REarthSource = 1;
|
|
63
|
+
|
|
64
|
+
const MAX_COUNT_SYNPER = 5;
|
|
65
|
+
const MAX_COUNT_SYNPER_MAX = 1000000;
|
|
66
|
+
const AvgRadiusMoon = 15.541 / 60;
|
|
67
|
+
|
|
68
|
+
/* WGS84 */
|
|
69
|
+
const Ra = 6378136.6;
|
|
70
|
+
|
|
71
|
+
/* Schaefer model */
|
|
72
|
+
const nL2erg = 1.02e-15;
|
|
73
|
+
const erg2nL = 1 / nL2erg;
|
|
74
|
+
const scaleHwater = 3000.0;
|
|
75
|
+
const scaleHrayleigh = 8515.0;
|
|
76
|
+
const scaleHaerosol = 3745.0;
|
|
77
|
+
const scaleHozone = 20000.0;
|
|
78
|
+
const astr2tau = 0.921034037197618;
|
|
79
|
+
const tau2astr = 1 / astr2tau;
|
|
80
|
+
|
|
81
|
+
/* meteorological */
|
|
82
|
+
const C2K = 273.15;
|
|
83
|
+
const LapseSA = 0.0065;
|
|
84
|
+
|
|
85
|
+
const LowestAppAlt = -3.5;
|
|
86
|
+
const epsilon = 0.001;
|
|
87
|
+
const staticAirmass = 0;
|
|
88
|
+
|
|
89
|
+
/* optic defaults */
|
|
90
|
+
const GOpticMag = 1;
|
|
91
|
+
const GOpticTrans = 0.8;
|
|
92
|
+
const GBinocular = 1;
|
|
93
|
+
const GOpticDia = 50;
|
|
94
|
+
|
|
95
|
+
/* conjunction reference table */
|
|
96
|
+
const tcon = [
|
|
97
|
+
0, 0,
|
|
98
|
+
2451550, 2451550, /* Moon */
|
|
99
|
+
2451604, 2451670, /* Mercury */
|
|
100
|
+
2451980, 2452280, /* Venus */
|
|
101
|
+
2451727, 2452074, /* Mars */
|
|
102
|
+
2451673, 2451877, /* Jupiter */
|
|
103
|
+
2451675, 2451868, /* Saturn */
|
|
104
|
+
2451581, 2451768, /* Uranus */
|
|
105
|
+
2451568, 2451753, /* Neptune */
|
|
106
|
+
];
|
|
107
|
+
|
|
108
|
+
/* ---- Module-level caches (replacing C static TLS) ---- */
|
|
109
|
+
let sunRA_tjdlast = 0;
|
|
110
|
+
let sunRA_ralast = 0;
|
|
111
|
+
let kOZ_alts_last = -99999;
|
|
112
|
+
let kOZ_sunra_last = -99999;
|
|
113
|
+
let kOZ_last = 0;
|
|
114
|
+
let ka_alts_last = -99999;
|
|
115
|
+
let ka_sunra_last = -99999;
|
|
116
|
+
let ka_last = 0;
|
|
117
|
+
let deltam_alts_last = -99999;
|
|
118
|
+
let deltam_alto_last = -99999;
|
|
119
|
+
let deltam_sunra_last = -99999;
|
|
120
|
+
let deltam_last = 0;
|
|
121
|
+
let fixstarMag_star_save = '';
|
|
122
|
+
let fixstarMag_dmag = 0;
|
|
123
|
+
|
|
124
|
+
/* ================================================================
|
|
125
|
+
* A. Pure math functions (no swed)
|
|
126
|
+
* ================================================================ */
|
|
127
|
+
|
|
128
|
+
function Sgn(x: number): number {
|
|
129
|
+
if (x < 0) return -1;
|
|
130
|
+
return 1;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function Kelvin(Temp: number): number {
|
|
134
|
+
return Temp + C2K;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function HourAngle(TopoAlt: number, TopoDecl: number, Lat: number): number {
|
|
138
|
+
const Alti = TopoAlt * DEGTORAD;
|
|
139
|
+
const decli = TopoDecl * DEGTORAD;
|
|
140
|
+
const Lati = Lat * DEGTORAD;
|
|
141
|
+
let ha = (Math.sin(Alti) - Math.sin(Lati) * Math.sin(decli)) / Math.cos(Lati) / Math.cos(decli);
|
|
142
|
+
if (ha < -1) ha = -1;
|
|
143
|
+
if (ha > 1) ha = 1;
|
|
144
|
+
return Math.acos(ha) / DEGTORAD / 15.0;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function DistanceAngle(LatA: number, LongA: number, LatB: number, LongB: number): number {
|
|
148
|
+
const dlon = LongB - LongA;
|
|
149
|
+
const dlat = LatB - LatA;
|
|
150
|
+
const sindlat2 = Math.sin(dlat / 2);
|
|
151
|
+
const sindlon2 = Math.sin(dlon / 2);
|
|
152
|
+
let corde = sindlat2 * sindlat2 + Math.cos(LatA) * Math.cos(LatB) * sindlon2 * sindlon2;
|
|
153
|
+
if (corde > 1) corde = 1;
|
|
154
|
+
return 2 * Math.asin(Math.sqrt(corde));
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function TopoAltfromAppAlt(AppAlt: number, TempE: number, PresE: number): number {
|
|
158
|
+
let R = 0;
|
|
159
|
+
let retalt = 0;
|
|
160
|
+
if (AppAlt >= LowestAppAlt) {
|
|
161
|
+
if (AppAlt > 17.904104638432)
|
|
162
|
+
R = 0.97 / Math.tan(AppAlt * DEGTORAD);
|
|
163
|
+
else
|
|
164
|
+
R = (34.46 + 4.23 * AppAlt + 0.004 * AppAlt * AppAlt) / (1 + 0.505 * AppAlt + 0.0845 * AppAlt * AppAlt);
|
|
165
|
+
R = (PresE - 80) / 930 / (1 + 0.00008 * (R + 39) * (TempE - 10)) * R;
|
|
166
|
+
retalt = AppAlt - R * Min2Deg;
|
|
167
|
+
} else {
|
|
168
|
+
retalt = AppAlt;
|
|
169
|
+
}
|
|
170
|
+
return retalt;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
function AppAltfromTopoAlt(TopoAlt: number, TempE: number, PresE: number, helflag: number): number {
|
|
174
|
+
let nloop = 2;
|
|
175
|
+
let newAppAlt = TopoAlt;
|
|
176
|
+
let newTopoAlt = 0.0;
|
|
177
|
+
let oudAppAlt = newAppAlt;
|
|
178
|
+
let oudTopoAlt = newTopoAlt;
|
|
179
|
+
let verschil: number;
|
|
180
|
+
if (helflag & SE_HELFLAG_HIGH_PRECISION)
|
|
181
|
+
nloop = 5;
|
|
182
|
+
for (let i = 0; i <= nloop; i++) {
|
|
183
|
+
newTopoAlt = newAppAlt - TopoAltfromAppAlt(newAppAlt, TempE, PresE);
|
|
184
|
+
verschil = newAppAlt - oudAppAlt;
|
|
185
|
+
oudAppAlt = newTopoAlt - oudTopoAlt - verschil;
|
|
186
|
+
if (verschil !== 0 && oudAppAlt !== 0)
|
|
187
|
+
verschil = newAppAlt - verschil * (TopoAlt + newTopoAlt - newAppAlt) / oudAppAlt;
|
|
188
|
+
else
|
|
189
|
+
verschil = TopoAlt + newTopoAlt;
|
|
190
|
+
oudAppAlt = newAppAlt;
|
|
191
|
+
oudTopoAlt = newTopoAlt;
|
|
192
|
+
newAppAlt = verschil;
|
|
193
|
+
}
|
|
194
|
+
const retalt = TopoAlt + newTopoAlt;
|
|
195
|
+
if (retalt < LowestAppAlt)
|
|
196
|
+
return TopoAlt;
|
|
197
|
+
return retalt;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
function TempEfromTempS(TempS: number, HeightEye: number, Lapse: number): number {
|
|
201
|
+
return TempS - Lapse * HeightEye;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
function PresEfromPresS(TempS: number, Press: number, HeightEye: number): number {
|
|
205
|
+
return Press * Math.exp(-9.80665 * 0.0289644 / (Kelvin(TempS) + 3.25 * HeightEye / 1000) / 8.31441 * HeightEye);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
function Airmass(AppAltO: number, Press: number): number {
|
|
209
|
+
let zend = (90 - AppAltO) * DEGTORAD;
|
|
210
|
+
if (zend > PI / 2) zend = PI / 2;
|
|
211
|
+
const airm = 1 / (Math.cos(zend) + 0.025 * Math.exp(-11 * Math.cos(zend)));
|
|
212
|
+
return Press / 1013 * airm;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
function Xext(scaleH: number, zend: number, Press: number): number {
|
|
216
|
+
return Press / 1013.0 / (Math.cos(zend) + 0.01 * Math.sqrt(scaleH / 1000.0) * Math.exp(-30.0 / Math.sqrt(scaleH / 1000.0) * Math.cos(zend)));
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
function Xlay(scaleH: number, zend: number, Press: number): number {
|
|
220
|
+
const a = Math.sin(zend) / (1.0 + scaleH / Ra);
|
|
221
|
+
return Press / 1013.0 / Math.sqrt(1.0 - a * a);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
function MoonsBrightness(dist: number, phasemoon: number): number {
|
|
225
|
+
const log10 = 2.302585092994;
|
|
226
|
+
return -21.62 + 5 * Math.log(dist / (Ra / 1000)) / log10 + 0.026 * Math.abs(phasemoon) + 0.000000004 * Math.pow(phasemoon, 4);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
function MoonPhase(AltM: number, AziM: number, AltS: number, AziS: number): number {
|
|
230
|
+
const AltMi = AltM * DEGTORAD;
|
|
231
|
+
const AltSi = AltS * DEGTORAD;
|
|
232
|
+
const AziMi = AziM * DEGTORAD;
|
|
233
|
+
const AziSi = AziS * DEGTORAD;
|
|
234
|
+
const MoonAvgPar = 0.95;
|
|
235
|
+
return 180 - Math.acos(Math.cos(AziSi - AziMi - MoonAvgPar * DEGTORAD) * Math.cos(AltMi + MoonAvgPar * DEGTORAD) * Math.cos(AltSi) + Math.sin(AltSi) * Math.sin(AltMi + MoonAvgPar * DEGTORAD)) / DEGTORAD;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
function WidthMoon(AltO: number, AziO: number, AltS: number, AziS: number, parallax: number): number {
|
|
239
|
+
const GeoAltO = AltO + parallax;
|
|
240
|
+
return 0.27245 * parallax * (1 + Math.sin(GeoAltO * DEGTORAD) * Math.sin(parallax * DEGTORAD)) * (1 - Math.cos((AltS - GeoAltO) * DEGTORAD) * Math.cos((AziS - AziO) * DEGTORAD));
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
function LengthMoon(W: number, Diamoon: number): number {
|
|
244
|
+
let D = Diamoon;
|
|
245
|
+
if (D === 0) D = AvgRadiusMoon * 2;
|
|
246
|
+
const Wi = W * 60;
|
|
247
|
+
D = D * 60;
|
|
248
|
+
return (D - 0.3 * (D + Wi) / 2.0 / Wi) / 60.0;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
function qYallop(W: number, GeoARCVact: number): number {
|
|
252
|
+
const Wi = W * 60;
|
|
253
|
+
return (GeoARCVact - (11.8371 - 6.3226 * Wi + 0.7319 * Wi * Wi - 0.1018 * Wi * Wi * Wi)) / 10;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
function crossing(A: number, B: number, C: number, D: number): number {
|
|
257
|
+
return (C - A) / ((B - A) - (D - C));
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
function x2min(A: number, B: number, C: number): number {
|
|
261
|
+
const term = A + C - 2 * B;
|
|
262
|
+
if (term === 0) return 0;
|
|
263
|
+
return -(A - C) / 2.0 / term;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
function funct2(A: number, B: number, C: number, x: number): number {
|
|
267
|
+
return (A + C - 2 * B) / 2.0 * x * x + (A - C) / 2.0 * x + B;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
function CVA(B: number, SN: number, helflag: number): number {
|
|
271
|
+
let is_scotopic = false;
|
|
272
|
+
if (B < 1394) is_scotopic = true;
|
|
273
|
+
if (helflag & SE_HELFLAG_VISLIM_PHOTOPIC) is_scotopic = false;
|
|
274
|
+
if (helflag & SE_HELFLAG_VISLIM_SCOTOPIC) is_scotopic = true;
|
|
275
|
+
if (is_scotopic)
|
|
276
|
+
return Math.min(900, 380 / SN * Math.pow(10, 0.3 * Math.pow(B, -0.29))) / 60.0 / 60.0;
|
|
277
|
+
else
|
|
278
|
+
return (40.0 / SN) * Math.pow(10, 8.28 * Math.pow(B, -0.29)) / 60.0 / 60.0;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
function PupilDia(Age: number, B: number): number {
|
|
282
|
+
return (0.534 - 0.00211 * Age - (0.236 - 0.00127 * Age) * Math.tanh(0.4 * Math.log(B) / Math.log(10) - 2.2)) * 10;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
function getSynodicPeriod(Planet: number): number {
|
|
286
|
+
switch (Planet) {
|
|
287
|
+
case SE_MOON: return 29.530588853;
|
|
288
|
+
case SE_MERCURY: return 115.8775;
|
|
289
|
+
case SE_VENUS: return 583.9214;
|
|
290
|
+
case SE_MARS: return 779.9361;
|
|
291
|
+
case SE_JUPITER: return 398.8840;
|
|
292
|
+
case SE_SATURN: return 378.0919;
|
|
293
|
+
case SE_URANUS: return 369.6560;
|
|
294
|
+
case SE_NEPTUNE: return 367.4867;
|
|
295
|
+
case SE_PLUTO: return 366.7207;
|
|
296
|
+
}
|
|
297
|
+
return 366;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
function DeterObject(ObjectName: string): number {
|
|
301
|
+
const s = ObjectName.toLowerCase();
|
|
302
|
+
if (s.startsWith('sun')) return SE_SUN;
|
|
303
|
+
if (s.startsWith('venus')) return SE_VENUS;
|
|
304
|
+
if (s.startsWith('mars')) return SE_MARS;
|
|
305
|
+
if (s.startsWith('mercur')) return SE_MERCURY;
|
|
306
|
+
if (s.startsWith('jupiter')) return SE_JUPITER;
|
|
307
|
+
if (s.startsWith('saturn')) return SE_SATURN;
|
|
308
|
+
if (s.startsWith('uranus')) return SE_URANUS;
|
|
309
|
+
if (s.startsWith('neptun')) return SE_NEPTUNE;
|
|
310
|
+
if (s.startsWith('moon')) return SE_MOON;
|
|
311
|
+
const ipl = parseInt(s, 10);
|
|
312
|
+
if (ipl > 0) return ipl + SE_AST_OFFSET;
|
|
313
|
+
return -1;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
function strcpyVBsafe(sin: string): string {
|
|
317
|
+
let out = '';
|
|
318
|
+
for (let i = 0; i < sin.length && out.length < 30; i++) {
|
|
319
|
+
const c = sin[i];
|
|
320
|
+
if (/[a-zA-Z0-9 ,\-]/.test(c)) out += c;
|
|
321
|
+
else break;
|
|
322
|
+
}
|
|
323
|
+
return out;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
function tolowerStringStar(str: string): string {
|
|
327
|
+
const commaIdx = str.indexOf(',');
|
|
328
|
+
if (commaIdx === -1) return str.toLowerCase();
|
|
329
|
+
return str.substring(0, commaIdx).toLowerCase() + str.substring(commaIdx);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
function defaultHeliacalParameters(datm: number[], dgeo: number[], dobs: number[], helflag: number): void {
|
|
333
|
+
if (datm[0] <= 0) {
|
|
334
|
+
datm[0] = 1013.25 * Math.pow(1 - 0.0065 * dgeo[2] / 288, 5.255);
|
|
335
|
+
if (datm[1] === 0) datm[1] = 15 - 0.0065 * dgeo[2];
|
|
336
|
+
if (datm[2] === 0) datm[2] = 40;
|
|
337
|
+
} else {
|
|
338
|
+
if (datm[2] <= 0.00000001) datm[2] = 0.00000001;
|
|
339
|
+
if (datm[2] >= 99.99999999) datm[2] = 99.99999999;
|
|
340
|
+
}
|
|
341
|
+
if (dobs[0] === 0) dobs[0] = 36;
|
|
342
|
+
if (dobs[1] === 0) dobs[1] = 1;
|
|
343
|
+
if (!(helflag & SE_HELFLAG_OPTICAL_PARAMS)) {
|
|
344
|
+
for (let i = 2; i <= 5; i++) dobs[i] = 0;
|
|
345
|
+
}
|
|
346
|
+
if (dobs[3] === 0) {
|
|
347
|
+
dobs[2] = 1;
|
|
348
|
+
dobs[3] = 1;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
/* ================================================================
|
|
353
|
+
* B. Atmospheric extinction (with caches)
|
|
354
|
+
* ================================================================ */
|
|
355
|
+
|
|
356
|
+
function kW(HeightEye: number, TempS: number, RH: number): number {
|
|
357
|
+
let WT = 0.031;
|
|
358
|
+
WT *= 0.94 * (RH / 100.0) * Math.exp(TempS / 15) * Math.exp(-1 * HeightEye / scaleHwater);
|
|
359
|
+
return WT;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
function kR(AltS: number, HeightEye: number): number {
|
|
363
|
+
let val = -AltS - 12;
|
|
364
|
+
if (val < 0) val = 0;
|
|
365
|
+
if (val > 6) val = 6;
|
|
366
|
+
const CHANGEK = 1 - 0.166667 * val;
|
|
367
|
+
const LAMBDA = 0.55 + (CHANGEK - 1) * 0.04;
|
|
368
|
+
return 0.1066 * Math.exp(-1 * HeightEye / scaleHrayleigh) * Math.pow(LAMBDA / 0.55, -4);
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
function kOZ(AltS: number, sunra: number, Lat: number): number {
|
|
372
|
+
if (AltS === kOZ_alts_last && sunra === kOZ_sunra_last) return kOZ_last;
|
|
373
|
+
kOZ_alts_last = AltS;
|
|
374
|
+
kOZ_sunra_last = sunra;
|
|
375
|
+
const OZ = 0.031;
|
|
376
|
+
const LT = Lat * DEGTORAD;
|
|
377
|
+
let kOZret = OZ * (3.0 + 0.4 * (LT * Math.cos(sunra * DEGTORAD) - Math.cos(3 * LT))) / 3.0;
|
|
378
|
+
let altslim = -AltS - 12;
|
|
379
|
+
if (altslim < 0) altslim = 0;
|
|
380
|
+
const CHANGEKO = (100 - 11.6 * Math.min(6, altslim)) / 100;
|
|
381
|
+
kOZ_last = kOZret * CHANGEKO;
|
|
382
|
+
return kOZ_last;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
function ka(AltS: number, sunra: number, Lat: number, HeightEye: number, TempS: number, RH: number, VR: number, serrRef: { value: string }): number {
|
|
386
|
+
const SL = Sgn(Lat);
|
|
387
|
+
if (AltS === ka_alts_last && sunra === ka_sunra_last) return ka_last;
|
|
388
|
+
ka_alts_last = AltS;
|
|
389
|
+
ka_sunra_last = sunra;
|
|
390
|
+
const CHANGEKA = 1 - 0.166667 * Math.min(6, Math.max(-AltS - 12, 0));
|
|
391
|
+
const LAMBDA = 0.55 + (CHANGEKA - 1) * 0.04;
|
|
392
|
+
let kaact: number;
|
|
393
|
+
if (VR !== 0) {
|
|
394
|
+
if (VR >= 1) {
|
|
395
|
+
const BetaVr = 3.912 / VR;
|
|
396
|
+
const Betaa = BetaVr - (kW(HeightEye, TempS, RH) / scaleHwater + kR(AltS, HeightEye) / scaleHrayleigh) * 1000 * astr2tau;
|
|
397
|
+
kaact = Betaa * scaleHaerosol / 1000 * tau2astr;
|
|
398
|
+
if (kaact < 0) {
|
|
399
|
+
serrRef.value = 'The provided Meteorological range is too long, when taking into acount other atmospheric parameters';
|
|
400
|
+
}
|
|
401
|
+
} else {
|
|
402
|
+
kaact = VR - kW(HeightEye, TempS, RH) - kR(AltS, HeightEye) - kOZ(AltS, sunra, Lat);
|
|
403
|
+
if (kaact < 0) {
|
|
404
|
+
serrRef.value = 'The provided atmosphic coeefficent (ktot) is too low, when taking into acount other atmospheric parameters';
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
} else {
|
|
408
|
+
kaact = 0.1 * Math.exp(-1 * HeightEye / scaleHaerosol) * Math.pow(1 - 0.32 / Math.log(RH / 100.0), 1.33) * (1 + 0.33 * SL * Math.sin(sunra * DEGTORAD));
|
|
409
|
+
kaact = kaact * Math.pow(LAMBDA / 0.55, -1.3);
|
|
410
|
+
}
|
|
411
|
+
ka_last = kaact;
|
|
412
|
+
return kaact;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
function kt(AltS: number, sunra: number, Lat: number, HeightEye: number, TempS: number, RH: number, VR: number, ExtType: number, serrRef: { value: string }): number {
|
|
416
|
+
let kRact = 0, kWact = 0, kOZact = 0, kaact = 0;
|
|
417
|
+
if (ExtType === 2 || ExtType === 4) kRact = kR(AltS, HeightEye);
|
|
418
|
+
if (ExtType === 1 || ExtType === 4) kWact = kW(HeightEye, TempS, RH);
|
|
419
|
+
if (ExtType === 3 || ExtType === 4) kOZact = kOZ(AltS, sunra, Lat);
|
|
420
|
+
if (ExtType === 0 || ExtType === 4) kaact = ka(AltS, sunra, Lat, HeightEye, TempS, RH, VR, serrRef);
|
|
421
|
+
if (kaact < 0) kaact = 0;
|
|
422
|
+
return kWact + kRact + kOZact + kaact;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
function Deltam(AltO: number, AltS: number, sunra: number, Lat: number, HeightEye: number, datm: number[], helflag: number, serrRef: { value: string }): number {
|
|
426
|
+
if (AltS === deltam_alts_last && AltO === deltam_alto_last && sunra === deltam_sunra_last) return deltam_last;
|
|
427
|
+
deltam_alts_last = AltS;
|
|
428
|
+
deltam_alto_last = AltO;
|
|
429
|
+
deltam_sunra_last = sunra;
|
|
430
|
+
const PresE = PresEfromPresS(datm[1], datm[0], HeightEye);
|
|
431
|
+
const TempE = TempEfromTempS(datm[1], HeightEye, LapseSA);
|
|
432
|
+
const AppAltO = AppAltfromTopoAlt(AltO, TempE, PresE, helflag);
|
|
433
|
+
let deltam: number;
|
|
434
|
+
if (staticAirmass === 0) {
|
|
435
|
+
let zend = (90 - AppAltO) * DEGTORAD;
|
|
436
|
+
if (zend > PI / 2) zend = PI / 2;
|
|
437
|
+
const xR = Xext(scaleHrayleigh, zend, datm[0]);
|
|
438
|
+
const XW = Xext(scaleHwater, zend, datm[0]);
|
|
439
|
+
const Xa = Xext(scaleHaerosol, zend, datm[0]);
|
|
440
|
+
const XOZ = Xlay(scaleHozone, zend, datm[0]);
|
|
441
|
+
deltam = kR(AltS, HeightEye) * xR + kt(AltS, sunra, Lat, HeightEye, datm[1], datm[2], datm[3], 0, serrRef) * Xa + kOZ(AltS, sunra, Lat) * XOZ + kW(HeightEye, datm[1], datm[2]) * XW;
|
|
442
|
+
} else {
|
|
443
|
+
deltam = kt(AltS, sunra, Lat, HeightEye, datm[1], datm[2], datm[3], 4, serrRef) * Airmass(AppAltO, datm[0]);
|
|
444
|
+
}
|
|
445
|
+
deltam_last = deltam;
|
|
446
|
+
return deltam;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
/* ================================================================
|
|
450
|
+
* C. Sky brightness
|
|
451
|
+
* ================================================================ */
|
|
452
|
+
|
|
453
|
+
function Bn(AltO: number, JDNDayUT: number, AltS: number, sunra: number, Lat: number, HeightEye: number, datm: number[], helflag: number, serrRef: { value: string }): number {
|
|
454
|
+
const PresE = PresEfromPresS(datm[1], datm[0], HeightEye);
|
|
455
|
+
const TempE = TempEfromTempS(datm[1], HeightEye, LapseSA);
|
|
456
|
+
let AppAltO = AppAltfromTopoAlt(AltO, TempE, PresE, helflag);
|
|
457
|
+
const B0 = 0.0000000000001;
|
|
458
|
+
if (AppAltO < 10) AppAltO = 10;
|
|
459
|
+
const zend = (90 - AppAltO) * DEGTORAD;
|
|
460
|
+
const r = revJul(JDNDayUT, SE_GREG_CAL);
|
|
461
|
+
const YearB = r.year;
|
|
462
|
+
const MonthB = r.month;
|
|
463
|
+
const DayB = r.day;
|
|
464
|
+
const Bna = B0 * (1 + 0.3 * Math.cos(6.283 * (YearB + ((DayB - 1) / 30.4 + MonthB - 1) / 12 - 1990.33) / 11.1));
|
|
465
|
+
const kX = Deltam(AltO, AltS, sunra, Lat, HeightEye, datm, helflag, serrRef);
|
|
466
|
+
const Bnb = Bna * (0.4 + 0.6 / Math.sqrt(1 - 0.96 * Math.pow(Math.sin(zend), 2))) * Math.pow(10, -0.4 * kX);
|
|
467
|
+
return Math.max(Bnb, 0) * erg2nL;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
function Bm(AltO: number, AziO: number, AltM: number, AziM: number, AltS: number, AziS: number, sunra: number, Lat: number, HeightEye: number, datm: number[], helflag: number, serrRef: { value: string }): number {
|
|
471
|
+
const M0 = -11.05;
|
|
472
|
+
let BmVal = 0;
|
|
473
|
+
const lunar_radius = 0.25 * DEGTORAD;
|
|
474
|
+
const object_is_moon = (AltO === AltM && AziO === AziM);
|
|
475
|
+
if (AltM > -0.26 && !object_is_moon) {
|
|
476
|
+
let RM = DistanceAngle(AltO * DEGTORAD, AziO * DEGTORAD, AltM * DEGTORAD, AziM * DEGTORAD) / DEGTORAD;
|
|
477
|
+
if (RM <= lunar_radius / DEGTORAD) RM = lunar_radius / DEGTORAD;
|
|
478
|
+
const kXM = Deltam(AltM, AltS, sunra, Lat, HeightEye, datm, helflag, serrRef);
|
|
479
|
+
const kX = Deltam(AltO, AltS, sunra, Lat, HeightEye, datm, helflag, serrRef);
|
|
480
|
+
const C3 = Math.pow(10, -0.4 * kXM);
|
|
481
|
+
const FM = 62000000.0 / RM / RM + Math.pow(10, 6.15 - RM / 40) + Math.pow(10, 5.36) * (1.06 + Math.pow(Math.cos(RM * DEGTORAD), 2));
|
|
482
|
+
BmVal = FM * C3 + 440000 * (1 - C3);
|
|
483
|
+
const phasemoon = MoonPhase(AltM, AziM, AltS, AziS);
|
|
484
|
+
const MM = MoonsBrightness(384410.4978, phasemoon);
|
|
485
|
+
BmVal = BmVal * Math.pow(10, -0.4 * (MM - M0 + 43.27));
|
|
486
|
+
BmVal = BmVal * (1 - Math.pow(10, -0.4 * kX));
|
|
487
|
+
}
|
|
488
|
+
BmVal = Math.max(BmVal, 0) * erg2nL;
|
|
489
|
+
return BmVal;
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
function Btwi(AltO: number, AziO: number, AltS: number, AziS: number, sunra: number, Lat: number, HeightEye: number, datm: number[], helflag: number, serrRef: { value: string }): number {
|
|
493
|
+
const M0 = -11.05;
|
|
494
|
+
const MS = -26.74;
|
|
495
|
+
const PresE = PresEfromPresS(datm[1], datm[0], HeightEye);
|
|
496
|
+
const TempE = TempEfromTempS(datm[1], HeightEye, LapseSA);
|
|
497
|
+
const AppAltO = AppAltfromTopoAlt(AltO, TempE, PresE, helflag);
|
|
498
|
+
const ZendO = 90 - AppAltO;
|
|
499
|
+
const RS = DistanceAngle(AltO * DEGTORAD, AziO * DEGTORAD, AltS * DEGTORAD, AziS * DEGTORAD) / DEGTORAD;
|
|
500
|
+
const kX = Deltam(AltO, AltS, sunra, Lat, HeightEye, datm, helflag, serrRef);
|
|
501
|
+
const k = kt(AltS, sunra, Lat, HeightEye, datm[1], datm[2], datm[3], 4, serrRef);
|
|
502
|
+
let BtwiVal = Math.pow(10, -0.4 * (MS - M0 + 32.5 - AltS - (ZendO / (360 * k))));
|
|
503
|
+
BtwiVal = BtwiVal * (100 / RS) * (1 - Math.pow(10, -0.4 * kX));
|
|
504
|
+
BtwiVal = Math.max(BtwiVal, 0) * erg2nL;
|
|
505
|
+
return BtwiVal;
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
function Bday(AltO: number, AziO: number, AltS: number, AziS: number, sunra: number, Lat: number, HeightEye: number, datm: number[], helflag: number, serrRef: { value: string }): number {
|
|
509
|
+
const M0 = -11.05;
|
|
510
|
+
const MS = -26.74;
|
|
511
|
+
const RS = DistanceAngle(AltO * DEGTORAD, AziO * DEGTORAD, AltS * DEGTORAD, AziS * DEGTORAD) / DEGTORAD;
|
|
512
|
+
const kXS = Deltam(AltS, AltS, sunra, Lat, HeightEye, datm, helflag, serrRef);
|
|
513
|
+
const kX = Deltam(AltO, AltS, sunra, Lat, HeightEye, datm, helflag, serrRef);
|
|
514
|
+
const C4 = Math.pow(10, -0.4 * kXS);
|
|
515
|
+
const FS = 62000000.0 / RS / RS + Math.pow(10, 6.15 - RS / 40) + Math.pow(10, 5.36) * (1.06 + Math.pow(Math.cos(RS * DEGTORAD), 2));
|
|
516
|
+
let BdayVal = FS * C4 + 440000.0 * (1 - C4);
|
|
517
|
+
BdayVal = BdayVal * Math.pow(10, -0.4 * (MS - M0 + 43.27));
|
|
518
|
+
BdayVal = BdayVal * (1 - Math.pow(10, -0.4 * kX));
|
|
519
|
+
BdayVal = Math.max(BdayVal, 0) * erg2nL;
|
|
520
|
+
return BdayVal;
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
function Bcity(Value: number, _Press: number): number {
|
|
524
|
+
return Math.max(Value, 0);
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
function Bsky(AltO: number, AziO: number, AltM: number, AziM: number, JDNDaysUT: number, AltS: number, AziS: number, sunra: number, Lat: number, HeightEye: number, datm: number[], helflag: number, serrRef: { value: string }): number {
|
|
528
|
+
let BskyVal = 0;
|
|
529
|
+
if (AltS < -3) {
|
|
530
|
+
BskyVal += Btwi(AltO, AziO, AltS, AziS, sunra, Lat, HeightEye, datm, helflag, serrRef);
|
|
531
|
+
} else {
|
|
532
|
+
if (AltS > 4) {
|
|
533
|
+
BskyVal += Bday(AltO, AziO, AltS, AziS, sunra, Lat, HeightEye, datm, helflag, serrRef);
|
|
534
|
+
} else {
|
|
535
|
+
BskyVal += Math.min(Bday(AltO, AziO, AltS, AziS, sunra, Lat, HeightEye, datm, helflag, serrRef), Btwi(AltO, AziO, AltS, AziS, sunra, Lat, HeightEye, datm, helflag, serrRef));
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
if (BskyVal < 200000000.0)
|
|
539
|
+
BskyVal += Bm(AltO, AziO, AltM, AziM, AltS, AziS, sunra, Lat, HeightEye, datm, helflag, serrRef);
|
|
540
|
+
if (AltS <= 0)
|
|
541
|
+
BskyVal += Bcity(0, datm[0]);
|
|
542
|
+
if (BskyVal < 5000)
|
|
543
|
+
BskyVal += Bn(AltO, JDNDaysUT, AltS, sunra, Lat, HeightEye, datm, helflag, serrRef);
|
|
544
|
+
return BskyVal;
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
/* ================================================================
|
|
548
|
+
* D. Optic factor and visual limit magnitude
|
|
549
|
+
* ================================================================ */
|
|
550
|
+
|
|
551
|
+
function OpticFactor(Bback: number, kX: number, dobs: number[], JDNDaysUT: number, ObjectName: string, TypeFactor: number, helflag: number): number {
|
|
552
|
+
const Age = dobs[0];
|
|
553
|
+
const SN = dobs[1];
|
|
554
|
+
let SNi = SN;
|
|
555
|
+
const Binocular = dobs[2];
|
|
556
|
+
let OpticMag = dobs[3];
|
|
557
|
+
let OpticDia = dobs[4];
|
|
558
|
+
let OpticTrans = dobs[5];
|
|
559
|
+
let is_scotopic = false;
|
|
560
|
+
if (SNi <= 0.00000001) SNi = 0.00000001;
|
|
561
|
+
const Pst = PupilDia(23, Bback);
|
|
562
|
+
if (OpticMag === 1) {
|
|
563
|
+
OpticTrans = 1;
|
|
564
|
+
OpticDia = Pst;
|
|
565
|
+
}
|
|
566
|
+
const CIb = 0.7;
|
|
567
|
+
const CIi = 0.5;
|
|
568
|
+
const ObjectSize = 0;
|
|
569
|
+
let Fb = 1;
|
|
570
|
+
if (Binocular === 0) Fb = 1.41;
|
|
571
|
+
if (Bback < 1645) is_scotopic = true;
|
|
572
|
+
if (helflag & SE_HELFLAG_VISLIM_PHOTOPIC) is_scotopic = false;
|
|
573
|
+
if (helflag & SE_HELFLAG_VISLIM_SCOTOPIC) is_scotopic = true;
|
|
574
|
+
let Fe: number, Fsc: number, Fci: number, Fcb: number;
|
|
575
|
+
if (is_scotopic) {
|
|
576
|
+
Fe = Math.pow(10, 0.48 * kX);
|
|
577
|
+
Fsc = Math.min(1, (1 - Math.pow(Pst / 124.4, 4)) / (1 - Math.pow(OpticDia / OpticMag / 124.4, 4)));
|
|
578
|
+
Fci = Math.pow(10, -0.4 * (1 - CIi / 2.0));
|
|
579
|
+
Fcb = Math.pow(10, -0.4 * (1 - CIb / 2.0));
|
|
580
|
+
} else {
|
|
581
|
+
Fe = Math.pow(10, 0.4 * kX);
|
|
582
|
+
Fsc = Math.min(1, Math.pow(OpticDia / OpticMag / Pst, 2) * (1 - Math.exp(-Math.pow(Pst / 6.2, 2))) / (1 - Math.exp(-Math.pow(OpticDia / OpticMag / 6.2, 2))));
|
|
583
|
+
Fci = 1;
|
|
584
|
+
Fcb = 1;
|
|
585
|
+
}
|
|
586
|
+
const Ft = 1 / OpticTrans;
|
|
587
|
+
const Fp = Math.max(1, Math.pow(Pst / (OpticMag * PupilDia(Age, Bback)), 2));
|
|
588
|
+
const Fa = Math.pow(Pst / OpticDia, 2);
|
|
589
|
+
const Fr = (1 + 0.03 * Math.pow(OpticMag * ObjectSize / CVA(Bback, SNi, helflag), 2)) / Math.pow(SNi, 2);
|
|
590
|
+
const Fm = Math.pow(OpticMag, 2);
|
|
591
|
+
if (TypeFactor === 0)
|
|
592
|
+
return Fb * Fe * Ft * Fp * Fa * Fr * Fsc * Fci;
|
|
593
|
+
else
|
|
594
|
+
return Fb * Ft * Fp * Fa * Fm * Fsc * Fcb;
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
function VisLimMagn(dobs: number[], AltO: number, AziO: number, AltM: number, AziM: number, JDNDaysUT: number, AltS: number, AziS: number, sunra: number, Lat: number, HeightEye: number, datm: number[], helflag: number, scotopic_flag: { value: number } | null, serrRef: { value: string }): number {
|
|
598
|
+
const log10 = 2.302585092994;
|
|
599
|
+
let is_scotopic = false;
|
|
600
|
+
let Bsk = Bsky(AltO, AziO, AltM, AziM, JDNDaysUT, AltS, AziS, sunra, Lat, HeightEye, datm, helflag, serrRef);
|
|
601
|
+
const kX = Deltam(AltO, AltS, sunra, Lat, HeightEye, datm, helflag, serrRef);
|
|
602
|
+
const CorrFactor1 = OpticFactor(Bsk, kX, dobs, JDNDaysUT, '', 1, helflag);
|
|
603
|
+
const CorrFactor2 = OpticFactor(Bsk, kX, dobs, JDNDaysUT, '', 0, helflag);
|
|
604
|
+
if (Bsk < 1645) is_scotopic = true;
|
|
605
|
+
if (helflag & SE_HELFLAG_VISLIM_PHOTOPIC) is_scotopic = false;
|
|
606
|
+
if (helflag & SE_HELFLAG_VISLIM_SCOTOPIC) is_scotopic = true;
|
|
607
|
+
let C1: number, C2: number;
|
|
608
|
+
if (is_scotopic) {
|
|
609
|
+
C1 = 1.5848931924611e-10;
|
|
610
|
+
C2 = 0.012589254117942;
|
|
611
|
+
if (scotopic_flag !== null) scotopic_flag.value = 1;
|
|
612
|
+
} else {
|
|
613
|
+
C1 = 4.4668359215096e-9;
|
|
614
|
+
C2 = 1.2589254117942e-6;
|
|
615
|
+
if (scotopic_flag !== null) scotopic_flag.value = 0;
|
|
616
|
+
}
|
|
617
|
+
if (scotopic_flag !== null) {
|
|
618
|
+
if (BNIGHT * BNIGHT_FACTOR > Bsk && BNIGHT / BNIGHT_FACTOR < Bsk)
|
|
619
|
+
scotopic_flag.value |= 2;
|
|
620
|
+
}
|
|
621
|
+
Bsk = Bsk * CorrFactor1;
|
|
622
|
+
const Th = C1 * Math.pow(1 + Math.sqrt(C2 * Bsk), 2) * CorrFactor2;
|
|
623
|
+
return -16.57 - 2.5 * (Math.log(Th) / log10);
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
/* ================================================================
|
|
627
|
+
* E. Swiss Ephemeris wrappers (need swed)
|
|
628
|
+
* ================================================================ */
|
|
629
|
+
|
|
630
|
+
function callSweFixstar(swed: SweData, star: string, tjd: number, iflag: number): { retval: number; xx: Float64Array; serr: string } {
|
|
631
|
+
const r = sweFixstar(swed, star, tjd, iflag);
|
|
632
|
+
return { retval: r.flags === ERR ? ERR : OK, xx: r.xx, serr: r.serr };
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
function callSweFixstarMag(swed: SweData, star: string): { retval: number; mag: number; serr: string } {
|
|
636
|
+
if (star === fixstarMag_star_save) {
|
|
637
|
+
return { retval: OK, mag: fixstarMag_dmag, serr: '' };
|
|
638
|
+
}
|
|
639
|
+
fixstarMag_star_save = star;
|
|
640
|
+
const r = sweFixstarMag(swed, star);
|
|
641
|
+
fixstarMag_dmag = r.mag;
|
|
642
|
+
return { retval: r.serr ? ERR : OK, mag: r.mag, serr: r.serr };
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
function callSweRiseTrans(swed: SweData, tjd: number, ipl: number, star: string, helflag: number, eventtype: number, dgeo: number[], atpress: number, attemp: number): { retval: number; tret: number; serr: string } {
|
|
646
|
+
const iflag = helflag & (SEFLG_JPLEPH | SEFLG_SWIEPH | SEFLG_MOSEPH);
|
|
647
|
+
const serrRef = { value: '' };
|
|
648
|
+
const r = sweRiseTrans(swed, tjd, ipl, star || null, iflag, eventtype, dgeo, atpress, attemp, serrRef);
|
|
649
|
+
return { retval: r.retval, tret: r.tret, serr: serrRef.value };
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
function SunRA(swed: SweData, JDNDaysUT: number, helflag: number): { ra: number; serr: string } {
|
|
653
|
+
let serr = '';
|
|
654
|
+
if (JDNDaysUT === sunRA_tjdlast) return { ra: sunRA_ralast, serr: '' };
|
|
655
|
+
const epheflag = helflag & (SEFLG_JPLEPH | SEFLG_SWIEPH | SEFLG_MOSEPH);
|
|
656
|
+
const iflag = epheflag | SEFLG_EQUATORIAL | SEFLG_NONUT | SEFLG_TRUEPOS;
|
|
657
|
+
const tjd_tt = JDNDaysUT + sweDeltatEx(JDNDaysUT, epheflag, swed);
|
|
658
|
+
const r = sweCalc(swed, tjd_tt, SE_SUN, iflag);
|
|
659
|
+
if (r.flags !== ERR) {
|
|
660
|
+
sunRA_ralast = r.xx[0];
|
|
661
|
+
sunRA_tjdlast = JDNDaysUT;
|
|
662
|
+
return { ra: sunRA_ralast, serr: r.serr };
|
|
663
|
+
}
|
|
664
|
+
/* fallback approximation */
|
|
665
|
+
const rv = revJul(JDNDaysUT, SE_GREG_CAL);
|
|
666
|
+
sunRA_tjdlast = JDNDaysUT;
|
|
667
|
+
sunRA_ralast = sweDegnorm((rv.month + (rv.day - 1) / 30.4 - 3.69) * 30);
|
|
668
|
+
return { ra: sunRA_ralast, serr };
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
function Magnitude(swed: SweData, JDNDaysUT: number, dgeo: number[], ObjectName: string, helflag: number): { retval: number; dmag: number; serr: string } {
|
|
672
|
+
const epheflag = helflag & (SEFLG_JPLEPH | SEFLG_SWIEPH | SEFLG_MOSEPH);
|
|
673
|
+
let dmag = -99.0;
|
|
674
|
+
const Planet = DeterObject(ObjectName);
|
|
675
|
+
let iflag = SEFLG_TOPOCTR | SEFLG_EQUATORIAL | epheflag;
|
|
676
|
+
if (!(helflag & SE_HELFLAG_HIGH_PRECISION))
|
|
677
|
+
iflag |= SEFLG_NONUT | SEFLG_TRUEPOS;
|
|
678
|
+
if (Planet !== -1) {
|
|
679
|
+
sweSetTopo(swed, dgeo[0], dgeo[1], dgeo[2]);
|
|
680
|
+
const serrRef = { value: '' };
|
|
681
|
+
const r = swePhenoUt(swed, JDNDaysUT, Planet, iflag, serrRef);
|
|
682
|
+
if (r.retval === ERR) return { retval: ERR, dmag, serr: serrRef.value };
|
|
683
|
+
dmag = r.attr[4];
|
|
684
|
+
return { retval: OK, dmag, serr: serrRef.value };
|
|
685
|
+
} else {
|
|
686
|
+
const r = callSweFixstarMag(swed, ObjectName);
|
|
687
|
+
if (r.retval === ERR) return { retval: ERR, dmag, serr: r.serr };
|
|
688
|
+
dmag = r.mag;
|
|
689
|
+
return { retval: OK, dmag, serr: r.serr };
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
function ObjectLoc(swed: SweData, JDNDaysUT: number, dgeo: number[], datm: number[], ObjectName: string, Angle: number, helflag: number): { retval: number; dret: number; serr: string } {
|
|
694
|
+
const epheflag = helflag & (SEFLG_JPLEPH | SEFLG_SWIEPH | SEFLG_MOSEPH);
|
|
695
|
+
let iflag = SEFLG_EQUATORIAL | epheflag;
|
|
696
|
+
if (!(helflag & SE_HELFLAG_HIGH_PRECISION))
|
|
697
|
+
iflag |= SEFLG_NONUT | SEFLG_TRUEPOS;
|
|
698
|
+
let AngleAdj = Angle;
|
|
699
|
+
if (AngleAdj < 5) iflag |= SEFLG_TOPOCTR;
|
|
700
|
+
if (AngleAdj === 7) AngleAdj = 0;
|
|
701
|
+
const tjd_tt = JDNDaysUT + sweDeltatEx(JDNDaysUT, epheflag, swed);
|
|
702
|
+
const Planet = DeterObject(ObjectName);
|
|
703
|
+
let x: Float64Array;
|
|
704
|
+
let serr = '';
|
|
705
|
+
if (Planet !== -1) {
|
|
706
|
+
const r = sweCalc(swed, tjd_tt, Planet, iflag);
|
|
707
|
+
if (r.flags === ERR) return { retval: ERR, dret: 0, serr: r.serr };
|
|
708
|
+
x = r.xx;
|
|
709
|
+
serr = r.serr;
|
|
710
|
+
} else {
|
|
711
|
+
const r = callSweFixstar(swed, ObjectName, tjd_tt, iflag);
|
|
712
|
+
if (r.retval === ERR) return { retval: ERR, dret: 0, serr: r.serr };
|
|
713
|
+
x = r.xx;
|
|
714
|
+
serr = r.serr;
|
|
715
|
+
}
|
|
716
|
+
if (AngleAdj === 2 || AngleAdj === 5) {
|
|
717
|
+
return { retval: OK, dret: x[1], serr };
|
|
718
|
+
} else if (AngleAdj === 3 || AngleAdj === 6) {
|
|
719
|
+
return { retval: OK, dret: x[0], serr };
|
|
720
|
+
} else {
|
|
721
|
+
const xin = [x[0], x[1]];
|
|
722
|
+
const xaz = [0, 0, 0];
|
|
723
|
+
sweAzalt(swed, JDNDaysUT, SE_EQU2HOR, dgeo, datm[0], datm[1], xin, xaz);
|
|
724
|
+
if (AngleAdj === 0) return { retval: OK, dret: xaz[1], serr };
|
|
725
|
+
if (AngleAdj === 4) return { retval: OK, dret: AppAltfromTopoAlt(xaz[1], datm[0], datm[1], helflag), serr };
|
|
726
|
+
if (AngleAdj === 1) {
|
|
727
|
+
let azi = xaz[0] + 180;
|
|
728
|
+
if (azi >= 360) azi -= 360;
|
|
729
|
+
return { retval: OK, dret: azi, serr };
|
|
730
|
+
}
|
|
731
|
+
return { retval: OK, dret: xaz[1], serr };
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
function azaltCart(swed: SweData, JDNDaysUT: number, dgeo: number[], datm: number[], ObjectName: string, helflag: number): { retval: number; dret: number[]; serr: string } {
|
|
736
|
+
const epheflag = helflag & (SEFLG_JPLEPH | SEFLG_SWIEPH | SEFLG_MOSEPH);
|
|
737
|
+
let iflag = SEFLG_EQUATORIAL | epheflag;
|
|
738
|
+
if (!(helflag & SE_HELFLAG_HIGH_PRECISION))
|
|
739
|
+
iflag |= SEFLG_NONUT | SEFLG_TRUEPOS;
|
|
740
|
+
iflag |= SEFLG_TOPOCTR;
|
|
741
|
+
const tjd_tt = JDNDaysUT + sweDeltatEx(JDNDaysUT, epheflag, swed);
|
|
742
|
+
const Planet = DeterObject(ObjectName);
|
|
743
|
+
let x: Float64Array;
|
|
744
|
+
let serr = '';
|
|
745
|
+
if (Planet !== -1) {
|
|
746
|
+
const r = sweCalc(swed, tjd_tt, Planet, iflag);
|
|
747
|
+
if (r.flags === ERR) return { retval: ERR, dret: [0, 0, 0, 0, 0, 0], serr: r.serr };
|
|
748
|
+
x = r.xx; serr = r.serr;
|
|
749
|
+
} else {
|
|
750
|
+
const r = callSweFixstar(swed, ObjectName, tjd_tt, iflag);
|
|
751
|
+
if (r.retval === ERR) return { retval: ERR, dret: [0, 0, 0, 0, 0, 0], serr: r.serr };
|
|
752
|
+
x = r.xx; serr = r.serr;
|
|
753
|
+
}
|
|
754
|
+
const xin = [x[0], x[1]];
|
|
755
|
+
const xaz = [0, 0, 0];
|
|
756
|
+
sweAzalt(swed, JDNDaysUT, SE_EQU2HOR, dgeo, datm[0], datm[1], xin, xaz);
|
|
757
|
+
const dret = [xaz[0], xaz[1], xaz[2], 0, 0, 0];
|
|
758
|
+
const xazCart = [xaz[0], xaz[2], 1];
|
|
759
|
+
const cart = [0, 0, 0];
|
|
760
|
+
swiPolcart(xazCart, cart);
|
|
761
|
+
dret[3] = cart[0]; dret[4] = cart[1]; dret[5] = cart[2];
|
|
762
|
+
return { retval: OK, dret, serr };
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
function calcRiseAndSet(swed: SweData, tjd_start: number, ipl: number, dgeo: number[], datm: number[], eventflag: number, helflag: number): { retval: number; tret: number; serr: string } {
|
|
766
|
+
const dfac = 1 / 365.25;
|
|
767
|
+
const epheflag = helflag & (SEFLG_JPLEPH | SEFLG_SWIEPH | SEFLG_MOSEPH);
|
|
768
|
+
let iflag = epheflag | SEFLG_EQUATORIAL;
|
|
769
|
+
if (!(helflag & SE_HELFLAG_HIGH_PRECISION))
|
|
770
|
+
iflag |= SEFLG_NONUT | SEFLG_TRUEPOS;
|
|
771
|
+
const rs = sweCalcUt(swed, tjd_start, SE_SUN, iflag);
|
|
772
|
+
if (rs.flags === ERR) return { retval: ERR, tret: 0, serr: 'error in calc_rise_and_set(): calc(sun) failed' };
|
|
773
|
+
const xs = rs.xx;
|
|
774
|
+
const rx = sweCalcUt(swed, tjd_start, ipl, iflag);
|
|
775
|
+
if (rx.flags === ERR) return { retval: ERR, tret: 0, serr: 'error in calc_rise_and_set(): calc failed' };
|
|
776
|
+
const xx = rx.xx;
|
|
777
|
+
let tjdnoon = Math.trunc(tjd_start) - dgeo[0] / 15.0 / 24.0;
|
|
778
|
+
tjdnoon -= sweDegnorm(xs[0] - xx[0]) / 360.0;
|
|
779
|
+
const xaz = [0, 0, 0];
|
|
780
|
+
sweAzalt(swed, tjd_start, SE_EQU2HOR, dgeo, datm[0], datm[1], [xx[0], xx[1]], xaz);
|
|
781
|
+
if (eventflag & SE_CALC_RISE) {
|
|
782
|
+
if (xaz[2] > 0) {
|
|
783
|
+
while (tjdnoon - tjd_start < 0.5) tjdnoon += 1;
|
|
784
|
+
while (tjdnoon - tjd_start > 1.5) tjdnoon -= 1;
|
|
785
|
+
} else {
|
|
786
|
+
while (tjdnoon - tjd_start < 0.0) tjdnoon += 1;
|
|
787
|
+
while (tjdnoon - tjd_start > 1.0) tjdnoon -= 1;
|
|
788
|
+
}
|
|
789
|
+
} else {
|
|
790
|
+
if (xaz[2] > 0) {
|
|
791
|
+
while (tjd_start - tjdnoon > 0.5) tjdnoon += 1;
|
|
792
|
+
while (tjd_start - tjdnoon < -0.5) tjdnoon -= 1;
|
|
793
|
+
} else {
|
|
794
|
+
while (tjd_start - tjdnoon > 0.0) tjdnoon += 1;
|
|
795
|
+
while (tjd_start - tjdnoon < -1.0) tjdnoon -= 1;
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
let iflag2 = epheflag | SEFLG_EQUATORIAL;
|
|
799
|
+
const rn = sweCalcUt(swed, tjdnoon, ipl, iflag2);
|
|
800
|
+
if (rn.flags === ERR) return { retval: ERR, tret: 0, serr: 'error in calc_rise_and_set(): calc failed' };
|
|
801
|
+
const xxn = rn.xx;
|
|
802
|
+
let rdi = 0;
|
|
803
|
+
if (ipl === SE_SUN)
|
|
804
|
+
rdi = Math.asin(696000000.0 / 1.49597870691e+11 / xxn[2]) / DEGTORAD;
|
|
805
|
+
else if (ipl === SE_MOON)
|
|
806
|
+
rdi = Math.asin(1737000.0 / 1.49597870691e+11 / xxn[2]) / DEGTORAD;
|
|
807
|
+
if (eventflag & SE_BIT_DISC_CENTER) rdi = 0;
|
|
808
|
+
const rh = -(34.5 / 60.0 + rdi);
|
|
809
|
+
const sda = Math.acos(-Math.tan(dgeo[1] * DEGTORAD) * Math.tan(xxn[1] * DEGTORAD)) * RADTODEG;
|
|
810
|
+
let tjdrise: number;
|
|
811
|
+
if (eventflag & SE_CALC_RISE)
|
|
812
|
+
tjdrise = tjdnoon - sda / 360.0;
|
|
813
|
+
else
|
|
814
|
+
tjdrise = tjdnoon + sda / 360.0;
|
|
815
|
+
iflag2 = epheflag | SEFLG_SPEED | SEFLG_EQUATORIAL;
|
|
816
|
+
if (ipl === SE_MOON) iflag2 |= SEFLG_TOPOCTR;
|
|
817
|
+
if (!(helflag & SE_HELFLAG_HIGH_PRECISION))
|
|
818
|
+
iflag2 |= SEFLG_NONUT | SEFLG_TRUEPOS;
|
|
819
|
+
for (let i = 0; i < 2; i++) {
|
|
820
|
+
const rc = sweCalcUt(swed, tjdrise, ipl, iflag2);
|
|
821
|
+
if (rc.flags === ERR) return { retval: ERR, tret: 0, serr: rc.serr };
|
|
822
|
+
const xxi = rc.xx;
|
|
823
|
+
const xazi = [0, 0, 0];
|
|
824
|
+
sweAzalt(swed, tjdrise, SE_EQU2HOR, dgeo, datm[0], datm[1], [xxi[0], xxi[1]], xazi);
|
|
825
|
+
const xxPrev = [xxi[0] - xxi[3] * dfac, xxi[1] - xxi[4] * dfac];
|
|
826
|
+
const xaz2 = [0, 0, 0];
|
|
827
|
+
sweAzalt(swed, tjdrise - dfac, SE_EQU2HOR, dgeo, datm[0], datm[1], xxPrev, xaz2);
|
|
828
|
+
tjdrise -= (xazi[1] - rh) / (xazi[1] - xaz2[1]) * dfac;
|
|
829
|
+
}
|
|
830
|
+
return { retval: OK, tret: tjdrise, serr: '' };
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
function myRiseTrans(swed: SweData, tjd: number, ipl: number, starname: string, eventtype: number, helflag: number, dgeo: number[], datm: number[]): { retval: number; tret: number; serr: string } {
|
|
834
|
+
let iplAdj = ipl;
|
|
835
|
+
if (starname !== '' && starname !== null) iplAdj = DeterObject(starname);
|
|
836
|
+
if (iplAdj !== -1 && Math.abs(dgeo[1]) < 63) {
|
|
837
|
+
return calcRiseAndSet(swed, tjd, iplAdj, dgeo, datm, eventtype, helflag);
|
|
838
|
+
} else {
|
|
839
|
+
return callSweRiseTrans(swed, tjd, ipl, starname, helflag, eventtype, dgeo, datm[0], datm[1]);
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
function RiseSet(swed: SweData, JDNDaysUT: number, dgeo: number[], datm: number[], ObjectName: string, RSEvent: number, helflag: number, Rim: number): { retval: number; tret: number; serr: string } {
|
|
844
|
+
let eventtype = RSEvent;
|
|
845
|
+
if (Rim === 0) eventtype |= SE_BIT_DISC_CENTER;
|
|
846
|
+
const Planet = DeterObject(ObjectName);
|
|
847
|
+
if (Planet !== -1)
|
|
848
|
+
return myRiseTrans(swed, JDNDaysUT, Planet, '', eventtype, helflag, dgeo, datm);
|
|
849
|
+
else
|
|
850
|
+
return myRiseTrans(swed, JDNDaysUT, -1, ObjectName, eventtype, helflag, dgeo, datm);
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
function TopoArcVisionis(swed: SweData, Magn: number, dobs: number[], AltO: number, AziO: number, AltM: number, AziM: number, JDNDaysUT: number, AziS: number, sunra: number, Lat: number, HeightEye: number, datm: number[], helflag: number): { retval: number; dret: number; serr: string } {
|
|
854
|
+
const serrRef = { value: '' };
|
|
855
|
+
let xR = 0;
|
|
856
|
+
let Xl = 45;
|
|
857
|
+
const Yl = Magn - VisLimMagn(dobs, AltO, AziO, AltM, AziM, JDNDaysUT, AltO - Xl, AziS, sunra, Lat, HeightEye, datm, helflag, null, serrRef);
|
|
858
|
+
let Yr = Magn - VisLimMagn(dobs, AltO, AziO, AltM, AziM, JDNDaysUT, AltO - xR, AziS, sunra, Lat, HeightEye, datm, helflag, null, serrRef);
|
|
859
|
+
let Xm: number;
|
|
860
|
+
if (Yl * Yr <= 0) {
|
|
861
|
+
let YlMut = Yl;
|
|
862
|
+
while (Math.abs(xR - Xl) > epsilon) {
|
|
863
|
+
Xm = (xR + Xl) / 2.0;
|
|
864
|
+
const AltSi = AltO - Xm;
|
|
865
|
+
const Ym = Magn - VisLimMagn(dobs, AltO, AziO, AltM, AziM, JDNDaysUT, AltSi, AziS, sunra, Lat, HeightEye, datm, helflag, null, serrRef);
|
|
866
|
+
if (YlMut * Ym > 0) { Xl = Xm; YlMut = Ym; }
|
|
867
|
+
else { xR = Xm; Yr = Ym; }
|
|
868
|
+
}
|
|
869
|
+
Xm = (xR + Xl) / 2.0;
|
|
870
|
+
} else {
|
|
871
|
+
Xm = 99;
|
|
872
|
+
}
|
|
873
|
+
if (Xm < AltO) Xm = AltO;
|
|
874
|
+
return { retval: OK, dret: Xm, serr: serrRef.value };
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
function HeliacalAngle(swed: SweData, Magn: number, dobs: number[], AziO: number, AltM: number, AziM: number, JDNDaysUT: number, AziS: number, dgeo: number[], datm: number[], helflag: number): { retval: number; dangret: number[]; serr: string } {
|
|
878
|
+
const serrRef = { value: '' };
|
|
879
|
+
const sunra = SunRA(swed, JDNDaysUT, helflag).ra;
|
|
880
|
+
const Lat = dgeo[1];
|
|
881
|
+
const HeightEye = dgeo[2];
|
|
882
|
+
const dangret = [0, 0, 0];
|
|
883
|
+
if (PLSV as number === 1) {
|
|
884
|
+
dangret[0] = criticalangle;
|
|
885
|
+
dangret[1] = criticalangle + Magn * 2.492 + 13.447;
|
|
886
|
+
dangret[2] = -(Magn * 2.492 + 13.447);
|
|
887
|
+
return { retval: OK, dangret, serr: '' };
|
|
888
|
+
}
|
|
889
|
+
const minx = 2, maxx = 20;
|
|
890
|
+
let xmin = 0, ymin = 10000;
|
|
891
|
+
for (let x = minx; x <= maxx; x++) {
|
|
892
|
+
const r = TopoArcVisionis(swed, Magn, dobs, x, AziO, AltM, AziM, JDNDaysUT, AziS, sunra, Lat, HeightEye, datm, helflag);
|
|
893
|
+
if (r.retval === ERR) return { retval: ERR, dangret, serr: r.serr };
|
|
894
|
+
if (r.dret < ymin) { ymin = r.dret; xmin = x; }
|
|
895
|
+
}
|
|
896
|
+
let XlH = xmin - 1;
|
|
897
|
+
let xRH = xmin + 1;
|
|
898
|
+
let rr = TopoArcVisionis(swed, Magn, dobs, xRH, AziO, AltM, AziM, JDNDaysUT, AziS, sunra, Lat, HeightEye, datm, helflag);
|
|
899
|
+
if (rr.retval === ERR) return { retval: ERR, dangret, serr: rr.serr };
|
|
900
|
+
let Yr = rr.dret;
|
|
901
|
+
let rl = TopoArcVisionis(swed, Magn, dobs, XlH, AziO, AltM, AziM, JDNDaysUT, AziS, sunra, Lat, HeightEye, datm, helflag);
|
|
902
|
+
if (rl.retval === ERR) return { retval: ERR, dangret, serr: rl.serr };
|
|
903
|
+
let Yl = rl.dret;
|
|
904
|
+
while (Math.abs(xRH - XlH) > 0.1) {
|
|
905
|
+
const Xm = (xRH + XlH) / 2.0;
|
|
906
|
+
const DELTAx = 0.025;
|
|
907
|
+
const rm = TopoArcVisionis(swed, Magn, dobs, Xm, AziO, AltM, AziM, JDNDaysUT, AziS, sunra, Lat, HeightEye, datm, helflag);
|
|
908
|
+
if (rm.retval === ERR) return { retval: ERR, dangret, serr: rm.serr };
|
|
909
|
+
const Ym = rm.dret;
|
|
910
|
+
const rmd = TopoArcVisionis(swed, Magn, dobs, Xm + DELTAx, AziO, AltM, AziM, JDNDaysUT, AziS, sunra, Lat, HeightEye, datm, helflag);
|
|
911
|
+
if (rmd.retval === ERR) return { retval: ERR, dangret, serr: rmd.serr };
|
|
912
|
+
if (Ym >= rmd.dret) { XlH = Xm; Yl = Ym; }
|
|
913
|
+
else { xRH = Xm; Yr = Ym; }
|
|
914
|
+
}
|
|
915
|
+
const XmF = (xRH + XlH) / 2.0;
|
|
916
|
+
const YmF = (Yr + Yl) / 2.0;
|
|
917
|
+
dangret[1] = YmF;
|
|
918
|
+
dangret[2] = XmF - YmF;
|
|
919
|
+
dangret[0] = XmF;
|
|
920
|
+
return { retval: OK, dangret, serr: serrRef.value };
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
function DeterTAV(swed: SweData, dobs: number[], JDNDaysUT: number, dgeo: number[], datm: number[], ObjectName: string, helflag: number): { retval: number; dret: number; serr: string } {
|
|
924
|
+
const sunra = SunRA(swed, JDNDaysUT, helflag).ra;
|
|
925
|
+
const mr = Magnitude(swed, JDNDaysUT, dgeo, ObjectName, helflag);
|
|
926
|
+
if (mr.retval === ERR) return { retval: ERR, dret: 0, serr: mr.serr };
|
|
927
|
+
const altO = ObjectLoc(swed, JDNDaysUT, dgeo, datm, ObjectName, 0, helflag);
|
|
928
|
+
if (altO.retval === ERR) return { retval: ERR, dret: 0, serr: altO.serr };
|
|
929
|
+
const aziO = ObjectLoc(swed, JDNDaysUT, dgeo, datm, ObjectName, 1, helflag);
|
|
930
|
+
if (aziO.retval === ERR) return { retval: ERR, dret: 0, serr: aziO.serr };
|
|
931
|
+
let AltM: number, AziM: number;
|
|
932
|
+
if (ObjectName.startsWith('moon')) {
|
|
933
|
+
AltM = -90; AziM = 0;
|
|
934
|
+
} else {
|
|
935
|
+
const rm = ObjectLoc(swed, JDNDaysUT, dgeo, datm, 'moon', 0, helflag);
|
|
936
|
+
if (rm.retval === ERR) return { retval: ERR, dret: 0, serr: rm.serr };
|
|
937
|
+
AltM = rm.dret;
|
|
938
|
+
const rma = ObjectLoc(swed, JDNDaysUT, dgeo, datm, 'moon', 1, helflag);
|
|
939
|
+
if (rma.retval === ERR) return { retval: ERR, dret: 0, serr: rma.serr };
|
|
940
|
+
AziM = rma.dret;
|
|
941
|
+
}
|
|
942
|
+
const aziS = ObjectLoc(swed, JDNDaysUT, dgeo, datm, 'sun', 1, helflag);
|
|
943
|
+
if (aziS.retval === ERR) return { retval: ERR, dret: 0, serr: aziS.serr };
|
|
944
|
+
return TopoArcVisionis(swed, mr.dmag, dobs, altO.dret, aziO.dret, AltM, AziM, JDNDaysUT, aziS.dret, sunra, dgeo[1], dgeo[2], datm, helflag);
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
/* ================================================================
|
|
948
|
+
* F. Event search functions
|
|
949
|
+
* ================================================================ */
|
|
950
|
+
|
|
951
|
+
function getAscObl(swed: SweData, tjd: number, ipl: number, star: string, iflag: number, dgeo: number[], desc_obl: boolean): { retval: number; daop: number; serr: string } {
|
|
952
|
+
const epheflag = iflag & (SEFLG_JPLEPH | SEFLG_SWIEPH | SEFLG_MOSEPH);
|
|
953
|
+
let x: Float64Array;
|
|
954
|
+
let serr = '';
|
|
955
|
+
if (ipl === -1) {
|
|
956
|
+
const star2 = star;
|
|
957
|
+
const r = sweFixstar(swed, star2, tjd, epheflag | SEFLG_EQUATORIAL);
|
|
958
|
+
if (r.flags === ERR) return { retval: ERR, daop: 0, serr: r.serr };
|
|
959
|
+
x = r.xx; serr = r.serr;
|
|
960
|
+
} else {
|
|
961
|
+
const r = sweCalc(swed, tjd, ipl, epheflag | SEFLG_EQUATORIAL);
|
|
962
|
+
if (r.flags === ERR) return { retval: ERR, daop: 0, serr: r.serr };
|
|
963
|
+
x = r.xx; serr = r.serr;
|
|
964
|
+
}
|
|
965
|
+
const adpRaw = Math.tan(dgeo[1] * DEGTORAD) * Math.tan(x[1] * DEGTORAD);
|
|
966
|
+
if (Math.abs(adpRaw) > 1) {
|
|
967
|
+
let s: string;
|
|
968
|
+
if (star !== '') s = star;
|
|
969
|
+
else s = sweGetPlanetName(ipl, swed);
|
|
970
|
+
return { retval: -2, daop: 0, serr: `${s} is circumpolar, cannot calculate heliacal event` };
|
|
971
|
+
}
|
|
972
|
+
const adp = Math.asin(adpRaw) / DEGTORAD;
|
|
973
|
+
let daop: number;
|
|
974
|
+
if (desc_obl) daop = x[0] + adp;
|
|
975
|
+
else daop = x[0] - adp;
|
|
976
|
+
daop = sweDegnorm(daop);
|
|
977
|
+
return { retval: OK, daop, serr };
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
function getAscOblDiff(swed: SweData, tjd: number, ipl: number, star: string, iflag: number, dgeo: number[], desc_obl: boolean, is_acronychal: boolean): { retval: number; dsunpl: number; serr: string } {
|
|
981
|
+
const r1 = getAscObl(swed, tjd, SE_SUN, '', iflag, dgeo, desc_obl);
|
|
982
|
+
if (r1.retval !== OK) return { retval: r1.retval, dsunpl: 0, serr: r1.serr };
|
|
983
|
+
let desc_obl2 = desc_obl;
|
|
984
|
+
if (is_acronychal) desc_obl2 = !desc_obl2;
|
|
985
|
+
const r2 = getAscObl(swed, tjd, ipl, star, iflag, dgeo, desc_obl2);
|
|
986
|
+
if (r2.retval !== OK) return { retval: r2.retval, dsunpl: 0, serr: r2.serr };
|
|
987
|
+
let dsunpl = sweDegnorm(r1.daop - r2.daop);
|
|
988
|
+
if (is_acronychal) dsunpl = sweDegnorm(dsunpl - 180);
|
|
989
|
+
if (dsunpl > 180) dsunpl -= 360;
|
|
990
|
+
return { retval: OK, dsunpl, serr: '' };
|
|
991
|
+
}
|
|
992
|
+
|
|
993
|
+
function getAscOblWithSun(swed: SweData, tjd_start: number, ipl: number, star: string, helflag: number, evtyp: number, dperiod: number, dgeo: number[]): { retval: number; tjdret: number; serr: string } {
|
|
994
|
+
const epheflag = helflag & (SEFLG_JPLEPH | SEFLG_SWIEPH | SEFLG_MOSEPH);
|
|
995
|
+
let is_acronychal = false;
|
|
996
|
+
let desc_obl = false;
|
|
997
|
+
let retro = false;
|
|
998
|
+
if (evtyp === SE_EVENING_LAST || evtyp === SE_EVENING_FIRST) desc_obl = true;
|
|
999
|
+
if (evtyp === SE_MORNING_FIRST || evtyp === SE_EVENING_LAST) retro = true;
|
|
1000
|
+
if (evtyp === SE_ACRONYCHAL_RISING) desc_obl = true;
|
|
1001
|
+
if (evtyp === SE_ACRONYCHAL_RISING || evtyp === SE_ACRONYCHAL_SETTING) {
|
|
1002
|
+
is_acronychal = true;
|
|
1003
|
+
if (ipl !== SE_MOON) retro = true;
|
|
1004
|
+
}
|
|
1005
|
+
let tjd = tjd_start;
|
|
1006
|
+
let dsunpl_save = -999999999;
|
|
1007
|
+
let r = getAscOblDiff(swed, tjd, ipl, star, epheflag, dgeo, desc_obl, is_acronychal);
|
|
1008
|
+
if (r.retval !== OK) return { retval: r.retval, tjdret: 0, serr: r.serr };
|
|
1009
|
+
let dsunpl = r.dsunpl;
|
|
1010
|
+
let daystep = 20;
|
|
1011
|
+
let i = 0;
|
|
1012
|
+
while (dsunpl_save === -999999999 ||
|
|
1013
|
+
Math.abs(dsunpl) + Math.abs(dsunpl_save) > 180 ||
|
|
1014
|
+
(retro && !(dsunpl_save < 0 && dsunpl >= 0)) ||
|
|
1015
|
+
(!retro && !(dsunpl_save >= 0 && dsunpl < 0))) {
|
|
1016
|
+
i++;
|
|
1017
|
+
if (i > 5000) return { retval: ERR, tjdret: 0, serr: 'loop in get_asc_obl_with_sun() (1)' };
|
|
1018
|
+
dsunpl_save = dsunpl;
|
|
1019
|
+
tjd += 10.0;
|
|
1020
|
+
if (dperiod > 0 && tjd - tjd_start > dperiod) return { retval: -2, tjdret: 0, serr: '' };
|
|
1021
|
+
r = getAscOblDiff(swed, tjd, ipl, star, epheflag, dgeo, desc_obl, is_acronychal);
|
|
1022
|
+
if (r.retval !== OK) return { retval: r.retval, tjdret: 0, serr: r.serr };
|
|
1023
|
+
dsunpl = r.dsunpl;
|
|
1024
|
+
}
|
|
1025
|
+
let tjd_s = tjd - daystep;
|
|
1026
|
+
daystep /= 2.0;
|
|
1027
|
+
tjd = tjd_s + daystep;
|
|
1028
|
+
let rt = getAscOblDiff(swed, tjd, ipl, star, epheflag, dgeo, desc_obl, is_acronychal);
|
|
1029
|
+
if (rt.retval !== OK) return { retval: rt.retval, tjdret: 0, serr: rt.serr };
|
|
1030
|
+
let dsunpl_test = rt.dsunpl;
|
|
1031
|
+
i = 0;
|
|
1032
|
+
while (Math.abs(dsunpl) > 0.00001) {
|
|
1033
|
+
i++;
|
|
1034
|
+
if (i > 5000) return { retval: ERR, tjdret: 0, serr: 'loop in get_asc_obl_with_sun() (2)' };
|
|
1035
|
+
if (dsunpl_save * dsunpl_test >= 0) {
|
|
1036
|
+
dsunpl_save = dsunpl_test;
|
|
1037
|
+
tjd_s = tjd;
|
|
1038
|
+
} else {
|
|
1039
|
+
dsunpl = dsunpl_test;
|
|
1040
|
+
}
|
|
1041
|
+
daystep /= 2.0;
|
|
1042
|
+
tjd = tjd_s + daystep;
|
|
1043
|
+
rt = getAscOblDiff(swed, tjd, ipl, star, epheflag, dgeo, desc_obl, is_acronychal);
|
|
1044
|
+
if (rt.retval !== OK) return { retval: rt.retval, tjdret: 0, serr: rt.serr };
|
|
1045
|
+
dsunpl_test = rt.dsunpl;
|
|
1046
|
+
}
|
|
1047
|
+
return { retval: OK, tjdret: tjd, serr: '' };
|
|
1048
|
+
}
|
|
1049
|
+
|
|
1050
|
+
function findConjunctSun(swed: SweData, tjd_start: number, ipl: number, helflag: number, TypeEvent: number): { retval: number; tjd: number; serr: string } {
|
|
1051
|
+
const epheflag = helflag & (SEFLG_JPLEPH | SEFLG_SWIEPH | SEFLG_MOSEPH);
|
|
1052
|
+
let daspect = 0;
|
|
1053
|
+
if (ipl >= SE_MARS && TypeEvent >= 3) daspect = 180;
|
|
1054
|
+
const i = Math.trunc((TypeEvent - 1) / 2) + ipl * 2;
|
|
1055
|
+
const tjd0 = tcon[i];
|
|
1056
|
+
const dsynperiod = getSynodicPeriod(ipl);
|
|
1057
|
+
let tjdcon = tjd0 + (Math.floor((tjd_start - tjd0) / dsynperiod) + 1) * dsynperiod;
|
|
1058
|
+
let ds = 100;
|
|
1059
|
+
while (ds > 0.5) {
|
|
1060
|
+
const rx = sweCalc(swed, tjdcon, ipl, epheflag | SEFLG_SPEED);
|
|
1061
|
+
if (rx.flags === ERR) return { retval: ERR, tjd: 0, serr: rx.serr };
|
|
1062
|
+
const rs = sweCalc(swed, tjdcon, SE_SUN, epheflag | SEFLG_SPEED);
|
|
1063
|
+
if (rs.flags === ERR) return { retval: ERR, tjd: 0, serr: rs.serr };
|
|
1064
|
+
ds = sweDegnorm(rx.xx[0] - rs.xx[0] - daspect);
|
|
1065
|
+
if (ds > 180) ds -= 360;
|
|
1066
|
+
tjdcon -= ds / (rx.xx[3] - rs.xx[3]);
|
|
1067
|
+
}
|
|
1068
|
+
return { retval: OK, tjd: tjdcon, serr: '' };
|
|
1069
|
+
}
|
|
1070
|
+
|
|
1071
|
+
function moonEventArcVis(swed: SweData, JDNDaysUTStart: number, dgeo: number[], datm: number[], dobs: number[], TypeEventIn: number, helflag: number): { retval: number; dret: number; serr: string } {
|
|
1072
|
+
const epheflag = helflag & (SEFLG_JPLEPH | SEFLG_SWIEPH | SEFLG_MOSEPH);
|
|
1073
|
+
const avkind = helflag & SE_HELFLAG_AVKIND;
|
|
1074
|
+
if (avkind === 0 || avkind !== SE_HELFLAG_AVKIND_VR)
|
|
1075
|
+
return { retval: ERR, dret: JDNDaysUTStart, serr: 'error: in valid AV kind for the moon' };
|
|
1076
|
+
if (TypeEventIn === 1 || TypeEventIn === 2)
|
|
1077
|
+
return { retval: ERR, dret: JDNDaysUTStart, serr: 'error: the moon has no morning first or evening last' };
|
|
1078
|
+
const ObjectName = 'moon';
|
|
1079
|
+
const Planet = SE_MOON;
|
|
1080
|
+
let iflag = SEFLG_TOPOCTR | SEFLG_EQUATORIAL | epheflag;
|
|
1081
|
+
if (!(helflag & SE_HELFLAG_HIGH_PRECISION))
|
|
1082
|
+
iflag |= SEFLG_NONUT | SEFLG_TRUEPOS;
|
|
1083
|
+
let Daystep = 1;
|
|
1084
|
+
let TypeEvent: number;
|
|
1085
|
+
if (TypeEventIn === 3) { TypeEvent = 2; }
|
|
1086
|
+
else { TypeEvent = 1; Daystep = -Daystep; }
|
|
1087
|
+
let JDNDaysUT = JDNDaysUTStart;
|
|
1088
|
+
if (TypeEvent === 1) JDNDaysUT += 30;
|
|
1089
|
+
const serrObj = { value: '' };
|
|
1090
|
+
let pr = swePhenoUt(swed, JDNDaysUT, Planet, iflag, serrObj);
|
|
1091
|
+
let phase2 = pr.attr[0];
|
|
1092
|
+
let goingup = 0;
|
|
1093
|
+
let phase1: number;
|
|
1094
|
+
do {
|
|
1095
|
+
JDNDaysUT += Daystep;
|
|
1096
|
+
phase1 = phase2;
|
|
1097
|
+
pr = swePhenoUt(swed, JDNDaysUT, Planet, iflag, serrObj);
|
|
1098
|
+
phase2 = pr.attr[0];
|
|
1099
|
+
if (phase2 > phase1) goingup = 1;
|
|
1100
|
+
} while (goingup === 0 || (goingup === 1 && phase2 > phase1));
|
|
1101
|
+
JDNDaysUT -= Daystep;
|
|
1102
|
+
const JDNDaysUTi = JDNDaysUT;
|
|
1103
|
+
JDNDaysUT -= Daystep;
|
|
1104
|
+
let MinTAVoud = 199;
|
|
1105
|
+
let MinTAV: number, OldestMinTAV: number;
|
|
1106
|
+
let DeltaAlt = 90;
|
|
1107
|
+
let DeltaAltoud = 0;
|
|
1108
|
+
let tjd_moonevent = 0;
|
|
1109
|
+
do {
|
|
1110
|
+
JDNDaysUT += Daystep;
|
|
1111
|
+
const rrs = RiseSet(swed, JDNDaysUT, dgeo, datm, ObjectName, TypeEvent, helflag, 0);
|
|
1112
|
+
if (rrs.retval !== OK) return { retval: rrs.retval, dret: JDNDaysUTStart, serr: rrs.serr };
|
|
1113
|
+
tjd_moonevent = rrs.tret;
|
|
1114
|
+
const tjd_moonevent_start = tjd_moonevent;
|
|
1115
|
+
MinTAV = 199;
|
|
1116
|
+
OldestMinTAV = MinTAV;
|
|
1117
|
+
let LocalminCheck = 0;
|
|
1118
|
+
do {
|
|
1119
|
+
OldestMinTAV = MinTAVoud;
|
|
1120
|
+
MinTAVoud = MinTAV;
|
|
1121
|
+
DeltaAltoud = DeltaAlt;
|
|
1122
|
+
tjd_moonevent -= 1.0 / 60.0 / 24.0 * Sgn(Daystep);
|
|
1123
|
+
const rAltS = ObjectLoc(swed, tjd_moonevent, dgeo, datm, 'sun', 0, helflag);
|
|
1124
|
+
if (rAltS.retval === ERR) return { retval: ERR, dret: JDNDaysUTStart, serr: rAltS.serr };
|
|
1125
|
+
const rAltO = ObjectLoc(swed, tjd_moonevent, dgeo, datm, ObjectName, 0, helflag);
|
|
1126
|
+
if (rAltO.retval === ERR) return { retval: ERR, dret: JDNDaysUTStart, serr: rAltO.serr };
|
|
1127
|
+
DeltaAlt = rAltO.dret - rAltS.dret;
|
|
1128
|
+
const rTAV = DeterTAV(swed, dobs, tjd_moonevent, dgeo, datm, ObjectName, helflag);
|
|
1129
|
+
if (rTAV.retval === ERR) return { retval: ERR, dret: JDNDaysUTStart, serr: rTAV.serr };
|
|
1130
|
+
MinTAV = rTAV.dret;
|
|
1131
|
+
const TimeCheck = tjd_moonevent - LocalMinStep / 60.0 / 24.0 * Sgn(Daystep);
|
|
1132
|
+
const rLC = DeterTAV(swed, dobs, TimeCheck, dgeo, datm, ObjectName, helflag);
|
|
1133
|
+
if (rLC.retval === ERR) return { retval: ERR, dret: JDNDaysUTStart, serr: rLC.serr };
|
|
1134
|
+
LocalminCheck = rLC.dret;
|
|
1135
|
+
} while ((MinTAV <= MinTAVoud || LocalminCheck < MinTAV) && Math.abs(tjd_moonevent - tjd_moonevent_start) < 120.0 / 60.0 / 24.0);
|
|
1136
|
+
} while (DeltaAltoud < MinTAVoud && Math.abs(JDNDaysUT - JDNDaysUTi) < 15);
|
|
1137
|
+
if (Math.abs(JDNDaysUT - JDNDaysUTi) < 15) {
|
|
1138
|
+
tjd_moonevent += (1 - x2min(MinTAV, MinTAVoud, OldestMinTAV)) * Sgn(Daystep) / 60.0 / 24.0;
|
|
1139
|
+
} else {
|
|
1140
|
+
return { retval: ERR, dret: JDNDaysUTStart, serr: 'no date found for lunar event' };
|
|
1141
|
+
}
|
|
1142
|
+
return { retval: OK, dret: tjd_moonevent, serr: '' };
|
|
1143
|
+
}
|
|
1144
|
+
|
|
1145
|
+
function heliacalUtArcVis(swed: SweData, JDNDaysUTStart: number, dgeo: number[], datm: number[], dobs: number[], ObjectName: string, TypeEventIn: number, helflag: number): { retval: number; dret: number; serr: string } {
|
|
1146
|
+
let serr = '';
|
|
1147
|
+
let retval: number = OK;
|
|
1148
|
+
const Planet = DeterObject(ObjectName);
|
|
1149
|
+
const Pressure = datm[0];
|
|
1150
|
+
const Temperature = datm[1];
|
|
1151
|
+
let objectmagn = 0;
|
|
1152
|
+
const mr = Magnitude(swed, JDNDaysUTStart, dgeo, ObjectName, helflag);
|
|
1153
|
+
if (mr.retval === ERR) return { retval: ERR, dret: JDNDaysUTStart, serr: mr.serr };
|
|
1154
|
+
objectmagn = mr.dmag;
|
|
1155
|
+
const epheflag = helflag & (SEFLG_JPLEPH | SEFLG_SWIEPH | SEFLG_MOSEPH);
|
|
1156
|
+
let iflag = SEFLG_TOPOCTR | SEFLG_EQUATORIAL | epheflag;
|
|
1157
|
+
if (!(helflag & SE_HELFLAG_HIGH_PRECISION))
|
|
1158
|
+
iflag |= SEFLG_NONUT | SEFLG_TRUEPOS;
|
|
1159
|
+
let DayStep: number, maxlength: number;
|
|
1160
|
+
switch (Planet) {
|
|
1161
|
+
case SE_MERCURY: DayStep = 1; maxlength = 100; break;
|
|
1162
|
+
case SE_VENUS: DayStep = 64; maxlength = 384; break;
|
|
1163
|
+
case SE_MARS: DayStep = 128; maxlength = 640; break;
|
|
1164
|
+
case SE_JUPITER: DayStep = 64; maxlength = 384; break;
|
|
1165
|
+
case SE_SATURN: DayStep = 64; maxlength = 256; break;
|
|
1166
|
+
default: DayStep = 64; maxlength = 256; break;
|
|
1167
|
+
}
|
|
1168
|
+
let TypeEvent = TypeEventIn;
|
|
1169
|
+
let eventtype = TypeEvent;
|
|
1170
|
+
if (eventtype === 2) DayStep = -DayStep;
|
|
1171
|
+
if (eventtype === 4) { eventtype = 1; DayStep = -DayStep; }
|
|
1172
|
+
if (eventtype === 3) eventtype = 2;
|
|
1173
|
+
eventtype |= SE_BIT_DISC_CENTER;
|
|
1174
|
+
let JDNDaysUT = JDNDaysUTStart;
|
|
1175
|
+
let JDNDaysUTfinal = JDNDaysUT + maxlength;
|
|
1176
|
+
JDNDaysUT -= 1;
|
|
1177
|
+
if (DayStep < 0) {
|
|
1178
|
+
const tmp = JDNDaysUT; JDNDaysUT = JDNDaysUTfinal; JDNDaysUTfinal = tmp;
|
|
1179
|
+
}
|
|
1180
|
+
let JDNDaysUTstep = JDNDaysUT - DayStep;
|
|
1181
|
+
let doneoneday = 0;
|
|
1182
|
+
let ArcusVisDelta = 199;
|
|
1183
|
+
let ArcusVisPto = -5.55;
|
|
1184
|
+
let JDNarcvisUT = 0;
|
|
1185
|
+
let JDNDaysUTstepoud: number, ArcusVisDeltaoud: number;
|
|
1186
|
+
do {
|
|
1187
|
+
if (Math.abs(DayStep) === 1) doneoneday = 1;
|
|
1188
|
+
do {
|
|
1189
|
+
JDNDaysUTstepoud = JDNDaysUTstep;
|
|
1190
|
+
ArcusVisDeltaoud = ArcusVisDelta;
|
|
1191
|
+
JDNDaysUTstep += DayStep;
|
|
1192
|
+
const rrt = myRiseTrans(swed, JDNDaysUTstep, SE_SUN, '', eventtype, helflag, dgeo, datm);
|
|
1193
|
+
if (rrt.retval === ERR) return { retval: ERR, dret: JDNDaysUTStart, serr: rrt.serr };
|
|
1194
|
+
const tret = rrt.tret;
|
|
1195
|
+
const tjd_tt = tret + sweDeltatEx(tret, epheflag, swed);
|
|
1196
|
+
let rc = sweCalc(swed, tjd_tt, SE_SUN, iflag);
|
|
1197
|
+
if (rc.flags === ERR) return { retval: ERR, dret: JDNDaysUTStart, serr: rc.serr };
|
|
1198
|
+
const xin = [rc.xx[0], rc.xx[1]];
|
|
1199
|
+
const xaz = [0, 0, 0];
|
|
1200
|
+
sweAzalt(swed, tret, SE_EQU2HOR, dgeo, Pressure, Temperature, xin, xaz);
|
|
1201
|
+
const Trise = HourAngle(xaz[1], rc.xx[1], dgeo[1]);
|
|
1202
|
+
let sunsangle = ArcusVisPto;
|
|
1203
|
+
if (helflag & SE_HELFLAG_AVKIND_MIN7) sunsangle = -7;
|
|
1204
|
+
if (helflag & SE_HELFLAG_AVKIND_MIN9) sunsangle = -9;
|
|
1205
|
+
const Theliacal = HourAngle(sunsangle, rc.xx[1], dgeo[1]);
|
|
1206
|
+
let Tdelta = Theliacal - Trise;
|
|
1207
|
+
if (TypeEvent === 2 || TypeEvent === 3) Tdelta = -Tdelta;
|
|
1208
|
+
JDNarcvisUT = tret - Tdelta / 24;
|
|
1209
|
+
const tjd_tt2 = JDNarcvisUT + sweDeltatEx(JDNarcvisUT, epheflag, swed);
|
|
1210
|
+
rc = sweCalc(swed, tjd_tt2, SE_SUN, iflag);
|
|
1211
|
+
if (rc.flags === ERR) return { retval: ERR, dret: JDNDaysUTStart, serr: rc.serr };
|
|
1212
|
+
const xin2 = [rc.xx[0], rc.xx[1]];
|
|
1213
|
+
const xaz2 = [0, 0, 0];
|
|
1214
|
+
sweAzalt(swed, JDNarcvisUT, SE_EQU2HOR, dgeo, Pressure, Temperature, xin2, xaz2);
|
|
1215
|
+
let AziS = xaz2[0] + 180; if (AziS >= 360) AziS -= 360;
|
|
1216
|
+
const AltS = xaz2[1];
|
|
1217
|
+
let x: Float64Array;
|
|
1218
|
+
if (Planet !== -1) {
|
|
1219
|
+
const rp = sweCalc(swed, tjd_tt2, Planet, iflag);
|
|
1220
|
+
if (rp.flags === ERR) return { retval: ERR, dret: JDNDaysUTStart, serr: rp.serr };
|
|
1221
|
+
x = rp.xx;
|
|
1222
|
+
const mm = Magnitude(swed, JDNarcvisUT, dgeo, ObjectName, helflag);
|
|
1223
|
+
if (mm.retval === ERR) return { retval: ERR, dret: JDNDaysUTStart, serr: mm.serr };
|
|
1224
|
+
objectmagn = mm.dmag;
|
|
1225
|
+
} else {
|
|
1226
|
+
const rf = callSweFixstar(swed, ObjectName, tjd_tt2, iflag);
|
|
1227
|
+
if (rf.retval === ERR) return { retval: ERR, dret: JDNDaysUTStart, serr: rf.serr };
|
|
1228
|
+
x = rf.xx;
|
|
1229
|
+
}
|
|
1230
|
+
const xin3 = [x[0], x[1]];
|
|
1231
|
+
const xaz3 = [0, 0, 0];
|
|
1232
|
+
sweAzalt(swed, JDNarcvisUT, SE_EQU2HOR, dgeo, Pressure, Temperature, xin3, xaz3);
|
|
1233
|
+
let AziO = xaz3[0] + 180; if (AziO >= 360) AziO -= 360;
|
|
1234
|
+
const AltO = xaz3[1];
|
|
1235
|
+
const DeltaAlt = AltO - AltS;
|
|
1236
|
+
const rha = HeliacalAngle(swed, objectmagn, dobs, AziO, -1, 0, JDNarcvisUT, AziS, dgeo, datm, helflag);
|
|
1237
|
+
if (rha.retval === ERR) return { retval: ERR, dret: JDNDaysUTStart, serr: rha.serr };
|
|
1238
|
+
ArcusVisPto = rha.dangret[2];
|
|
1239
|
+
ArcusVisDelta = DeltaAlt - rha.dangret[1];
|
|
1240
|
+
} while ((ArcusVisDeltaoud > 0 || ArcusVisDelta < 0) && (JDNDaysUTfinal - JDNDaysUTstep) * Sgn(DayStep) > 0);
|
|
1241
|
+
if (doneoneday === 0 && (JDNDaysUTfinal - JDNDaysUTstep) * Sgn(DayStep) > 0) {
|
|
1242
|
+
ArcusVisDelta = ArcusVisDeltaoud;
|
|
1243
|
+
DayStep = Math.trunc(Math.abs(DayStep) / 2.0) * Sgn(DayStep);
|
|
1244
|
+
JDNDaysUTstep = JDNDaysUTstepoud;
|
|
1245
|
+
}
|
|
1246
|
+
} while (doneoneday === 0 && (JDNDaysUTfinal - JDNDaysUTstep) * Sgn(DayStep) > 0);
|
|
1247
|
+
const d = (JDNDaysUTfinal - JDNDaysUTstep) * Sgn(DayStep);
|
|
1248
|
+
if (d <= 0 || d >= maxlength) {
|
|
1249
|
+
return { retval: -2, dret: JDNDaysUTStart, serr: `heliacal event not found within maxlength ${maxlength}` };
|
|
1250
|
+
}
|
|
1251
|
+
const direct = DayStep < 0 ? -TimeStepDefault / 24.0 / 60.0 : TimeStepDefault / 24.0 / 60.0;
|
|
1252
|
+
if (helflag & SE_HELFLAG_AVKIND_VR) {
|
|
1253
|
+
let TimeStep = direct;
|
|
1254
|
+
let TbVR = 0;
|
|
1255
|
+
let TimePointer = JDNarcvisUT;
|
|
1256
|
+
let rOld = DeterTAV(swed, dobs, TimePointer, dgeo, datm, ObjectName, helflag);
|
|
1257
|
+
if (rOld.retval === ERR) return { retval: ERR, dret: JDNDaysUTStart, serr: rOld.serr };
|
|
1258
|
+
let OldestMinTAV = rOld.dret;
|
|
1259
|
+
TimePointer += TimeStep;
|
|
1260
|
+
let rNew = DeterTAV(swed, dobs, TimePointer, dgeo, datm, ObjectName, helflag);
|
|
1261
|
+
if (rNew.retval === ERR) return { retval: ERR, dret: JDNDaysUTStart, serr: rNew.serr };
|
|
1262
|
+
let MinTAVoud: number, MinTAVact: number;
|
|
1263
|
+
if (rNew.dret > OldestMinTAV) {
|
|
1264
|
+
TimePointer = JDNarcvisUT; TimeStep = -TimeStep;
|
|
1265
|
+
MinTAVact = OldestMinTAV;
|
|
1266
|
+
} else {
|
|
1267
|
+
MinTAVact = rNew.dret; MinTAVoud = OldestMinTAV;
|
|
1268
|
+
}
|
|
1269
|
+
MinTAVoud = OldestMinTAV;
|
|
1270
|
+
do {
|
|
1271
|
+
TimePointer += TimeStep;
|
|
1272
|
+
OldestMinTAV = MinTAVoud;
|
|
1273
|
+
MinTAVoud = MinTAVact;
|
|
1274
|
+
const rr = DeterTAV(swed, dobs, TimePointer, dgeo, datm, ObjectName, helflag);
|
|
1275
|
+
if (rr.retval === ERR) return { retval: ERR, dret: JDNDaysUTStart, serr: rr.serr };
|
|
1276
|
+
MinTAVact = rr.dret;
|
|
1277
|
+
if (MinTAVoud < MinTAVact) {
|
|
1278
|
+
const extrax = x2min(MinTAVact, MinTAVoud, OldestMinTAV);
|
|
1279
|
+
TbVR = TimePointer - (1 - extrax) * TimeStep;
|
|
1280
|
+
}
|
|
1281
|
+
} while (TbVR === 0);
|
|
1282
|
+
JDNarcvisUT = TbVR;
|
|
1283
|
+
}
|
|
1284
|
+
if (helflag & SE_HELFLAG_AVKIND_PTO) {
|
|
1285
|
+
let OudeDatum: number;
|
|
1286
|
+
do {
|
|
1287
|
+
OudeDatum = JDNarcvisUT;
|
|
1288
|
+
JDNarcvisUT -= direct;
|
|
1289
|
+
const tjd_tt = JDNarcvisUT + sweDeltatEx(JDNarcvisUT, epheflag, swed);
|
|
1290
|
+
let x: Float64Array;
|
|
1291
|
+
if (Planet !== -1) {
|
|
1292
|
+
const rp = sweCalc(swed, tjd_tt, Planet, iflag);
|
|
1293
|
+
if (rp.flags === ERR) return { retval: ERR, dret: JDNDaysUTStart, serr: rp.serr };
|
|
1294
|
+
x = rp.xx;
|
|
1295
|
+
} else {
|
|
1296
|
+
const rf = callSweFixstar(swed, ObjectName, tjd_tt, iflag);
|
|
1297
|
+
if (rf.retval === ERR) return { retval: ERR, dret: JDNDaysUTStart, serr: rf.serr };
|
|
1298
|
+
x = rf.xx;
|
|
1299
|
+
}
|
|
1300
|
+
const xin = [x[0], x[1]];
|
|
1301
|
+
const xaz = [0, 0, 0];
|
|
1302
|
+
sweAzalt(swed, JDNarcvisUT, SE_EQU2HOR, dgeo, Pressure, Temperature, xin, xaz);
|
|
1303
|
+
if (xaz[1] <= 0) break;
|
|
1304
|
+
} while (true);
|
|
1305
|
+
JDNarcvisUT = (JDNarcvisUT + OudeDatum!) / 2.0;
|
|
1306
|
+
}
|
|
1307
|
+
if (JDNarcvisUT < -9999999 || JDNarcvisUT > 9999999) {
|
|
1308
|
+
return { retval: ERR, dret: JDNDaysUT, serr: 'no heliacal date found' };
|
|
1309
|
+
}
|
|
1310
|
+
return { retval: OK, dret: JDNarcvisUT, serr };
|
|
1311
|
+
}
|
|
1312
|
+
|
|
1313
|
+
function getHeliacalDay(swed: SweData, tjd: number, dgeo: number[], datm: number[], dobs: number[], ObjectName: string, helflag: number, TypeEvent: number): { retval: number; thel: number; serr: string } {
|
|
1314
|
+
let is_rise_or_set = 0, direct_day = 0, direct_time = 0;
|
|
1315
|
+
const ipl = DeterObject(ObjectName);
|
|
1316
|
+
switch (TypeEvent) {
|
|
1317
|
+
case 1: is_rise_or_set = SE_CALC_RISE; direct_day = 1; direct_time = -1; break;
|
|
1318
|
+
case 2: is_rise_or_set = SE_CALC_SET; direct_day = -1; direct_time = 1; break;
|
|
1319
|
+
case 3: is_rise_or_set = SE_CALC_SET; direct_day = 1; direct_time = 1; break;
|
|
1320
|
+
case 4: is_rise_or_set = SE_CALC_RISE; direct_day = -1; direct_time = -1; break;
|
|
1321
|
+
}
|
|
1322
|
+
let tfac = 1;
|
|
1323
|
+
let ndays: number, daystep: number;
|
|
1324
|
+
let dmag: number;
|
|
1325
|
+
switch (ipl) {
|
|
1326
|
+
case SE_MOON: ndays = 16; daystep = 1; break;
|
|
1327
|
+
case SE_MERCURY: ndays = 60; daystep = 5; tfac = 5; break;
|
|
1328
|
+
case SE_VENUS: ndays = 300; tjd -= 30 * direct_day; daystep = 5;
|
|
1329
|
+
if (TypeEvent >= 3) { daystep = 15; tfac = 3; } break;
|
|
1330
|
+
case SE_MARS: ndays = 400; daystep = 15; tfac = 5; break;
|
|
1331
|
+
case SE_SATURN: ndays = 300; daystep = 20; tfac = 5; break;
|
|
1332
|
+
case -1:
|
|
1333
|
+
ndays = 300; daystep = 15; tfac = 10;
|
|
1334
|
+
const rmag = callSweFixstarMag(swed, ObjectName);
|
|
1335
|
+
if (rmag.retval === ERR) return { retval: ERR, thel: 0, serr: rmag.serr };
|
|
1336
|
+
dmag = rmag.mag;
|
|
1337
|
+
if (dmag > 2) daystep = 15;
|
|
1338
|
+
if (dmag < 0) tfac = 3;
|
|
1339
|
+
break;
|
|
1340
|
+
default: ndays = 300; daystep = 15; tfac = 3; break;
|
|
1341
|
+
}
|
|
1342
|
+
const tend = tjd + ndays * direct_day;
|
|
1343
|
+
let retval_old = -2;
|
|
1344
|
+
for (let tday = tjd, i = 0;
|
|
1345
|
+
(direct_day > 0 && tday < tend) || (direct_day < 0 && tday > tend);
|
|
1346
|
+
tday += daystep * direct_day, i++) {
|
|
1347
|
+
if (i > 0) tday -= 0.3 * direct_day;
|
|
1348
|
+
const rrt = myRiseTrans(swed, tday, SE_SUN, '', is_rise_or_set, helflag, dgeo, datm);
|
|
1349
|
+
if (rrt.retval === ERR) return { retval: ERR, thel: 0, serr: rrt.serr };
|
|
1350
|
+
if (rrt.retval === -2) { retval_old = -2; continue; }
|
|
1351
|
+
let tret = rrt.tret;
|
|
1352
|
+
let rv = sweVisLimitMag(swed, tret, dgeo, datm, dobs, ObjectName, helflag);
|
|
1353
|
+
if (rv.retval === ERR) return { retval: ERR, thel: 0, serr: rv.serr };
|
|
1354
|
+
if (retval_old === -2 && rv.retval >= 0 && daystep > 1) {
|
|
1355
|
+
retval_old = rv.retval;
|
|
1356
|
+
tday -= daystep * direct_day;
|
|
1357
|
+
daystep = 1;
|
|
1358
|
+
if (ipl >= SE_MARS || ipl === -1) daystep = 5;
|
|
1359
|
+
continue;
|
|
1360
|
+
}
|
|
1361
|
+
retval_old = rv.retval;
|
|
1362
|
+
if (rv.retval === -2) continue;
|
|
1363
|
+
const div = 1440.0;
|
|
1364
|
+
let vd = -1;
|
|
1365
|
+
let visible_at_sunsetrise = 1;
|
|
1366
|
+
while (rv.retval !== -2 && (vd = rv.dret[0] - rv.dret[7]) < 0) {
|
|
1367
|
+
visible_at_sunsetrise = 0;
|
|
1368
|
+
if (vd < -1.0) tret += 5.0 / div * direct_time * tfac;
|
|
1369
|
+
else if (vd < -0.5) tret += 2.0 / div * direct_time * tfac;
|
|
1370
|
+
else if (vd < -0.1) tret += 1.0 / div * direct_time * tfac;
|
|
1371
|
+
else tret += 1.0 / div * direct_time;
|
|
1372
|
+
rv = sweVisLimitMag(swed, tret, dgeo, datm, dobs, ObjectName, helflag);
|
|
1373
|
+
if (rv.retval === ERR) return { retval: ERR, thel: 0, serr: rv.serr };
|
|
1374
|
+
}
|
|
1375
|
+
if (visible_at_sunsetrise) {
|
|
1376
|
+
for (let j = 0; j < 10; j++) {
|
|
1377
|
+
const rvn = sweVisLimitMag(swed, tret + 1.0 / div * direct_time, dgeo, datm, dobs, ObjectName, helflag);
|
|
1378
|
+
if (rvn.retval >= 0 && rvn.dret[0] - rvn.dret[7] > vd) {
|
|
1379
|
+
vd = rvn.dret[0] - rvn.dret[7];
|
|
1380
|
+
tret += 1.0 / div * direct_time;
|
|
1381
|
+
}
|
|
1382
|
+
}
|
|
1383
|
+
}
|
|
1384
|
+
const vdelta = rv.dret[0] - rv.dret[7];
|
|
1385
|
+
if (vdelta > 0) {
|
|
1386
|
+
if ((ipl >= SE_MARS || ipl === -1) && daystep > 1) {
|
|
1387
|
+
tday -= daystep * direct_day;
|
|
1388
|
+
daystep = 1;
|
|
1389
|
+
} else {
|
|
1390
|
+
return { retval: OK, thel: tret, serr: '' };
|
|
1391
|
+
}
|
|
1392
|
+
}
|
|
1393
|
+
}
|
|
1394
|
+
return { retval: -2, thel: 0, serr: 'heliacal event does not happen' };
|
|
1395
|
+
}
|
|
1396
|
+
|
|
1397
|
+
function timeOptimumVisibility(swed: SweData, tjd: number, dgeo: number[], datm: number[], dobs: number[], ObjectName: string, helflag: number): { retval: number; tret: number; serr: string } {
|
|
1398
|
+
let rv = sweVisLimitMag(swed, tjd, dgeo, datm, dobs, ObjectName, helflag);
|
|
1399
|
+
if (rv.retval === ERR) return { retval: ERR, tret: tjd, serr: rv.serr };
|
|
1400
|
+
let retval_sv = rv.retval;
|
|
1401
|
+
let t1 = tjd, t2 = tjd, vl1 = -1, vl2 = -1;
|
|
1402
|
+
let phot_scot_opic_sv = retval_sv & SE_SCOTOPIC_FLAG;
|
|
1403
|
+
for (let i = 0, d = 100.0 / 86400.0; i < 3; i++, d /= 10.0) {
|
|
1404
|
+
t1 += d;
|
|
1405
|
+
let t_has_changed = 0;
|
|
1406
|
+
while (true) {
|
|
1407
|
+
rv = sweVisLimitMag(swed, t1 - d, dgeo, datm, dobs, ObjectName, helflag);
|
|
1408
|
+
if (rv.retval < 0 || rv.dret[0] <= rv.dret[7] || rv.dret[0] - rv.dret[7] <= vl1) break;
|
|
1409
|
+
t1 -= d; vl1 = rv.dret[0] - rv.dret[7]; t_has_changed = 1;
|
|
1410
|
+
retval_sv = rv.retval;
|
|
1411
|
+
phot_scot_opic_sv = rv.retval & SE_SCOTOPIC_FLAG;
|
|
1412
|
+
}
|
|
1413
|
+
if (t_has_changed === 0) t1 -= d;
|
|
1414
|
+
if (rv.retval === ERR) return { retval: ERR, tret: tjd, serr: rv.serr };
|
|
1415
|
+
}
|
|
1416
|
+
for (let i = 0, d = 100.0 / 86400.0; i < 3; i++, d /= 10.0) {
|
|
1417
|
+
t2 -= d;
|
|
1418
|
+
let t_has_changed = 0;
|
|
1419
|
+
while (true) {
|
|
1420
|
+
rv = sweVisLimitMag(swed, t2 + d, dgeo, datm, dobs, ObjectName, helflag);
|
|
1421
|
+
if (rv.retval < 0 || rv.dret[0] <= rv.dret[7] || rv.dret[0] - rv.dret[7] <= vl2) break;
|
|
1422
|
+
t2 += d; vl2 = rv.dret[0] - rv.dret[7]; t_has_changed = 1;
|
|
1423
|
+
retval_sv = rv.retval;
|
|
1424
|
+
phot_scot_opic_sv = rv.retval & SE_SCOTOPIC_FLAG;
|
|
1425
|
+
}
|
|
1426
|
+
if (t_has_changed === 0) t2 += d;
|
|
1427
|
+
if (rv.retval === ERR) return { retval: ERR, tret: tjd, serr: rv.serr };
|
|
1428
|
+
}
|
|
1429
|
+
const tret = vl2 > vl1 ? t2 : t1;
|
|
1430
|
+
if (rv.retval >= 0) {
|
|
1431
|
+
const phot_scot_opic = rv.retval & SE_SCOTOPIC_FLAG;
|
|
1432
|
+
if (phot_scot_opic_sv !== phot_scot_opic) return { retval: -2, tret, serr: '' };
|
|
1433
|
+
if (retval_sv & SE_MIXEDOPIC_FLAG) return { retval: -2, tret, serr: '' };
|
|
1434
|
+
}
|
|
1435
|
+
return { retval: OK, tret, serr: '' };
|
|
1436
|
+
}
|
|
1437
|
+
|
|
1438
|
+
function timeLimitInvisible(swed: SweData, tjd: number, dgeo: number[], datm: number[], dobs: number[], ObjectName: string, helflag: number, direct: number): { retval: number; tret: number; serr: string } {
|
|
1439
|
+
let ncnt = 3;
|
|
1440
|
+
let d0 = 100.0 / 86400.0;
|
|
1441
|
+
let tjdAdj = tjd;
|
|
1442
|
+
if (ObjectName === 'moon') { d0 *= 10; ncnt = 4; }
|
|
1443
|
+
let rv = sweVisLimitMag(swed, tjdAdj, dgeo, datm, dobs, ObjectName, helflag);
|
|
1444
|
+
if (rv.retval === ERR) return { retval: ERR, tret: tjd, serr: rv.serr };
|
|
1445
|
+
let retval_sv = rv.retval;
|
|
1446
|
+
let phot_scot_opic_sv = rv.retval & SE_SCOTOPIC_FLAG;
|
|
1447
|
+
for (let i = 0, d = d0; i < ncnt; i++, d /= 10.0) {
|
|
1448
|
+
while (true) {
|
|
1449
|
+
rv = sweVisLimitMag(swed, tjdAdj + d * direct, dgeo, datm, dobs, ObjectName, helflag);
|
|
1450
|
+
if (rv.retval < 0 || rv.dret[0] <= rv.dret[7]) break;
|
|
1451
|
+
tjdAdj += d * direct;
|
|
1452
|
+
retval_sv = rv.retval;
|
|
1453
|
+
phot_scot_opic_sv = rv.retval & SE_SCOTOPIC_FLAG;
|
|
1454
|
+
}
|
|
1455
|
+
}
|
|
1456
|
+
if (rv.retval >= 0) {
|
|
1457
|
+
const phot_scot_opic = rv.retval & SE_SCOTOPIC_FLAG;
|
|
1458
|
+
if (phot_scot_opic_sv !== phot_scot_opic) return { retval: -2, tret: tjdAdj, serr: '' };
|
|
1459
|
+
if (retval_sv & SE_MIXEDOPIC_FLAG) return { retval: -2, tret: tjdAdj, serr: '' };
|
|
1460
|
+
}
|
|
1461
|
+
return { retval: OK, tret: tjdAdj, serr: '' };
|
|
1462
|
+
}
|
|
1463
|
+
|
|
1464
|
+
function getAcronchalDay(swed: SweData, tjd: number, dgeo: number[], datm: number[], dobs: number[], ObjectName: string, helflag: number, TypeEvent: number): { retval: number; thel: number; serr: string } {
|
|
1465
|
+
const ipl = DeterObject(ObjectName);
|
|
1466
|
+
const helflagP = helflag | SE_HELFLAG_VISLIM_PHOTOPIC;
|
|
1467
|
+
let is_rise_or_set: number, direct: number;
|
|
1468
|
+
if (TypeEvent === 3 || TypeEvent === 5) { is_rise_or_set = SE_CALC_RISE; direct = -1; }
|
|
1469
|
+
else { is_rise_or_set = SE_CALC_SET; direct = 1; }
|
|
1470
|
+
let dtret = 999;
|
|
1471
|
+
let tjdAdj = tjd;
|
|
1472
|
+
while (Math.abs(dtret) > 0.5 / 1440.0) {
|
|
1473
|
+
tjdAdj += 0.7 * direct;
|
|
1474
|
+
if (direct < 0) tjdAdj -= 1;
|
|
1475
|
+
const rrt = myRiseTrans(swed, tjdAdj, ipl, ObjectName, is_rise_or_set, helflagP, dgeo, datm);
|
|
1476
|
+
if (rrt.retval === ERR) return { retval: ERR, thel: 0, serr: rrt.serr };
|
|
1477
|
+
tjdAdj = rrt.tret;
|
|
1478
|
+
let rv = sweVisLimitMag(swed, tjdAdj, dgeo, datm, dobs, ObjectName, helflagP);
|
|
1479
|
+
if (rv.retval === ERR) return { retval: ERR, thel: 0, serr: rv.serr };
|
|
1480
|
+
while (rv.dret[0] < rv.dret[7]) {
|
|
1481
|
+
tjdAdj += 10.0 / 1440.0 * -direct;
|
|
1482
|
+
rv = sweVisLimitMag(swed, tjdAdj, dgeo, datm, dobs, ObjectName, helflagP);
|
|
1483
|
+
if (rv.retval === ERR) return { retval: ERR, thel: 0, serr: rv.serr };
|
|
1484
|
+
}
|
|
1485
|
+
const rd = timeLimitInvisible(swed, tjdAdj, dgeo, datm, dobs, ObjectName, helflagP | SE_HELFLAG_VISLIM_DARK, direct);
|
|
1486
|
+
if (rd.retval === ERR) return { retval: ERR, thel: 0, serr: rd.serr };
|
|
1487
|
+
const tret_dark = rd.tret;
|
|
1488
|
+
const rn = timeLimitInvisible(swed, tjdAdj, dgeo, datm, dobs, ObjectName, helflagP | SE_HELFLAG_VISLIM_NOMOON, direct);
|
|
1489
|
+
if (rn.retval === ERR) return { retval: ERR, thel: 0, serr: rn.serr };
|
|
1490
|
+
const tret = rn.tret;
|
|
1491
|
+
dtret = Math.abs(tret - tret_dark);
|
|
1492
|
+
}
|
|
1493
|
+
const rsun = azaltCart(swed, tjdAdj, dgeo, datm, 'sun', helflag);
|
|
1494
|
+
if (rsun.retval === ERR) return { retval: ERR, thel: 0, serr: rsun.serr };
|
|
1495
|
+
let serr = '';
|
|
1496
|
+
if (rsun.dret[1] < -12) serr = `acronychal rising/setting not available, ${rsun.dret[1]}`;
|
|
1497
|
+
else serr = `solar altitude, ${rsun.dret[1]}`;
|
|
1498
|
+
return { retval: OK, thel: tjdAdj, serr };
|
|
1499
|
+
}
|
|
1500
|
+
|
|
1501
|
+
function getHeliacalDetails(swed: SweData, tday: number, dgeo: number[], datm: number[], dobs: number[], ObjectName: string, TypeEvent: number, helflag: number): { retval: number; dret: number[]; serr: string } {
|
|
1502
|
+
const dret = [0, 0, 0];
|
|
1503
|
+
let optimum_undefined = false, limit_1_undefined = false, limit_2_undefined = false;
|
|
1504
|
+
let r = timeOptimumVisibility(swed, tday, dgeo, datm, dobs, ObjectName, helflag);
|
|
1505
|
+
if (r.retval === ERR) return { retval: ERR, dret, serr: r.serr };
|
|
1506
|
+
if (r.retval === -2) optimum_undefined = true;
|
|
1507
|
+
dret[1] = r.tret;
|
|
1508
|
+
let direct = 1;
|
|
1509
|
+
if (TypeEvent === 1 || TypeEvent === 4) direct = -1;
|
|
1510
|
+
r = timeLimitInvisible(swed, tday, dgeo, datm, dobs, ObjectName, helflag, direct);
|
|
1511
|
+
if (r.retval === ERR) return { retval: ERR, dret, serr: r.serr };
|
|
1512
|
+
if (r.retval === -2) limit_1_undefined = true;
|
|
1513
|
+
dret[0] = r.tret;
|
|
1514
|
+
direct *= -1;
|
|
1515
|
+
r = timeLimitInvisible(swed, dret[1], dgeo, datm, dobs, ObjectName, helflag, direct);
|
|
1516
|
+
if (r.retval === ERR) return { retval: ERR, dret, serr: r.serr };
|
|
1517
|
+
if (r.retval === -2) limit_2_undefined = true;
|
|
1518
|
+
dret[2] = r.tret;
|
|
1519
|
+
if (TypeEvent === 2 || TypeEvent === 3) {
|
|
1520
|
+
const tmp = dret[2]; dret[2] = dret[0]; dret[0] = tmp;
|
|
1521
|
+
const tmpB = limit_1_undefined; limit_1_undefined = limit_2_undefined; limit_2_undefined = tmpB;
|
|
1522
|
+
}
|
|
1523
|
+
let serr = '';
|
|
1524
|
+
if (optimum_undefined || limit_1_undefined || limit_2_undefined) {
|
|
1525
|
+
serr = 'return values [';
|
|
1526
|
+
if (limit_1_undefined) serr += '0,';
|
|
1527
|
+
if (optimum_undefined) serr += '1,';
|
|
1528
|
+
if (limit_2_undefined) serr += '2,';
|
|
1529
|
+
serr += '] are uncertain due to change between photopic and scotopic vision';
|
|
1530
|
+
}
|
|
1531
|
+
return { retval: OK, dret, serr };
|
|
1532
|
+
}
|
|
1533
|
+
|
|
1534
|
+
function heliacalUtVisLim(swed: SweData, tjd_start: number, dgeo: number[], datm: number[], dobs: number[], ObjectName: string, TypeEventIn: number, helflag: number): { retval: number; dret: number[]; serr: string } {
|
|
1535
|
+
const dret = new Array(10).fill(0);
|
|
1536
|
+
dret[0] = tjd_start;
|
|
1537
|
+
let serr = '';
|
|
1538
|
+
const ipl = DeterObject(ObjectName);
|
|
1539
|
+
let tjd = ipl === SE_MERCURY ? tjd_start - 30 : tjd_start - 50;
|
|
1540
|
+
const helflag2 = helflag;
|
|
1541
|
+
let retval: number;
|
|
1542
|
+
const TypeEvent = TypeEventIn;
|
|
1543
|
+
if (ipl === SE_MERCURY || ipl === SE_VENUS || TypeEvent <= 2) {
|
|
1544
|
+
if (ipl === -1) {
|
|
1545
|
+
const r = getAscOblWithSun(swed, tjd, ipl, ObjectName, helflag, TypeEvent, 0, dgeo);
|
|
1546
|
+
if (r.retval !== OK) return { retval: r.retval, dret, serr: r.serr };
|
|
1547
|
+
tjd = r.tjdret;
|
|
1548
|
+
} else {
|
|
1549
|
+
const r = findConjunctSun(swed, tjd, ipl, helflag, TypeEvent);
|
|
1550
|
+
if (r.retval === ERR) return { retval: ERR, dret, serr: r.serr };
|
|
1551
|
+
tjd = r.tjd;
|
|
1552
|
+
}
|
|
1553
|
+
const r = getHeliacalDay(swed, tjd, dgeo, datm, dobs, ObjectName, helflag2, TypeEvent);
|
|
1554
|
+
if (r.retval !== OK) return { retval: r.retval, dret, serr: r.serr };
|
|
1555
|
+
dret[0] = r.thel;
|
|
1556
|
+
} else {
|
|
1557
|
+
const r = getAscOblWithSun(swed, tjd, ipl, ObjectName, helflag, TypeEvent, 0, dgeo);
|
|
1558
|
+
if (r.retval !== OK) return { retval: r.retval, dret, serr: r.serr };
|
|
1559
|
+
tjd = r.tjdret;
|
|
1560
|
+
const ra = getAcronchalDay(swed, tjd, dgeo, datm, dobs, ObjectName, helflag2, TypeEvent);
|
|
1561
|
+
if (ra.retval !== OK) return { retval: ra.retval, dret, serr: ra.serr };
|
|
1562
|
+
dret[0] = ra.thel;
|
|
1563
|
+
serr = ra.serr;
|
|
1564
|
+
}
|
|
1565
|
+
if (!(helflag & SE_HELFLAG_NO_DETAILS)) {
|
|
1566
|
+
if (ipl === SE_MERCURY || ipl === SE_VENUS || TypeEvent <= 2) {
|
|
1567
|
+
const r = getHeliacalDetails(swed, dret[0], dgeo, datm, dobs, ObjectName, TypeEvent, helflag2);
|
|
1568
|
+
if (r.retval === ERR) return { retval: ERR, dret, serr: r.serr };
|
|
1569
|
+
dret[0] = r.dret[0]; dret[1] = r.dret[1]; dret[2] = r.dret[2];
|
|
1570
|
+
if (r.serr) serr = r.serr;
|
|
1571
|
+
}
|
|
1572
|
+
}
|
|
1573
|
+
return { retval: OK, dret, serr };
|
|
1574
|
+
}
|
|
1575
|
+
|
|
1576
|
+
function moonEventVisLim(swed: SweData, tjdstart: number, dgeo: number[], datm: number[], dobs: number[], TypeEvent: number, helflag: number): { retval: number; dret: number[]; serr: string } {
|
|
1577
|
+
const dret = [tjdstart, 0, 0];
|
|
1578
|
+
if (TypeEvent === 1 || TypeEvent === 2)
|
|
1579
|
+
return { retval: ERR, dret, serr: 'error: the moon has no morning first or evening last' };
|
|
1580
|
+
const ObjectName = 'moon';
|
|
1581
|
+
const ipl = SE_MOON;
|
|
1582
|
+
const helflag2 = helflag & ~SE_HELFLAG_HIGH_PRECISION;
|
|
1583
|
+
let tjd = tjdstart - 30;
|
|
1584
|
+
const rc = findConjunctSun(swed, tjd, ipl, helflag, TypeEvent);
|
|
1585
|
+
if (rc.retval === ERR) return { retval: ERR, dret, serr: rc.serr };
|
|
1586
|
+
tjd = rc.tjd;
|
|
1587
|
+
const rh = getHeliacalDay(swed, tjd, dgeo, datm, dobs, ObjectName, helflag2, TypeEvent);
|
|
1588
|
+
if (rh.retval !== OK) return { retval: rh.retval, dret, serr: rh.serr };
|
|
1589
|
+
tjd = rh.thel;
|
|
1590
|
+
dret[0] = tjd;
|
|
1591
|
+
const ro = timeOptimumVisibility(swed, tjd, dgeo, datm, dobs, ObjectName, helflag);
|
|
1592
|
+
if (ro.retval === ERR) return { retval: ERR, dret, serr: ro.serr };
|
|
1593
|
+
dret[1] = ro.tret;
|
|
1594
|
+
tjd = ro.tret;
|
|
1595
|
+
let direct = 1;
|
|
1596
|
+
if (TypeEvent === 4) direct = -1;
|
|
1597
|
+
const rl = timeLimitInvisible(swed, tjd, dgeo, datm, dobs, ObjectName, helflag, direct);
|
|
1598
|
+
if (rl.retval === ERR) return { retval: ERR, dret, serr: rl.serr };
|
|
1599
|
+
dret[2] = rl.tret;
|
|
1600
|
+
const rl2 = timeLimitInvisible(swed, dret[1], dgeo, datm, dobs, ObjectName, helflag, -direct);
|
|
1601
|
+
if (rl2.retval === ERR) return { retval: ERR, dret, serr: rl2.serr };
|
|
1602
|
+
dret[0] = rl2.tret;
|
|
1603
|
+
if (TypeEvent === 3) {
|
|
1604
|
+
const rs = myRiseTrans(swed, rl2.tret, SE_SUN, '', SE_CALC_SET, helflag, dgeo, datm);
|
|
1605
|
+
if (rs.retval === ERR) return { retval: ERR, dret, serr: rs.serr };
|
|
1606
|
+
if (rs.tret < dret[1]) dret[0] = rs.tret;
|
|
1607
|
+
} else {
|
|
1608
|
+
const rs = myRiseTrans(swed, dret[1], SE_SUN, '', SE_CALC_RISE, helflag, dgeo, datm);
|
|
1609
|
+
if (rs.retval === ERR) return { retval: ERR, dret, serr: rs.serr };
|
|
1610
|
+
if (dret[0] > rs.tret) dret[0] = rs.tret;
|
|
1611
|
+
}
|
|
1612
|
+
if (TypeEvent === 4) {
|
|
1613
|
+
const tmp = dret[0]; dret[0] = dret[2]; dret[2] = tmp;
|
|
1614
|
+
}
|
|
1615
|
+
return { retval: OK, dret, serr: '' };
|
|
1616
|
+
}
|
|
1617
|
+
|
|
1618
|
+
function MoonEventJDut(swed: SweData, JDNDaysUTStart: number, dgeo: number[], datm: number[], dobs: number[], TypeEvent: number, helflag: number): { retval: number; dret: number[]; serr: string } {
|
|
1619
|
+
const avkind = helflag & SE_HELFLAG_AVKIND;
|
|
1620
|
+
if (avkind) {
|
|
1621
|
+
const r = moonEventArcVis(swed, JDNDaysUTStart, dgeo, datm, dobs, TypeEvent, helflag);
|
|
1622
|
+
return { retval: r.retval, dret: [r.dret], serr: r.serr };
|
|
1623
|
+
} else {
|
|
1624
|
+
return moonEventVisLim(swed, JDNDaysUTStart, dgeo, datm, dobs, TypeEvent, helflag);
|
|
1625
|
+
}
|
|
1626
|
+
}
|
|
1627
|
+
|
|
1628
|
+
function heliacalUt(swed: SweData, JDNDaysUTStart: number, dgeo: number[], datm: number[], dobs: number[], ObjectName: string, TypeEventIn: number, helflag: number): { retval: number; dret: number[]; serr: string } {
|
|
1629
|
+
const avkind = helflag & SE_HELFLAG_AVKIND;
|
|
1630
|
+
if (avkind) {
|
|
1631
|
+
const r = heliacalUtArcVis(swed, JDNDaysUTStart, dgeo, datm, dobs, ObjectName, TypeEventIn, helflag);
|
|
1632
|
+
return { retval: r.retval, dret: [r.dret], serr: r.serr };
|
|
1633
|
+
} else {
|
|
1634
|
+
return heliacalUtVisLim(swed, JDNDaysUTStart, dgeo, datm, dobs, ObjectName, TypeEventIn, helflag);
|
|
1635
|
+
}
|
|
1636
|
+
}
|
|
1637
|
+
|
|
1638
|
+
/* ================================================================
|
|
1639
|
+
* G. Public API functions
|
|
1640
|
+
* ================================================================ */
|
|
1641
|
+
|
|
1642
|
+
export function sweVisLimitMag(
|
|
1643
|
+
swed: SweData, tjdut: number, dgeo: number[], datm: number[], dobs: number[],
|
|
1644
|
+
ObjectName: string, helflag: number,
|
|
1645
|
+
): { retval: number; dret: number[]; serr: string } {
|
|
1646
|
+
const dret = new Array(8).fill(0);
|
|
1647
|
+
const datmC = [...datm];
|
|
1648
|
+
const dobsC = [...dobs];
|
|
1649
|
+
let objectName = tolowerStringStar(ObjectName);
|
|
1650
|
+
if (DeterObject(objectName) === SE_SUN)
|
|
1651
|
+
return { retval: ERR, dret, serr: 'it makes no sense to call swe_vis_limit_mag() for the Sun' };
|
|
1652
|
+
const sunra = SunRA(swed, tjdut, helflag).ra;
|
|
1653
|
+
defaultHeliacalParameters(datmC, dgeo, dobsC, helflag);
|
|
1654
|
+
sweSetTopo(swed, dgeo[0], dgeo[1], dgeo[2]);
|
|
1655
|
+
const rAltO = ObjectLoc(swed, tjdut, dgeo, datmC, objectName, 0, helflag);
|
|
1656
|
+
if (rAltO.retval === ERR) return { retval: ERR, dret, serr: rAltO.serr };
|
|
1657
|
+
if (rAltO.dret < 0) { dret[0] = -100; return { retval: -2, dret, serr: 'object is below local horizon' }; }
|
|
1658
|
+
const rAziO = ObjectLoc(swed, tjdut, dgeo, datmC, objectName, 1, helflag);
|
|
1659
|
+
if (rAziO.retval === ERR) return { retval: ERR, dret, serr: rAziO.serr };
|
|
1660
|
+
let AltS: number, AziS: number;
|
|
1661
|
+
if (helflag & SE_HELFLAG_VISLIM_DARK) { AltS = -90; AziS = 0; }
|
|
1662
|
+
else {
|
|
1663
|
+
const rs = ObjectLoc(swed, tjdut, dgeo, datmC, 'sun', 0, helflag);
|
|
1664
|
+
if (rs.retval === ERR) return { retval: ERR, dret, serr: rs.serr };
|
|
1665
|
+
AltS = rs.dret;
|
|
1666
|
+
const rsa = ObjectLoc(swed, tjdut, dgeo, datmC, 'sun', 1, helflag);
|
|
1667
|
+
if (rsa.retval === ERR) return { retval: ERR, dret, serr: rsa.serr };
|
|
1668
|
+
AziS = rsa.dret;
|
|
1669
|
+
}
|
|
1670
|
+
let AltM: number, AziM: number;
|
|
1671
|
+
if (objectName.startsWith('moon') || (helflag & SE_HELFLAG_VISLIM_DARK) || (helflag & SE_HELFLAG_VISLIM_NOMOON)) {
|
|
1672
|
+
AltM = -90; AziM = 0;
|
|
1673
|
+
} else {
|
|
1674
|
+
const rm = ObjectLoc(swed, tjdut, dgeo, datmC, 'moon', 0, helflag);
|
|
1675
|
+
if (rm.retval === ERR) return { retval: ERR, dret, serr: rm.serr };
|
|
1676
|
+
AltM = rm.dret;
|
|
1677
|
+
const rma = ObjectLoc(swed, tjdut, dgeo, datmC, 'moon', 1, helflag);
|
|
1678
|
+
if (rma.retval === ERR) return { retval: ERR, dret, serr: rma.serr };
|
|
1679
|
+
AziM = rma.dret;
|
|
1680
|
+
}
|
|
1681
|
+
const scotopic_flag = { value: 0 };
|
|
1682
|
+
const serrRef = { value: '' };
|
|
1683
|
+
dret[0] = VisLimMagn(dobsC, rAltO.dret, rAziO.dret, AltM, AziM, tjdut, AltS, AziS, sunra, dgeo[1], dgeo[2], datmC, helflag, scotopic_flag, serrRef);
|
|
1684
|
+
dret[1] = rAltO.dret; dret[2] = rAziO.dret;
|
|
1685
|
+
dret[3] = AltS; dret[4] = AziS; dret[5] = AltM; dret[6] = AziM;
|
|
1686
|
+
const rm = Magnitude(swed, tjdut, dgeo, objectName, helflag);
|
|
1687
|
+
if (rm.retval === ERR) return { retval: ERR, dret, serr: rm.serr };
|
|
1688
|
+
dret[7] = rm.dmag;
|
|
1689
|
+
return { retval: scotopic_flag.value, dret, serr: serrRef.value };
|
|
1690
|
+
}
|
|
1691
|
+
|
|
1692
|
+
export function sweTopoArcusVisionis(
|
|
1693
|
+
swed: SweData, tjdut: number, dgeo: number[], datm: number[], dobs: number[],
|
|
1694
|
+
helflag: number, mag: number, azi_obj: number, alt_obj: number,
|
|
1695
|
+
azi_sun: number, azi_moon: number, alt_moon: number,
|
|
1696
|
+
): { retval: number; dret: number; serr: string } {
|
|
1697
|
+
const datmC = [...datm]; const dobsC = [...dobs];
|
|
1698
|
+
const sunra = SunRA(swed, tjdut, helflag).ra;
|
|
1699
|
+
defaultHeliacalParameters(datmC, dgeo, dobsC, helflag);
|
|
1700
|
+
return TopoArcVisionis(swed, mag, dobsC, alt_obj, azi_obj, alt_moon, azi_moon, tjdut, azi_sun, sunra, dgeo[1], dgeo[2], datmC, helflag);
|
|
1701
|
+
}
|
|
1702
|
+
|
|
1703
|
+
export function sweHeliacalAngle(
|
|
1704
|
+
swed: SweData, tjdut: number, dgeo: number[], datm: number[], dobs: number[],
|
|
1705
|
+
helflag: number, mag: number, azi_obj: number, azi_sun: number,
|
|
1706
|
+
azi_moon: number, alt_moon: number,
|
|
1707
|
+
): { retval: number; dret: number[]; serr: string } {
|
|
1708
|
+
if (dgeo[2] < SEI_ECL_GEOALT_MIN || dgeo[2] > SEI_ECL_GEOALT_MAX)
|
|
1709
|
+
return { retval: ERR, dret: [0, 0, 0], serr: `location for heliacal events must be between ${SEI_ECL_GEOALT_MIN} and ${SEI_ECL_GEOALT_MAX} m above sea` };
|
|
1710
|
+
const datmC = [...datm]; const dobsC = [...dobs];
|
|
1711
|
+
defaultHeliacalParameters(datmC, dgeo, dobsC, helflag);
|
|
1712
|
+
const r = HeliacalAngle(swed, mag, dobsC, azi_obj, alt_moon, azi_moon, tjdut, azi_sun, dgeo, datmC, helflag);
|
|
1713
|
+
return { retval: r.retval, dret: r.dangret, serr: r.serr };
|
|
1714
|
+
}
|
|
1715
|
+
|
|
1716
|
+
export function sweHeliacalPhenoUt(
|
|
1717
|
+
swed: SweData, JDNDaysUT: number, dgeo: number[], datm: number[], dobs: number[],
|
|
1718
|
+
ObjectNameIn: string, TypeEvent: number, helflag: number,
|
|
1719
|
+
): { retval: number; darr: number[]; serr: string } {
|
|
1720
|
+
const darr = new Array(30).fill(0);
|
|
1721
|
+
if (dgeo[2] < SEI_ECL_GEOALT_MIN || dgeo[2] > SEI_ECL_GEOALT_MAX)
|
|
1722
|
+
return { retval: ERR, darr, serr: `location for heliacal events must be between ${SEI_ECL_GEOALT_MIN} and ${SEI_ECL_GEOALT_MAX} m above sea` };
|
|
1723
|
+
const datmC = [...datm]; const dobsC = [...dobs];
|
|
1724
|
+
const ObjectName = tolowerStringStar(strcpyVBsafe(ObjectNameIn));
|
|
1725
|
+
const sunra = SunRA(swed, JDNDaysUT, helflag).ra;
|
|
1726
|
+
defaultHeliacalParameters(datmC, dgeo, dobsC, helflag);
|
|
1727
|
+
sweSetTopo(swed, dgeo[0], dgeo[1], dgeo[2]);
|
|
1728
|
+
const iflag = helflag & (SEFLG_JPLEPH | SEFLG_SWIEPH | SEFLG_MOSEPH);
|
|
1729
|
+
let r = ObjectLoc(swed, JDNDaysUT, dgeo, datmC, 'sun', 1, helflag);
|
|
1730
|
+
if (r.retval === ERR) return { retval: ERR, darr, serr: r.serr };
|
|
1731
|
+
const AziS = r.dret;
|
|
1732
|
+
r = ObjectLoc(swed, JDNDaysUT, dgeo, datmC, 'sun', 0, helflag);
|
|
1733
|
+
if (r.retval === ERR) return { retval: ERR, darr, serr: r.serr };
|
|
1734
|
+
const AltS = r.dret;
|
|
1735
|
+
r = ObjectLoc(swed, JDNDaysUT, dgeo, datmC, ObjectName, 1, helflag);
|
|
1736
|
+
if (r.retval === ERR) return { retval: ERR, darr, serr: r.serr };
|
|
1737
|
+
const AziO = r.dret;
|
|
1738
|
+
r = ObjectLoc(swed, JDNDaysUT, dgeo, datmC, ObjectName, 0, helflag);
|
|
1739
|
+
if (r.retval === ERR) return { retval: ERR, darr, serr: r.serr };
|
|
1740
|
+
const AltO = r.dret;
|
|
1741
|
+
r = ObjectLoc(swed, JDNDaysUT, dgeo, datmC, ObjectName, 7, helflag);
|
|
1742
|
+
if (r.retval === ERR) return { retval: ERR, darr, serr: r.serr };
|
|
1743
|
+
const GeoAltO = r.dret;
|
|
1744
|
+
const AppAltO = AppAltfromTopoAlt(AltO, datmC[1], datmC[0], helflag);
|
|
1745
|
+
const DAZact = AziS - AziO;
|
|
1746
|
+
const TAVact = AltO - AltS;
|
|
1747
|
+
const ParO = GeoAltO - AltO;
|
|
1748
|
+
const mr = Magnitude(swed, JDNDaysUT, dgeo, ObjectName, helflag);
|
|
1749
|
+
if (mr.retval === ERR) return { retval: ERR, darr, serr: mr.serr };
|
|
1750
|
+
const MagnO = mr.dmag;
|
|
1751
|
+
const ARCVact = TAVact + ParO;
|
|
1752
|
+
const ARCLact = Math.acos(Math.cos(ARCVact * DEGTORAD) * Math.cos(DAZact * DEGTORAD)) / DEGTORAD;
|
|
1753
|
+
const Planet = DeterObject(ObjectName);
|
|
1754
|
+
let elong: number, illum: number;
|
|
1755
|
+
if (Planet === -1) { elong = ARCLact; illum = 100; }
|
|
1756
|
+
else {
|
|
1757
|
+
const serrRef = { value: '' };
|
|
1758
|
+
const rp = swePhenoUt(swed, JDNDaysUT, Planet, iflag | SEFLG_TOPOCTR | SEFLG_EQUATORIAL, serrRef);
|
|
1759
|
+
if (rp.retval === ERR) return { retval: ERR, darr, serr: serrRef.value };
|
|
1760
|
+
elong = rp.attr[2]; illum = rp.attr[1] * 100;
|
|
1761
|
+
}
|
|
1762
|
+
const serrRef2 = { value: '' };
|
|
1763
|
+
const kact = kt(AltS, sunra, dgeo[1], dgeo[2], datmC[1], datmC[2], datmC[3], 4, serrRef2);
|
|
1764
|
+
let WMoon = 0, qYal = 0, qCrit = 0, LMoon = 0;
|
|
1765
|
+
if (Planet === SE_MOON) {
|
|
1766
|
+
WMoon = WidthMoon(AltO, AziO, AltS, AziS, ParO);
|
|
1767
|
+
LMoon = LengthMoon(WMoon, 0);
|
|
1768
|
+
qYal = qYallop(WMoon, ARCVact);
|
|
1769
|
+
if (qYal > 0.216) qCrit = 1;
|
|
1770
|
+
if (qYal < 0.216 && qYal > -0.014) qCrit = 2;
|
|
1771
|
+
if (qYal < -0.014 && qYal > -0.16) qCrit = 3;
|
|
1772
|
+
if (qYal < -0.16 && qYal > -0.232) qCrit = 4;
|
|
1773
|
+
if (qYal < -0.232 && qYal > -0.293) qCrit = 5;
|
|
1774
|
+
if (qYal < -0.293) qCrit = 6;
|
|
1775
|
+
}
|
|
1776
|
+
let RS = 2;
|
|
1777
|
+
if (TypeEvent === 1 || TypeEvent === 4) RS = 1;
|
|
1778
|
+
const rrs = RiseSet(swed, JDNDaysUT - 4.0 / 24.0, dgeo, datmC, 'sun', RS, helflag, 0);
|
|
1779
|
+
if (rrs.retval === ERR) return { retval: ERR, darr, serr: rrs.serr };
|
|
1780
|
+
const RiseSetS = rrs.tret;
|
|
1781
|
+
const rro = RiseSet(swed, JDNDaysUT - 4.0 / 24.0, dgeo, datmC, ObjectName, RS, helflag, 0);
|
|
1782
|
+
if (rro.retval === ERR) return { retval: ERR, darr, serr: rro.serr };
|
|
1783
|
+
const RiseSetO = rro.tret;
|
|
1784
|
+
let noriseO = false;
|
|
1785
|
+
let Lag: number;
|
|
1786
|
+
let TbYallop = TJD_INVALID;
|
|
1787
|
+
if (rro.retval === -2) { Lag = 0; noriseO = true; }
|
|
1788
|
+
else {
|
|
1789
|
+
Lag = RiseSetO - RiseSetS;
|
|
1790
|
+
if (Planet === SE_MOON) TbYallop = (RiseSetO * 4 + RiseSetS * 5) / 9.0;
|
|
1791
|
+
}
|
|
1792
|
+
let TfirstVR = TJD_INVALID, TbVR = TJD_INVALID, TlastVR = TJD_INVALID, TvisVR = 0, MinTAV = 0;
|
|
1793
|
+
if (!((TypeEvent === 3 || TypeEvent === 4) && (Planet === -1 || Planet >= SE_MARS))) {
|
|
1794
|
+
let MinTAVact = 199, DeltaAlt = 0, OldestMinTAV = 0, Ta = 0, Tc = 0;
|
|
1795
|
+
let MinTAVoud = 0, DeltaAltoud = 0;
|
|
1796
|
+
TbVR = 0;
|
|
1797
|
+
let TimeStep = -TimeStepDefault / 24.0 / 60.0;
|
|
1798
|
+
if (RS === 2) TimeStep = -TimeStep;
|
|
1799
|
+
let TimePointer = RiseSetS - TimeStep;
|
|
1800
|
+
do {
|
|
1801
|
+
TimePointer += TimeStep;
|
|
1802
|
+
OldestMinTAV = MinTAVoud;
|
|
1803
|
+
MinTAVoud = MinTAVact;
|
|
1804
|
+
DeltaAltoud = DeltaAlt;
|
|
1805
|
+
const rs2 = ObjectLoc(swed, TimePointer, dgeo, datmC, 'sun', 0, helflag);
|
|
1806
|
+
if (rs2.retval !== OK) return { retval: ERR, darr, serr: rs2.serr };
|
|
1807
|
+
const ro2 = ObjectLoc(swed, TimePointer, dgeo, datmC, ObjectName, 0, helflag);
|
|
1808
|
+
if (ro2.retval !== OK) return { retval: ERR, darr, serr: ro2.serr };
|
|
1809
|
+
DeltaAlt = ro2.dret - rs2.dret;
|
|
1810
|
+
const rt = DeterTAV(swed, dobsC, TimePointer, dgeo, datmC, ObjectName, helflag);
|
|
1811
|
+
if (rt.retval === ERR) return { retval: ERR, darr, serr: rt.serr };
|
|
1812
|
+
MinTAVact = rt.dret;
|
|
1813
|
+
if (MinTAVoud < MinTAVact && TbVR === 0) {
|
|
1814
|
+
let TimeCheck = TimePointer + Sgn(TimeStep) * LocalMinStep / 24.0 / 60.0;
|
|
1815
|
+
if (RiseSetO !== 0) {
|
|
1816
|
+
if (TimeStep > 0) TimeCheck = Math.min(TimeCheck, RiseSetO);
|
|
1817
|
+
else TimeCheck = Math.max(TimeCheck, RiseSetO);
|
|
1818
|
+
}
|
|
1819
|
+
const rlc = DeterTAV(swed, dobsC, TimeCheck, dgeo, datmC, ObjectName, helflag);
|
|
1820
|
+
if (rlc.retval === ERR) return { retval: ERR, darr, serr: rlc.serr };
|
|
1821
|
+
if (rlc.dret > MinTAVact) {
|
|
1822
|
+
const extrax = x2min(MinTAVact, MinTAVoud, OldestMinTAV);
|
|
1823
|
+
TbVR = TimePointer - (1 - extrax) * TimeStep;
|
|
1824
|
+
MinTAV = funct2(MinTAVact, MinTAVoud, OldestMinTAV, extrax);
|
|
1825
|
+
}
|
|
1826
|
+
}
|
|
1827
|
+
if (DeltaAlt > MinTAVact && Tc === 0 && TbVR === 0) {
|
|
1828
|
+
const cp = crossing(DeltaAltoud, DeltaAlt, MinTAVoud, MinTAVact);
|
|
1829
|
+
Tc = TimePointer - TimeStep * (1 - cp);
|
|
1830
|
+
}
|
|
1831
|
+
if (DeltaAlt < MinTAVact && Ta === 0 && Tc !== 0) {
|
|
1832
|
+
const cp = crossing(DeltaAltoud, DeltaAlt, MinTAVoud, MinTAVact);
|
|
1833
|
+
Ta = TimePointer - TimeStep * (1 - cp);
|
|
1834
|
+
}
|
|
1835
|
+
} while (Math.abs(TimePointer - RiseSetS) <= MaxTryHours / 24.0 && Ta === 0 &&
|
|
1836
|
+
!((TbVR !== 0 && (TypeEvent === 3 || TypeEvent === 4) && !ObjectName.startsWith('moon') && !ObjectName.startsWith('venus') && !ObjectName.startsWith('mercury'))));
|
|
1837
|
+
if (RS === 2) { TfirstVR = Tc; TlastVR = Ta; }
|
|
1838
|
+
else { TfirstVR = Ta; TlastVR = Tc; }
|
|
1839
|
+
if (TfirstVR === 0 && TlastVR === 0) {
|
|
1840
|
+
if (RS === 1) TfirstVR = TbVR - 0.000001;
|
|
1841
|
+
else TlastVR = TbVR + 0.000001;
|
|
1842
|
+
}
|
|
1843
|
+
if (!noriseO) {
|
|
1844
|
+
if (RS === 1) TfirstVR = Math.max(TfirstVR, RiseSetO);
|
|
1845
|
+
else TlastVR = Math.min(TlastVR, RiseSetO);
|
|
1846
|
+
}
|
|
1847
|
+
TvisVR = TJD_INVALID;
|
|
1848
|
+
if (TlastVR !== 0 && TfirstVR !== 0) TvisVR = TlastVR - TfirstVR;
|
|
1849
|
+
if (TlastVR === 0) TlastVR = TJD_INVALID;
|
|
1850
|
+
if (TbVR === 0) TbVR = TJD_INVALID;
|
|
1851
|
+
if (TfirstVR === 0) TfirstVR = TJD_INVALID;
|
|
1852
|
+
}
|
|
1853
|
+
darr[0] = AltO; darr[1] = AppAltO; darr[2] = GeoAltO; darr[3] = AziO;
|
|
1854
|
+
darr[4] = AltS; darr[5] = AziS; darr[6] = TAVact; darr[7] = ARCVact;
|
|
1855
|
+
darr[8] = DAZact; darr[9] = ARCLact; darr[10] = kact; darr[11] = MinTAV;
|
|
1856
|
+
darr[12] = TfirstVR; darr[13] = TbVR; darr[14] = TlastVR; darr[15] = TbYallop;
|
|
1857
|
+
darr[16] = WMoon; darr[17] = qYal; darr[18] = qCrit; darr[19] = ParO;
|
|
1858
|
+
darr[20] = MagnO; darr[21] = RiseSetO; darr[22] = RiseSetS; darr[23] = Lag;
|
|
1859
|
+
darr[24] = TvisVR; darr[25] = LMoon; darr[26] = elong; darr[27] = illum;
|
|
1860
|
+
return { retval: OK, darr, serr: '' };
|
|
1861
|
+
}
|
|
1862
|
+
|
|
1863
|
+
export function sweHeliacalUt(
|
|
1864
|
+
swed: SweData, JDNDaysUTStart: number, dgeo: number[], datm: number[], dobs: number[],
|
|
1865
|
+
ObjectNameIn: string, TypeEvent: number, helflag: number,
|
|
1866
|
+
): { retval: number; dret: number[]; serr: string } {
|
|
1867
|
+
const dret = [0, 0, 0];
|
|
1868
|
+
if (dgeo[2] < SEI_ECL_GEOALT_MIN || dgeo[2] > SEI_ECL_GEOALT_MAX)
|
|
1869
|
+
return { retval: ERR, dret, serr: `location for heliacal events must be between ${SEI_ECL_GEOALT_MIN} and ${SEI_ECL_GEOALT_MAX} m above sea` };
|
|
1870
|
+
const datmC = [...datm]; const dobsC = [...dobs];
|
|
1871
|
+
const ObjectName = tolowerStringStar(strcpyVBsafe(ObjectNameIn));
|
|
1872
|
+
defaultHeliacalParameters(datmC, dgeo, dobsC, helflag);
|
|
1873
|
+
sweSetTopo(swed, dgeo[0], dgeo[1], dgeo[2]);
|
|
1874
|
+
const Planet = DeterObject(ObjectName);
|
|
1875
|
+
if (Planet === SE_SUN)
|
|
1876
|
+
return { retval: ERR, dret, serr: 'the sun has no heliacal rising or setting' };
|
|
1877
|
+
let MaxCountSynodicPeriod = MAX_COUNT_SYNPER;
|
|
1878
|
+
if (helflag & SE_HELFLAG_LONG_SEARCH) MaxCountSynodicPeriod = MAX_COUNT_SYNPER_MAX;
|
|
1879
|
+
const sevent = ['', 'morning first', 'evening last', 'evening first', 'morning last', 'acronychal rising', 'acronychal setting'];
|
|
1880
|
+
let TypeEventAdj = TypeEvent;
|
|
1881
|
+
/* Moon events */
|
|
1882
|
+
if (Planet === SE_MOON) {
|
|
1883
|
+
if (TypeEvent === 1 || TypeEvent === 2)
|
|
1884
|
+
return { retval: ERR, dret, serr: `${sevent[TypeEvent]} (event type ${TypeEvent}) does not exist for the moon` };
|
|
1885
|
+
let tjd = JDNDaysUTStart;
|
|
1886
|
+
let r = MoonEventJDut(swed, tjd, dgeo, datmC, dobsC, TypeEvent, helflag);
|
|
1887
|
+
while (r.retval !== -2 && r.dret[0] < JDNDaysUTStart) {
|
|
1888
|
+
tjd += 15;
|
|
1889
|
+
r = MoonEventJDut(swed, tjd, dgeo, datmC, dobsC, TypeEvent, helflag);
|
|
1890
|
+
}
|
|
1891
|
+
dret[0] = r.dret[0]; if (r.dret.length > 1) dret[1] = r.dret[1]; if (r.dret.length > 2) dret[2] = r.dret[2];
|
|
1892
|
+
return { retval: r.retval, dret, serr: r.serr };
|
|
1893
|
+
}
|
|
1894
|
+
/* planets and fixed stars */
|
|
1895
|
+
if (!(helflag & SE_HELFLAG_AVKIND)) {
|
|
1896
|
+
if (Planet === -1 || Planet >= SE_MARS) {
|
|
1897
|
+
if (TypeEvent === 3 || TypeEvent === 4) {
|
|
1898
|
+
const s = Planet === -1 ? ObjectName : sweGetPlanetName(Planet, swed);
|
|
1899
|
+
return { retval: ERR, dret, serr: `${sevent[TypeEvent]} (event type ${TypeEvent}) does not exist for ${s}` };
|
|
1900
|
+
}
|
|
1901
|
+
}
|
|
1902
|
+
}
|
|
1903
|
+
if (helflag & SE_HELFLAG_AVKIND) {
|
|
1904
|
+
if (Planet === -1 || Planet >= SE_MARS) {
|
|
1905
|
+
if (TypeEventAdj === SE_ACRONYCHAL_RISING) TypeEventAdj = 3;
|
|
1906
|
+
if (TypeEventAdj === SE_ACRONYCHAL_SETTING) TypeEventAdj = 4;
|
|
1907
|
+
}
|
|
1908
|
+
} else {
|
|
1909
|
+
if (TypeEventAdj === SE_ACRONYCHAL_RISING || TypeEventAdj === SE_ACRONYCHAL_SETTING) {
|
|
1910
|
+
const s = Planet === -1 ? ObjectName : sweGetPlanetName(Planet, swed);
|
|
1911
|
+
return { retval: ERR, dret, serr: `${sevent[TypeEvent]} (event type ${TypeEvent}) is not provided for ${s}` };
|
|
1912
|
+
}
|
|
1913
|
+
}
|
|
1914
|
+
const dsynperiod = getSynodicPeriod(Planet);
|
|
1915
|
+
const tjdmax = JDNDaysUTStart + dsynperiod * MaxCountSynodicPeriod;
|
|
1916
|
+
let tadd = dsynperiod * 0.6;
|
|
1917
|
+
if (Planet === SE_MERCURY) tadd = 30;
|
|
1918
|
+
let retval = -2;
|
|
1919
|
+
for (let tjd = JDNDaysUTStart; tjd < tjdmax && retval === -2; tjd += tadd) {
|
|
1920
|
+
let r = heliacalUt(swed, tjd, dgeo, datmC, dobsC, ObjectName, TypeEventAdj, helflag);
|
|
1921
|
+
retval = r.retval;
|
|
1922
|
+
dret[0] = r.dret[0]; if (r.dret.length > 1) dret[1] = r.dret[1]; if (r.dret.length > 2) dret[2] = r.dret[2];
|
|
1923
|
+
while (retval !== -2 && dret[0] < JDNDaysUTStart) {
|
|
1924
|
+
tjd += tadd;
|
|
1925
|
+
r = heliacalUt(swed, tjd, dgeo, datmC, dobsC, ObjectName, TypeEventAdj, helflag);
|
|
1926
|
+
retval = r.retval; dret[0] = r.dret[0];
|
|
1927
|
+
if (r.dret.length > 1) dret[1] = r.dret[1]; if (r.dret.length > 2) dret[2] = r.dret[2];
|
|
1928
|
+
}
|
|
1929
|
+
}
|
|
1930
|
+
let serr = '';
|
|
1931
|
+
if ((helflag & SE_HELFLAG_SEARCH_1_PERIOD) && (retval === -2 || dret[0] > JDNDaysUTStart + dsynperiod * 1.5)) {
|
|
1932
|
+
serr = 'no heliacal date found within this synodic period';
|
|
1933
|
+
retval = -2;
|
|
1934
|
+
} else if (retval === -2) {
|
|
1935
|
+
serr = `no heliacal date found within ${MaxCountSynodicPeriod} synodic periods`;
|
|
1936
|
+
retval = ERR;
|
|
1937
|
+
}
|
|
1938
|
+
return { retval, dret, serr };
|
|
1939
|
+
}
|