swe4r 0.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/ext/swe4r/extconf.rb +3 -0
- data/ext/swe4r/src/swemptab.c +10642 -0
- data/ext/swe4r/swe4r.c +129 -0
- data/ext/swe4r/swecl.c +4948 -0
- data/ext/swe4r/swedate.c +590 -0
- data/ext/swe4r/swedate.h +82 -0
- data/ext/swe4r/swehel.c +3445 -0
- data/ext/swe4r/swehouse.c +1727 -0
- data/ext/swe4r/swehouse.h +85 -0
- data/ext/swe4r/swejpl.c +937 -0
- data/ext/swe4r/swejpl.h +105 -0
- data/ext/swe4r/swemmoon.c +1824 -0
- data/ext/swe4r/swemplan.c +959 -0
- data/ext/swe4r/swenut2000a.h +2820 -0
- data/ext/swe4r/sweodef.h +325 -0
- data/ext/swe4r/sweph.c +6241 -0
- data/ext/swe4r/sweph.h +556 -0
- data/ext/swe4r/swephexp.h +749 -0
- data/ext/swe4r/swephlib.c +2581 -0
- data/ext/swe4r/swephlib.h +177 -0
- data/lib/swe4r.rb +2 -0
- metadata +66 -0
data/ext/swe4r/swehel.c
ADDED
@@ -0,0 +1,3445 @@
|
|
1
|
+
/* SWISSEPH
|
2
|
+
$Header: /home/dieter/sweph/RCS/swehel.c,v 1.1 2009/04/21 06:05:59 dieter Exp dieter $
|
3
|
+
|
4
|
+
Heliacal risings and related calculations
|
5
|
+
|
6
|
+
Author: Victor Reijs
|
7
|
+
This program code is a translation of part of:
|
8
|
+
Victor Reijs' software ARCHAEOCOSMO (archaeoastronomy and
|
9
|
+
geodesy functions),
|
10
|
+
http://www.iol.ie/~geniet/eng/archaeocosmoprocedures.htm
|
11
|
+
|
12
|
+
Translation from VB into C by Dieter Koch
|
13
|
+
|
14
|
+
Problem reports can be sent to victor.reijs@gmail.com or dieter@astro.ch
|
15
|
+
|
16
|
+
Copyright (c) Victor Reijs, 2008
|
17
|
+
|
18
|
+
License conditions
|
19
|
+
------------------
|
20
|
+
|
21
|
+
This file is part of Swiss Ephemeris.
|
22
|
+
|
23
|
+
Swiss Ephemeris is distributed with NO WARRANTY OF ANY KIND. No author
|
24
|
+
or distributor accepts any responsibility for the consequences of using it,
|
25
|
+
or for whether it serves any particular purpose or works at all, unless he
|
26
|
+
or she says so in writing.
|
27
|
+
|
28
|
+
Swiss Ephemeris is made available by its authors under a dual licensing
|
29
|
+
system. The software developer, who uses any part of Swiss Ephemeris
|
30
|
+
in his or her software, must choose between one of the two license models,
|
31
|
+
which are
|
32
|
+
a) GNU public license version 2 or later
|
33
|
+
b) Swiss Ephemeris Professional License
|
34
|
+
|
35
|
+
The choice must be made before the software developer distributes software
|
36
|
+
containing parts of Swiss Ephemeris to others, and before any public
|
37
|
+
service using the developed software is activated.
|
38
|
+
|
39
|
+
If the developer choses the GNU GPL software license, he or she must fulfill
|
40
|
+
the conditions of that license, which includes the obligation to place his
|
41
|
+
or her whole software project under the GNU GPL or a compatible license.
|
42
|
+
See http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
43
|
+
|
44
|
+
If the developer choses the Swiss Ephemeris Professional license,
|
45
|
+
he must follow the instructions as found in http://www.astro.com/swisseph/
|
46
|
+
and purchase the Swiss Ephemeris Professional Edition from Astrodienst
|
47
|
+
and sign the corresponding license contract.
|
48
|
+
|
49
|
+
The License grants you the right to use, copy, modify and redistribute
|
50
|
+
Swiss Ephemeris, but only under certain conditions described in the License.
|
51
|
+
Among other things, the License requires that the copyright notices and
|
52
|
+
this notice be preserved on all copies.
|
53
|
+
|
54
|
+
The authors of Swiss Ephemeris have no control or influence over any of
|
55
|
+
the derived works, i.e. over software or services created by other
|
56
|
+
programmers which use Swiss Ephemeris functions.
|
57
|
+
|
58
|
+
The names of the authors or of the copyright holder must not
|
59
|
+
be used for promoting any software, product or service which uses or contains
|
60
|
+
the Swiss Ephemeris. This copyright notice is the ONLY place where the
|
61
|
+
names of the authors can legally appear, except in cases where they have
|
62
|
+
given special permission in writing.
|
63
|
+
|
64
|
+
The trademarks 'Swiss Ephemeris' and 'Swiss Ephemeris inside' may be used
|
65
|
+
for promoting such software, products or services.
|
66
|
+
*/
|
67
|
+
|
68
|
+
#include "swephexp.h"
|
69
|
+
#include "sweph.h"
|
70
|
+
#include "swephlib.h"
|
71
|
+
#include <sys/stat.h>
|
72
|
+
|
73
|
+
#define PLSV 0 /*if Planet, Lunar and Stellar Visibility formula is needed PLSV=1*/
|
74
|
+
#define criticalangle 0.0 /*[deg]*/
|
75
|
+
#define BNIGHT 1479.0 /*[nL]*/
|
76
|
+
#define BNIGHT_FACTOR 1.0
|
77
|
+
#define PI M_PI
|
78
|
+
#define Min2Deg (1.0 / 60.0)
|
79
|
+
#define DEBUG 0
|
80
|
+
#define DONE 1
|
81
|
+
#define MaxTryHours 4
|
82
|
+
#define TimeStepDefault 1
|
83
|
+
#define LocalMinStep 8
|
84
|
+
|
85
|
+
/* time constants */
|
86
|
+
#define Y2D 365.25 /*[Day]*/
|
87
|
+
#define D2Y (1 / Y2D) /*[Year]*/
|
88
|
+
#define D2H 24.0 /*[Hour]*/
|
89
|
+
#define H2S 3600.0 /*[sec]*/
|
90
|
+
#define D2S (D2H * H2S) /*[sec]*/
|
91
|
+
#define S2H (1.0 / H2S) /*[Hour]*/
|
92
|
+
#define JC2D 36525.0 /*[Day]*/
|
93
|
+
#define M2S 60.0 /*[sec]*/
|
94
|
+
|
95
|
+
/* Determines which algorimths are used*/
|
96
|
+
#define USE_DELTA_T_VR 0
|
97
|
+
#define REFR_SINCLAIR 0
|
98
|
+
#define REFR_BENNETTH 1
|
99
|
+
#define FormAstroRefrac REFR_SINCLAIR /*for Astronomical refraction can be "bennetth" or "sinclair"*/
|
100
|
+
#define GravitySource 2 /*0=RGO, 1=Wikipedia,2=Exp. Suppl. 1992,3=van der Werf*/
|
101
|
+
#define REarthSource 1 /*0=RGO (constant), 1=WGS84 method*/
|
102
|
+
|
103
|
+
#define StartYear 1820 /*[year]*/
|
104
|
+
#define Average 1.80546834626888 /*[msec/cy]*/
|
105
|
+
#define Periodicy 1443.67123144531 /*[year]*/
|
106
|
+
#define Amplitude 3.75606495492684 /*[msec]*/
|
107
|
+
#define phase 0 /*[deg]*/
|
108
|
+
#define MAX_COUNT_SYNPER 5 /* search within 10 synodic periods */
|
109
|
+
#define MAX_COUNT_SYNPER_MAX 1000000 /* high, so there is not max count */
|
110
|
+
#define AvgRadiusMoon (15.541 / 60) /* '[Deg] at 2007 CE or BCE*/
|
111
|
+
|
112
|
+
/* WGS84 ellipsoid constants
|
113
|
+
* http://w3sli.wcape.gov.za/Surveys/Mapping/wgs84.htm*/
|
114
|
+
#define Ra 6378136.6 /*'[m]*/
|
115
|
+
#define Rb 6356752.314 /*'[m]*/
|
116
|
+
|
117
|
+
/* choices in Schaefer's model */
|
118
|
+
#define nL2erg (1.02E-15)
|
119
|
+
#define erg2nL (1 / nL2erg) /*erg2nL to nLambert*/
|
120
|
+
#define MoonDistance 384410.4978 /*[km]*/
|
121
|
+
#define scaleHwater 3000.0 /*[m] Ricchiazzi [1997] 8200 Schaefer [2000]*/
|
122
|
+
#define scaleHrayleigh 8515.0 /*[m] Su [2003] 8200 Schaefer [2000]*/
|
123
|
+
#define scaleHaerosol 3745.0 /*m Su [2003] 1500 Schaefer [2000]*/
|
124
|
+
#define scaleHozone 20000.0 /*[m] Schaefer [2000]*/
|
125
|
+
#define astr2tau 0.921034037197618 /*LN(10 ^ 0.4)*/
|
126
|
+
#define tau2astr 1 / astr2tau
|
127
|
+
|
128
|
+
/* meteorological constants*/
|
129
|
+
#define C2K 273.15 /*[K]*/
|
130
|
+
#define DELTA 18.36
|
131
|
+
#define TempNulDiff 0.000001
|
132
|
+
#define PressRef 1000 /*[mbar]*/
|
133
|
+
#define MD 28.964 /*[kg] Mol weight of dry air van der Werf*/
|
134
|
+
#define MW 18.016 /*[kg] Mol weight of water vapor*/
|
135
|
+
#define GCR 8314.472 /*[L/kmol/K] van der Werf*/
|
136
|
+
#define LapseSA 0.0065 /*[K/m] standard atmosphere*/
|
137
|
+
#define LapseDA 0.0098 /*[K/m] dry adiabatic*/
|
138
|
+
|
139
|
+
/* lowest apparent altitude to provide*/
|
140
|
+
#define LowestAppAlt -3.5 /*[Deg]*/
|
141
|
+
|
142
|
+
/*optimization delta*/
|
143
|
+
#define epsilon 0.001
|
144
|
+
/* for Airmass usage*/
|
145
|
+
#define staticAirmass 0 /* use staticAirmass=1 instead depending on difference k's*/
|
146
|
+
|
147
|
+
/* optic stuff */
|
148
|
+
#define GOpticMag 1 /*telescope magnification*/
|
149
|
+
#define GOpticTrans 0.8 /*telescope transmission*/
|
150
|
+
#define GBinocular 1 /*1-binocular 0=monocular*/
|
151
|
+
#define GOpticDia 50 /*telescope diameter [mm]*/
|
152
|
+
|
153
|
+
static double mymin(double a, double b)
|
154
|
+
{
|
155
|
+
if (a <= b)
|
156
|
+
return a;
|
157
|
+
return b;
|
158
|
+
}
|
159
|
+
|
160
|
+
static double mymax(double a, double b)
|
161
|
+
{
|
162
|
+
if (a >= b)
|
163
|
+
return a;
|
164
|
+
return b;
|
165
|
+
}
|
166
|
+
|
167
|
+
/*###################################################################*/
|
168
|
+
static double Tanh(double x)
|
169
|
+
{
|
170
|
+
return (exp(x) - exp(-x)) / (exp(x) + exp(-x));
|
171
|
+
}
|
172
|
+
|
173
|
+
/*
|
174
|
+
' B [nL]
|
175
|
+
' SN [-]
|
176
|
+
' CVA [deg]
|
177
|
+
*/
|
178
|
+
static double CVA(double B, double SN)
|
179
|
+
{
|
180
|
+
/*Schaefer, Astronomy and the limits of vision, Archaeoastronomy, 1993*/
|
181
|
+
if (B > BNIGHT)
|
182
|
+
return (40.0 / SN) * pow(10, (8.28 * pow(B, (-0.29)))) / 60.0 / 60.0;
|
183
|
+
else
|
184
|
+
return mymin(900, 380 / SN * pow(10, (0.3 * pow(B, (-0.29))))) / 60.0 / 60.0;
|
185
|
+
}
|
186
|
+
|
187
|
+
/*
|
188
|
+
' age [year]
|
189
|
+
' B [nL]
|
190
|
+
' PupilDia [mm]
|
191
|
+
*/
|
192
|
+
static double PupilDia(double Age, double B)
|
193
|
+
{
|
194
|
+
/* age dependancy from Garstang [2000]*/
|
195
|
+
return (0.534 - 0.00211 * Age - (0.236 - 0.00127 * Age) * Tanh(0.4 * log(B) / log(10) - 2.2)) * 10;
|
196
|
+
}
|
197
|
+
|
198
|
+
/*
|
199
|
+
'Input
|
200
|
+
' Bback [nL]
|
201
|
+
' kX [-]
|
202
|
+
' Binocular [-]
|
203
|
+
' OpticMag [-]
|
204
|
+
' OpticDia [mm]
|
205
|
+
' OpticTrans [-]
|
206
|
+
' JDNDaysUT [JDN]
|
207
|
+
' Age [Year]
|
208
|
+
' SN [-]
|
209
|
+
' ObjectName
|
210
|
+
' TypeFactor [0=itensity factor 1=background factor]
|
211
|
+
'Output
|
212
|
+
' OpticFactor [-]
|
213
|
+
*/
|
214
|
+
static double OpticFactor(double Bback, double kX, double *dobs, double JDNDaysUT, char *ObjectName, int TypeFactor, int helflag)
|
215
|
+
{
|
216
|
+
double Pst, CIb, CIi, ObjectSize, Fb, Fe, Fsc, Fci, Fcb, Ft, Fp, Fa, Fr, Fm;
|
217
|
+
double Age = dobs[0];
|
218
|
+
double SN = dobs[1], SNi;
|
219
|
+
double Binocular = dobs[2];
|
220
|
+
double OpticMag = dobs[3];
|
221
|
+
double OpticDia = dobs[4];
|
222
|
+
double OpticTrans = dobs[5];
|
223
|
+
SNi = SN;
|
224
|
+
if (SNi <= 0.00000001) SNi = 0.00000001;
|
225
|
+
/* 23 jaar as standard from Garstang*/
|
226
|
+
Pst = PupilDia(23, Bback);
|
227
|
+
if (OpticMag == 1) { /*OpticMagn=1 means using eye*/
|
228
|
+
OpticTrans = 1;
|
229
|
+
OpticDia = Pst;
|
230
|
+
}
|
231
|
+
#if 0 /*is done in default_heliacal_parameters()*/
|
232
|
+
if (OpticMag == 0) { /*OpticMagn=0 (undefined) using eye*/
|
233
|
+
OpticTrans = 1;
|
234
|
+
OpticDia = Pst;
|
235
|
+
Binocular = 1;
|
236
|
+
OpticMag = 1;
|
237
|
+
}
|
238
|
+
#endif
|
239
|
+
/* Schaefer, Astronomy and the limits of vision, Archaeoastronomy, 1993*/
|
240
|
+
CIb = 0.7; /* color of background (from Ben Sugerman)*/
|
241
|
+
CIi = 0.5; /* Color index for white (from Ben Sugerman), should be function of ObjectName*/
|
242
|
+
ObjectSize = 0;
|
243
|
+
if (strcmp(ObjectName, "moon") == 0) {
|
244
|
+
/*ObjectSize and CI needs to be determined (depending on JDNDaysUT)*/
|
245
|
+
;
|
246
|
+
}
|
247
|
+
Fb = 1;
|
248
|
+
if (Binocular == 0) Fb = 1.41;
|
249
|
+
if (Bback < BNIGHT && !(helflag & SE_HELFLAG_VISLIM_PHOTOPIC)) {
|
250
|
+
Fe = pow(10, (0.48 * kX));
|
251
|
+
Fsc = mymin(1, (1 - pow(Pst / 124.4, 4)) / (1 - pow((OpticDia / OpticMag / 124.4), 4)));
|
252
|
+
Fci = pow(10, (-0.4 * (1 - CIi / 2.0)));
|
253
|
+
Fcb = pow(10, (-0.4 * (1 - CIb / 2.0)));
|
254
|
+
} else {
|
255
|
+
Fe = pow(10, (0.4 * kX));
|
256
|
+
Fsc = mymin(1, pow((OpticDia / OpticMag / Pst), 2) * (1 - exp(-pow((Pst / 6.2), 2))) / (1 - exp(-pow((OpticDia / OpticMag / 6.2), 2))));
|
257
|
+
Fci = 1;
|
258
|
+
Fcb = 1;
|
259
|
+
}
|
260
|
+
Ft = 1 / OpticTrans;
|
261
|
+
Fp = mymax(1, pow((Pst / (OpticMag * PupilDia(Age, Bback))), 2));
|
262
|
+
Fa = pow((Pst / OpticDia), 2);
|
263
|
+
Fr = (1 + 0.03 * pow((OpticMag * ObjectSize / CVA(Bback, SNi)), 2)) / pow(SNi, 2);
|
264
|
+
Fm = pow(OpticMag, 2);
|
265
|
+
#if DEBUG
|
266
|
+
fprintf(stderr, "Pst=%f\n", Pst);
|
267
|
+
fprintf(stderr, "Fb =%f\n", Fb);
|
268
|
+
fprintf(stderr, "Fe =%f\n", Fe);
|
269
|
+
fprintf(stderr, "Ft =%f\n", Ft);
|
270
|
+
fprintf(stderr, "Fp =%f\n", Fp);
|
271
|
+
fprintf(stderr, "Fa =%f\n", Fa);
|
272
|
+
fprintf(stderr, "Fm =%f\n", Fm);
|
273
|
+
fprintf(stderr, "Fsc=%f\n", Fsc);
|
274
|
+
fprintf(stderr, "Fci=%f\n", Fci);
|
275
|
+
fprintf(stderr, "Fcb=%f\n", Fcb);
|
276
|
+
fprintf(stderr, "Fr =%f\n", Fr );
|
277
|
+
#endif
|
278
|
+
if (TypeFactor == 0)
|
279
|
+
return Fb * Fe * Ft * Fp * Fa * Fr * Fsc * Fci;
|
280
|
+
else
|
281
|
+
return Fb * Ft * Fp * Fa * Fm * Fsc * Fcb;
|
282
|
+
}
|
283
|
+
|
284
|
+
/*###################################################################
|
285
|
+
*/
|
286
|
+
static int32 DeterObject(char *ObjectName)
|
287
|
+
{
|
288
|
+
char s[AS_MAXCH];
|
289
|
+
char *sp;
|
290
|
+
int32 ipl;
|
291
|
+
strcpy(s, ObjectName);
|
292
|
+
for (sp = s; *sp != '\0'; sp++)
|
293
|
+
*sp = tolower(*sp);
|
294
|
+
if (strncmp(s, "sun", 3) == 0)
|
295
|
+
return SE_SUN;
|
296
|
+
if (strncmp(s, "venus", 5) == 0)
|
297
|
+
return SE_VENUS;
|
298
|
+
if (strncmp(s, "mars", 4) == 0)
|
299
|
+
return SE_MARS;
|
300
|
+
if (strncmp(s, "mercur", 6) == 0)
|
301
|
+
return SE_MERCURY;
|
302
|
+
if (strncmp(s, "jupiter", 7) == 0)
|
303
|
+
return SE_JUPITER;
|
304
|
+
if (strncmp(s, "saturn", 6) == 0)
|
305
|
+
return SE_SATURN;
|
306
|
+
if (strncmp(s, "uranus", 6) == 0)
|
307
|
+
return SE_URANUS;
|
308
|
+
if (strncmp(s, "neptun", 6) == 0)
|
309
|
+
return SE_NEPTUNE;
|
310
|
+
if (strncmp(s, "moon", 4) == 0)
|
311
|
+
return SE_MOON;
|
312
|
+
if ((ipl = atoi(s)) > 0) {
|
313
|
+
ipl += SE_AST_OFFSET;
|
314
|
+
return ipl;
|
315
|
+
}
|
316
|
+
return -1;
|
317
|
+
}
|
318
|
+
|
319
|
+
#if 0
|
320
|
+
int32 call_swe_calc(double tjd, int32 ipl, int32 iflag, double *x, char *serr)
|
321
|
+
{
|
322
|
+
int32 retval = OK, ipli, i;
|
323
|
+
double dtjd;
|
324
|
+
static double tjdsv[3];
|
325
|
+
static double xsv[3][6];
|
326
|
+
static int32 iflagsv[3];
|
327
|
+
ipli = ipl;
|
328
|
+
if (ipli > SE_MOON)
|
329
|
+
ipli = 2;
|
330
|
+
dtjd = tjd - tjdsv[ipli];
|
331
|
+
if (tjdsv[ipli] != 0 && iflag == iflagsv[ipli] && fabs(dtjd) < 5.0 / 1440.0) {
|
332
|
+
for (i = 0; i < 3; i++)
|
333
|
+
x[i] = xsv[ipli][i] + dtjd * xsv[ipli][i+3];
|
334
|
+
for (i = 3; i < 6; i++)
|
335
|
+
x[i] = xsv[ipli][i];
|
336
|
+
} else {
|
337
|
+
retval = swe_calc(tjd, ipl, iflag, x, serr);
|
338
|
+
tjdsv[ipli] = tjd;
|
339
|
+
iflagsv[ipli] = iflag;
|
340
|
+
for (i = 0; i < 6; i++)
|
341
|
+
xsv[ipli][i] = x[i];
|
342
|
+
}
|
343
|
+
return retval;
|
344
|
+
}
|
345
|
+
#endif
|
346
|
+
|
347
|
+
/* avoids problems with star name string that may be overwritten by
|
348
|
+
swe_fixstar() */
|
349
|
+
int32 call_swe_fixstar(char *star, double tjd, int32 iflag, double *xx, char *serr)
|
350
|
+
{
|
351
|
+
int32 retval;
|
352
|
+
char star2[AS_MAXCH];
|
353
|
+
strcpy(star2, star);
|
354
|
+
retval = swe_fixstar(star2, tjd, iflag, xx, serr);
|
355
|
+
return retval;
|
356
|
+
}
|
357
|
+
|
358
|
+
/* avoids problems with star name string that may be overwritten by
|
359
|
+
swe_fixstar_mag() */
|
360
|
+
int32 call_swe_fixstar_mag(char *star, double *mag, char *serr)
|
361
|
+
{
|
362
|
+
int32 retval;
|
363
|
+
char star2[AS_MAXCH];
|
364
|
+
static double dmag;
|
365
|
+
static char star_save[AS_MAXCH];
|
366
|
+
if (strcmp(star, star_save) == 0) {
|
367
|
+
*mag = dmag;
|
368
|
+
return OK;
|
369
|
+
}
|
370
|
+
strcpy(star_save, star);
|
371
|
+
strcpy(star2, star);
|
372
|
+
retval = swe_fixstar_mag(star2, &dmag, serr);
|
373
|
+
*mag = dmag;
|
374
|
+
return retval;
|
375
|
+
}
|
376
|
+
|
377
|
+
/* avoids problems with star name string that may be overwritten by
|
378
|
+
swe_fixstar() */
|
379
|
+
int32 call_swe_rise_trans(double tjd, int32 ipl, char *star, int32 helflag, int32 eventtype, double *dgeo, double atpress, double attemp, double *tret, char *serr)
|
380
|
+
{
|
381
|
+
int32 retval;
|
382
|
+
int32 iflag = helflag & (SEFLG_JPLEPH|SEFLG_SWIEPH|SEFLG_MOSEPH);
|
383
|
+
char star2[AS_MAXCH];
|
384
|
+
strcpy(star2, star);
|
385
|
+
retval = swe_rise_trans(tjd, ipl, star2, iflag, eventtype, dgeo, atpress, attemp, tret, serr);
|
386
|
+
return retval;
|
387
|
+
}
|
388
|
+
|
389
|
+
/*
|
390
|
+
* Written by Dieter Koch:
|
391
|
+
* Fast function for risings and settings of planets, can be used instead of
|
392
|
+
* swe_rise_trans(), which is much slower.
|
393
|
+
* For circumpolar and near-circumpolar planets use swe_rise_trans(), or
|
394
|
+
* generally use it for geographical latitudes higher than 58N/S.
|
395
|
+
* For fixed stars, swe_rise_trans() is fast enough.
|
396
|
+
*/
|
397
|
+
static int32 calc_rise_and_set(double tjd_start, int32 ipl, double *dgeo, double *datm, int32 eventflag, int32 helflag, double *trise, char *serr)
|
398
|
+
{
|
399
|
+
int retc = OK, i;
|
400
|
+
double sda, xs[6], xx[6], xaz[6], xaz2[6], dfac = 1/365.25;
|
401
|
+
double rdi, rh;
|
402
|
+
double tjd0 = tjd_start, tjdrise;
|
403
|
+
double tjdnoon = (int) tjd0 - dgeo[0] / 15.0 / 24.0;
|
404
|
+
int32 iflag = helflag & (SEFLG_JPLEPH|SEFLG_SWIEPH|SEFLG_MOSEPH);
|
405
|
+
iflag |= SEFLG_EQUATORIAL;
|
406
|
+
if (!(helflag & SE_HELFLAG_HIGH_PRECISION))
|
407
|
+
iflag |= SEFLG_NONUT|SEFLG_TRUEPOS;
|
408
|
+
if (swe_calc_ut(tjd0, SE_SUN, iflag, xs, serr) == 0) {
|
409
|
+
if (serr != NULL)
|
410
|
+
strcpy(serr, "error in calc_rise_and_set(): calc(sun) failed ");
|
411
|
+
return ERR;
|
412
|
+
}
|
413
|
+
if (swe_calc_ut(tjd0, ipl, iflag, xx, serr) == 0) {
|
414
|
+
if (serr != NULL)
|
415
|
+
strcpy(serr, "error in calc_rise_and_set(): calc(sun) failed ");
|
416
|
+
return ERR;
|
417
|
+
}
|
418
|
+
tjdnoon -= swe_degnorm(xs[0] - xx[0])/360.0 + 0;
|
419
|
+
/* is planet above horizon or below? */
|
420
|
+
swe_azalt(tjd0, SE_EQU2HOR, dgeo, datm[0], datm[1], xx, xaz);
|
421
|
+
if (eventflag & SE_CALC_RISE) {
|
422
|
+
if (xaz[2] > 0) {
|
423
|
+
while (tjdnoon - tjd0 < 0.5) {/*printf("e");*/tjdnoon += 1;}
|
424
|
+
while (tjdnoon - tjd0 > 1.5) {/*printf("f");*/tjdnoon -= 1;}
|
425
|
+
} else {
|
426
|
+
while (tjdnoon - tjd0 < 0.0) {/*printf("g");*/tjdnoon += 1;}
|
427
|
+
while (tjdnoon - tjd0 > 1.0) {/*printf("h");*/tjdnoon -= 1;}
|
428
|
+
}
|
429
|
+
} else {
|
430
|
+
if (xaz[2] > 0) {
|
431
|
+
while (tjd0 - tjdnoon > 0.5) {/*printf("a");*/ tjdnoon += 1;}
|
432
|
+
while (tjd0 - tjdnoon < -0.5) {/*printf("b");*/ tjdnoon -= 1;}
|
433
|
+
} else {
|
434
|
+
while (tjd0 - tjdnoon > 0.0) {/*printf("c");*/ tjdnoon += 1;}
|
435
|
+
while (tjd0 - tjdnoon < -1.0) {/*printf("d");*/ tjdnoon -= 1;}
|
436
|
+
}
|
437
|
+
}
|
438
|
+
/* position of planet */
|
439
|
+
if (swe_calc_ut(tjdnoon, ipl, iflag, xx, serr) == ERR) {
|
440
|
+
if (serr != NULL)
|
441
|
+
strcpy(serr, "error in calc_rise_and_set(): calc(sun) failed ");
|
442
|
+
return ERR;
|
443
|
+
}
|
444
|
+
/* apparent radius of solar disk (ignoring refraction) */
|
445
|
+
rdi = asin(696000000.0 / 1.49597870691e+11 / xx[2]) / DEGTORAD;
|
446
|
+
if (eventflag & SE_BIT_DISC_CENTER)
|
447
|
+
rdi = 0;
|
448
|
+
/* true altitude of sun, when it appears at the horizon */
|
449
|
+
/* refraction for a body visible at the horizon at 0m above sea,
|
450
|
+
* atmospheric temperature 10 deg C, atmospheric pressure 1013.25 is 34.5 arcmin*/
|
451
|
+
rh = -(34.5 / 60.0 + rdi);
|
452
|
+
/* semidiurnal arc of sun */
|
453
|
+
sda = acos(-tan(dgeo[1] * DEGTORAD) * tan(xx[1] * DEGTORAD)) * RADTODEG;
|
454
|
+
/* rough rising and setting times */
|
455
|
+
if (eventflag & SE_CALC_RISE)
|
456
|
+
tjdrise = tjdnoon - sda / 360.0;
|
457
|
+
else
|
458
|
+
tjdrise = tjdnoon + sda / 360.0;
|
459
|
+
/*ph->tset = tjd_start + sda / 360.0;*/
|
460
|
+
/* now calculate more accurate rising and setting times.
|
461
|
+
* use vertical speed in order to determine crossing of the horizon
|
462
|
+
* refraction of 34' and solar disk diameter of 16' = 50' = 0.84 deg */
|
463
|
+
iflag = SEFLG_SPEED|SEFLG_EQUATORIAL;
|
464
|
+
if (ipl == SE_MOON)
|
465
|
+
iflag |= SEFLG_TOPOCTR;
|
466
|
+
if (!(helflag & SE_HELFLAG_HIGH_PRECISION))
|
467
|
+
iflag |= SEFLG_NONUT|SEFLG_TRUEPOS;
|
468
|
+
for (i = 0; i < 2; i++) {
|
469
|
+
if (swe_calc_ut(tjdrise, ipl, iflag, xx, serr) == ERR)
|
470
|
+
return ERR;
|
471
|
+
swe_azalt(tjdrise, SE_EQU2HOR, dgeo, datm[0], datm[1], xx, xaz);
|
472
|
+
xx[0] -= xx[3] * dfac;
|
473
|
+
xx[1] -= xx[4] * dfac;
|
474
|
+
swe_azalt(tjdrise - dfac, SE_EQU2HOR, dgeo, datm[0], datm[1], xx, xaz2);
|
475
|
+
tjdrise -= (xaz[1] - rh) / (xaz[1] - xaz2[1]) * dfac;
|
476
|
+
/*fprintf(stderr, "%f\n", ph->trise);*/
|
477
|
+
}
|
478
|
+
*trise = tjdrise;
|
479
|
+
return retc;
|
480
|
+
}
|
481
|
+
|
482
|
+
static int32 my_rise_trans(double tjd, int32 ipl, char* starname, int32 eventtype, int32 helflag, double *dgeo, double *datm, double *tret, char *serr)
|
483
|
+
{
|
484
|
+
int retc = OK;
|
485
|
+
if (starname != NULL && *starname != '\0')
|
486
|
+
ipl = DeterObject(starname);
|
487
|
+
/* for non-circumpolar planets we can use a faster algorithm */
|
488
|
+
/*if (!(helflag & SE_HELFLAG_HIGH_PRECISION) && ipl != -1 && fabs(dgeo[1]) < 58) {*/
|
489
|
+
if (ipl != -1 && fabs(dgeo[1]) < 63) {
|
490
|
+
retc = calc_rise_and_set(tjd, ipl, dgeo, datm, eventtype, helflag, tret, serr);
|
491
|
+
/* for stars and circumpolar planets we use a rigorous algorithm */
|
492
|
+
} else {
|
493
|
+
retc = call_swe_rise_trans(tjd, ipl, starname, helflag, eventtype, dgeo, datm[0], datm[1], tret, serr);
|
494
|
+
}
|
495
|
+
/* printf("%f, %f\n", tjd, *tret);*/
|
496
|
+
return retc;
|
497
|
+
}
|
498
|
+
|
499
|
+
/*###################################################################
|
500
|
+
' JDNDaysUT [Days]
|
501
|
+
' dgeo [array: longitude, latitude, eye height above sea m]
|
502
|
+
' TempE [C]
|
503
|
+
' PresE [mbar]
|
504
|
+
' ObjectName (string)
|
505
|
+
' RSEvent (1=rise, 2=set,3=up transit,4=down transit)
|
506
|
+
' Rim [0=center,1=top]
|
507
|
+
' RiseSet [Day]
|
508
|
+
*/
|
509
|
+
static int32 RiseSet(double JDNDaysUT, double *dgeo, double *datm, char *ObjectName, int32 RSEvent, int32 helflag, int32 Rim, double *tret, char *serr)
|
510
|
+
{
|
511
|
+
int32 eventtype = RSEvent, Planet, retval;
|
512
|
+
if (Rim == 0)
|
513
|
+
eventtype |= SE_BIT_DISC_CENTER;
|
514
|
+
Planet = DeterObject(ObjectName);
|
515
|
+
if (Planet != -1)
|
516
|
+
retval = my_rise_trans(JDNDaysUT, Planet, "", eventtype, helflag, dgeo, datm, tret, serr);
|
517
|
+
else
|
518
|
+
retval = my_rise_trans(JDNDaysUT, -1, ObjectName, eventtype, helflag, dgeo, datm, tret, serr);
|
519
|
+
return retval;
|
520
|
+
}
|
521
|
+
|
522
|
+
/*###################################################################
|
523
|
+
' JDNDaysUT [Days]
|
524
|
+
' actual [0= approximation, 1=actual]
|
525
|
+
' SunRA [deg]
|
526
|
+
*/
|
527
|
+
static double SunRA(double JDNDaysUT, int32 helflag, char *serr)
|
528
|
+
{
|
529
|
+
double tjd_tt;
|
530
|
+
int imon, iday, iyar, calflag = SE_GREG_CAL;
|
531
|
+
double dut;
|
532
|
+
static double tjdlast;
|
533
|
+
static double ralast;
|
534
|
+
tjd_tt = 0;
|
535
|
+
if (JDNDaysUT == tjdlast)
|
536
|
+
return ralast;
|
537
|
+
#ifndef SIMULATE_VICTORVB
|
538
|
+
if (1) { /*helflag & SE_HELFLAG_HIGH_PRECISION) {*/
|
539
|
+
double x[6];
|
540
|
+
int32 epheflag = helflag & (SEFLG_JPLEPH|SEFLG_SWIEPH|SEFLG_MOSEPH);
|
541
|
+
int32 iflag = epheflag | SEFLG_EQUATORIAL;
|
542
|
+
iflag |= SEFLG_NONUT | SEFLG_TRUEPOS;
|
543
|
+
tjd_tt = JDNDaysUT + swe_deltat(JDNDaysUT);
|
544
|
+
if (swe_calc(tjd_tt, SE_SUN, iflag, x, serr) != ERR) {
|
545
|
+
ralast = x[0];
|
546
|
+
tjdlast = JDNDaysUT;
|
547
|
+
return ralast;
|
548
|
+
}
|
549
|
+
}
|
550
|
+
#endif
|
551
|
+
swe_revjul(JDNDaysUT, calflag, &iyar, &imon, &iday, &dut); /* this seems to be much faster than calling swe_revjul() ! Note: only because SunRA is called 1000s of times */
|
552
|
+
tjdlast = JDNDaysUT;
|
553
|
+
ralast = swe_degnorm((imon + (iday - 1) / 30.4 - 3.69) * 30);
|
554
|
+
/*ralast = (DatefromJDut(JDNDaysUT, 2) + (DatefromJDut(JDNDaysUT, 3) - 1) / 30.4 - 3.69) * 30;*/
|
555
|
+
return ralast;
|
556
|
+
}
|
557
|
+
|
558
|
+
/*###################################################################
|
559
|
+
' Temp [C]
|
560
|
+
' Kelvin [K]
|
561
|
+
*/
|
562
|
+
static double Kelvin(double Temp)
|
563
|
+
{
|
564
|
+
/*' http://en.wikipedia.org/wiki/Kelvin*/
|
565
|
+
return Temp + C2K;
|
566
|
+
}
|
567
|
+
|
568
|
+
/*###################################################################
|
569
|
+
' AppAlt [deg]
|
570
|
+
' TempE [C]
|
571
|
+
' PresE [mbar]
|
572
|
+
' TopoAltitudefromAppAlt [deg]
|
573
|
+
*/
|
574
|
+
static double TopoAltfromAppAlt(double AppAlt, double TempE, double PresE)
|
575
|
+
{
|
576
|
+
double R = 0;
|
577
|
+
double retalt = 0;
|
578
|
+
if (AppAlt >= LowestAppAlt) {
|
579
|
+
if (AppAlt > 17.904104638432)
|
580
|
+
R = 0.97 / tan(AppAlt * DEGTORAD);
|
581
|
+
else
|
582
|
+
R = (34.46 + 4.23 * AppAlt + 0.004 * AppAlt * AppAlt) / (1 + 0.505 * AppAlt + 0.0845 * AppAlt * AppAlt);
|
583
|
+
R = (PresE - 80) / 930 / (1 + 0.00008 * (R + 39) * (TempE - 10)) * R;
|
584
|
+
retalt = AppAlt - R * Min2Deg;
|
585
|
+
} else {
|
586
|
+
retalt = AppAlt;
|
587
|
+
}
|
588
|
+
return retalt;
|
589
|
+
}
|
590
|
+
|
591
|
+
/*###################################################################
|
592
|
+
' TopoAlt [deg]
|
593
|
+
' TempE [C]
|
594
|
+
' PresE [mbar]
|
595
|
+
' AppAltfromTopoAlt [deg]
|
596
|
+
' call this instead of swe_azalt(), because it is faster (lower precision
|
597
|
+
' is required)
|
598
|
+
*/
|
599
|
+
static double AppAltfromTopoAlt(double TopoAlt, double TempE, double PresE, int32 helflag)
|
600
|
+
{
|
601
|
+
/* using methodology of Newtown derivatives (analogue to what Swiss Emphemeris uses)*/
|
602
|
+
int i, nloop = 2;
|
603
|
+
double newAppAlt = TopoAlt;
|
604
|
+
double newTopoAlt = 0.0;
|
605
|
+
double oudAppAlt = newAppAlt;
|
606
|
+
double oudTopoAlt = newTopoAlt;
|
607
|
+
double verschil, retalt;
|
608
|
+
if (helflag & SE_HELFLAG_HIGH_PRECISION)
|
609
|
+
nloop = 5;
|
610
|
+
for (i = 0; i <= nloop; i++) {
|
611
|
+
newTopoAlt = newAppAlt - TopoAltfromAppAlt(newAppAlt, TempE, PresE);
|
612
|
+
/*newTopoAlt = newAppAlt - swe_refrac(newAppAlt, PresE, TempE, SE_CALC_APP_TO_TRUE);*/
|
613
|
+
verschil = newAppAlt - oudAppAlt;
|
614
|
+
oudAppAlt = newTopoAlt - oudTopoAlt - verschil;
|
615
|
+
if ((verschil != 0) && (oudAppAlt != 0))
|
616
|
+
verschil = newAppAlt - verschil * (TopoAlt + newTopoAlt - newAppAlt) / oudAppAlt;
|
617
|
+
else
|
618
|
+
verschil = TopoAlt + newTopoAlt;
|
619
|
+
oudAppAlt = newAppAlt;
|
620
|
+
oudTopoAlt = newTopoAlt;
|
621
|
+
newAppAlt = verschil;
|
622
|
+
}
|
623
|
+
retalt = TopoAlt + newTopoAlt;
|
624
|
+
if (retalt < LowestAppAlt)
|
625
|
+
retalt = TopoAlt;
|
626
|
+
return retalt;
|
627
|
+
}
|
628
|
+
|
629
|
+
/*###################################################################
|
630
|
+
' TopoAlt [deg]
|
631
|
+
' TopoDecl [deg]
|
632
|
+
' Lat [deg]
|
633
|
+
' HourAngle [hour]
|
634
|
+
*/
|
635
|
+
static double HourAngle(double TopoAlt, double TopoDecl, double Lat)
|
636
|
+
{
|
637
|
+
double Alti = TopoAlt * DEGTORAD;
|
638
|
+
double decli = TopoDecl * DEGTORAD;
|
639
|
+
double Lati = Lat * DEGTORAD;
|
640
|
+
double ha = (sin(Alti) - sin(Lati) * sin(decli)) / cos(Lati) / cos(decli);
|
641
|
+
if (ha < -1) ha = -1;
|
642
|
+
if (ha > 1) ha = 1;
|
643
|
+
/* from http://star-www.st-and.ac.uk/~fv/webnotes/chapt12.htm*/
|
644
|
+
return acos(ha) / DEGTORAD / 15.0;
|
645
|
+
}
|
646
|
+
|
647
|
+
/*###################################################################
|
648
|
+
' JDNDays [Days]
|
649
|
+
' COD [msec/cy]
|
650
|
+
' DeltaTSE [Sec]
|
651
|
+
*/
|
652
|
+
static double DeltaTSE(double JDNDays, int COD)
|
653
|
+
{
|
654
|
+
double OffSetYear;
|
655
|
+
int gregflag = SE_GREG_CAL;
|
656
|
+
if (StartYear < 1583)
|
657
|
+
gregflag = SE_JUL_CAL;
|
658
|
+
/* from Swiss Emphemeris */
|
659
|
+
if (COD != 0) {
|
660
|
+
/* Determined by V. Reijs*/
|
661
|
+
OffSetYear = (swe_julday((int) StartYear, 1, 1, 0, gregflag) - JDNDays) / 365.25;
|
662
|
+
return (OffSetYear * OffSetYear / 100.0 / 2.0 * COD * Y2D) / 1000.0;
|
663
|
+
}
|
664
|
+
return swe_deltat(JDNDays) * D2S;
|
665
|
+
}
|
666
|
+
|
667
|
+
/*###################################################################
|
668
|
+
' JDNDays [Day]
|
669
|
+
' COD [msec/cy]
|
670
|
+
' DeltaTVR [Sec]
|
671
|
+
*/
|
672
|
+
static double DeltaTVR(double JDNDays, int COD)
|
673
|
+
{
|
674
|
+
/* Determined by V. Reijs */
|
675
|
+
double DeltaTVR;
|
676
|
+
int gregflag = SE_GREG_CAL;
|
677
|
+
double OffSetYear;
|
678
|
+
if (StartYear < 1583)
|
679
|
+
gregflag = SE_JUL_CAL;
|
680
|
+
OffSetYear = (swe_julday((int) StartYear, 1, 1, 0, gregflag) - JDNDays) / 365.25;
|
681
|
+
if (COD == 0) {
|
682
|
+
DeltaTVR = (OffSetYear * OffSetYear / 100.0 / 2.0 * Average + Periodicy / 2.0 / PI * Amplitude * (cos((2 * PI * OffSetYear / Periodicy)) - 1)) * Y2D;
|
683
|
+
} else {
|
684
|
+
DeltaTVR = OffSetYear * OffSetYear / 100.0 / 2.0 * COD * Y2D;
|
685
|
+
}
|
686
|
+
return DeltaTVR / 1000.0;
|
687
|
+
}
|
688
|
+
|
689
|
+
/*###################################################################
|
690
|
+
' JDNDays [Days]
|
691
|
+
' COD [msec/cy]
|
692
|
+
' DeltaT [Sec]
|
693
|
+
*/
|
694
|
+
static double DeltaT(double JDNDays, int COD)
|
695
|
+
{
|
696
|
+
if (USE_DELTA_T_VR)
|
697
|
+
return DeltaTVR(JDNDays, COD);
|
698
|
+
return DeltaTSE(JDNDays, COD);
|
699
|
+
}
|
700
|
+
|
701
|
+
/*###################################################################
|
702
|
+
' JDNDaysUT [Days]
|
703
|
+
' dgeo [array: longitude, latitude, eye height above sea m]
|
704
|
+
' TempE [C]
|
705
|
+
' PresE [mbar]
|
706
|
+
' ObjectName [-]
|
707
|
+
' Angle (0 = TopoAlt, 1 = Azi, 2=Topo Declination, 3=Topo Rectascension, 4=AppAlt,5=Geo Declination, 6=Geo Rectascension)
|
708
|
+
' ObjectLoc [deg]
|
709
|
+
*/
|
710
|
+
static int32 ObjectLoc(double JDNDaysUT, double *dgeo, double *datm, char *ObjectName, int32 Angle, int32 helflag, double *dret, char *serr)
|
711
|
+
{
|
712
|
+
double x[6], xin[3], xaz[3], tjd_tt;
|
713
|
+
int32 Planet;
|
714
|
+
int32 epheflag;
|
715
|
+
int32 iflag = SEFLG_EQUATORIAL;
|
716
|
+
epheflag = helflag & (SEFLG_JPLEPH|SEFLG_SWIEPH|SEFLG_MOSEPH);
|
717
|
+
iflag |= epheflag;
|
718
|
+
if (!(helflag & SE_HELFLAG_HIGH_PRECISION))
|
719
|
+
iflag |= SEFLG_NONUT | SEFLG_TRUEPOS;
|
720
|
+
if (Angle < 5) iflag = iflag | SEFLG_TOPOCTR;
|
721
|
+
if (Angle == 7) Angle = 0;
|
722
|
+
tjd_tt = JDNDaysUT + DeltaT(JDNDaysUT, 0) / D2S;
|
723
|
+
Planet = DeterObject(ObjectName);
|
724
|
+
if (Planet != -1) {
|
725
|
+
if (swe_calc(tjd_tt, Planet, iflag, x, serr) == ERR)
|
726
|
+
return ERR;
|
727
|
+
} else {
|
728
|
+
if (call_swe_fixstar(ObjectName, tjd_tt, iflag, x, serr) == ERR)
|
729
|
+
return ERR;
|
730
|
+
}
|
731
|
+
if (Angle == 2 || Angle == 5) {
|
732
|
+
*dret = x[1];
|
733
|
+
} else {
|
734
|
+
if (Angle == 3 || Angle == 6) {
|
735
|
+
*dret = x[0];
|
736
|
+
} else {
|
737
|
+
xin[0] = x[0];
|
738
|
+
xin[1] = x[1];
|
739
|
+
swe_azalt(JDNDaysUT, SE_EQU2HOR, dgeo, datm[0], datm[1], xin, xaz);
|
740
|
+
if (Angle == 0)
|
741
|
+
*dret = xaz[1];
|
742
|
+
if (Angle == 4)
|
743
|
+
*dret = AppAltfromTopoAlt(xaz[1], datm[0], datm[1], helflag);
|
744
|
+
if (Angle == 1) {
|
745
|
+
xaz[0] += 180;
|
746
|
+
if (xaz[0] >= 360)
|
747
|
+
xaz[0] -= 360;
|
748
|
+
*dret = xaz[0];
|
749
|
+
}
|
750
|
+
}
|
751
|
+
}
|
752
|
+
return OK;
|
753
|
+
}
|
754
|
+
|
755
|
+
/*###################################################################
|
756
|
+
' JDNDaysUT [Days]
|
757
|
+
' dgeo [array: longitude, latitude, eye height above sea m]
|
758
|
+
' TempE [C]
|
759
|
+
' PresE [mbar]
|
760
|
+
' ObjectName [-]
|
761
|
+
' Angle (0 = TopoAlt, 1 = Azi, 2=Topo Declination, 3=Topo Rectascension, 4=AppAlt,5=Geo Declination, 6=Geo Rectascension)
|
762
|
+
' ObjectLoc [deg]
|
763
|
+
*/
|
764
|
+
static int32 azalt_cart(double JDNDaysUT, double *dgeo, double *datm, char *ObjectName, int32 helflag, double *dret, char *serr)
|
765
|
+
{
|
766
|
+
double x[6], xin[3], xaz[3], tjd_tt;
|
767
|
+
int32 Planet;
|
768
|
+
int32 epheflag;
|
769
|
+
int32 iflag = SEFLG_EQUATORIAL;
|
770
|
+
epheflag = helflag & (SEFLG_JPLEPH|SEFLG_SWIEPH|SEFLG_MOSEPH);
|
771
|
+
iflag |= epheflag;
|
772
|
+
if (!(helflag & SE_HELFLAG_HIGH_PRECISION))
|
773
|
+
iflag |= SEFLG_NONUT | SEFLG_TRUEPOS;
|
774
|
+
iflag = iflag | SEFLG_TOPOCTR;
|
775
|
+
tjd_tt = JDNDaysUT + DeltaT(JDNDaysUT, 0) / D2S;
|
776
|
+
Planet = DeterObject(ObjectName);
|
777
|
+
if (Planet != -1) {
|
778
|
+
if (swe_calc(tjd_tt, Planet, iflag, x, serr) == ERR)
|
779
|
+
return ERR;
|
780
|
+
} else {
|
781
|
+
if (call_swe_fixstar(ObjectName, tjd_tt, iflag, x, serr) == ERR)
|
782
|
+
return ERR;
|
783
|
+
}
|
784
|
+
xin[0] = x[0];
|
785
|
+
xin[1] = x[1];
|
786
|
+
swe_azalt(JDNDaysUT, SE_EQU2HOR, dgeo, datm[0], datm[1], xin, xaz);
|
787
|
+
dret[0] = xaz[0];
|
788
|
+
dret[1] = xaz[1]; /* true altitude */
|
789
|
+
dret[2] = xaz[2]; /* apparent altitude */
|
790
|
+
/* also return cartesian coordinates, for apparent altitude */
|
791
|
+
xaz[1] = xaz[2];
|
792
|
+
xaz[2] = 1;
|
793
|
+
swi_polcart(xaz, xaz);
|
794
|
+
dret[3] = xaz[0];
|
795
|
+
dret[4] = xaz[1];
|
796
|
+
dret[5] = xaz[2];
|
797
|
+
return OK;
|
798
|
+
}
|
799
|
+
|
800
|
+
/*###################################################################
|
801
|
+
' LatA [rad]
|
802
|
+
' LongA [rad]
|
803
|
+
' LatB [rad]
|
804
|
+
' LongB [rad]
|
805
|
+
' DistanceAngle [rad]
|
806
|
+
*/
|
807
|
+
static double DistanceAngle(double LatA, double LongA, double LatB, double LongB)
|
808
|
+
{
|
809
|
+
double dlon = LongB - LongA;
|
810
|
+
double dlat = LatB - LatA;
|
811
|
+
/* Haversine formula
|
812
|
+
* http://www.movable-type.co.uk/scripts/GIS-FAQ-5.1.html
|
813
|
+
* R.W. Sinnott, Virtues of the Haversine, Sky and Telescope, vol. 68, no. 2, 1984, p. 159
|
814
|
+
*/
|
815
|
+
double sindlat2 = sin(dlat / 2);
|
816
|
+
double sindlon2 = sin(dlon / 2);
|
817
|
+
double corde = sindlat2 * sindlat2 + cos(LatA) * cos(LatB) * sindlon2 *sindlon2;
|
818
|
+
if (corde > 1) corde = 1;
|
819
|
+
return 2 * asin(sqrt(corde));
|
820
|
+
}
|
821
|
+
|
822
|
+
/*###################################################################
|
823
|
+
' heighteye [m]
|
824
|
+
' TempS [C]
|
825
|
+
' RH [%]
|
826
|
+
' kW [-]
|
827
|
+
*/
|
828
|
+
static double kW(double HeightEye, double TempS, double RH)
|
829
|
+
{
|
830
|
+
/* From Schaefer , Archaeoastronomy, XV, 2000, page 128*/
|
831
|
+
double WT = 0.031;
|
832
|
+
WT *= 0.94 * (RH / 100.0) * exp(TempS / 15) * exp(-1 * HeightEye / scaleHwater);
|
833
|
+
return WT;
|
834
|
+
}
|
835
|
+
|
836
|
+
/*###################################################################
|
837
|
+
' JDNDaysUT [-]
|
838
|
+
' AltS [deg]
|
839
|
+
' lat [deg]
|
840
|
+
' kOZ [-]
|
841
|
+
*/
|
842
|
+
static double kOZ(double AltS, double sunra, double Lat)
|
843
|
+
{
|
844
|
+
double CHANGEKO, OZ, LT, kOZret;
|
845
|
+
static double koz_last, alts_last, sunra_last;
|
846
|
+
if (AltS == alts_last && sunra == sunra_last)
|
847
|
+
return koz_last;
|
848
|
+
alts_last = AltS; sunra_last = sunra;
|
849
|
+
OZ = 0.031;
|
850
|
+
LT = Lat * DEGTORAD;
|
851
|
+
/* From Schaefer , Archaeoastronomy, XV, 2000, page 128*/
|
852
|
+
kOZret = OZ * (3.0 + 0.4 * (LT * cos(sunra * DEGTORAD) - cos(3 * LT))) / 3.0;
|
853
|
+
/* depending on day/night vision (altitude of sun < start astronomical twilight), KO changes from 100% to 30%
|
854
|
+
* see extinction section of Vistas in Astronomy page 343*/
|
855
|
+
CHANGEKO = (100 - 11.6 * mymin(6, mymax(-AltS - 12, 0))) / 100;
|
856
|
+
koz_last = kOZret * CHANGEKO;
|
857
|
+
return koz_last;
|
858
|
+
}
|
859
|
+
|
860
|
+
/*###################################################################
|
861
|
+
' AltS [deg]
|
862
|
+
' heighteye [m]
|
863
|
+
' kR [-]
|
864
|
+
*/
|
865
|
+
static double kR(double AltS, double HeightEye)
|
866
|
+
{
|
867
|
+
/* depending on day/night vision (altitude of sun < start astronomical twilight),
|
868
|
+
* lambda eye sensibility changes
|
869
|
+
* see extinction section of Vistas in Astronomy page 343*/
|
870
|
+
double CHANGEK, LAMBDA;
|
871
|
+
double val = -AltS - 12;
|
872
|
+
if (val < 0) val = 0;
|
873
|
+
if (val > 6) val = 6;
|
874
|
+
/*CHANGEK = (1 - 0.166667 * Min(6, Max(-AltS - 12, 0)));*/
|
875
|
+
CHANGEK = (1 - 0.166667 * val );
|
876
|
+
LAMBDA = 0.55 + (CHANGEK - 1) * 0.04;
|
877
|
+
/* From Schaefer , Archaeoastronomy, XV, 2000, page 128 */
|
878
|
+
return 0.1066 * exp(-1 * HeightEye / scaleHrayleigh) * pow(LAMBDA / 0.55 , -4);
|
879
|
+
}
|
880
|
+
|
881
|
+
static int Sgn(double x)
|
882
|
+
{
|
883
|
+
if (x < 0)
|
884
|
+
return -1;
|
885
|
+
return 1;
|
886
|
+
}
|
887
|
+
|
888
|
+
/*###################################################################
|
889
|
+
' JDNDaysUT [-]
|
890
|
+
' AltS [deg]
|
891
|
+
' lat [deg]
|
892
|
+
' heighteye [m]
|
893
|
+
' TempS [C]
|
894
|
+
' RH [%]
|
895
|
+
' VR [km]
|
896
|
+
' ka [-]
|
897
|
+
*/
|
898
|
+
static double ka(double AltS, double sunra, double Lat, double HeightEye, double TempS, double RH, double VR, char *serr)
|
899
|
+
{
|
900
|
+
double CHANGEKA, LAMBDA, BetaVr, Betaa, kaact;
|
901
|
+
double SL = Sgn(Lat);
|
902
|
+
/* depending on day/night vision (altitude of sun < start astronomical twilight),
|
903
|
+
* lambda eye sensibility changes
|
904
|
+
* see extinction section of Vistas in Astronomy page 343 */
|
905
|
+
static double alts_last, sunra_last, ka_last;
|
906
|
+
if (AltS == alts_last && sunra == sunra_last)
|
907
|
+
return ka_last;
|
908
|
+
alts_last = AltS; sunra_last = sunra;
|
909
|
+
CHANGEKA = (1 - 0.166667 * mymin(6, mymax(-AltS - 12, 0)));
|
910
|
+
LAMBDA = 0.55 + (CHANGEKA - 1) * 0.04;
|
911
|
+
if (VR != 0) {
|
912
|
+
if (VR >= 1) {
|
913
|
+
/* Visbility range from http://www1.cs.columbia.edu/CAVE/publications/pdfs/Narasimhan_CVPR03.pdf
|
914
|
+
* http://www.icao.int/anb/SG/AMOSSG/meetings/amossg3/wp/SN11Rev.pdf where MOR=2.995/ke
|
915
|
+
* factor 1.3 is the relation between "prevailing visibility" and
|
916
|
+
* meteorological range was derived by Koshmeider in the 1920's */
|
917
|
+
BetaVr = 3.912 / VR;
|
918
|
+
Betaa = BetaVr - (kW(HeightEye, TempS, RH) / scaleHwater + kR(AltS, HeightEye) / scaleHrayleigh) * 1000 * astr2tau;
|
919
|
+
kaact = Betaa * scaleHaerosol / 1000 * tau2astr;
|
920
|
+
if (kaact < 0) {
|
921
|
+
if (serr != NULL)
|
922
|
+
strcpy(serr, "The provided Meteorological range is too long, when taking into acount other atmospheric parameters"); /* is a warning */
|
923
|
+
/* return 0; * return "#HIGHVR"; */
|
924
|
+
}
|
925
|
+
} else {
|
926
|
+
kaact = VR - kW(HeightEye, TempS, RH) - kR(AltS, HeightEye) - kOZ(AltS, sunra, Lat);
|
927
|
+
if (kaact < 0) {
|
928
|
+
if (serr != NULL)
|
929
|
+
strcpy(serr, "The provided atmosphic coeefficent (ktot) is too low, when taking into acount other atmospheric parameters"); /* is a warning */
|
930
|
+
/* return 0; * "#LOWktot"; */
|
931
|
+
}
|
932
|
+
}
|
933
|
+
} else {
|
934
|
+
/* From Schaefer , Archaeoastronomy, XV, 2000, page 128 */
|
935
|
+
#ifdef SIMULATE_VICTORVB
|
936
|
+
if (RH <= 0.00000001) RH = 0.00000001;
|
937
|
+
if (RH >= 99.99999999) RH = 99.99999999;
|
938
|
+
#endif
|
939
|
+
kaact = 0.1 * exp(-1 * HeightEye / scaleHaerosol) * pow(1 - 0.32 / log(RH / 100.0), 1.33) * (1 + 0.33 * SL * sin(sunra * DEGTORAD));
|
940
|
+
kaact = kaact * pow(LAMBDA / 0.55, -1.3);
|
941
|
+
}
|
942
|
+
ka_last = kaact;
|
943
|
+
return kaact;
|
944
|
+
}
|
945
|
+
|
946
|
+
/*###################################################################
|
947
|
+
' JDNDaysUT [-]
|
948
|
+
' AltS [deg]
|
949
|
+
' lat [deg]
|
950
|
+
' heighteye [m]
|
951
|
+
' TempS [C]
|
952
|
+
' RH [%]
|
953
|
+
' VR [km]
|
954
|
+
' ExtType [0=ka,1=kW,2=kR,3=kOZ,4=ktot]
|
955
|
+
' kt [-]
|
956
|
+
*/
|
957
|
+
static double kt(double AltS, double sunra, double Lat, double HeightEye, double TempS, double RH, double VR, int32 ExtType, char *serr)
|
958
|
+
{
|
959
|
+
double kRact = 0;
|
960
|
+
double kWact = 0;
|
961
|
+
double kOZact = 0;
|
962
|
+
double kaact = 0;
|
963
|
+
if (ExtType == 2 || ExtType == 4)
|
964
|
+
kRact = kR(AltS, HeightEye);
|
965
|
+
if (ExtType == 1 || ExtType == 4)
|
966
|
+
kWact = kW(HeightEye, TempS, RH);
|
967
|
+
if (ExtType == 3 || ExtType == 4)
|
968
|
+
kOZact = kOZ(AltS, sunra, Lat);
|
969
|
+
if (ExtType == 0 || ExtType == 4)
|
970
|
+
kaact = ka(AltS, sunra, Lat, HeightEye, TempS, RH, VR, serr);
|
971
|
+
if (kaact < 0)
|
972
|
+
kaact = 0;
|
973
|
+
return kWact + kRact + kOZact + kaact;
|
974
|
+
}
|
975
|
+
|
976
|
+
/*###################################################################
|
977
|
+
' AppAlt0 [deg]
|
978
|
+
' PresS [mbar]
|
979
|
+
' Airmass [??]
|
980
|
+
*/
|
981
|
+
static double Airmass(double AppAltO, double Press)
|
982
|
+
{
|
983
|
+
double airm, zend;
|
984
|
+
zend = (90 - AppAltO) * DEGTORAD;
|
985
|
+
if (zend > PI / 2)
|
986
|
+
zend = PI / 2;
|
987
|
+
airm = 1 / (cos(zend) + 0.025 * exp(-11 * cos(zend)));
|
988
|
+
return Press / 1013 * airm;
|
989
|
+
}
|
990
|
+
|
991
|
+
/*###################################################################
|
992
|
+
' scaleH '[m]
|
993
|
+
' zend [rad]
|
994
|
+
' PresS [mbar]
|
995
|
+
' Xext [-]
|
996
|
+
*/
|
997
|
+
static double Xext(double scaleH, double zend, double Press)
|
998
|
+
{
|
999
|
+
return Press / 1013.0 / (cos(zend) + 0.01 * sqrt(scaleH / 1000.0) * exp(-30.0 / sqrt(scaleH / 1000.0) * cos(zend)));
|
1000
|
+
}
|
1001
|
+
|
1002
|
+
/*###################################################################
|
1003
|
+
' scaleH '[m]
|
1004
|
+
' zend [rad]
|
1005
|
+
' PresS [mbar]
|
1006
|
+
' Xlay [-]
|
1007
|
+
*/
|
1008
|
+
static double Xlay(double scaleH, double zend, double Press)
|
1009
|
+
{
|
1010
|
+
/*return Press / 1013.0 / sqrt(1.0 - pow(sin(zend) / (1.0 + (scaleH / Ra)), 2));*/
|
1011
|
+
double a = sin(zend) / (1.0 + (scaleH / Ra));
|
1012
|
+
return Press / 1013.0 / sqrt(1.0 - a * a);
|
1013
|
+
}
|
1014
|
+
|
1015
|
+
/*###################################################################
|
1016
|
+
' Meteorological formula
|
1017
|
+
'###################################################################
|
1018
|
+
' TempS [C]
|
1019
|
+
' HeightEye [m]
|
1020
|
+
' TempEfromTempS [C]
|
1021
|
+
*/
|
1022
|
+
static double TempEfromTempS(double TempS, double HeightEye, double Lapse)
|
1023
|
+
{
|
1024
|
+
return TempS - Lapse * HeightEye;
|
1025
|
+
}
|
1026
|
+
|
1027
|
+
/*###################################################################
|
1028
|
+
' TempS [C]
|
1029
|
+
' PresS [mbar]
|
1030
|
+
' HeightEye [m]
|
1031
|
+
' PresEfromPresS [mbar]
|
1032
|
+
*/
|
1033
|
+
static double PresEfromPresS(double TempS, double Press, double HeightEye)
|
1034
|
+
{
|
1035
|
+
return Press * exp(-9.80665 * 0.0289644 / (Kelvin(TempS) + 3.25 * HeightEye / 1000) / 8.31441 * HeightEye);
|
1036
|
+
}
|
1037
|
+
|
1038
|
+
/*###################################################################
|
1039
|
+
' AltO [deg]
|
1040
|
+
' JDNDaysUT [-]
|
1041
|
+
' AltS [deg]
|
1042
|
+
' lat [deg]
|
1043
|
+
' heighteye [m]
|
1044
|
+
' TempS [C]
|
1045
|
+
' PresS [mbar]
|
1046
|
+
' RH [%]
|
1047
|
+
' VR [km]
|
1048
|
+
' Deltam [-]
|
1049
|
+
*/
|
1050
|
+
static double Deltam(double AltO, double AltS, double sunra, double Lat, double HeightEye, double *datm, int32 helflag, char *serr)
|
1051
|
+
{
|
1052
|
+
double zend, xR, XW, Xa, XOZ;
|
1053
|
+
double PresE = PresEfromPresS(datm[1], datm[0], HeightEye);
|
1054
|
+
double TempE = TempEfromTempS(datm[1], HeightEye, LapseSA);
|
1055
|
+
double AppAltO = AppAltfromTopoAlt(AltO, TempE, PresE, helflag);
|
1056
|
+
double deltam;
|
1057
|
+
static double alts_last, alto_last, sunra_last, deltam_last;
|
1058
|
+
if (AltS == alts_last && AltO == alto_last && sunra == sunra_last)
|
1059
|
+
return deltam_last;
|
1060
|
+
alts_last = AltS; alto_last = AltO; sunra_last = sunra;
|
1061
|
+
if (staticAirmass == 0) {
|
1062
|
+
zend = (90 - AppAltO) * DEGTORAD;
|
1063
|
+
if (zend > PI / 2)
|
1064
|
+
zend = PI / 2;
|
1065
|
+
/* From Schaefer , Archaeoastronomy, XV, 2000, page 128*/
|
1066
|
+
xR = Xext(scaleHrayleigh, zend, datm[0]);
|
1067
|
+
XW = Xext(scaleHwater, zend, datm[0]);
|
1068
|
+
Xa = Xext(scaleHaerosol, zend, datm[0]);
|
1069
|
+
XOZ = Xlay(scaleHozone, zend, datm[0]);
|
1070
|
+
deltam = kR(AltS, HeightEye) * xR + kt(AltS, sunra, Lat, HeightEye, datm[1], datm[2], datm[3], 0, serr) * Xa + kOZ(AltS, sunra, Lat) * XOZ + kW(HeightEye, datm[1], datm[2]) * XW;
|
1071
|
+
} else {
|
1072
|
+
deltam = kt(AltS, sunra, Lat, HeightEye, datm[1], datm[2], datm[3], 4, serr) * Airmass(AppAltO, datm[0]);
|
1073
|
+
}
|
1074
|
+
deltam_last = deltam;
|
1075
|
+
return deltam;
|
1076
|
+
}
|
1077
|
+
|
1078
|
+
/*###################################################################
|
1079
|
+
' AltO [deg]
|
1080
|
+
' JDNDaysUT [-]
|
1081
|
+
' AltS [deg]
|
1082
|
+
' lat [deg]
|
1083
|
+
' heighteye [m]
|
1084
|
+
' TempS [C]
|
1085
|
+
' PresS [mbar]
|
1086
|
+
' RH [%]
|
1087
|
+
' VR [km]
|
1088
|
+
' Bn [nL]
|
1089
|
+
*/
|
1090
|
+
static double Bn(double AltO, double JDNDayUT, double AltS, double sunra, double Lat, double HeightEye, double *datm, int32 helflag, char *serr)
|
1091
|
+
{
|
1092
|
+
double PresE = PresEfromPresS(datm[1], datm[0], HeightEye);
|
1093
|
+
double TempE = TempEfromTempS(datm[1], HeightEye, LapseSA);
|
1094
|
+
double AppAltO = AppAltfromTopoAlt(AltO, TempE, PresE, helflag);
|
1095
|
+
double zend, YearB, MonthB, DayB, Bna, kX, Bnb;
|
1096
|
+
double B0 = 0.0000000000001, dut;
|
1097
|
+
int iyar, imon, iday;
|
1098
|
+
/* Below altitude of 10 degrees, the Bn stays the same (see page 343 Vistas in Astronomy) */
|
1099
|
+
if (AppAltO < 10)
|
1100
|
+
AppAltO = 10;
|
1101
|
+
zend = (90 - AppAltO) * DEGTORAD;
|
1102
|
+
/* From Schaefer , Archaeoastronomy, XV, 2000, page 128 and adjusted for sunspot period*/
|
1103
|
+
/*YearB = DatefromJDut(JDNDayUT, 1);
|
1104
|
+
MonthB = DatefromJDut(JDNDayUT, 2);
|
1105
|
+
DayB = DatefromJDut(JDNDayUT, 3);*/
|
1106
|
+
swe_revjul(JDNDayUT, SE_GREG_CAL, &iyar, &imon, &iday, &dut);
|
1107
|
+
YearB = iyar; MonthB = imon; DayB = iday;
|
1108
|
+
Bna = B0 * (1 + 0.3 * cos(6.283 * (YearB + ((DayB - 1) / 30.4 + MonthB - 1) / 12 - 1990.33) / 11.1));
|
1109
|
+
kX = Deltam(AltO, AltS, sunra, Lat, HeightEye, datm, helflag, serr);
|
1110
|
+
/* From Schaefer , Archaeoastronomy, XV, 2000, page 129 */
|
1111
|
+
Bnb = Bna * (0.4 + 0.6 / sqrt(1 - 0.96 * pow(sin(zend), 2))) * pow(10, -0.4 * kX);
|
1112
|
+
return mymax(Bnb, 0) * erg2nL;
|
1113
|
+
}
|
1114
|
+
|
1115
|
+
/*###################################################################
|
1116
|
+
' JDNDaysUT [-]
|
1117
|
+
' dgeo [array: longitude, latitude, eye height above sea m]
|
1118
|
+
' TempE [C]
|
1119
|
+
' PresE [mbar]
|
1120
|
+
' ObjectName [-]
|
1121
|
+
' Magnitude [-]
|
1122
|
+
*/
|
1123
|
+
static int32 Magnitude(double JDNDaysUT, double *dgeo, char *ObjectName, int32 helflag, double *dmag, char *serr)
|
1124
|
+
{
|
1125
|
+
double x[20];
|
1126
|
+
int32 Planet, iflag, epheflag;
|
1127
|
+
epheflag = helflag & (SEFLG_JPLEPH|SEFLG_SWIEPH|SEFLG_MOSEPH);
|
1128
|
+
*dmag = -99.0;
|
1129
|
+
Planet = DeterObject(ObjectName);
|
1130
|
+
iflag = SEFLG_TOPOCTR | SEFLG_EQUATORIAL | epheflag;
|
1131
|
+
if (!(helflag & SE_HELFLAG_HIGH_PRECISION))
|
1132
|
+
iflag |= SEFLG_NONUT|SEFLG_TRUEPOS;
|
1133
|
+
if (Planet != -1) {
|
1134
|
+
/**dmag = Phenomena(JDNDaysUT, Lat, Longitude, HeightEye, TempE, PresE, ObjectName, 4);*/
|
1135
|
+
swe_set_topo(dgeo[0], dgeo[1], dgeo[2]);
|
1136
|
+
if (swe_pheno_ut(JDNDaysUT, Planet, iflag, x, serr) == ERR)
|
1137
|
+
return ERR;
|
1138
|
+
*dmag = x[4];
|
1139
|
+
} else {
|
1140
|
+
if (call_swe_fixstar_mag(ObjectName, dmag, serr) == ERR)
|
1141
|
+
return ERR;
|
1142
|
+
}
|
1143
|
+
return OK;
|
1144
|
+
}
|
1145
|
+
|
1146
|
+
#if 0
|
1147
|
+
static int32 fast_magnitude(double tjd, double *dgeo, char *ObjectName, int32 helflag, double *dmag, char *serr)
|
1148
|
+
{
|
1149
|
+
int32 retval = OK, ipl, ipli;
|
1150
|
+
double dtjd;
|
1151
|
+
static double tjdsv[3];
|
1152
|
+
static double dmagsv[3];
|
1153
|
+
static int32 helflagsv[3];
|
1154
|
+
ipl = DeterObject(ObjectName);
|
1155
|
+
ipli = ipl;
|
1156
|
+
if (ipli > SE_MOON)
|
1157
|
+
ipli = 2;
|
1158
|
+
dtjd = tjd - tjdsv[ipli];
|
1159
|
+
if (tjdsv[ipli] != 0 && helflag == helflagsv[ipli] && fabs(dtjd) < 5.0 / 1440.0) {
|
1160
|
+
*dmag = dmagsv[ipli];
|
1161
|
+
} else {
|
1162
|
+
retval = Magnitude(tjd, dgeo, ObjectName, helflag, dmag, serr);
|
1163
|
+
tjdsv[ipli] = tjd;
|
1164
|
+
helflagsv[ipli] = helflag;
|
1165
|
+
dmagsv[ipli] = *dmag;
|
1166
|
+
}
|
1167
|
+
return retval;
|
1168
|
+
}
|
1169
|
+
#endif
|
1170
|
+
|
1171
|
+
/*###################################################################
|
1172
|
+
' dist [km]
|
1173
|
+
' phasemoon [-]
|
1174
|
+
' MoonsBrightness [-]
|
1175
|
+
*/
|
1176
|
+
static double MoonsBrightness(double dist, double phasemoon)
|
1177
|
+
{
|
1178
|
+
double log10 = 2.302585092994;
|
1179
|
+
/*Moon's brightness changes with distance: http://hem.passagen.se/pausch/comp/ppcomp.html#15 */
|
1180
|
+
return -21.62 + 5 * log(dist / (Ra / 1000)) / log10 + 0.026 * fabs(phasemoon) + 0.000000004 * pow(phasemoon, 4);
|
1181
|
+
}
|
1182
|
+
|
1183
|
+
/*###################################################################
|
1184
|
+
' AltM [deg]
|
1185
|
+
' AziM [deg]
|
1186
|
+
' AziS [deg]
|
1187
|
+
' MoonPhase [deg]
|
1188
|
+
*/
|
1189
|
+
static double MoonPhase(double AltM, double AziM, double AziS)
|
1190
|
+
{
|
1191
|
+
double AltMi = AltM * DEGTORAD;
|
1192
|
+
double AziMi = AziM * DEGTORAD;
|
1193
|
+
double AziSi = AziS * DEGTORAD;
|
1194
|
+
return 180 - acos(cos(AziSi - AziMi) * cos(AltMi + 0.95 * DEGTORAD)) / DEGTORAD;
|
1195
|
+
}
|
1196
|
+
|
1197
|
+
/*###################################################################
|
1198
|
+
' Pressure [mbar]
|
1199
|
+
*/
|
1200
|
+
static double Bm(double AltO, double AziO, double AltM, double AziM, double AltS, double AziS, double sunra, double Lat, double HeightEye, double *datm, int32 helflag, char *serr)
|
1201
|
+
{
|
1202
|
+
double M0 = -11.05;
|
1203
|
+
double Bm = 0;
|
1204
|
+
double RM, kXM, kX, C3, FM, phasemoon, MM;
|
1205
|
+
if (AltM > -0.26) {
|
1206
|
+
/* moon only adds light when (partly) above horizon
|
1207
|
+
* From Schaefer , Archaeoastronomy, XV, 2000, page 129*/
|
1208
|
+
RM = DistanceAngle(AltO * DEGTORAD, AziO * DEGTORAD, AltM * DEGTORAD, AziM * DEGTORAD) / DEGTORAD;
|
1209
|
+
kXM = Deltam(AltM, AltS, sunra, Lat, HeightEye, datm, helflag, serr);
|
1210
|
+
kX = Deltam(AltO, AltS, sunra, Lat, HeightEye, datm, helflag, serr);
|
1211
|
+
C3 = pow(10, -0.4 * kXM);
|
1212
|
+
FM = (62000000.0) / RM / RM + pow(10, 6.15 - RM / 40) + pow(10, 5.36) * (1.06 + pow(cos(RM * DEGTORAD), 2));
|
1213
|
+
Bm = FM * C3 + 440000 * (1 - C3);
|
1214
|
+
phasemoon = MoonPhase(AltM, AziM, AziS);
|
1215
|
+
MM = MoonsBrightness(MoonDistance, phasemoon);
|
1216
|
+
Bm = Bm * pow(10, -0.4 * (MM - M0 + 43.27));
|
1217
|
+
Bm = Bm * (1 - pow(10, -0.4 * kX));
|
1218
|
+
}
|
1219
|
+
Bm = mymax(Bm, 0) * erg2nL;
|
1220
|
+
return Bm;
|
1221
|
+
}
|
1222
|
+
|
1223
|
+
/*###################################################################
|
1224
|
+
' Pressure [mbar]
|
1225
|
+
*/
|
1226
|
+
static double Btwi(double AltO, double AziO, double AltS, double AziS, double sunra, double Lat, double HeightEye, double *datm, int32 helflag, char *serr)
|
1227
|
+
{
|
1228
|
+
double M0 = -11.05;
|
1229
|
+
double MS = -26.74;
|
1230
|
+
double PresE = PresEfromPresS(datm[1], datm[0], HeightEye);
|
1231
|
+
double TempE = TempEfromTempS(datm[1], HeightEye, LapseSA);
|
1232
|
+
double AppAltO = AppAltfromTopoAlt(AltO, TempE, PresE, helflag);
|
1233
|
+
double ZendO = 90 - AppAltO;
|
1234
|
+
double RS = DistanceAngle(AltO * DEGTORAD, AziO * DEGTORAD, AltS * DEGTORAD, AziS * DEGTORAD) / DEGTORAD;
|
1235
|
+
double kX = Deltam(AltO, AltS, sunra, Lat, HeightEye, datm, helflag, serr);
|
1236
|
+
double k = kt(AltS, sunra, Lat, HeightEye, datm[1], datm[2], datm[3], 4, serr);
|
1237
|
+
/* From Schaefer , Archaeoastronomy, XV, 2000, page 129*/
|
1238
|
+
double Btwi = pow(10, -0.4 * (MS - M0 + 32.5 - AltS - (ZendO / (360 * k))));
|
1239
|
+
Btwi = Btwi * (100 / RS) * (1 - pow(10, -0.4 * kX));
|
1240
|
+
Btwi = mymax(Btwi, 0) * erg2nL;
|
1241
|
+
return Btwi;
|
1242
|
+
}
|
1243
|
+
|
1244
|
+
/*###################################################################
|
1245
|
+
' Pressure [mbar]
|
1246
|
+
*/
|
1247
|
+
static double Bday(double AltO, double AziO, double AltS, double AziS, double sunra, double Lat, double HeightEye, double *datm, int32 helflag, char *serr)
|
1248
|
+
{
|
1249
|
+
double M0 = -11.05;
|
1250
|
+
double MS = -26.74;
|
1251
|
+
double RS = DistanceAngle(AltO * DEGTORAD, AziO * DEGTORAD, AltS * DEGTORAD, AziS * DEGTORAD) / DEGTORAD;
|
1252
|
+
double kXS = Deltam(AltS, AltS, sunra, Lat, HeightEye, datm, helflag, serr);
|
1253
|
+
double kX = Deltam(AltO, AltS, sunra, Lat, HeightEye, datm, helflag, serr);
|
1254
|
+
/* From Schaefer , Archaeoastronomy, XV, 2000, page 129*/
|
1255
|
+
double C4 = pow(10, -0.4 * kXS);
|
1256
|
+
double FS = (62000000.0) / RS / RS + pow(10, (6.15 - RS / 40)) + pow(10, 5.36) * (1.06 + pow(cos(RS * DEGTORAD), 2));
|
1257
|
+
double Bday = FS * C4 + 440000.0 * (1 - C4);
|
1258
|
+
Bday = Bday * pow(10, (-0.4 * (MS - M0 + 43.27)));
|
1259
|
+
Bday = Bday * (1 - pow(10, -0.4 * kX));
|
1260
|
+
Bday = mymax(Bday, 0) * erg2nL;
|
1261
|
+
return Bday;
|
1262
|
+
}
|
1263
|
+
|
1264
|
+
/*###################################################################
|
1265
|
+
' Value [nL]
|
1266
|
+
' PresS [mbar]
|
1267
|
+
' Bcity [nL]
|
1268
|
+
*/
|
1269
|
+
static double Bcity(double Value, double Press)
|
1270
|
+
{
|
1271
|
+
double Bcity = Value;
|
1272
|
+
Bcity = mymax(Bcity, 0);
|
1273
|
+
return Bcity;
|
1274
|
+
}
|
1275
|
+
|
1276
|
+
/*###################################################################
|
1277
|
+
' Pressure [mbar]
|
1278
|
+
*/
|
1279
|
+
static double Bsky(double AltO, double AziO, double AltM, double AziM, double JDNDaysUT, double AltS, double AziS, double sunra, double Lat, double HeightEye, double *datm, int32 helflag, char *serr)
|
1280
|
+
{
|
1281
|
+
double Bsky = 0;
|
1282
|
+
if (AltS < -3) {
|
1283
|
+
Bsky += Btwi(AltO, AziO, AltS, AziS, sunra, Lat, HeightEye, datm, helflag, serr);
|
1284
|
+
} else {
|
1285
|
+
if (AltS > 4) {
|
1286
|
+
Bsky += Bday(AltO, AziO, AltS, AziS, sunra, Lat, HeightEye, datm, helflag, serr);
|
1287
|
+
} else {
|
1288
|
+
Bsky += mymin(Bday(AltO, AziO, AltS, AziS, sunra, Lat, HeightEye, datm, helflag, serr), Btwi(AltO, AziO, AltS, AziS, sunra, Lat, HeightEye, datm, helflag, serr));
|
1289
|
+
}
|
1290
|
+
}
|
1291
|
+
/* if max. Bm [1E7] <5% of Bsky don't add Bm*/
|
1292
|
+
if (Bsky < 200000000.0)
|
1293
|
+
Bsky += Bm(AltO, AziO, AltM, AziM, AltS, AziS, sunra, Lat, HeightEye, datm, helflag, serr);
|
1294
|
+
if (AltS <= 0)
|
1295
|
+
Bsky += Bcity(0, datm[0]);
|
1296
|
+
/* if max. Bn [250] <5% of Bsky don't add Bn*/
|
1297
|
+
if (Bsky < 5000)
|
1298
|
+
Bsky = Bsky + Bn(AltO, JDNDaysUT, AltS, sunra, Lat, HeightEye, datm, helflag, serr);
|
1299
|
+
/* if max. Bm [1E7] <5% of Bsky don't add Bm*/
|
1300
|
+
return Bsky;
|
1301
|
+
}
|
1302
|
+
|
1303
|
+
/* default handling:
|
1304
|
+
* 1. datm (atmospheric conditions):
|
1305
|
+
* datm consists of
|
1306
|
+
* [0] atmospheric pressure
|
1307
|
+
* [1] temperature
|
1308
|
+
* [2] relative humidity
|
1309
|
+
* [3] extinction coefficient
|
1310
|
+
* In order to get default values for [0..2], set datm[0] = 0.
|
1311
|
+
* Default values for [1-2] are only provided if [0] == 0.
|
1312
|
+
* [3] defaults outside this function, depending on [0-2].
|
1313
|
+
*
|
1314
|
+
* 2. dobs (observer definition):
|
1315
|
+
* [0] age (default 36)
|
1316
|
+
* [1] Snellen ratio or visual acuity of observer (default 1)
|
1317
|
+
*/
|
1318
|
+
static void default_heliacal_parameters(double *datm, double *dgeo, double *dobs, int helflag)
|
1319
|
+
{
|
1320
|
+
int i;
|
1321
|
+
if (datm[0] <= 0) {
|
1322
|
+
/* estimate atmospheric pressure, according to the
|
1323
|
+
* International Standard Atmosphere (ISA) */
|
1324
|
+
datm[0] = 1013.25 * pow(1 - 0.0065 * dgeo[2] / 288, 5.255);
|
1325
|
+
/* temperature */
|
1326
|
+
if (datm[1] == 0)
|
1327
|
+
datm[1] = 15 - 0.0065 * dgeo[2];
|
1328
|
+
/* relative humidity, independent of atmospheric pressure and altitude */
|
1329
|
+
if (datm[2] == 0)
|
1330
|
+
datm[2] = 40;
|
1331
|
+
/* note: datm[3] / VR defaults outside this function */
|
1332
|
+
} else {
|
1333
|
+
#ifndef SIMULATE_VICTORVB
|
1334
|
+
if (datm[2] <= 0.00000001) datm[2] = 0.00000001;
|
1335
|
+
if (datm[2] >= 99.99999999) datm[2] = 99.99999999;
|
1336
|
+
#endif
|
1337
|
+
}
|
1338
|
+
/* age of observer */
|
1339
|
+
if (dobs[0] == 0)
|
1340
|
+
dobs[0] = 36;
|
1341
|
+
/* SN Snellen factor of the visual acuity of the observer */
|
1342
|
+
if (dobs[1] == 0)
|
1343
|
+
dobs[1] = 1;
|
1344
|
+
if (!(helflag & SE_HELFLAG_OPTICAL_PARAMS)) {
|
1345
|
+
for (i = 2; i <= 5; i++)
|
1346
|
+
dobs[i] = 0;
|
1347
|
+
}
|
1348
|
+
/* OpticMagn undefined -> use eye */
|
1349
|
+
if (dobs[3] == 0) {
|
1350
|
+
dobs[2] = 1; /* Binocular = 1 */
|
1351
|
+
dobs[3] = 1; /* OpticMagn = 1: use eye */
|
1352
|
+
/* dobs[4] and dobs[5] (OpticDia and OpticTrans) will be defaulted in
|
1353
|
+
* OpticFactor() */
|
1354
|
+
}
|
1355
|
+
}
|
1356
|
+
|
1357
|
+
/*###################################################################
|
1358
|
+
' age [Year]
|
1359
|
+
' SN [-]
|
1360
|
+
' AltO [deg]
|
1361
|
+
' AziO [deg]
|
1362
|
+
' AltM [deg]
|
1363
|
+
' AziM [deg]
|
1364
|
+
' MoonDistance [km]
|
1365
|
+
' JDNDaysUT [-]
|
1366
|
+
' AltS [deg]
|
1367
|
+
' AziS [deg]
|
1368
|
+
' lat [deg]
|
1369
|
+
' heighteye [m]
|
1370
|
+
' TempS [C]
|
1371
|
+
' PresS [mbar]
|
1372
|
+
' RH [%]
|
1373
|
+
' VR [km]
|
1374
|
+
' VisLimMagn [-]
|
1375
|
+
*/
|
1376
|
+
static double VisLimMagn(double *dobs, double AltO, double AziO, double AltM, double AziM, double JDNDaysUT, double AltS, double AziS, double sunra, double Lat, double HeightEye, double *datm, int32 helflag, int32 *scotopic_flag, char *serr)
|
1377
|
+
{
|
1378
|
+
double C1, C2, Th, kX, Bsk, CorrFactor1, CorrFactor2;
|
1379
|
+
double log10 = 2.302585092994;
|
1380
|
+
/*double Age = dobs[0];*/
|
1381
|
+
/*double SN = dobs[1];*/
|
1382
|
+
Bsk = Bsky(AltO, AziO, AltM, AziM, JDNDaysUT, AltS, AziS, sunra, Lat, HeightEye, datm, helflag, serr);
|
1383
|
+
/* Schaefer, Astronomy and the limits of vision, Archaeoastronomy, 1993 Verder:*/
|
1384
|
+
kX = Deltam(AltO, AltS, sunra, Lat, HeightEye, datm, helflag, serr);
|
1385
|
+
/* influence of age*/
|
1386
|
+
/*Fa = mymax(1, pow(p(23, Bsk) / p(Age, Bsk), 2)); */
|
1387
|
+
CorrFactor1 = OpticFactor(Bsk, kX, dobs, JDNDaysUT, "", 1, helflag);
|
1388
|
+
CorrFactor2 = OpticFactor(Bsk, kX, dobs, JDNDaysUT, "", 0, helflag);
|
1389
|
+
/* From Schaefer , Archaeoastronomy, XV, 2000, page 129*/
|
1390
|
+
if (Bsk < BNIGHT && !(helflag & SE_HELFLAG_VISLIM_PHOTOPIC)) {
|
1391
|
+
C1 = 1.5848931924611e-10; /*pow(10, -9.8);*/ /* C1 = 10 ^ (-9.8);*/
|
1392
|
+
C2 = 0.012589254117942; /*pow(10, -1.9);*/ /* C2 = 10 ^ (-1.9);*/
|
1393
|
+
if (scotopic_flag != NULL)
|
1394
|
+
*scotopic_flag = 1;
|
1395
|
+
} else {
|
1396
|
+
C1 = 4.4668359215096e-9; /*pow(10, -8.35);*/ /* C1 = 10 ^ (-8.35);*/
|
1397
|
+
C2 = 1.2589254117942e-6; /*pow(10, -5.9);*/ /* C2 = 10 ^ (-5.9);*/
|
1398
|
+
if (scotopic_flag != NULL)
|
1399
|
+
*scotopic_flag = 0;
|
1400
|
+
}
|
1401
|
+
if (scotopic_flag != NULL) {
|
1402
|
+
if (BNIGHT * BNIGHT_FACTOR > Bsk && BNIGHT / BNIGHT_FACTOR < Bsk)
|
1403
|
+
*scotopic_flag |= 2;
|
1404
|
+
}
|
1405
|
+
/*Th = C1 * pow(1 + sqrt(C2 * Bsk), 2) * Fa;*/
|
1406
|
+
Bsk = Bsk / CorrFactor1;
|
1407
|
+
Th = C1 * pow(1 + sqrt(C2 * Bsk), 2) * CorrFactor2;
|
1408
|
+
#if DEBUG
|
1409
|
+
fprintf(stderr, "Bsk=%f\n", Bsk);
|
1410
|
+
fprintf(stderr, "kX =%f\n", kX);
|
1411
|
+
fprintf(stderr, "Th =%f\n", Th);
|
1412
|
+
fprintf(stderr, "CorrFactor1=%f\n", CorrFactor1);
|
1413
|
+
fprintf(stderr, "CorrFactor2=%f\n", CorrFactor2);
|
1414
|
+
#endif
|
1415
|
+
/* Visual limiting magnitude of point source*/
|
1416
|
+
#if 0
|
1417
|
+
if (SN <= 0.00000001)
|
1418
|
+
SN = 0.00000001;
|
1419
|
+
return -16.57 - 2.5 * (log(Th) / log10) - kX + 5.0 * (log(SN) / log10);*/
|
1420
|
+
#endif
|
1421
|
+
return -16.57 - 2.5 * (log(Th) / log10);
|
1422
|
+
}
|
1423
|
+
|
1424
|
+
/* Limiting magnitude in dark skies
|
1425
|
+
* function returns:
|
1426
|
+
* -1 Error
|
1427
|
+
* -2 Object is below horizon
|
1428
|
+
* 0 OK, photopic vision
|
1429
|
+
* |1 OK, scotopic vision
|
1430
|
+
* |2 OK, near limit photopic/scotopic
|
1431
|
+
*/
|
1432
|
+
int32 FAR PASCAL_CONV swe_vis_limit_mag(double tjdut, double *dgeo, double *datm, double *dobs, char *ObjectName, int32 helflag, double *dret, char *serr)
|
1433
|
+
{
|
1434
|
+
int32 retval = OK, i, scotopic_flag = 0;
|
1435
|
+
double AltO, AziO, AltM, AziM, AltS, AziS;
|
1436
|
+
double sunra = SunRA(tjdut, helflag, serr);
|
1437
|
+
default_heliacal_parameters(datm, dgeo, dobs, helflag);
|
1438
|
+
swe_set_topo(dgeo[0], dgeo[1], dgeo[2]);
|
1439
|
+
for (i = 0; i < 7; i++)
|
1440
|
+
dret[i] = 0;
|
1441
|
+
if (ObjectLoc(tjdut, dgeo, datm, ObjectName, 0, helflag, &AltO, serr) == ERR)
|
1442
|
+
return ERR;
|
1443
|
+
if (AltO < 0 && serr != NULL) {
|
1444
|
+
strcpy(serr, "object is below local horizon");
|
1445
|
+
*dret = -100;
|
1446
|
+
return -2;
|
1447
|
+
}
|
1448
|
+
if (ObjectLoc(tjdut, dgeo, datm, ObjectName, 1, helflag, &AziO, serr) == ERR)
|
1449
|
+
return ERR;
|
1450
|
+
if (helflag & SE_HELFLAG_VISLIM_DARK) {
|
1451
|
+
AltS = -90;
|
1452
|
+
AziS = 0;
|
1453
|
+
} else {
|
1454
|
+
if (ObjectLoc(tjdut, dgeo, datm, "sun", 0, helflag, &AltS, serr) == ERR)
|
1455
|
+
return ERR;
|
1456
|
+
if (ObjectLoc(tjdut, dgeo, datm, "sun", 1, helflag, &AziS, serr) == ERR)
|
1457
|
+
return ERR;
|
1458
|
+
}
|
1459
|
+
if (strncmp(ObjectName, "moon", 4) == 0 ||
|
1460
|
+
(helflag & SE_HELFLAG_VISLIM_DARK) ||
|
1461
|
+
(helflag & SE_HELFLAG_VISLIM_NOMOON)
|
1462
|
+
) {
|
1463
|
+
AltM = -90; AziM = 0;
|
1464
|
+
} else {
|
1465
|
+
if (ObjectLoc(tjdut, dgeo, datm, "moon", 0, helflag, &AltM, serr) == ERR)
|
1466
|
+
return ERR;
|
1467
|
+
if (ObjectLoc(tjdut, dgeo, datm, "moon", 1, helflag, &AziM, serr) == ERR)
|
1468
|
+
return ERR;
|
1469
|
+
}
|
1470
|
+
#if DEBUG
|
1471
|
+
{
|
1472
|
+
int i;
|
1473
|
+
for (i = 0; i < 6;i++)
|
1474
|
+
printf("dobs[%d] = %f\n", i, dobs[i]);
|
1475
|
+
printf("AltO = %.10f, AziO = %.10f\n", AltO, AziO);
|
1476
|
+
printf("AltM = %.10f, AziM = %.10f\n", AltM, AziM);
|
1477
|
+
printf("AltS = %.10f, AziS = %.10f\n", AltS, AziS);
|
1478
|
+
printf("JD = %.10f\n", tjdut);
|
1479
|
+
printf("lat = %f, eyeh = %f\n", dgeo[1], dgeo[2]);
|
1480
|
+
for (i = 0; i < 4;i++)
|
1481
|
+
printf("datm[%d] = %f\n", i, datm[i]);
|
1482
|
+
printf("helflag = %d\n", helflag);
|
1483
|
+
}
|
1484
|
+
#endif
|
1485
|
+
dret[0] = VisLimMagn(dobs, AltO, AziO, AltM, AziM, tjdut, AltS, AziS, sunra, dgeo[1], dgeo[2], datm, helflag, &scotopic_flag, serr);
|
1486
|
+
dret[1] = AltO;
|
1487
|
+
dret[2] = AziO;
|
1488
|
+
dret[3] = AltS;
|
1489
|
+
dret[4] = AziS;
|
1490
|
+
dret[5] = AltM;
|
1491
|
+
dret[6] = AziM;
|
1492
|
+
if (Magnitude(tjdut, dgeo, ObjectName, helflag, &(dret[7]), serr) == ERR)
|
1493
|
+
return ERR;
|
1494
|
+
retval = scotopic_flag;
|
1495
|
+
/*dret[8] = (double) is_scotopic;*/
|
1496
|
+
/*if (*serr != '\0') * in VisLimMagn(), serr is only a warning *
|
1497
|
+
retval = ERR; */
|
1498
|
+
return retval;
|
1499
|
+
}
|
1500
|
+
|
1501
|
+
/*###################################################################
|
1502
|
+
' Magn [-]
|
1503
|
+
' age [Year]
|
1504
|
+
' SN [-]
|
1505
|
+
' AltO [deg]
|
1506
|
+
' AziO [deg]
|
1507
|
+
' AltM [deg]
|
1508
|
+
' AziM [deg]
|
1509
|
+
' MoonDistance [km]
|
1510
|
+
' JDNDaysUT [-]
|
1511
|
+
' AziS [deg]
|
1512
|
+
' lat [deg]
|
1513
|
+
' heighteye [m]
|
1514
|
+
' Temperature [C]
|
1515
|
+
' Pressure [mbar]
|
1516
|
+
' RH [%]
|
1517
|
+
' VR [km]
|
1518
|
+
' TopoArcVisionis [deg]
|
1519
|
+
*/
|
1520
|
+
static int32 TopoArcVisionis(double Magn, double *dobs, double AltO, double AziO, double AltM, double AziM, double JDNDaysUT, double AziS, double sunra, double Lat, double HeightEye, double *datm, int32 helflag, double *dret, char *serr)
|
1521
|
+
{
|
1522
|
+
double Xm, Ym, AltSi, AziSi;
|
1523
|
+
double xR = 0;
|
1524
|
+
double Xl = 45;
|
1525
|
+
double Yl, Yr;
|
1526
|
+
Yl = Magn - VisLimMagn(dobs, AltO, AziO, AltM, AziM, JDNDaysUT, AltO - Xl, AziS, sunra, Lat, HeightEye, datm, helflag, NULL, serr);
|
1527
|
+
/* if (*serr != '\0') return ERR; * serr is only a warning */
|
1528
|
+
Yr = Magn - VisLimMagn(dobs, AltO, AziO, AltM, AziM, JDNDaysUT, AltO - xR, AziS, sunra, Lat, HeightEye, datm, helflag, NULL, serr);
|
1529
|
+
/* if (*serr != '\0') return ERR; * serr is only a warning */
|
1530
|
+
/* http://en.wikipedia.org/wiki/Bisection_method*/
|
1531
|
+
if ((Yl * Yr) <= 0) {
|
1532
|
+
while(fabs(xR - Xl) > epsilon) {
|
1533
|
+
/*Calculate midpoint of domain*/
|
1534
|
+
Xm = (xR + Xl) / 2.0;
|
1535
|
+
AltSi = AltO - Xm;
|
1536
|
+
AziSi = AziS;
|
1537
|
+
Ym = Magn - VisLimMagn(dobs, AltO, AziO, AltM, AziM, JDNDaysUT, AltSi, AziSi, sunra, Lat, HeightEye, datm, helflag, NULL, serr);
|
1538
|
+
/* if (*serr != '\0') return ERR; * serr is only a warning */
|
1539
|
+
if ((Yl * Ym) > 0) {
|
1540
|
+
/* Throw away left half*/
|
1541
|
+
Xl = Xm;
|
1542
|
+
Yl = Ym;
|
1543
|
+
} else {
|
1544
|
+
/* Throw away right half */
|
1545
|
+
xR = Xm;
|
1546
|
+
Yr = Ym;
|
1547
|
+
}
|
1548
|
+
}
|
1549
|
+
Xm = (xR + Xl) / 2.0;
|
1550
|
+
} else {
|
1551
|
+
Xm = 99;
|
1552
|
+
}
|
1553
|
+
if (Xm < AltO)
|
1554
|
+
Xm = AltO;
|
1555
|
+
*dret = Xm;
|
1556
|
+
return OK;
|
1557
|
+
}
|
1558
|
+
|
1559
|
+
int32 FAR PASCAL_CONV swe_topo_arcus_visionis(double tjdut, double *dgeo, double *datm, double *dobs, int32 helflag, double mag, double azi_obj, double alt_obj, double azi_sun, double azi_moon, double alt_moon, double *dret, char *serr)
|
1560
|
+
{
|
1561
|
+
double sunra = SunRA(tjdut, helflag, serr);
|
1562
|
+
if (serr != NULL && *serr != '\0')
|
1563
|
+
return ERR;
|
1564
|
+
return TopoArcVisionis(mag, dobs, alt_obj, azi_obj, alt_moon, azi_moon, tjdut, azi_sun, sunra, dgeo[1], dgeo[2], datm, helflag, dret, serr);
|
1565
|
+
}
|
1566
|
+
|
1567
|
+
/*###################################################################*/
|
1568
|
+
/*' Magn [-]
|
1569
|
+
' age [Year]
|
1570
|
+
' SN Snellen factor of the visual aquity of the observer
|
1571
|
+
see: http://www.i-see.org/eyecharts.html#make-your-own
|
1572
|
+
' AziO [deg]
|
1573
|
+
' AltM [deg]
|
1574
|
+
' AziM [deg]
|
1575
|
+
' MoonDistance [km]
|
1576
|
+
' JDNDaysUT [-]
|
1577
|
+
' AziS [deg]
|
1578
|
+
' Lat [deg]
|
1579
|
+
' HeightEye [m]
|
1580
|
+
' Temperature [C]
|
1581
|
+
' Pressure [mbar]
|
1582
|
+
' RH [%] relative humidity
|
1583
|
+
' VR [km] Meteorological Range,
|
1584
|
+
see http://www.iol.ie/~geniet/eng/atmoastroextinction.htm
|
1585
|
+
' TypeAngle
|
1586
|
+
' [0=Object's altitude,
|
1587
|
+
' 1=Arcus Visonis (Object's altitude - Sun's altitude),
|
1588
|
+
' 2=Sun's altitude]
|
1589
|
+
' HeliacalAngle [deg]
|
1590
|
+
*/
|
1591
|
+
static int32 HeliacalAngle(double Magn, double *dobs, double AziO, double AltM, double AziM, double JDNDaysUT, double AziS, double *dgeo, double *datm, int32 helflag, double *dangret, char *serr)
|
1592
|
+
{
|
1593
|
+
double x, minx, maxx, xmin, ymin, Xl, xR, Yr, Yl, Xm, Ym, xmd, ymd;
|
1594
|
+
double Arc, DELTAx;
|
1595
|
+
double sunra = SunRA(JDNDaysUT, helflag, serr);
|
1596
|
+
double Lat = dgeo[1];
|
1597
|
+
double HeightEye = dgeo[2];
|
1598
|
+
if (PLSV == 1) {
|
1599
|
+
dangret[0] = criticalangle;
|
1600
|
+
dangret[1] = criticalangle + Magn * 2.492 + 13.447;
|
1601
|
+
dangret[2] = -(Magn * 2.492 + 13.447); /* Magn * 1.1 + 8.9;*/
|
1602
|
+
return OK;
|
1603
|
+
}
|
1604
|
+
minx = 2;
|
1605
|
+
maxx = 20;
|
1606
|
+
xmin = 0;
|
1607
|
+
ymin = 10000;
|
1608
|
+
for (x = minx; x <= maxx; x++) {
|
1609
|
+
if (TopoArcVisionis(Magn, dobs, x, AziO, AltM, AziM, JDNDaysUT, AziS, sunra, Lat, HeightEye, datm, helflag, &Arc, serr) == ERR)
|
1610
|
+
return ERR;
|
1611
|
+
if (Arc < ymin) {
|
1612
|
+
ymin = Arc;
|
1613
|
+
xmin = x;
|
1614
|
+
}
|
1615
|
+
}
|
1616
|
+
Xl = xmin - 1;
|
1617
|
+
xR = xmin + 1;
|
1618
|
+
if (TopoArcVisionis(Magn, dobs, xR, AziO, AltM, AziM, JDNDaysUT, AziS, sunra, Lat, HeightEye, datm, helflag, &Yr, serr) == ERR)
|
1619
|
+
return ERR;
|
1620
|
+
if (TopoArcVisionis(Magn, dobs, Xl, AziO, AltM, AziM, JDNDaysUT, AziS, sunra, Lat, HeightEye, datm, helflag, &Yl, serr) == ERR)
|
1621
|
+
return ERR;
|
1622
|
+
/* http://en.wikipedia.org/wiki/Bisection_method*/
|
1623
|
+
while(fabs(xR - Xl) > 0.1) {
|
1624
|
+
/* Calculate midpoint of domain */
|
1625
|
+
Xm = (xR + Xl) / 2.0;
|
1626
|
+
DELTAx = 0.025;
|
1627
|
+
xmd = Xm + DELTAx;
|
1628
|
+
if (TopoArcVisionis(Magn, dobs, Xm, AziO, AltM, AziM, JDNDaysUT, AziS, sunra, Lat, HeightEye, datm, helflag, &Ym, serr) == ERR)
|
1629
|
+
return ERR;
|
1630
|
+
if (TopoArcVisionis(Magn, dobs, xmd, AziO, AltM, AziM, JDNDaysUT, AziS, sunra, Lat, HeightEye, datm, helflag, &ymd, serr) == ERR)
|
1631
|
+
return ERR;
|
1632
|
+
if (Ym >= ymd) {
|
1633
|
+
/* Throw away left half */
|
1634
|
+
Xl = Xm;
|
1635
|
+
Yl = Ym;
|
1636
|
+
} else {
|
1637
|
+
/*Throw away right half */
|
1638
|
+
xR = Xm;
|
1639
|
+
Yr = Ym;
|
1640
|
+
}
|
1641
|
+
}
|
1642
|
+
Xm = (xR + Xl) / 2.0;
|
1643
|
+
Ym = (Yr + Yl) / 2.0;
|
1644
|
+
dangret[1] = Ym;
|
1645
|
+
dangret[2] = Xm - Ym;
|
1646
|
+
dangret[0] = Xm;
|
1647
|
+
return OK;
|
1648
|
+
}
|
1649
|
+
|
1650
|
+
int32 FAR PASCAL_CONV swe_heliacal_angle(double tjdut, double *dgeo, double *datm, double *dobs, int32 helflag, double mag, double azi_obj, double azi_sun, double azi_moon, double alt_moon, double *dret, char *serr)
|
1651
|
+
{
|
1652
|
+
return HeliacalAngle(mag, dobs, azi_obj, alt_moon, azi_moon, tjdut, azi_sun, dgeo, datm, helflag, dret, serr);
|
1653
|
+
}
|
1654
|
+
|
1655
|
+
/*###################################################################
|
1656
|
+
' AltO [deg]
|
1657
|
+
' AziO [deg]
|
1658
|
+
' AltS [deg]
|
1659
|
+
' AziS [deg]
|
1660
|
+
' parallax [deg]
|
1661
|
+
' WidthMoon [deg]
|
1662
|
+
*/
|
1663
|
+
static double WidthMoon(double AltO, double AziO, double AltS, double AziS, double parallax)
|
1664
|
+
{
|
1665
|
+
/* Yallop 1998, page 3*/
|
1666
|
+
double GeoAltO = AltO + parallax;
|
1667
|
+
return 0.27245 * parallax * (1 + sin(GeoAltO * DEGTORAD) * sin(parallax * DEGTORAD)) * (1 - cos((AltS - GeoAltO) * DEGTORAD) * cos((AziS - AziO) * DEGTORAD));
|
1668
|
+
}
|
1669
|
+
|
1670
|
+
/*###################################################################
|
1671
|
+
' W [deg]
|
1672
|
+
' LengthMoon [deg]
|
1673
|
+
*/
|
1674
|
+
static double LengthMoon(double W, double Diamoon)
|
1675
|
+
{
|
1676
|
+
double Wi, D;
|
1677
|
+
if (Diamoon == 0) Diamoon = AvgRadiusMoon * 2;
|
1678
|
+
Wi = W * 60;
|
1679
|
+
D = Diamoon * 60;
|
1680
|
+
/* Crescent length according: http://calendar.ut.ac.ir/Fa/Crescent/Data/Sultan2005.pdf*/
|
1681
|
+
return (D - 0.3 * (D + Wi) / 2.0 / Wi) / 60.0;
|
1682
|
+
}
|
1683
|
+
|
1684
|
+
/*###################################################################
|
1685
|
+
' W [deg]
|
1686
|
+
' GeoARCVact [deg]
|
1687
|
+
' q [-]
|
1688
|
+
*/
|
1689
|
+
static double qYallop(double W, double GeoARCVact)
|
1690
|
+
{
|
1691
|
+
double Wi = W * 60;
|
1692
|
+
return (GeoARCVact - (11.8371 - 6.3226 * Wi + 0.7319 * Wi * Wi - 0.1018 * Wi * Wi * Wi)) / 10;
|
1693
|
+
}
|
1694
|
+
|
1695
|
+
/*###################################################################
|
1696
|
+
'A (0,p)
|
1697
|
+
'B (1,q)
|
1698
|
+
'C (0,r)
|
1699
|
+
'D (1,s)
|
1700
|
+
*/
|
1701
|
+
static double crossing(double A, double B, double C, double D)
|
1702
|
+
{
|
1703
|
+
return (C - A) / ((B - A) - (D - C));
|
1704
|
+
}
|
1705
|
+
|
1706
|
+
/*###################################################################*/
|
1707
|
+
static int32 DeterTAV(double *dobs, double JDNDaysUT, double *dgeo, double *datm, char *ObjectName, int32 helflag, double *dret, char *serr)
|
1708
|
+
{
|
1709
|
+
double Magn, AltO, AziS, AziO, AziM, AltM;
|
1710
|
+
double sunra = SunRA(JDNDaysUT, helflag, serr);
|
1711
|
+
if (Magnitude(JDNDaysUT, dgeo, ObjectName, helflag, &Magn, serr) == ERR)
|
1712
|
+
return ERR;
|
1713
|
+
if (ObjectLoc(JDNDaysUT, dgeo, datm, ObjectName, 0, helflag, &AltO, serr) == ERR)
|
1714
|
+
return ERR;
|
1715
|
+
if (ObjectLoc(JDNDaysUT, dgeo, datm, ObjectName, 1, helflag, &AziO, serr) == ERR)
|
1716
|
+
return ERR;
|
1717
|
+
if (strncmp(ObjectName, "moon", 4) == 0) {
|
1718
|
+
AltM = -90;
|
1719
|
+
AziM = 0;
|
1720
|
+
} else {
|
1721
|
+
if (ObjectLoc(JDNDaysUT, dgeo, datm, "moon", 0, helflag, &AltM, serr) == ERR)
|
1722
|
+
return ERR;
|
1723
|
+
if (ObjectLoc(JDNDaysUT, dgeo, datm, "moon", 1, helflag, &AziM, serr) == ERR)
|
1724
|
+
return ERR;
|
1725
|
+
}
|
1726
|
+
if (ObjectLoc(JDNDaysUT, dgeo, datm, "sun", 1, helflag, &AziS, serr) == ERR)
|
1727
|
+
return ERR;
|
1728
|
+
if (TopoArcVisionis(Magn, dobs, AltO, AziO, AltM, AziM, JDNDaysUT, AziS, sunra, dgeo[1], dgeo[2], datm, helflag, dret, serr) == ERR)
|
1729
|
+
return ERR;
|
1730
|
+
return OK;
|
1731
|
+
}
|
1732
|
+
|
1733
|
+
/*###################################################################
|
1734
|
+
' A y-value at x=1
|
1735
|
+
' B y-value at x=0
|
1736
|
+
' C y-value at x=-1
|
1737
|
+
' x2min minimum for the quadratic function
|
1738
|
+
*/
|
1739
|
+
static double x2min(double A, double B, double C)
|
1740
|
+
{
|
1741
|
+
double term = A + C - 2 * B;
|
1742
|
+
if (term == 0)
|
1743
|
+
return 0;
|
1744
|
+
return -(A - C) / 2.0 / term;
|
1745
|
+
}
|
1746
|
+
|
1747
|
+
|
1748
|
+
/*###################################################################
|
1749
|
+
' A y-value at x=1
|
1750
|
+
' B y-value at x=0
|
1751
|
+
' C y-value at x=-1
|
1752
|
+
' x
|
1753
|
+
' y is y-value of quadratic function
|
1754
|
+
*/
|
1755
|
+
static double funct2(double A, double B, double C, double x)
|
1756
|
+
{
|
1757
|
+
return (A + C - 2 * B) / 2.0 * x * x + (A - C) / 2.0 * x + B;
|
1758
|
+
}
|
1759
|
+
|
1760
|
+
static void strcpy_VBsafe(char *sout, char *sin)
|
1761
|
+
{
|
1762
|
+
char *sp, *sp2;
|
1763
|
+
int iw = 0;
|
1764
|
+
sp = sin;
|
1765
|
+
sp2 = sout;
|
1766
|
+
while((isalnum(*sp) || *sp == ' ' || *sp == '-') && iw < 30) {
|
1767
|
+
*sp2 = *sp;
|
1768
|
+
sp++; sp2++; iw++;
|
1769
|
+
}
|
1770
|
+
*sp2 = '\0';
|
1771
|
+
}
|
1772
|
+
|
1773
|
+
/*###################################################################
|
1774
|
+
' JDNDaysUT [JDN]
|
1775
|
+
' HPheno
|
1776
|
+
'0=AltO [deg] topocentric altitude of object (unrefracted)
|
1777
|
+
'1=AppAltO [deg] apparent altitude of object (refracted)
|
1778
|
+
'2=GeoAltO [deg] geocentric altitude of object
|
1779
|
+
'3=AziO [deg] azimuth of object
|
1780
|
+
'4=AltS [deg] topocentric altitude of Sun
|
1781
|
+
'5=AziS [deg] azimuth of Sun
|
1782
|
+
'6=TAVact [deg] actual topocentric arcus visionis
|
1783
|
+
'7=ARCVact [deg] actual (geocentric) arcus visionis
|
1784
|
+
'8=DAZact [deg] actual difference between object's and sun's azimuth
|
1785
|
+
'9=ARCLact [deg] actual longitude difference between object and sun
|
1786
|
+
'10=kact [-] extinction coefficient
|
1787
|
+
'11=minTAV [deg] smallest topocentric arcus visionis
|
1788
|
+
'12=TfistVR [JDN] first time object is visible, according to VR
|
1789
|
+
'13=TbVR [JDN] optimum time the object is visible, according to VR
|
1790
|
+
'14=TlastVR [JDN] last time object is visible, according to VR
|
1791
|
+
'15=TbYallop[JDN] best time the object is visible, according to Yallop
|
1792
|
+
'16=WMoon [deg] cresent width of moon
|
1793
|
+
'17=qYal [-] q-test value of Yallop
|
1794
|
+
'18=qCrit [-] q-test criterion of Yallop
|
1795
|
+
'19=ParO [deg] parallax of object
|
1796
|
+
'20 Magn [-] magnitude of object
|
1797
|
+
'21=RiseO [JDN] rise/set time of object
|
1798
|
+
'22=RiseS [JDN] rise/set time of sun
|
1799
|
+
'23=Lag [JDN] rise/set time of object minus rise/set time of sun
|
1800
|
+
'24=TvisVR [JDN] visibility duration
|
1801
|
+
'25=LMoon [deg] cresent length of moon
|
1802
|
+
'26=CVAact [deg]
|
1803
|
+
'27=Illum [%] 'new
|
1804
|
+
'28=CVAact [deg] 'new
|
1805
|
+
'29=MSk [-]
|
1806
|
+
*/
|
1807
|
+
int32 FAR PASCAL_CONV swe_heliacal_pheno_ut(double JDNDaysUT, double *dgeo, double *datm, double *dobs, char *ObjectNameIn, int32 TypeEvent, int32 helflag, double *darr, char *serr)
|
1808
|
+
{
|
1809
|
+
double AziS, AltS, AltS2, AziO, AltO, AltO2, GeoAltO, AppAltO, DAZact, TAVact, ParO, MagnO;
|
1810
|
+
double ARCVact, ARCLact, kact, WMoon, LMoon = 0, qYal, qCrit;
|
1811
|
+
double RiseSetO, RiseSetS, Lag, TbYallop, TfirstVR, TlastVR, TbVR;
|
1812
|
+
double MinTAV, MinTAVact, Ta, Tc, TimeStep, TimePointer, MinTAVoud = 0, DeltaAltoud = 0, DeltaAlt, TvisVR, crosspoint;
|
1813
|
+
double OldestDeltaAlt, OldestMinTAV, extrax, illum;
|
1814
|
+
double elong, attr[30];
|
1815
|
+
double TimeCheck, LocalminCheck;
|
1816
|
+
int32 retval = OK, RS, Planet;
|
1817
|
+
AS_BOOL noriseO = FALSE;
|
1818
|
+
char ObjectName[AS_MAXCH];
|
1819
|
+
double sunra = SunRA(JDNDaysUT, helflag, serr);
|
1820
|
+
int32 iflag = helflag & (SEFLG_JPLEPH|SEFLG_SWIEPH|SEFLG_MOSEPH);
|
1821
|
+
/* note, the fixed stars functions rewrite the star name. The input string
|
1822
|
+
may be too short, so we have to make sure we have enough space */
|
1823
|
+
strcpy_VBsafe(ObjectName, ObjectNameIn);
|
1824
|
+
default_heliacal_parameters(datm, dgeo, dobs, helflag);
|
1825
|
+
swe_set_topo(dgeo[0], dgeo[1], dgeo[2]);
|
1826
|
+
retval = ObjectLoc(JDNDaysUT, dgeo, datm, "sun", 1, helflag, &AziS, serr);
|
1827
|
+
if (retval == OK)
|
1828
|
+
retval = ObjectLoc(JDNDaysUT, dgeo, datm, "sun", 0, helflag, &AltS, serr);
|
1829
|
+
if (retval == OK)
|
1830
|
+
retval = ObjectLoc(JDNDaysUT, dgeo, datm, ObjectName, 1, helflag, &AziO, serr);
|
1831
|
+
if (retval == OK)
|
1832
|
+
retval = ObjectLoc(JDNDaysUT, dgeo, datm, ObjectName, 0, helflag, &AltO, serr);
|
1833
|
+
if (retval == OK)
|
1834
|
+
retval = ObjectLoc(JDNDaysUT, dgeo, datm, ObjectName, 7, helflag, &GeoAltO, serr);
|
1835
|
+
if (retval == ERR)
|
1836
|
+
return ERR;
|
1837
|
+
AppAltO = AppAltfromTopoAlt(AltO, datm[1], datm[0], helflag);
|
1838
|
+
DAZact = AziS - AziO;
|
1839
|
+
TAVact = AltO - AltS;
|
1840
|
+
/*this parallax seems to be somewhat smaller then in Yallop and SkyMap! Needs to be studied*/
|
1841
|
+
ParO = GeoAltO - AltO;
|
1842
|
+
if (Magnitude(JDNDaysUT, dgeo, ObjectName, helflag, &MagnO, serr) == ERR)
|
1843
|
+
return ERR;
|
1844
|
+
ARCVact = TAVact + ParO;
|
1845
|
+
ARCLact = acos(cos(ARCVact * DEGTORAD) * cos(DAZact * DEGTORAD)) / DEGTORAD;
|
1846
|
+
Planet = DeterObject(ObjectName);
|
1847
|
+
if (Planet == -1) {
|
1848
|
+
elong = ARCLact;
|
1849
|
+
illum = 100;
|
1850
|
+
} else {
|
1851
|
+
retval = swe_pheno_ut(JDNDaysUT, Planet, iflag|(SEFLG_TOPOCTR|SEFLG_EQUATORIAL), attr, serr);
|
1852
|
+
if (retval == ERR) return ERR;
|
1853
|
+
elong = attr[2];
|
1854
|
+
illum = attr[1] * 100;
|
1855
|
+
}
|
1856
|
+
kact = kt(AltS, sunra, dgeo[1], dgeo[2], datm[1], datm[2], datm[3], 4, serr);
|
1857
|
+
if (0) {
|
1858
|
+
darr[26] = kR(AltS, dgeo[2]);
|
1859
|
+
darr[27] = kW(dgeo[2], datm[1], datm[2]);
|
1860
|
+
darr[28] = kOZ(AltS, sunra, dgeo[1]);
|
1861
|
+
darr[29] = ka(AltS, sunra, dgeo[1], dgeo[2], datm[1], datm[2], datm[3], serr);
|
1862
|
+
darr[30] = darr[26] + darr[27] + darr[28] + darr[29];
|
1863
|
+
}
|
1864
|
+
WMoon = 0;
|
1865
|
+
qYal = 0;
|
1866
|
+
qCrit = 0;
|
1867
|
+
LMoon = 0;
|
1868
|
+
if (Planet == SE_MOON) {
|
1869
|
+
WMoon = WidthMoon(AltO, AziO, AltS, AziS, ParO);
|
1870
|
+
LMoon = LengthMoon(WMoon, 0);
|
1871
|
+
qYal = qYallop(WMoon, ARCVact);
|
1872
|
+
if (qYal > 0.216) qCrit = 1; /* A */
|
1873
|
+
if (qYal < 0.216 && qYal > -0.014) qCrit = 2; /* B */
|
1874
|
+
if (qYal < -0.014 && qYal > -0.16) qCrit = 3; /* C */
|
1875
|
+
if (qYal < -0.16 && qYal > -0.232) qCrit = 4; /* D */
|
1876
|
+
if (qYal < -0.232 && qYal > -0.293) qCrit = 5; /* E */
|
1877
|
+
if (qYal < -0.293) qCrit = 6; /* F */
|
1878
|
+
}
|
1879
|
+
/*determine if rise or set event*/
|
1880
|
+
RS = 2;
|
1881
|
+
if (TypeEvent == 1 || TypeEvent == 4) RS = 1;
|
1882
|
+
retval = RiseSet(JDNDaysUT - 4.0 / 24.0, dgeo, datm, "sun", RS, helflag, 0, &RiseSetS, serr);
|
1883
|
+
if (retval == ERR)
|
1884
|
+
return ERR;
|
1885
|
+
retval = RiseSet(JDNDaysUT - 4.0 / 24.0, dgeo, datm, ObjectName, RS, helflag, 0, &RiseSetO, serr);
|
1886
|
+
if (retval == ERR)
|
1887
|
+
return ERR;
|
1888
|
+
TbYallop = TJD_INVALID;
|
1889
|
+
if (retval == -2) { /* object does not rise or set */
|
1890
|
+
Lag = 0;
|
1891
|
+
noriseO = TRUE;
|
1892
|
+
} else {
|
1893
|
+
Lag = RiseSetO - RiseSetS;
|
1894
|
+
if (Planet == SE_MOON)
|
1895
|
+
TbYallop = (RiseSetO * 4 + RiseSetS * 5) / 9.0;
|
1896
|
+
}
|
1897
|
+
if ((TypeEvent == 3 || TypeEvent == 4) && (Planet == -1 || Planet >= SE_MARS)) {
|
1898
|
+
TfirstVR = TJD_INVALID;
|
1899
|
+
TbVR = TJD_INVALID;
|
1900
|
+
TlastVR = TJD_INVALID;
|
1901
|
+
TvisVR = 0;
|
1902
|
+
MinTAV = 0;
|
1903
|
+
goto output_heliacal_pheno;
|
1904
|
+
}
|
1905
|
+
/* If HPheno >= 11 And HPheno <= 14 Or HPheno = 24 Then*/
|
1906
|
+
/*te bepalen m.b.v. walkthrough*/
|
1907
|
+
MinTAVact = 199;
|
1908
|
+
DeltaAlt = 0;
|
1909
|
+
OldestDeltaAlt = 0;
|
1910
|
+
OldestMinTAV = 0;
|
1911
|
+
Ta = 0;
|
1912
|
+
Tc = 0;
|
1913
|
+
TbVR = 0;
|
1914
|
+
TimeStep = -TimeStepDefault / 24.0 / 60.0;
|
1915
|
+
if (RS == 2) TimeStep = -TimeStep;
|
1916
|
+
TimePointer = RiseSetS - TimeStep;
|
1917
|
+
do {
|
1918
|
+
TimePointer = TimePointer + TimeStep;
|
1919
|
+
OldestDeltaAlt = DeltaAltoud;
|
1920
|
+
OldestMinTAV = MinTAVoud;
|
1921
|
+
MinTAVoud = MinTAVact;
|
1922
|
+
DeltaAltoud = DeltaAlt;
|
1923
|
+
retval = ObjectLoc(TimePointer, dgeo, datm, "sun", 0, helflag, &AltS2, serr);
|
1924
|
+
if (retval == OK)
|
1925
|
+
retval = ObjectLoc(TimePointer, dgeo, datm, ObjectName, 0, helflag, &AltO2, serr);
|
1926
|
+
if (retval != OK)
|
1927
|
+
return ERR;
|
1928
|
+
DeltaAlt = AltO2 - AltS2;
|
1929
|
+
if (DeterTAV(dobs, TimePointer, dgeo, datm, ObjectName, helflag, &MinTAVact, serr) == ERR)
|
1930
|
+
return ERR;
|
1931
|
+
if (MinTAVoud < MinTAVact && TbVR == 0) {
|
1932
|
+
/* determine if this is a local minimum with object still above horizon*/
|
1933
|
+
TimeCheck = TimePointer + Sgn(TimeStep) * LocalMinStep / 24.0 / 60.0;
|
1934
|
+
if (RiseSetO != 0) {
|
1935
|
+
if (TimeStep > 0)
|
1936
|
+
TimeCheck = mymin(TimeCheck, RiseSetO);
|
1937
|
+
else
|
1938
|
+
TimeCheck = mymax(TimeCheck, RiseSetO);
|
1939
|
+
}
|
1940
|
+
if (DeterTAV(dobs, TimeCheck, dgeo, datm, ObjectName, helflag, &LocalminCheck, serr) == ERR)
|
1941
|
+
return ERR;
|
1942
|
+
if (LocalminCheck > MinTAVact) {
|
1943
|
+
extrax = x2min(MinTAVact, MinTAVoud, OldestMinTAV);
|
1944
|
+
TbVR = TimePointer - (1 - extrax) * TimeStep;
|
1945
|
+
MinTAV = funct2(MinTAVact, MinTAVoud, OldestMinTAV, extrax);
|
1946
|
+
}
|
1947
|
+
}
|
1948
|
+
if (DeltaAlt > MinTAVact && Tc == 0 && TbVR == 0) {
|
1949
|
+
crosspoint = crossing(DeltaAltoud, DeltaAlt, MinTAVoud, MinTAVact);
|
1950
|
+
Tc = TimePointer - TimeStep * (1 - crosspoint);
|
1951
|
+
}
|
1952
|
+
if (DeltaAlt < MinTAVact && Ta == 0 && Tc != 0) {
|
1953
|
+
crosspoint = crossing(DeltaAltoud, DeltaAlt, MinTAVoud, MinTAVact);
|
1954
|
+
Ta = TimePointer - TimeStep * (1 - crosspoint);
|
1955
|
+
}
|
1956
|
+
} while (fabs(TimePointer - RiseSetS) <= MaxTryHours / 24.0 && Ta == 0 && !((TbVR != 0 && (TypeEvent == 3 || TypeEvent == 4) && (strncmp(ObjectName, "moon", 4) != 0 && strncmp(ObjectName, "venus", 5) != 0 && strncmp(ObjectName, "mercury", 7) != 0))));
|
1957
|
+
if (RS == 2) {
|
1958
|
+
TfirstVR = Tc;
|
1959
|
+
TlastVR = Ta;
|
1960
|
+
} else {
|
1961
|
+
TfirstVR = Ta;
|
1962
|
+
TlastVR = Tc;
|
1963
|
+
}
|
1964
|
+
if (TfirstVR == 0 && TlastVR == 0) {
|
1965
|
+
if (RS == 1)
|
1966
|
+
TfirstVR = TbVR - 0.000001;
|
1967
|
+
else
|
1968
|
+
TlastVR = TbVR + 0.000001;
|
1969
|
+
}
|
1970
|
+
if (!noriseO) {
|
1971
|
+
if (RS == 1)
|
1972
|
+
TfirstVR = mymax(TfirstVR, RiseSetO);
|
1973
|
+
else
|
1974
|
+
TlastVR = mymin(TlastVR, RiseSetO);
|
1975
|
+
}
|
1976
|
+
TvisVR = TJD_INVALID; /*"#NA!" */
|
1977
|
+
if (TlastVR != 0 && TfirstVR != 0)
|
1978
|
+
TvisVR = TlastVR - TfirstVR;
|
1979
|
+
if (TlastVR == 0) TlastVR = TJD_INVALID; /*"#NA!" */
|
1980
|
+
if (TbVR == 0) TbVR = TJD_INVALID; /*"#NA!" */
|
1981
|
+
if (TfirstVR == 0) TfirstVR = TJD_INVALID; /*"#NA!" */
|
1982
|
+
output_heliacal_pheno:
|
1983
|
+
/*End If*/
|
1984
|
+
darr[0] = AltO;
|
1985
|
+
darr[1] = AppAltO;
|
1986
|
+
darr[2] = GeoAltO;
|
1987
|
+
darr[3] = AziO;
|
1988
|
+
darr[4] = AltS;
|
1989
|
+
darr[5] = AziS;
|
1990
|
+
darr[6] = TAVact;
|
1991
|
+
darr[7] = ARCVact;
|
1992
|
+
darr[8] = DAZact;
|
1993
|
+
darr[9] = ARCLact;
|
1994
|
+
darr[10] = kact;
|
1995
|
+
darr[11] = MinTAV;
|
1996
|
+
darr[12] = TfirstVR;
|
1997
|
+
darr[13] = TbVR;
|
1998
|
+
darr[14] = TlastVR;
|
1999
|
+
darr[15] = TbYallop;
|
2000
|
+
darr[16] = WMoon;
|
2001
|
+
darr[17] = qYal;
|
2002
|
+
darr[18] = qCrit;
|
2003
|
+
darr[19] = ParO;
|
2004
|
+
darr[20] = MagnO;
|
2005
|
+
darr[21] = RiseSetO;
|
2006
|
+
darr[22] = RiseSetS;
|
2007
|
+
darr[23] = Lag;
|
2008
|
+
darr[24] = TvisVR;
|
2009
|
+
darr[25] = LMoon;
|
2010
|
+
darr[26] = elong;
|
2011
|
+
darr[27] = illum;
|
2012
|
+
return OK;
|
2013
|
+
}
|
2014
|
+
|
2015
|
+
#if 0
|
2016
|
+
int32 FAR PASCAL_CONV HeliacalJDut(double JDNDaysUTStart, double Age, double SN, double Lat, double Longitude, double HeightEye, double Temperature, double Pressure, double RH, double VR, char *ObjectName, int TypeEvent, char *AVkind, double *dret, char *serr)
|
2017
|
+
{
|
2018
|
+
double dgeo[3], datm[4], dobs[6];
|
2019
|
+
int32 helflag = SE_HELFLAG_HIGH_PRECISION;
|
2020
|
+
helflag |= SE_HELFLAG_AVKIND_VR;
|
2021
|
+
dgeo[0] = Longitude;
|
2022
|
+
dgeo[1] = Lat;
|
2023
|
+
dgeo[2] = HeightEye;
|
2024
|
+
datm[0] = Pressure;
|
2025
|
+
datm[1] = Temperature;
|
2026
|
+
datm[2] = RH;
|
2027
|
+
datm[3] = VR;
|
2028
|
+
dobs[0] = Age;
|
2029
|
+
dobs[1] = SN;
|
2030
|
+
return swe_heliacal_ut(JDNDaysUTStart, dgeo, datm, dobs, ObjectName, TypeEvent, helflag, dret, serr);
|
2031
|
+
}
|
2032
|
+
#endif
|
2033
|
+
|
2034
|
+
static double get_synodic_period(int Planet)
|
2035
|
+
{
|
2036
|
+
/* synodic periods from:
|
2037
|
+
* Kelley/Milone/Aveni, "Exploring ancient Skies", p. 43. */
|
2038
|
+
switch(Planet) {
|
2039
|
+
case SE_MOON: return 29.530588853;
|
2040
|
+
case SE_MERCURY: return 115.8775;
|
2041
|
+
case SE_VENUS: return 583.9214;
|
2042
|
+
case SE_MARS: return 779.9361;
|
2043
|
+
case SE_JUPITER: return 398.8840;
|
2044
|
+
case SE_SATURN: return 378.0919;
|
2045
|
+
case SE_URANUS: return 369.6560;
|
2046
|
+
case SE_NEPTUNE: return 367.4867;
|
2047
|
+
case SE_PLUTO: return 366.7207;
|
2048
|
+
}
|
2049
|
+
return 366; /* for stars and default for far away planets */
|
2050
|
+
}
|
2051
|
+
|
2052
|
+
/*###################################################################*/
|
2053
|
+
static int32 moon_event_arc_vis(double JDNDaysUTStart, double *dgeo, double *datm, double *dobs, int32 TypeEvent, int32 helflag, double *dret, char *serr)
|
2054
|
+
{
|
2055
|
+
double x[20], MinTAV, MinTAVoud, OldestMinTAV;
|
2056
|
+
double phase1, phase2, JDNDaysUT, JDNDaysUTi;
|
2057
|
+
double tjd_moonevent, tjd_moonevent_start;
|
2058
|
+
double DeltaAltoud, TimeCheck, LocalminCheck;
|
2059
|
+
double AltS, AltO, DeltaAlt = 90;
|
2060
|
+
char ObjectName[30];
|
2061
|
+
int32 iflag, Daystep, eventtype, goingup, Planet, i, retval;
|
2062
|
+
int32 avkind = helflag & SE_HELFLAG_AVKIND;
|
2063
|
+
int32 epheflag = helflag & (SEFLG_JPLEPH|SEFLG_SWIEPH|SEFLG_MOSEPH);
|
2064
|
+
dret[0] = JDNDaysUTStart; /* will be returned in error case */
|
2065
|
+
if (avkind == 0)
|
2066
|
+
avkind = SE_HELFLAG_AVKIND_VR;
|
2067
|
+
if (avkind != SE_HELFLAG_AVKIND_VR) {
|
2068
|
+
if (serr != NULL)
|
2069
|
+
strcpy(serr, "error: in valid AV kind for the moon");
|
2070
|
+
return ERR;
|
2071
|
+
}
|
2072
|
+
if (TypeEvent == 1 || TypeEvent == 2) {
|
2073
|
+
if (serr != NULL)
|
2074
|
+
strcpy(serr, "error: the moon has no morning first or evening last");
|
2075
|
+
return ERR;
|
2076
|
+
}
|
2077
|
+
strcpy(ObjectName, "moon");
|
2078
|
+
Planet = SE_MOON;
|
2079
|
+
iflag = SEFLG_TOPOCTR | SEFLG_EQUATORIAL | epheflag;
|
2080
|
+
if (!(helflag & SE_HELFLAG_HIGH_PRECISION))
|
2081
|
+
iflag |= SEFLG_NONUT|SEFLG_TRUEPOS;
|
2082
|
+
Daystep = 1;
|
2083
|
+
if (TypeEvent == 3) {
|
2084
|
+
/*morning last */
|
2085
|
+
TypeEvent = 2;
|
2086
|
+
} else {
|
2087
|
+
/*evening first*/
|
2088
|
+
TypeEvent = 1;
|
2089
|
+
Daystep = -Daystep;
|
2090
|
+
}
|
2091
|
+
eventtype = TypeEvent + SE_BIT_DISC_CENTER;
|
2092
|
+
/* check Synodic/phase Period */
|
2093
|
+
JDNDaysUT = JDNDaysUTStart;
|
2094
|
+
/* start 30 days later if TypeEvent=4 (1) */
|
2095
|
+
if (TypeEvent == 1) JDNDaysUT = JDNDaysUT + 30;
|
2096
|
+
/* determination of new moon date */
|
2097
|
+
i = swe_pheno_ut(JDNDaysUT, Planet, iflag, x, serr);
|
2098
|
+
phase2 = x[0];
|
2099
|
+
goingup = 0;
|
2100
|
+
do {
|
2101
|
+
JDNDaysUT = JDNDaysUT + Daystep;
|
2102
|
+
phase1 = phase2;
|
2103
|
+
i = swe_pheno_ut(JDNDaysUT, Planet, iflag, x, serr);
|
2104
|
+
phase2 = x[0];
|
2105
|
+
if (phase2 > phase1)
|
2106
|
+
goingup = 1;
|
2107
|
+
} while (goingup == 0 || (goingup == 1 && (phase2 > phase1)));
|
2108
|
+
/* fix the date to get the day with the smallest phase (nwest moon) */
|
2109
|
+
JDNDaysUT = JDNDaysUT - Daystep;
|
2110
|
+
/* initialize the date to look for set */
|
2111
|
+
JDNDaysUTi = JDNDaysUT;
|
2112
|
+
JDNDaysUT = JDNDaysUT - Daystep;
|
2113
|
+
MinTAVoud = 199;
|
2114
|
+
do {
|
2115
|
+
JDNDaysUT = JDNDaysUT + Daystep;
|
2116
|
+
if ((retval = RiseSet(JDNDaysUT, dgeo, datm, ObjectName, TypeEvent, helflag, 0, &tjd_moonevent, serr)) != OK)
|
2117
|
+
return retval;
|
2118
|
+
tjd_moonevent_start = tjd_moonevent;
|
2119
|
+
MinTAV = 199;
|
2120
|
+
OldestMinTAV = MinTAV;
|
2121
|
+
do {
|
2122
|
+
OldestMinTAV = MinTAVoud;
|
2123
|
+
MinTAVoud = MinTAV;
|
2124
|
+
DeltaAltoud = DeltaAlt;
|
2125
|
+
tjd_moonevent = tjd_moonevent - 1.0 / 60.0 / 24.0 * Sgn(Daystep);
|
2126
|
+
if (ObjectLoc(tjd_moonevent, dgeo, datm, "sun", 0, helflag, &AltS, serr) == ERR)
|
2127
|
+
return ERR;
|
2128
|
+
if (ObjectLoc(tjd_moonevent, dgeo, datm, ObjectName, 0, helflag, &AltO, serr) == ERR)
|
2129
|
+
return ERR;
|
2130
|
+
DeltaAlt = AltO - AltS;
|
2131
|
+
if (DeterTAV(dobs, tjd_moonevent, dgeo, datm, ObjectName, helflag, &MinTAV, serr) == ERR)
|
2132
|
+
return ERR;
|
2133
|
+
TimeCheck = tjd_moonevent - LocalMinStep / 60.0 / 24.0 * Sgn(Daystep);
|
2134
|
+
if (DeterTAV(dobs, TimeCheck, dgeo, datm, ObjectName, helflag, &LocalminCheck, serr) == ERR)
|
2135
|
+
return ERR;
|
2136
|
+
/*printf("%f, %f <= %f\n", tjd_moonevent, MinTAV, MinTAVoud);*/
|
2137
|
+
/* while (MinTAV <= MinTAVoud && fabs(tjd_moonevent - tjd_moonevent_start) < 120.0 / 60.0 / 24.0);*/
|
2138
|
+
} while ((MinTAV <= MinTAVoud || LocalminCheck < MinTAV) && fabs(tjd_moonevent - tjd_moonevent_start) < 120.0 / 60.0 / 24.0);
|
2139
|
+
/* while (DeltaAlt < MinTAVoud && fabs(JDNDaysUT - JDNDaysUTi) < 15);*/
|
2140
|
+
} while (DeltaAltoud < MinTAVoud && fabs(JDNDaysUT - JDNDaysUTi) < 15);
|
2141
|
+
if (fabs(JDNDaysUT - JDNDaysUTi) < 15) {
|
2142
|
+
tjd_moonevent += (1 - x2min(MinTAV, MinTAVoud, OldestMinTAV)) * Sgn(Daystep) / 60.0 / 24.0;
|
2143
|
+
} else {
|
2144
|
+
strcpy(serr, "no date found for lunar event");
|
2145
|
+
return ERR;
|
2146
|
+
}
|
2147
|
+
dret[0] = tjd_moonevent;
|
2148
|
+
return OK;
|
2149
|
+
}
|
2150
|
+
|
2151
|
+
static int32 heliacal_ut_arc_vis(double JDNDaysUTStart, double *dgeo, double *datm, double *dobs, char *ObjectName, int32 TypeEventIn, int32 helflag, double *dret, char *serr_ret)
|
2152
|
+
{
|
2153
|
+
double x[6];
|
2154
|
+
double xin[2];
|
2155
|
+
double xaz[2];
|
2156
|
+
double dang[3];
|
2157
|
+
double objectmagn = 0, maxlength, DayStep, DayStep0;
|
2158
|
+
double JDNDaysUT, JDNDaysUTfinal, JDNDaysUTstep, JDNDaysUTstepoud, JDNarcvisUT, tjd_tt, tret, OudeDatum, JDNDaysUTinp = JDNDaysUTStart, JDNDaysUTtijd;
|
2159
|
+
double ArcusVis, ArcusVisDelta, ArcusVisPto, ArcusVisDeltaoud;
|
2160
|
+
double Trise, sunsangle, Theliacal, Tdelta, Angle;
|
2161
|
+
double TimeStep, TimePointer, OldestMinTAV, MinTAVoud, MinTAVact, extrax, TbVR = 0;
|
2162
|
+
double AziS, AltS, AziO, AltO, DeltaAlt;
|
2163
|
+
double direct, Pressure, Temperature, RH, VR, d;
|
2164
|
+
int32 epheflag, retval = OK;
|
2165
|
+
int32 iflag, Planet, eventtype;
|
2166
|
+
int32 TypeEvent = TypeEventIn;
|
2167
|
+
int doneoneday;
|
2168
|
+
char serr[AS_MAXCH];
|
2169
|
+
*dret = JDNDaysUTStart;
|
2170
|
+
*serr = '\0';
|
2171
|
+
Planet = DeterObject(ObjectName);
|
2172
|
+
Pressure = datm[0];
|
2173
|
+
Temperature = datm[1];
|
2174
|
+
RH = datm[2];
|
2175
|
+
VR = datm[3];
|
2176
|
+
/* determine Magnitude of star*/
|
2177
|
+
if ((retval = Magnitude(JDNDaysUTStart, dgeo, ObjectName, helflag, &objectmagn, serr)) == ERR)
|
2178
|
+
goto swe_heliacal_err;
|
2179
|
+
epheflag = helflag & (SEFLG_JPLEPH|SEFLG_SWIEPH|SEFLG_MOSEPH);
|
2180
|
+
iflag = SEFLG_TOPOCTR | SEFLG_EQUATORIAL | epheflag;
|
2181
|
+
if (!(helflag & SE_HELFLAG_HIGH_PRECISION))
|
2182
|
+
iflag |= SEFLG_NONUT | SEFLG_TRUEPOS;
|
2183
|
+
/* start values for search of heliacal rise
|
2184
|
+
* maxlength = phase period in days, smaller than minimal synodic period */
|
2185
|
+
/* days per step (for heliacal rise) in power of two */
|
2186
|
+
switch(Planet) {
|
2187
|
+
case SE_MERCURY:
|
2188
|
+
DayStep = 1; maxlength = 100; break;
|
2189
|
+
case SE_VENUS:
|
2190
|
+
DayStep = 64; maxlength = 384; break;
|
2191
|
+
case SE_MARS:
|
2192
|
+
DayStep = 128; maxlength = 640; break;
|
2193
|
+
case SE_JUPITER:
|
2194
|
+
DayStep = 64; maxlength = 384; break;
|
2195
|
+
case SE_SATURN:
|
2196
|
+
DayStep = 64; maxlength = 256; break;
|
2197
|
+
default:
|
2198
|
+
DayStep = 64; maxlength = 256; break;
|
2199
|
+
}
|
2200
|
+
DayStep0 = DayStep;
|
2201
|
+
/* heliacal setting */
|
2202
|
+
eventtype = TypeEvent;
|
2203
|
+
if (eventtype == 2) DayStep = -DayStep;
|
2204
|
+
/* acronychal setting */
|
2205
|
+
if (eventtype == 4) {
|
2206
|
+
eventtype = 1;
|
2207
|
+
DayStep = -DayStep;
|
2208
|
+
}
|
2209
|
+
/* acronychal rising */
|
2210
|
+
if (eventtype == 3) eventtype = 2;
|
2211
|
+
eventtype |= SE_BIT_DISC_CENTER;
|
2212
|
+
/* normalize the maxlength to the step size */
|
2213
|
+
{
|
2214
|
+
/* check each Synodic/phase Period */
|
2215
|
+
JDNDaysUT = JDNDaysUTStart;
|
2216
|
+
/* make sure one can find an event on the just after the JDNDaysUTStart */
|
2217
|
+
JDNDaysUTfinal = JDNDaysUT + maxlength;
|
2218
|
+
JDNDaysUT = JDNDaysUT - 1;
|
2219
|
+
if (DayStep < 0) {
|
2220
|
+
JDNDaysUTtijd = JDNDaysUT;
|
2221
|
+
JDNDaysUT = JDNDaysUTfinal;
|
2222
|
+
JDNDaysUTfinal = JDNDaysUTtijd;
|
2223
|
+
}
|
2224
|
+
/* prepair the search */
|
2225
|
+
JDNDaysUTstep = JDNDaysUT - DayStep;
|
2226
|
+
doneoneday = 0;
|
2227
|
+
ArcusVisDelta = 199;
|
2228
|
+
ArcusVisPto = -5.55;
|
2229
|
+
do { /* this is a do {} while() loop */
|
2230
|
+
if (fabs(DayStep) == 1) doneoneday = 1;
|
2231
|
+
do { /* this is a do {} while() loop */
|
2232
|
+
/* init search for heliacal rise */
|
2233
|
+
JDNDaysUTstepoud = JDNDaysUTstep;
|
2234
|
+
ArcusVisDeltaoud = ArcusVisDelta;
|
2235
|
+
JDNDaysUTstep = JDNDaysUTstep + DayStep;
|
2236
|
+
/* determine rise/set time */
|
2237
|
+
if ((retval = my_rise_trans(JDNDaysUTstep, SE_SUN, "", eventtype, helflag, dgeo, datm, &tret, serr)) == ERR)
|
2238
|
+
goto swe_heliacal_err;
|
2239
|
+
/* determine time compensation to get Sun's altitude at heliacal rise */
|
2240
|
+
tjd_tt = tret + DeltaT(tret, 0) / D2S;
|
2241
|
+
if ((retval = swe_calc(tjd_tt, SE_SUN, iflag, x, serr)) == ERR)
|
2242
|
+
goto swe_heliacal_err;
|
2243
|
+
xin[0] = x[0];
|
2244
|
+
xin[1] = x[1];
|
2245
|
+
swe_azalt(tret, SE_EQU2HOR, dgeo, Pressure, Temperature, xin, xaz);
|
2246
|
+
Trise = HourAngle(xaz[1], x[1], dgeo[1]);
|
2247
|
+
sunsangle = ArcusVisPto;
|
2248
|
+
if (helflag & SE_HELFLAG_AVKIND_MIN7) sunsangle = -7;
|
2249
|
+
if (helflag & SE_HELFLAG_AVKIND_MIN9) sunsangle = -9;
|
2250
|
+
Theliacal = HourAngle(sunsangle, x[1], dgeo[1]);
|
2251
|
+
Tdelta = Theliacal - Trise;
|
2252
|
+
if (TypeEvent == 2 || TypeEvent== 3) Tdelta = -Tdelta;
|
2253
|
+
/* determine appr.time when sun is at the wanted Sun's altitude */
|
2254
|
+
JDNarcvisUT = tret - Tdelta / 24;
|
2255
|
+
tjd_tt = JDNarcvisUT + DeltaT(JDNarcvisUT, 0) / D2S;
|
2256
|
+
/* determine Sun's position */
|
2257
|
+
if ((retval = swe_calc(tjd_tt, SE_SUN, iflag, x, serr)) == ERR)
|
2258
|
+
goto swe_heliacal_err;
|
2259
|
+
xin[0] = x[0];
|
2260
|
+
xin[1] = x[1];
|
2261
|
+
swe_azalt(JDNarcvisUT, SE_EQU2HOR, dgeo, Pressure, Temperature, xin, xaz);
|
2262
|
+
AziS = xaz[0] + 180;
|
2263
|
+
if (AziS >= 360) AziS = AziS - 360;
|
2264
|
+
AltS = xaz[1];
|
2265
|
+
/* determine Moon's position */
|
2266
|
+
#if 0
|
2267
|
+
double AltM, AziM;
|
2268
|
+
if ((retval = swe_calc(tjd_tt, SE_MOON, iflag, x, serr)) == ERR)
|
2269
|
+
goto swe_heliacal_err;
|
2270
|
+
xin[0] = x[0];
|
2271
|
+
xin[1] = x[1];
|
2272
|
+
swe_azalt(JDNarcvisUT, SE_EQU2HOR, dgeo, Pressure, Temperature, xin, xaz);
|
2273
|
+
AziM = xaz[0] + 180;
|
2274
|
+
if (AziM >= 360) AziM = AziM - 360;
|
2275
|
+
AltM = xaz[1];
|
2276
|
+
#endif
|
2277
|
+
/* determine object's position */
|
2278
|
+
if (Planet != -1) {
|
2279
|
+
if ((retval = swe_calc(tjd_tt, Planet, iflag, x, serr)) == ERR)
|
2280
|
+
goto swe_heliacal_err;
|
2281
|
+
/* determine magnitude of Planet */
|
2282
|
+
if ((retval = Magnitude(JDNarcvisUT, dgeo, ObjectName, helflag, &objectmagn, serr)) == ERR)
|
2283
|
+
goto swe_heliacal_err;
|
2284
|
+
} else {
|
2285
|
+
if ((retval = call_swe_fixstar(ObjectName, tjd_tt, iflag, x, serr)) == ERR)
|
2286
|
+
goto swe_heliacal_err;
|
2287
|
+
}
|
2288
|
+
xin[0] = x[0];
|
2289
|
+
xin[1] = x[1];
|
2290
|
+
swe_azalt(JDNarcvisUT, SE_EQU2HOR, dgeo, Pressure, Temperature, xin, xaz);
|
2291
|
+
AziO = xaz[0] + 180;
|
2292
|
+
if (AziO >= 360) AziO = AziO - 360;
|
2293
|
+
AltO = xaz[1];
|
2294
|
+
/* determine arcusvisionis */
|
2295
|
+
DeltaAlt = AltO - AltS;
|
2296
|
+
/*if ((retval = HeliacalAngle(objectmagn, dobs, AziO, AltM, AziM, JDNarcvisUT, AziS, dgeo, datm, helflag, dang, serr)) == ERR)*/
|
2297
|
+
if ((retval = HeliacalAngle(objectmagn, dobs, AziO, -1, 0, JDNarcvisUT, AziS, dgeo, datm, helflag, dang, serr)) == ERR)
|
2298
|
+
goto swe_heliacal_err;
|
2299
|
+
ArcusVis = dang[1];
|
2300
|
+
ArcusVisPto = dang[2];
|
2301
|
+
ArcusVisDelta = DeltaAlt - ArcusVis;
|
2302
|
+
/*} while (((ArcusVisDeltaoud > 0 && ArcusVisDelta < 0) || ArcusVisDelta < 0) && (JDNDaysUTfinal - JDNDaysUTstep) * Sgn(DayStep) > 0);*/
|
2303
|
+
} while ((ArcusVisDeltaoud > 0 || ArcusVisDelta < 0) && (JDNDaysUTfinal - JDNDaysUTstep) * Sgn(DayStep) > 0);
|
2304
|
+
if (doneoneday == 0 && (JDNDaysUTfinal - JDNDaysUTstep) * Sgn(DayStep) > 0) {
|
2305
|
+
/* go back to date before heliacal altitude */
|
2306
|
+
ArcusVisDelta = ArcusVisDeltaoud;
|
2307
|
+
DayStep = ((int) (fabs(DayStep) / 2.0)) * Sgn(DayStep);
|
2308
|
+
JDNDaysUTstep = JDNDaysUTstepoud;
|
2309
|
+
}
|
2310
|
+
} while (doneoneday == 0 && (JDNDaysUTfinal - JDNDaysUTstep) * Sgn(DayStep) > 0);
|
2311
|
+
}
|
2312
|
+
d = (JDNDaysUTfinal - JDNDaysUTstep) * Sgn(DayStep);
|
2313
|
+
if (d <= 0 || d >= maxlength) {
|
2314
|
+
dret[0] = JDNDaysUTinp; /* no date found, just return input */
|
2315
|
+
retval = -2; /* marks "not found" within synodic period */
|
2316
|
+
sprintf(serr, "heliacal event not found within maxlength %f\n", maxlength);
|
2317
|
+
goto swe_heliacal_err;
|
2318
|
+
}
|
2319
|
+
#if 0
|
2320
|
+
if (helflag & SE_HELFLAG_AVKIND_VR) {
|
2321
|
+
double darr[40];
|
2322
|
+
if (swe_heliacal_pheno_ut(JDNarcvisUT, dgeo, datm, dobs, ObjectName, TypeEvent, helflag, darr, serr) != OK)
|
2323
|
+
return ERR;
|
2324
|
+
JDNarcvisUT = darr[13];
|
2325
|
+
}
|
2326
|
+
}
|
2327
|
+
#endif
|
2328
|
+
direct = TimeStepDefault / 24.0 / 60.0;
|
2329
|
+
if (DayStep < 0) direct = -direct;
|
2330
|
+
if (helflag & SE_HELFLAG_AVKIND_VR) {
|
2331
|
+
/*te bepalen m.b.v. walkthrough*/
|
2332
|
+
TimeStep = direct;
|
2333
|
+
TbVR = 0;
|
2334
|
+
TimePointer = JDNarcvisUT;
|
2335
|
+
if (DeterTAV(dobs, TimePointer, dgeo, datm, ObjectName, helflag, &OldestMinTAV, serr) == ERR)
|
2336
|
+
return ERR;
|
2337
|
+
TimePointer = TimePointer + TimeStep;
|
2338
|
+
if (DeterTAV(dobs, TimePointer, dgeo, datm, ObjectName, helflag, &MinTAVoud, serr) == ERR)
|
2339
|
+
return ERR;
|
2340
|
+
if (MinTAVoud > OldestMinTAV) {
|
2341
|
+
TimePointer = JDNarcvisUT;
|
2342
|
+
TimeStep = -TimeStep;
|
2343
|
+
MinTAVact = OldestMinTAV;
|
2344
|
+
} else {
|
2345
|
+
MinTAVact = MinTAVoud;
|
2346
|
+
MinTAVoud = OldestMinTAV;
|
2347
|
+
}
|
2348
|
+
/*TimePointer = TimePointer - Timestep*/
|
2349
|
+
do {
|
2350
|
+
TimePointer = TimePointer + TimeStep;
|
2351
|
+
OldestMinTAV = MinTAVoud;
|
2352
|
+
MinTAVoud = MinTAVact;
|
2353
|
+
if (DeterTAV(dobs, TimePointer, dgeo, datm, ObjectName, helflag, &MinTAVact, serr) == ERR)
|
2354
|
+
return ERR;
|
2355
|
+
if (MinTAVoud < MinTAVact) {
|
2356
|
+
extrax = x2min(MinTAVact, MinTAVoud, OldestMinTAV);
|
2357
|
+
TbVR = TimePointer - (1 - extrax) * TimeStep;
|
2358
|
+
}
|
2359
|
+
} while (TbVR == 0);
|
2360
|
+
JDNarcvisUT = TbVR;
|
2361
|
+
}
|
2362
|
+
/*if (strncmp(AVkind, "pto", 3) == 0) */
|
2363
|
+
if (helflag & SE_HELFLAG_AVKIND_PTO) {
|
2364
|
+
do {
|
2365
|
+
OudeDatum = JDNarcvisUT;
|
2366
|
+
JDNarcvisUT = JDNarcvisUT - direct;
|
2367
|
+
tjd_tt = JDNarcvisUT + DeltaT(JDNarcvisUT, 0) / D2S;
|
2368
|
+
if (Planet != -1) {
|
2369
|
+
if ((retval = swe_calc(tjd_tt, Planet, iflag, x, serr)) == ERR)
|
2370
|
+
goto swe_heliacal_err;
|
2371
|
+
} else {
|
2372
|
+
if ((retval = call_swe_fixstar(ObjectName, tjd_tt, iflag, x, serr)) == ERR)
|
2373
|
+
goto swe_heliacal_err;
|
2374
|
+
}
|
2375
|
+
xin[0] = x[0];
|
2376
|
+
xin[1] = x[1];
|
2377
|
+
swe_azalt(JDNarcvisUT, SE_EQU2HOR, dgeo, Pressure, Temperature, xin, xaz);
|
2378
|
+
Angle = xaz[1];
|
2379
|
+
} while (Angle > 0);
|
2380
|
+
JDNarcvisUT = (JDNarcvisUT + OudeDatum) / 2.0;
|
2381
|
+
}
|
2382
|
+
if (JDNarcvisUT < -9999999 || JDNarcvisUT > 9999999) {
|
2383
|
+
dret[0] = JDNDaysUT; /* no date found, just return input */
|
2384
|
+
strcpy(serr, "no heliacal date found");
|
2385
|
+
retval = ERR;
|
2386
|
+
goto swe_heliacal_err;
|
2387
|
+
}
|
2388
|
+
dret[0] = JDNarcvisUT;
|
2389
|
+
swe_heliacal_err:
|
2390
|
+
if (serr_ret != NULL && *serr != '\0')
|
2391
|
+
strcpy(serr_ret, serr);
|
2392
|
+
return retval;
|
2393
|
+
}
|
2394
|
+
|
2395
|
+
static int32 get_asc_obl(double tjd, int32 ipl, char *star, int32 iflag, double
|
2396
|
+
*dgeo, AS_BOOL desc_obl, double *daop, char *serr)
|
2397
|
+
{
|
2398
|
+
int32 retval;
|
2399
|
+
int32 epheflag = iflag & (SEFLG_JPLEPH|SEFLG_SWIEPH|SEFLG_MOSEPH);
|
2400
|
+
double x[6], adp;
|
2401
|
+
char s[AS_MAXCH];
|
2402
|
+
char star2[AS_MAXCH];
|
2403
|
+
strcpy(star2, star);
|
2404
|
+
if (ipl == -1) {
|
2405
|
+
if ((retval = swe_fixstar(star2, tjd, epheflag | SEFLG_EQUATORIAL, x, serr)) == ERR)
|
2406
|
+
return ERR;
|
2407
|
+
} else {
|
2408
|
+
if ((retval = swe_calc(tjd, ipl, epheflag | SEFLG_EQUATORIAL, x, serr)) == ERR)
|
2409
|
+
return ERR;
|
2410
|
+
}
|
2411
|
+
adp = tan(dgeo[1] * DEGTORAD) * tan(x[1] * DEGTORAD);
|
2412
|
+
if (fabs(adp) > 1) {
|
2413
|
+
if (star != NULL && *star != '\0')
|
2414
|
+
strcpy(s, star);
|
2415
|
+
else
|
2416
|
+
swe_get_planet_name(ipl, s);
|
2417
|
+
sprintf(serr, "%s is circumpolar, cannot calculate heliacal event", s);
|
2418
|
+
return -2;
|
2419
|
+
}
|
2420
|
+
adp = asin(adp) / DEGTORAD;
|
2421
|
+
if (desc_obl)
|
2422
|
+
*daop = x[0] + adp;
|
2423
|
+
else
|
2424
|
+
*daop = x[0] - adp;
|
2425
|
+
*daop = swe_degnorm(*daop);
|
2426
|
+
return OK;
|
2427
|
+
}
|
2428
|
+
|
2429
|
+
#if 0
|
2430
|
+
static int32 get_asc_obl_old(double tjd, int32 ipl, char *star, int32 iflag, double *dgeo, AS_BOOL desc_obl, double *daop, char *serr)
|
2431
|
+
{
|
2432
|
+
int32 retval;
|
2433
|
+
int32 epheflag = iflag & (SEFLG_JPLEPH|SEFLG_SWIEPH|SEFLG_MOSEPH);
|
2434
|
+
double x[6], adp;
|
2435
|
+
char s[AS_MAXCH];
|
2436
|
+
if (star != NULL && *star != '\0') {
|
2437
|
+
if ((retval = call_swe_fixstar(star, tjd, epheflag | SEFLG_EQUATORIAL, x, serr)) == ERR)
|
2438
|
+
return ERR;
|
2439
|
+
} else {
|
2440
|
+
if ((retval = swe_calc(tjd, ipl, epheflag | SEFLG_EQUATORIAL, x, serr)) == ERR)
|
2441
|
+
return ERR;
|
2442
|
+
}
|
2443
|
+
adp = tan(dgeo[1] * DEGTORAD) * tan(x[1] * DEGTORAD);
|
2444
|
+
if (fabs(adp) > 1) {
|
2445
|
+
if (star != NULL && *star != '\0')
|
2446
|
+
strcpy(s, star);
|
2447
|
+
else
|
2448
|
+
swe_get_planet_name(ipl, s);
|
2449
|
+
sprintf(serr, "%s is circumpolar, cannot calculate heliacal event", s);
|
2450
|
+
return -2;
|
2451
|
+
}
|
2452
|
+
adp = asin(adp) / DEGTORAD;
|
2453
|
+
if (desc_obl)
|
2454
|
+
*daop = x[0] + adp;
|
2455
|
+
else
|
2456
|
+
*daop = x[0] - adp;
|
2457
|
+
*daop = swe_degnorm(*daop);
|
2458
|
+
return OK;
|
2459
|
+
}
|
2460
|
+
#endif
|
2461
|
+
|
2462
|
+
static int32 get_asc_obl_diff(double tjd, int32 ipl, char *star, int32 iflag, double *dgeo, AS_BOOL desc_obl, AS_BOOL is_acronychal, double *dsunpl, char *serr)
|
2463
|
+
{
|
2464
|
+
int32 retval = OK;
|
2465
|
+
double aosun, aopl;
|
2466
|
+
/* ascensio obliqua of sun */
|
2467
|
+
retval = get_asc_obl(tjd, SE_SUN, "", iflag, dgeo, desc_obl, &aosun, serr);
|
2468
|
+
if (retval != OK)
|
2469
|
+
return retval;
|
2470
|
+
if (is_acronychal) {
|
2471
|
+
if (desc_obl == TRUE)
|
2472
|
+
desc_obl = FALSE;
|
2473
|
+
else
|
2474
|
+
desc_obl = TRUE;
|
2475
|
+
}
|
2476
|
+
/* ascensio obliqua of body */
|
2477
|
+
retval = get_asc_obl(tjd, ipl, star, iflag, dgeo, desc_obl, &aopl, serr);
|
2478
|
+
if (retval != OK)
|
2479
|
+
return retval;
|
2480
|
+
*dsunpl = swe_degnorm(aosun - aopl);
|
2481
|
+
if (is_acronychal)
|
2482
|
+
*dsunpl = swe_degnorm(*dsunpl - 180);
|
2483
|
+
if (*dsunpl > 180) *dsunpl -= 360;
|
2484
|
+
return OK;
|
2485
|
+
}
|
2486
|
+
|
2487
|
+
#if 0
|
2488
|
+
static int32 get_asc_obl_diff_old(double tjd, int32 ipl, char *star, int32 iflag, double *dgeo, AS_BOOL desc_obl, double *dsunpl, char *serr)
|
2489
|
+
{
|
2490
|
+
int32 retval = OK;
|
2491
|
+
double aosun, aopl;
|
2492
|
+
/* ascensio obliqua of sun */
|
2493
|
+
retval = get_asc_obl(tjd, SE_SUN, "", iflag, dgeo, desc_obl, &aosun, serr);
|
2494
|
+
if (retval != OK)
|
2495
|
+
return retval;
|
2496
|
+
/* ascensio obliqua of body */
|
2497
|
+
retval = get_asc_obl(tjd, ipl, star, iflag, dgeo, desc_obl, &aopl, serr);
|
2498
|
+
if (retval != OK)
|
2499
|
+
return retval;
|
2500
|
+
*dsunpl = swe_degnorm(aosun - aopl);
|
2501
|
+
return OK;
|
2502
|
+
}
|
2503
|
+
#endif
|
2504
|
+
|
2505
|
+
/* times of
|
2506
|
+
* - superior and inferior conjunction (Mercury and Venus)
|
2507
|
+
* - conjunction and opposition (ipl >= Mars)
|
2508
|
+
*/
|
2509
|
+
static double tcon[] =
|
2510
|
+
{
|
2511
|
+
0, 0,
|
2512
|
+
2451550, 2451550, /* Moon */
|
2513
|
+
2451604, 2451670, /* Mercury */
|
2514
|
+
2451980, 2452280, /* Venus */
|
2515
|
+
2451727, 2452074, /* Mars */
|
2516
|
+
2451673, 2451877, /* Jupiter */
|
2517
|
+
2451675, 2451868, /* Saturn */
|
2518
|
+
2451581, 2451768, /* Uranus */
|
2519
|
+
2451568, 2451753, /* Neptune */
|
2520
|
+
};
|
2521
|
+
|
2522
|
+
static int32 find_conjunct_sun(double tjd_start, int32 ipl, int32 helflag, int32 TypeEvent, double *tjd, char *serr)
|
2523
|
+
{
|
2524
|
+
int32 epheflag = helflag & (SEFLG_JPLEPH|SEFLG_SWIEPH|SEFLG_MOSEPH);
|
2525
|
+
int i;
|
2526
|
+
double tjdcon, tjd0, ds, dsynperiod, x[6], xs[6], daspect = 0;
|
2527
|
+
if (ipl >= SE_MARS && TypeEvent >= 3)
|
2528
|
+
daspect = 180;
|
2529
|
+
i = (TypeEvent - 1) / 2 + ipl * 2;
|
2530
|
+
tjd0 = tcon[i];
|
2531
|
+
dsynperiod = get_synodic_period(ipl);
|
2532
|
+
tjdcon = tjd0 + ((floor) ((tjd_start - tjd0) / dsynperiod) + 1) * dsynperiod;
|
2533
|
+
ds = 100;
|
2534
|
+
while (ds > 0.5) {
|
2535
|
+
if (swe_calc(tjdcon, ipl, epheflag|SEFLG_SPEED, x, serr) == ERR)
|
2536
|
+
return ERR;
|
2537
|
+
if (swe_calc(tjdcon, SE_SUN, epheflag|SEFLG_SPEED, xs, serr) == ERR)
|
2538
|
+
return ERR;
|
2539
|
+
ds = swe_degnorm(x[0] - xs[0] - daspect);
|
2540
|
+
if (ds > 180) ds -= 360;
|
2541
|
+
tjdcon -= ds / (x[3] - xs[3]);
|
2542
|
+
}
|
2543
|
+
*tjd = tjdcon;
|
2544
|
+
return OK;
|
2545
|
+
}
|
2546
|
+
|
2547
|
+
static int32 get_asc_obl_with_sun(double tjd_start, int32 ipl, char *star, int32 helflag, int32 evtyp, double dperiod, double *dgeo, double *tjdret, char *serr)
|
2548
|
+
{
|
2549
|
+
int i, retval;
|
2550
|
+
int32 is_acronychal = FALSE;
|
2551
|
+
int32 epheflag = helflag & (SEFLG_JPLEPH|SEFLG_SWIEPH|SEFLG_MOSEPH);
|
2552
|
+
double dsunpl = 1, dsunpl_save, dsunpl_test, tjd, daystep;
|
2553
|
+
AS_BOOL desc_obl = FALSE, retro = FALSE;
|
2554
|
+
if (evtyp == SE_EVENING_LAST || evtyp == SE_EVENING_FIRST)
|
2555
|
+
desc_obl = TRUE;
|
2556
|
+
if (evtyp == SE_MORNING_FIRST || evtyp == SE_EVENING_LAST)
|
2557
|
+
retro = TRUE;
|
2558
|
+
if (evtyp == SE_ACRONYCHAL_RISING)
|
2559
|
+
desc_obl = TRUE;
|
2560
|
+
if (evtyp == SE_ACRONYCHAL_RISING || evtyp == SE_ACRONYCHAL_SETTING) {
|
2561
|
+
is_acronychal = TRUE;
|
2562
|
+
if (ipl != SE_MOON)
|
2563
|
+
retro = TRUE;
|
2564
|
+
}
|
2565
|
+
// if (evtyp == 3 || evtyp == 4)
|
2566
|
+
// dangsearch = 180;
|
2567
|
+
/* find date when sun and object have the same ascensio obliqua */
|
2568
|
+
tjd = tjd_start;
|
2569
|
+
dsunpl_save = -999999999;
|
2570
|
+
retval = get_asc_obl_diff(tjd, ipl, star, epheflag, dgeo, desc_obl, is_acronychal, &dsunpl, serr);
|
2571
|
+
if (retval != OK) /* retval may be ERR or -2 */
|
2572
|
+
return retval;
|
2573
|
+
daystep = 20;
|
2574
|
+
i = 0;
|
2575
|
+
while (dsunpl_save == -999999999 ||
|
2576
|
+
/*fabs(dsunpl - dsunpl_save) > 180 ||*/
|
2577
|
+
fabs(dsunpl) + fabs(dsunpl_save) > 180 ||
|
2578
|
+
(retro && !(dsunpl_save < 0 && dsunpl >= 0)) ||
|
2579
|
+
(!retro && !(dsunpl_save >= 0 && dsunpl < 0))) {
|
2580
|
+
i++;
|
2581
|
+
if (i > 5000) {
|
2582
|
+
sprintf(serr, "loop in get_asc_obl_with_sun() (1)");
|
2583
|
+
return ERR;
|
2584
|
+
}
|
2585
|
+
dsunpl_save = dsunpl;
|
2586
|
+
tjd += 10.0;
|
2587
|
+
if (dperiod > 0 && tjd - tjd_start > dperiod)
|
2588
|
+
return -2;
|
2589
|
+
retval = get_asc_obl_diff(tjd, ipl, star, epheflag, dgeo, desc_obl, is_acronychal, &dsunpl, serr);
|
2590
|
+
if (retval != OK) /* retval may be ERR or -2 */
|
2591
|
+
return retval;
|
2592
|
+
}
|
2593
|
+
tjd_start = tjd - daystep;
|
2594
|
+
daystep /= 2.0;
|
2595
|
+
tjd = tjd_start + daystep;
|
2596
|
+
retval = get_asc_obl_diff(tjd, ipl, star, epheflag, dgeo, desc_obl, is_acronychal, &dsunpl_test, serr);
|
2597
|
+
if (retval != OK) /* retval may be ERR or -2 */
|
2598
|
+
return retval;
|
2599
|
+
i = 0;
|
2600
|
+
while (fabs(dsunpl) > 0.00001) {
|
2601
|
+
i++;
|
2602
|
+
if (i > 5000) {
|
2603
|
+
sprintf(serr, "loop in get_asc_obl_with_sun() (2)");
|
2604
|
+
return ERR;
|
2605
|
+
}
|
2606
|
+
if (dsunpl_save * dsunpl_test >= 0) {
|
2607
|
+
dsunpl_save = dsunpl_test;
|
2608
|
+
tjd_start = tjd;
|
2609
|
+
} else {
|
2610
|
+
dsunpl = dsunpl_test;
|
2611
|
+
}
|
2612
|
+
daystep /= 2.0;
|
2613
|
+
tjd = tjd_start + daystep;
|
2614
|
+
retval = get_asc_obl_diff(tjd, ipl, star, epheflag, dgeo, desc_obl, is_acronychal, &dsunpl_test, serr);
|
2615
|
+
if (retval != OK) /* retval may be ERR or -2 */
|
2616
|
+
return retval;
|
2617
|
+
}
|
2618
|
+
*tjdret = tjd;
|
2619
|
+
return OK;
|
2620
|
+
}
|
2621
|
+
|
2622
|
+
#if 0
|
2623
|
+
/* works only for fixed stars */
|
2624
|
+
static int32 get_asc_obl_with_sun_old(double tjd_start, int32 ipl, char *star, int32 helflag, int32 TypeEvent, double *dgeo, double *tjdret, char *serr)
|
2625
|
+
{
|
2626
|
+
int retval;
|
2627
|
+
int32 epheflag = helflag & (SEFLG_JPLEPH|SEFLG_SWIEPH|SEFLG_MOSEPH);
|
2628
|
+
double dsunpl = 1, tjd, daystep, dsunpl_save;
|
2629
|
+
double dsynperiod = 367;
|
2630
|
+
double dangsearch = 0;
|
2631
|
+
AS_BOOL desc_obl = FALSE;
|
2632
|
+
if (TypeEvent == 2 || TypeEvent == 3)
|
2633
|
+
desc_obl = TRUE;
|
2634
|
+
if (TypeEvent == 3 || TypeEvent == 4)
|
2635
|
+
dangsearch = 180;
|
2636
|
+
/* find date when sun and object have the same ascensio obliqua */
|
2637
|
+
daystep = dsynperiod;
|
2638
|
+
tjd = tjd_start;
|
2639
|
+
retval = get_asc_obl_diff(tjd, ipl, star, epheflag, dgeo, desc_obl, &dsunpl, serr);
|
2640
|
+
if (retval != OK) /* retval may be ERR or -2 */
|
2641
|
+
return retval;
|
2642
|
+
while (dsunpl < 359.99999) {
|
2643
|
+
dsunpl_save = dsunpl;
|
2644
|
+
daystep /= 2.0;
|
2645
|
+
retval = get_asc_obl_diff(tjd + daystep, ipl, star, epheflag, dgeo, desc_obl, &dsunpl, serr);
|
2646
|
+
if (retval != OK) /* retval may be ERR or -2 */
|
2647
|
+
return retval;
|
2648
|
+
if (dsunpl > dsunpl_save)
|
2649
|
+
tjd += daystep;
|
2650
|
+
else
|
2651
|
+
dsunpl = dsunpl_save;
|
2652
|
+
}
|
2653
|
+
*tjdret = tjd;
|
2654
|
+
return OK;
|
2655
|
+
}
|
2656
|
+
#endif
|
2657
|
+
|
2658
|
+
#if 0
|
2659
|
+
/* works only for fixed stars */
|
2660
|
+
static int32 get_asc_obl_acronychal(double tjd_start, int32 ipl, char *star, int32 helflag, int32 TypeEvent, double *dgeo, double *tjdret, char *serr)
|
2661
|
+
{
|
2662
|
+
int retval;
|
2663
|
+
int32 epheflag = helflag & (SEFLG_JPLEPH|SEFLG_SWIEPH|SEFLG_MOSEPH);
|
2664
|
+
double dsunpl = 1, tjd, daystep, dsunpl_save;
|
2665
|
+
double dsynperiod = 367;
|
2666
|
+
double aosun, aopl;
|
2667
|
+
AS_BOOL sun_desc = TRUE, obj_desc = FALSE;
|
2668
|
+
daystep = dsynperiod;
|
2669
|
+
tjd = tjd_start;
|
2670
|
+
if (TypeEvent == 4) {
|
2671
|
+
sun_desc = FALSE;
|
2672
|
+
obj_desc = TRUE;
|
2673
|
+
}
|
2674
|
+
/* ascensio (descensio) obliqua of sun */
|
2675
|
+
retval = get_asc_obl(tjd, SE_SUN, "", epheflag, dgeo, sun_desc, &aosun, serr);
|
2676
|
+
if (retval != OK) /* retval may be ERR or -2 */
|
2677
|
+
return retval;
|
2678
|
+
/* ascensio (descensio) obliqua of body */
|
2679
|
+
retval = get_asc_obl(tjd, ipl, star, epheflag, dgeo, obj_desc, &aopl, serr);
|
2680
|
+
if (retval != OK) /* retval may be ERR or -2 */
|
2681
|
+
return retval;
|
2682
|
+
dsunpl = swe_degnorm(aosun - aopl + 180);
|
2683
|
+
while (dsunpl < 359.99999) {
|
2684
|
+
dsunpl_save = dsunpl;
|
2685
|
+
daystep /= 2.0;
|
2686
|
+
/* ascensio (descensio) obliqua of sun */
|
2687
|
+
retval = get_asc_obl(tjd+daystep, SE_SUN, "", epheflag, dgeo, sun_desc, &aosun, serr);
|
2688
|
+
if (retval != OK) /* retval may be ERR or -2 */
|
2689
|
+
return retval;
|
2690
|
+
/* ascensio (descensio) obliqua of body */
|
2691
|
+
retval = get_asc_obl(tjd+daystep, ipl, star, epheflag, dgeo, obj_desc, &aopl, serr);
|
2692
|
+
if (retval != OK) /* retval may be ERR or -2 */
|
2693
|
+
return retval;
|
2694
|
+
dsunpl = swe_degnorm(aosun - aopl + 180);
|
2695
|
+
if (dsunpl > dsunpl_save)
|
2696
|
+
tjd += daystep;
|
2697
|
+
else
|
2698
|
+
dsunpl = dsunpl_save;
|
2699
|
+
}
|
2700
|
+
*tjdret = tjd;
|
2701
|
+
return OK;
|
2702
|
+
}
|
2703
|
+
#endif
|
2704
|
+
|
2705
|
+
static int32 get_heliacal_day(double tjd, double *dgeo, double *datm, double *dobs, char *ObjectName, int32 helflag, int32 TypeEvent, double *thel, char *serr)
|
2706
|
+
{
|
2707
|
+
int32 is_rise_or_set, ndays, retval, retval_old;
|
2708
|
+
double direct_day, direct_time, tfac, tend, daystep, tday, vdelta, tret;
|
2709
|
+
double darr[30], tsave, vd, dmag;
|
2710
|
+
int32 ipl = DeterObject(ObjectName);
|
2711
|
+
/*
|
2712
|
+
* find the day and minute on which the object becomes visible
|
2713
|
+
*/
|
2714
|
+
switch (TypeEvent) {
|
2715
|
+
/* morning first */
|
2716
|
+
case 1: is_rise_or_set = SE_CALC_RISE;
|
2717
|
+
direct_day = 1; direct_time = -1;
|
2718
|
+
break;
|
2719
|
+
/* evening last */
|
2720
|
+
case 2: is_rise_or_set = SE_CALC_SET;
|
2721
|
+
direct_day = -1; direct_time = 1;
|
2722
|
+
break;
|
2723
|
+
/* evening first */
|
2724
|
+
case 3: is_rise_or_set = SE_CALC_SET;
|
2725
|
+
direct_day = 1; direct_time = 1;
|
2726
|
+
break;
|
2727
|
+
/* morning last */
|
2728
|
+
case 4: is_rise_or_set = SE_CALC_RISE;
|
2729
|
+
direct_day = -1; direct_time = -1;
|
2730
|
+
break;
|
2731
|
+
}
|
2732
|
+
tfac = 1;
|
2733
|
+
switch (ipl) {
|
2734
|
+
case SE_MOON:
|
2735
|
+
ndays = 6;
|
2736
|
+
daystep = 1;
|
2737
|
+
break;
|
2738
|
+
case SE_MERCURY:
|
2739
|
+
ndays = 60; tjd -= 0 * direct_day;
|
2740
|
+
daystep = 5;
|
2741
|
+
tfac = 5;
|
2742
|
+
break;
|
2743
|
+
case SE_VENUS:
|
2744
|
+
ndays = 300; tjd -= 30 * direct_day;
|
2745
|
+
daystep = 5;
|
2746
|
+
if (TypeEvent >= 3) {
|
2747
|
+
daystep = 15;
|
2748
|
+
tfac = 3;
|
2749
|
+
}
|
2750
|
+
break;
|
2751
|
+
case SE_MARS:
|
2752
|
+
ndays = 400;
|
2753
|
+
daystep = 15;
|
2754
|
+
tfac = 5;
|
2755
|
+
break;
|
2756
|
+
case SE_SATURN:
|
2757
|
+
ndays = 300;
|
2758
|
+
daystep = 20;
|
2759
|
+
tfac = 5;
|
2760
|
+
break;
|
2761
|
+
case -1:
|
2762
|
+
ndays = 300;
|
2763
|
+
if (call_swe_fixstar_mag(ObjectName, &dmag, serr) == ERR)
|
2764
|
+
return ERR;
|
2765
|
+
daystep = 15;
|
2766
|
+
tfac = 10;
|
2767
|
+
if (dmag > 2) {
|
2768
|
+
daystep = 15;
|
2769
|
+
}
|
2770
|
+
break;
|
2771
|
+
default:
|
2772
|
+
ndays = 300;
|
2773
|
+
daystep = 15;
|
2774
|
+
tfac = 3;
|
2775
|
+
break;
|
2776
|
+
}
|
2777
|
+
tend = tjd + ndays * direct_day;
|
2778
|
+
retval_old = -2;
|
2779
|
+
for (tday = tjd;
|
2780
|
+
(direct_day > 0 && tday < tend) || (direct_day < 0 && tday > tend);
|
2781
|
+
tday += daystep * direct_day) {
|
2782
|
+
vdelta = -100;
|
2783
|
+
if ((retval = my_rise_trans(tday, SE_SUN, "", is_rise_or_set, helflag, dgeo, datm, &tret, serr)) == ERR)
|
2784
|
+
return ERR;
|
2785
|
+
/* sun does not rise: try next day */
|
2786
|
+
if (retval == -2) {
|
2787
|
+
retval_old = retval;
|
2788
|
+
continue;
|
2789
|
+
}
|
2790
|
+
retval = swe_vis_limit_mag(tret, dgeo, datm, dobs, ObjectName, helflag, darr, serr);
|
2791
|
+
if (retval == ERR)
|
2792
|
+
return ERR;
|
2793
|
+
#if 1
|
2794
|
+
/* object has appeared above horizon: reduce daystep */
|
2795
|
+
if (retval_old == -2 && retval >= 0 && daystep > 1) {
|
2796
|
+
retval_old = retval;
|
2797
|
+
tday -= daystep * direct_day;
|
2798
|
+
daystep = 1;
|
2799
|
+
/* Note: beyond latitude 55N (?), Mars can have a morning last.
|
2800
|
+
* If the period of visibility is less than 5 days, we may miss the
|
2801
|
+
* event. I don't know if this happens */
|
2802
|
+
if (ipl >= SE_MARS || ipl == -1)
|
2803
|
+
daystep = 5;
|
2804
|
+
continue;
|
2805
|
+
}
|
2806
|
+
retval_old = retval;
|
2807
|
+
#endif
|
2808
|
+
/* object below horizon: try next day */
|
2809
|
+
if (retval == -2)
|
2810
|
+
continue;
|
2811
|
+
vdelta = darr[0] - darr[7];
|
2812
|
+
/* find minute of object's becoming visible */
|
2813
|
+
tsave = tret;
|
2814
|
+
while (retval != -2 && (vd = darr[0] - darr[7]) < 0) {
|
2815
|
+
if (vd < -1.0)
|
2816
|
+
tret += 5.0 / 1440.0 * direct_time * tfac;
|
2817
|
+
else if (vd < -0.5)
|
2818
|
+
tret += 2.0 / 1440.0 * direct_time * tfac;
|
2819
|
+
else if (vd < -0.1)
|
2820
|
+
tret += 1.0 / 1440.0 * direct_time * tfac;
|
2821
|
+
else
|
2822
|
+
tret += 1.0 / 1440.0 * direct_time;
|
2823
|
+
retval = swe_vis_limit_mag(tret, dgeo, datm, dobs, ObjectName, helflag, darr, serr);
|
2824
|
+
if (retval == ERR)
|
2825
|
+
return ERR;
|
2826
|
+
}
|
2827
|
+
vdelta = darr[0] - darr[7];
|
2828
|
+
/* object is visible, save time of appearance */
|
2829
|
+
if (vdelta > 0) {
|
2830
|
+
if ((ipl >= SE_MARS || ipl == -1) && daystep > 1) {
|
2831
|
+
tday -= daystep * direct_day;
|
2832
|
+
daystep = 1;
|
2833
|
+
} else {
|
2834
|
+
*thel = tret;
|
2835
|
+
return OK;
|
2836
|
+
}
|
2837
|
+
}
|
2838
|
+
}
|
2839
|
+
sprintf(serr, "heliacal event does not happen");
|
2840
|
+
return -2;
|
2841
|
+
}
|
2842
|
+
|
2843
|
+
#if 0
|
2844
|
+
static int32 get_acronychal_day_new(double tjd, double *dgeo, double *datm, double *dobs, char *ObjectName, int32 helflag, int32 TypeEvent, double *thel, char *serr) {
|
2845
|
+
double tjdc = tjd, tret, x[6], xaz[6], AltO = -10;
|
2846
|
+
int32 retval, is_rise_or_set, iter_day;
|
2847
|
+
int32 ipl = DeterObject(ObjectName);
|
2848
|
+
int32 epheflag = helflag & (SEFLG_JPLEPH|SEFLG_SWIEPH|SEFLG_MOSEPH);
|
2849
|
+
int32 iflag = epheflag | SEFLG_EQUATORIAL | SEFLG_TOPOCTR;
|
2850
|
+
if ((retval = my_rise_trans(tret, 0, ObjectName, SE_CALC_RISE, helflag, dgeo, datm, &tret, serr)) == ERR) return ERR;
|
2851
|
+
trise = tret;
|
2852
|
+
tret += 0.01
|
2853
|
+
if ((retval = my_rise_trans(tret, 0, ObjectName, SE_CALC_SET, helflag, dgeo, datm, &tret, serr)) == ERR) return ERR;
|
2854
|
+
trise = tset;
|
2855
|
+
|
2856
|
+
*thel = tret;
|
2857
|
+
return OK;
|
2858
|
+
}
|
2859
|
+
#endif
|
2860
|
+
|
2861
|
+
#if 0
|
2862
|
+
static int32 get_acronychal_day_old(double tjd, double *dgeo, double *datm, double *dobs, char *ObjectName, int32 helflag, int32 TypeEvent, double *thel, char *serr) {
|
2863
|
+
double tjdc = tjd, tret, x[6], xaz[6], AltO = -10;
|
2864
|
+
int32 retval, is_rise_or_set, iter_day;
|
2865
|
+
int32 ipl = DeterObject(ObjectName);
|
2866
|
+
int32 epheflag = helflag & (SEFLG_JPLEPH|SEFLG_SWIEPH|SEFLG_MOSEPH);
|
2867
|
+
int32 iflag = epheflag | SEFLG_EQUATORIAL | SEFLG_TOPOCTR;
|
2868
|
+
if (TypeEvent == 3) {
|
2869
|
+
is_rise_or_set = SE_CALC_SET;
|
2870
|
+
tret = tjdc - 3;
|
2871
|
+
if (ipl >= SE_MARS)
|
2872
|
+
tret = tjdc - 3;
|
2873
|
+
iter_day = 1;
|
2874
|
+
} else {
|
2875
|
+
is_rise_or_set = SE_CALC_RISE;
|
2876
|
+
tret = tjdc + 3;
|
2877
|
+
if (ipl >= SE_MARS)
|
2878
|
+
tret = tjdc + 3;
|
2879
|
+
iter_day = -1;
|
2880
|
+
}
|
2881
|
+
while (AltO < 0) {
|
2882
|
+
tret += 0.3 * iter_day;
|
2883
|
+
if (iter_day == -1)
|
2884
|
+
tret -= 1;
|
2885
|
+
retval = my_rise_trans(tret, SE_SUN, "", is_rise_or_set, helflag, dgeo, datm, &tret, serr);
|
2886
|
+
if (retval != OK)
|
2887
|
+
return retval;
|
2888
|
+
/* determine object's position */
|
2889
|
+
if (ipl == -1)
|
2890
|
+
retval = call_swe_fixstar(ObjectName, tret+swe_deltat(tret), iflag, x, serr);
|
2891
|
+
else
|
2892
|
+
retval = swe_calc(tret+swe_deltat(tret), ipl, iflag, x, serr);
|
2893
|
+
if (retval == ERR) return ERR;
|
2894
|
+
swe_azalt(tret, SE_EQU2HOR, dgeo, datm[0], datm[1], x, xaz);
|
2895
|
+
AltO = xaz[2];
|
2896
|
+
}
|
2897
|
+
*thel = tret;
|
2898
|
+
return OK;
|
2899
|
+
}
|
2900
|
+
#endif
|
2901
|
+
|
2902
|
+
static int32 time_optimum_visibility(double tjd, double *dgeo, double *datm, double *dobs, char *ObjectName, int32 helflag, double *tret, char *serr)
|
2903
|
+
{
|
2904
|
+
int32 retval, retval_sv, i;
|
2905
|
+
double d, vl, darr[10], phot_scot_opic, phot_scot_opic_sv;
|
2906
|
+
*tret = tjd;
|
2907
|
+
retval = swe_vis_limit_mag(tjd, dgeo, datm, dobs, ObjectName, helflag, darr, serr);
|
2908
|
+
if (retval == ERR) return ERR;
|
2909
|
+
retval_sv = retval;
|
2910
|
+
vl = darr[0] - darr[7];
|
2911
|
+
phot_scot_opic_sv = retval & SE_SCOTOPIC_FLAG;
|
2912
|
+
for (i = 0, d = 100.0 / 86400.0; i < 3; i++, d /= 10.0) {
|
2913
|
+
while((retval = swe_vis_limit_mag(tjd - d, dgeo, datm, dobs, ObjectName, helflag, darr, serr)) >= 0
|
2914
|
+
&& darr[0] > darr[7]
|
2915
|
+
&& darr[0] - darr[7] > vl) {
|
2916
|
+
tjd -= d; vl = darr[0] - darr[7];
|
2917
|
+
retval_sv = retval;
|
2918
|
+
phot_scot_opic_sv = retval & SE_SCOTOPIC_FLAG;
|
2919
|
+
/* printf("1: %f\n", darr[8]);*/
|
2920
|
+
}
|
2921
|
+
if (retval == ERR) return ERR;
|
2922
|
+
while((retval = swe_vis_limit_mag(tjd + d, dgeo, datm, dobs, ObjectName, helflag, darr, serr)) >= 0
|
2923
|
+
&& darr[0] > darr[7]
|
2924
|
+
&& darr[0] - darr[7] > vl) {
|
2925
|
+
tjd += d; vl = darr[0] - darr[7];
|
2926
|
+
retval_sv = retval;
|
2927
|
+
phot_scot_opic_sv = retval & SE_SCOTOPIC_FLAG;
|
2928
|
+
/* printf("2: %f\n", darr[8]);*/
|
2929
|
+
}
|
2930
|
+
if (retval == ERR) return ERR;
|
2931
|
+
}
|
2932
|
+
/* printf("3: %f <-> %f\n", darr[8], phot_scot_opic_sv);*/
|
2933
|
+
*tret = tjd;
|
2934
|
+
if (retval >= 0) {
|
2935
|
+
/* search for optimum came to an end because change scotopic/photopic: */
|
2936
|
+
phot_scot_opic = (retval & SE_SCOTOPIC_FLAG);
|
2937
|
+
if (phot_scot_opic_sv != phot_scot_opic) {
|
2938
|
+
/* calling function writes warning into serr */
|
2939
|
+
return -2;
|
2940
|
+
}
|
2941
|
+
/* valid result found but it is close to the scotopic/photopic limit */
|
2942
|
+
if (retval_sv & SE_MIXEDOPIC_FLAG) {
|
2943
|
+
return -2;
|
2944
|
+
}
|
2945
|
+
}
|
2946
|
+
return OK;
|
2947
|
+
}
|
2948
|
+
|
2949
|
+
static int32 time_limit_invisible(double tjd, double *dgeo, double *datm, double *dobs, char *ObjectName, int32 helflag, int32 direct, double *tret, char *serr)
|
2950
|
+
{
|
2951
|
+
int32 retval, retval_sv, i, ncnt = 3;
|
2952
|
+
double d = 0, darr[10], phot_scot_opic, phot_scot_opic_sv;
|
2953
|
+
double d0 = 100.0 / 86400.0, tjd_save;
|
2954
|
+
*tret = tjd;
|
2955
|
+
tjd_save = tjd;
|
2956
|
+
if (strcmp(ObjectName, "moon") == 0) {
|
2957
|
+
d0 *= 10;
|
2958
|
+
ncnt = 4;
|
2959
|
+
}
|
2960
|
+
retval = swe_vis_limit_mag(tjd + d * direct, dgeo, datm, dobs, ObjectName, helflag, darr, serr);
|
2961
|
+
if (retval == ERR) return ERR;
|
2962
|
+
retval_sv = retval;
|
2963
|
+
phot_scot_opic_sv = retval & SE_SCOTOPIC_FLAG;
|
2964
|
+
for (i = 0, d = d0; i < ncnt; i++, d /= 10.0) {
|
2965
|
+
while((retval = swe_vis_limit_mag(tjd + d * direct, dgeo, datm, dobs, ObjectName, helflag, darr, serr)) >= 0
|
2966
|
+
&& darr[0] > darr[7]) {
|
2967
|
+
tjd += d * direct;
|
2968
|
+
retval_sv = retval;
|
2969
|
+
phot_scot_opic_sv = retval & SE_SCOTOPIC_FLAG;
|
2970
|
+
/* printf("%d: %f\n", direct, darr[8]); */
|
2971
|
+
}
|
2972
|
+
}
|
2973
|
+
/* printf("4: %f, %f/%f %f <-> %f\n", darr[8], darr[0], darr[7], tjd, phot_scot_opic_sv); */
|
2974
|
+
*tret = tjd;
|
2975
|
+
/* if object disappears at setting, retval is -2, but we want it OK, and
|
2976
|
+
* also suppress the warning "object is below local horizon" */
|
2977
|
+
*serr = '\0';
|
2978
|
+
if (retval >= 0) {
|
2979
|
+
/* search for limit came to an end because change scotopic/photopic: */
|
2980
|
+
phot_scot_opic = (retval & SE_SCOTOPIC_FLAG);
|
2981
|
+
if (phot_scot_opic_sv != phot_scot_opic) {
|
2982
|
+
/* calling function writes warning into serr */
|
2983
|
+
return -2;
|
2984
|
+
}
|
2985
|
+
/* valid result found but it is close to the scotopic/photopic limit */
|
2986
|
+
if (retval_sv & SE_MIXEDOPIC_FLAG) {
|
2987
|
+
return -2;
|
2988
|
+
}
|
2989
|
+
}
|
2990
|
+
return OK;
|
2991
|
+
}
|
2992
|
+
|
2993
|
+
static int32 get_acronychal_day(double tjd, double *dgeo, double *datm, double *dobs, char *ObjectName, int32 helflag, int32 TypeEvent, double *thel, char *serr) {
|
2994
|
+
double tret, tret_dark, darr[30], dtret, dtret_save;
|
2995
|
+
/* x[6], xaz[6], alto, azio, alto_dark, azio_dark;*/
|
2996
|
+
int32 retval, is_rise_or_set, direct;
|
2997
|
+
int32 ipl = DeterObject(ObjectName);
|
2998
|
+
helflag |= SE_HELFLAG_VISLIM_PHOTOPIC;
|
2999
|
+
/*int32 epheflag = helflag & (SEFLG_JPLEPH|SEFLG_SWIEPH|SEFLG_MOSEPH);*/
|
3000
|
+
/* int32 iflag = epheflag | SEFLG_EQUATORIAL | SEFLG_TOPOCTR;*/
|
3001
|
+
if (TypeEvent == 3 || TypeEvent == 5) {
|
3002
|
+
is_rise_or_set = SE_CALC_RISE;
|
3003
|
+
/* tret = tjdc - 3;
|
3004
|
+
if (ipl >= SE_MARS)
|
3005
|
+
tret = tjdc - 3;*/
|
3006
|
+
direct = -1;
|
3007
|
+
} else {
|
3008
|
+
is_rise_or_set = SE_CALC_SET;
|
3009
|
+
/*tret = tjdc + 3;
|
3010
|
+
if (ipl >= SE_MARS)
|
3011
|
+
tret = tjdc + 3;*/
|
3012
|
+
direct = 1;
|
3013
|
+
}
|
3014
|
+
dtret = 999;
|
3015
|
+
#if 0
|
3016
|
+
while (fabs(dtret) > 0.5) {
|
3017
|
+
#else
|
3018
|
+
while (fabs(dtret) > 0.5 / 1440.0) {
|
3019
|
+
#endif
|
3020
|
+
tjd += 0.7 * direct;
|
3021
|
+
if (direct < 0) tjd -= 1;
|
3022
|
+
retval = my_rise_trans(tjd, ipl, ObjectName, is_rise_or_set, helflag, dgeo, datm, &tjd, serr);
|
3023
|
+
if (retval == ERR) return ERR;
|
3024
|
+
retval = swe_vis_limit_mag(tjd, dgeo, datm, dobs, ObjectName, helflag, darr, serr);
|
3025
|
+
while(darr[0] < darr[7]) {
|
3026
|
+
tjd += 10.0 / 1440.0 * -direct;
|
3027
|
+
retval = swe_vis_limit_mag(tjd, dgeo, datm, dobs, ObjectName, helflag, darr, serr);
|
3028
|
+
}
|
3029
|
+
retval = time_limit_invisible(tjd, dgeo, datm, dobs, ObjectName, helflag | SE_HELFLAG_VISLIM_DARK, direct, &tret_dark, serr);
|
3030
|
+
if (retval == ERR) return ERR;
|
3031
|
+
retval = time_limit_invisible(tjd, dgeo, datm, dobs, ObjectName, helflag | SE_HELFLAG_VISLIM_NOMOON, direct, &tret, serr);
|
3032
|
+
if (retval == ERR) return ERR;
|
3033
|
+
dtret_save = dtret;
|
3034
|
+
#if 0
|
3035
|
+
if (azalt_cart(tret_dark, dgeo, datm, ObjectName, helflag, darr, serr) == ERR)
|
3036
|
+
return ERR;
|
3037
|
+
if (azalt_cart(tret, dgeo, datm, ObjectName, helflag, darr+6, serr) == ERR)
|
3038
|
+
return ERR;
|
3039
|
+
dtret = acos(swi_dot_prod_unit(darr+3, darr+9)) / DEGTORAD;
|
3040
|
+
#else
|
3041
|
+
dtret = fabs(tret - tret_dark);
|
3042
|
+
#endif
|
3043
|
+
/*printf("dtret = %f - %f\n", dtret * 1440, fabs(dtret - dtret_save) * 1440);*/
|
3044
|
+
}
|
3045
|
+
if (azalt_cart(tret, dgeo, datm, "sun", helflag, darr, serr) == ERR)
|
3046
|
+
return ERR;
|
3047
|
+
*thel = tret;
|
3048
|
+
if (darr[1] < -12) {
|
3049
|
+
sprintf(serr, "acronychal rising/setting not available, %f", darr[1]);
|
3050
|
+
return OK;
|
3051
|
+
} else {
|
3052
|
+
sprintf(serr, "solar altitude, %f", darr[1]);
|
3053
|
+
}
|
3054
|
+
return OK;
|
3055
|
+
}
|
3056
|
+
|
3057
|
+
static int32 get_heliacal_details(double tday, double *dgeo, double *datm, double *dobs, char *ObjectName, int32 TypeEvent, int32 helflag, double *dret, char *serr)
|
3058
|
+
{
|
3059
|
+
int32 i, retval, direct;
|
3060
|
+
AS_BOOL optimum_undefined, limit_1_undefined, limit_2_undefined;
|
3061
|
+
/* find next optimum visibility */
|
3062
|
+
optimum_undefined = FALSE;
|
3063
|
+
retval = time_optimum_visibility(tday, dgeo, datm, dobs, ObjectName, helflag, &(dret[1]), serr);
|
3064
|
+
if (retval == ERR) return ERR;
|
3065
|
+
if (retval == -2) {
|
3066
|
+
retval = OK;
|
3067
|
+
optimum_undefined = TRUE; /* change photopic <-> scotopic vision */
|
3068
|
+
}
|
3069
|
+
/* find moment of becoming visible */
|
3070
|
+
direct = 1;
|
3071
|
+
if (TypeEvent == 1 || TypeEvent == 4)
|
3072
|
+
direct = -1;
|
3073
|
+
limit_1_undefined = FALSE;
|
3074
|
+
retval = time_limit_invisible(tday, dgeo, datm, dobs, ObjectName, helflag, direct, &(dret[0]), serr);
|
3075
|
+
if (retval == ERR) return ERR;
|
3076
|
+
if (retval == -2) {
|
3077
|
+
retval = OK;
|
3078
|
+
limit_1_undefined = TRUE; /* change photopic <-> scotopic vision */
|
3079
|
+
}
|
3080
|
+
/* find moment of end of visibility */
|
3081
|
+
direct *= -1;
|
3082
|
+
limit_2_undefined = FALSE;
|
3083
|
+
retval = time_limit_invisible(dret[1], dgeo, datm, dobs, ObjectName, helflag, direct, &(dret[2]), serr);
|
3084
|
+
if (retval == ERR) return ERR;
|
3085
|
+
if (retval == -2) {
|
3086
|
+
retval = OK;
|
3087
|
+
limit_2_undefined = TRUE; /* change photopic <-> scotopic vision */
|
3088
|
+
}
|
3089
|
+
/* correct sequence of times:
|
3090
|
+
* with event types 2 and 3 swap dret[0] and dret[2] */
|
3091
|
+
if (TypeEvent == 2 || TypeEvent == 3) {
|
3092
|
+
tday = dret[2];
|
3093
|
+
dret[2] = dret[0];
|
3094
|
+
dret[0] = tday;
|
3095
|
+
i = (int) limit_1_undefined;
|
3096
|
+
limit_1_undefined = limit_2_undefined;
|
3097
|
+
limit_2_undefined = (AS_BOOL) i;
|
3098
|
+
}
|
3099
|
+
/*if (retval == OK && dret[0] == dret[1]) */
|
3100
|
+
if (optimum_undefined || limit_1_undefined || limit_2_undefined) {
|
3101
|
+
sprintf(serr, "return values [");
|
3102
|
+
if (limit_1_undefined)
|
3103
|
+
strcat(serr, "0,");
|
3104
|
+
if (optimum_undefined)
|
3105
|
+
strcat(serr, "1,");
|
3106
|
+
if (limit_2_undefined)
|
3107
|
+
strcat(serr, "2,");
|
3108
|
+
strcat(serr, "] are uncertain due to change between photopic and scotopic vision");
|
3109
|
+
}
|
3110
|
+
return OK;
|
3111
|
+
}
|
3112
|
+
|
3113
|
+
static int32 heliacal_ut_vis_lim(double tjd_start, double *dgeo, double *datm, double *dobs, char *ObjectName, int32 TypeEventIn, int32 helflag, double *dret, char *serr_ret)
|
3114
|
+
{
|
3115
|
+
int i;
|
3116
|
+
double d, darr[10], direct = 1, tjd, tday;
|
3117
|
+
int32 epheflag, retval = OK, helflag2;
|
3118
|
+
int32 iflag, ipl;
|
3119
|
+
int32 TypeEvent = TypeEventIn;
|
3120
|
+
char serr[AS_MAXCH];
|
3121
|
+
for (i = 0; i < 10; i++)
|
3122
|
+
dret[i] = 0;
|
3123
|
+
*dret = tjd_start;
|
3124
|
+
*serr = '\0';
|
3125
|
+
ipl = DeterObject(ObjectName);
|
3126
|
+
epheflag = helflag & (SEFLG_JPLEPH|SEFLG_SWIEPH|SEFLG_MOSEPH);
|
3127
|
+
iflag = SEFLG_TOPOCTR | SEFLG_EQUATORIAL | epheflag;
|
3128
|
+
if (!(helflag & SE_HELFLAG_HIGH_PRECISION))
|
3129
|
+
iflag |= SEFLG_NONUT | SEFLG_TRUEPOS;
|
3130
|
+
if (ipl == SE_MERCURY)
|
3131
|
+
tjd = tjd_start - 30;
|
3132
|
+
else
|
3133
|
+
tjd = tjd_start - 50; /* -50 makes sure, that no event is missed,
|
3134
|
+
* but may return an event before start date */
|
3135
|
+
helflag2 = helflag;
|
3136
|
+
/*helflag2 &= ~SE_HELFLAG_HIGH_PRECISION;*/
|
3137
|
+
/*
|
3138
|
+
* heliacal event
|
3139
|
+
*/
|
3140
|
+
if (ipl == SE_MERCURY || ipl == SE_VENUS || TypeEvent <= 2) {
|
3141
|
+
if (ipl == -1) {
|
3142
|
+
/* find date when star rises with sun (cosmic rising) */
|
3143
|
+
retval = get_asc_obl_with_sun(tjd, ipl, ObjectName, helflag, TypeEvent, 0, dgeo, &tjd, serr);
|
3144
|
+
if (retval != OK)
|
3145
|
+
goto swe_heliacal_err; /* retval may be -2 or ERR */
|
3146
|
+
} else {
|
3147
|
+
/* find date of conjunction of object with sun */
|
3148
|
+
if ((retval = find_conjunct_sun(tjd, ipl, helflag, TypeEvent, &tjd, serr)) == ERR)
|
3149
|
+
goto swe_heliacal_err;
|
3150
|
+
}
|
3151
|
+
/* find the day and minute on which the object becomes visible */
|
3152
|
+
retval = get_heliacal_day(tjd, dgeo, datm, dobs, ObjectName, helflag2, TypeEvent, &tday, serr);
|
3153
|
+
if (retval != OK)
|
3154
|
+
goto swe_heliacal_err;
|
3155
|
+
/*
|
3156
|
+
* acronychal event
|
3157
|
+
*/
|
3158
|
+
} else {
|
3159
|
+
if (1 || ipl == -1) {
|
3160
|
+
/*retval = get_asc_obl_acronychal(tjd, ipl, ObjectName, helflag2, TypeEvent, dgeo, &tjd, serr);*/
|
3161
|
+
retval = get_asc_obl_with_sun(tjd, ipl, ObjectName, helflag, TypeEvent, 0, dgeo, &tjd, serr);
|
3162
|
+
if (retval != OK)
|
3163
|
+
goto swe_heliacal_err;
|
3164
|
+
} else {
|
3165
|
+
/* find date of conjunction of object with sun */
|
3166
|
+
if ((retval = find_conjunct_sun(tjd, ipl, helflag, TypeEvent, &tjd, serr)) == ERR)
|
3167
|
+
goto swe_heliacal_err;
|
3168
|
+
}
|
3169
|
+
tday = tjd;
|
3170
|
+
retval = get_acronychal_day(tjd, dgeo, datm, dobs, ObjectName, helflag2, TypeEvent, &tday, serr);
|
3171
|
+
if (retval != OK)
|
3172
|
+
goto swe_heliacal_err;
|
3173
|
+
}
|
3174
|
+
dret[0] = tday;
|
3175
|
+
if (!(helflag & SE_HELFLAG_NO_DETAILS)) {
|
3176
|
+
/* more precise event times for
|
3177
|
+
* - morning first, evening last
|
3178
|
+
* - venus and mercury's evening first and morning last
|
3179
|
+
*/
|
3180
|
+
if (ipl == SE_MERCURY || ipl == SE_VENUS || TypeEvent <= 2) {
|
3181
|
+
retval = get_heliacal_details(tday, dgeo, datm, dobs, ObjectName, TypeEvent, helflag2, dret, serr);
|
3182
|
+
if (retval == ERR) goto swe_heliacal_err;
|
3183
|
+
} else if (0) {
|
3184
|
+
if (TypeEvent == 4 || TypeEvent == 6) direct = -1;
|
3185
|
+
for (i = 0, d = 100.0 / 86400.0; i < 3; i++, d /= 10.0) {
|
3186
|
+
while((retval = swe_vis_limit_mag(*dret + d * direct, dgeo, datm, dobs, ObjectName, helflag, darr, serr)) == -2 || (retval >= 0 && darr[0] < darr[7])) {
|
3187
|
+
*dret += d * direct;
|
3188
|
+
}
|
3189
|
+
}
|
3190
|
+
/* the last time step must be added */
|
3191
|
+
if (retval == OK)
|
3192
|
+
*dret += 1.0 / 86400.0 * direct;
|
3193
|
+
}
|
3194
|
+
} /* if (1) */
|
3195
|
+
swe_heliacal_err:
|
3196
|
+
if (serr_ret != NULL && *serr != '\0')
|
3197
|
+
strcpy(serr_ret, serr);
|
3198
|
+
return retval;
|
3199
|
+
}
|
3200
|
+
|
3201
|
+
/*###################################################################*/
|
3202
|
+
static int32 moon_event_vis_lim(double tjdstart, double *dgeo, double *datm, double *dobs, int32 TypeEvent, int32 helflag, double *dret, char *serr_ret)
|
3203
|
+
{
|
3204
|
+
double tjd, trise;
|
3205
|
+
char serr[AS_MAXCH];
|
3206
|
+
char ObjectName[30];
|
3207
|
+
int32 iflag, Daystep, eventtype, ipl, retval, helflag2, direct;
|
3208
|
+
int32 epheflag = helflag & (SEFLG_JPLEPH|SEFLG_SWIEPH|SEFLG_MOSEPH);
|
3209
|
+
dret[0] = tjdstart; /* will be returned in error case */
|
3210
|
+
if (TypeEvent == 1 || TypeEvent == 2) {
|
3211
|
+
if (serr != NULL)
|
3212
|
+
strcpy(serr, "error: the moon has no morning first or evening last");
|
3213
|
+
return ERR;
|
3214
|
+
}
|
3215
|
+
strcpy(ObjectName, "moon");
|
3216
|
+
ipl = SE_MOON;
|
3217
|
+
iflag = SEFLG_TOPOCTR | SEFLG_EQUATORIAL | epheflag;
|
3218
|
+
if (!(helflag & SE_HELFLAG_HIGH_PRECISION))
|
3219
|
+
iflag |= SEFLG_NONUT|SEFLG_TRUEPOS;
|
3220
|
+
helflag2 = helflag;
|
3221
|
+
helflag2 &= ~SE_HELFLAG_HIGH_PRECISION;
|
3222
|
+
Daystep = 1;
|
3223
|
+
eventtype = TypeEvent + SE_BIT_DISC_CENTER;
|
3224
|
+
/* check Synodic/phase Period */
|
3225
|
+
tjd = tjdstart - 30; /* -50 makes sure, that no event is missed,
|
3226
|
+
* but may return an event before start date */
|
3227
|
+
if ((retval = find_conjunct_sun(tjd, ipl, helflag, TypeEvent, &tjd, serr)) == ERR)
|
3228
|
+
return ERR;
|
3229
|
+
/* find the day and minute on which the object becomes visible */
|
3230
|
+
retval = get_heliacal_day(tjd, dgeo, datm, dobs, ObjectName, helflag2, TypeEvent, &tjd, serr);
|
3231
|
+
if (retval != OK)
|
3232
|
+
goto moon_event_err;
|
3233
|
+
dret[0] = tjd;
|
3234
|
+
/* find next optimum visibility */
|
3235
|
+
retval = time_optimum_visibility(tjd, dgeo, datm, dobs, ObjectName, helflag, &tjd, serr);
|
3236
|
+
if (retval == ERR) goto moon_event_err;
|
3237
|
+
dret[1] = tjd;
|
3238
|
+
/* find moment of becoming visible */
|
3239
|
+
/* Note: The on the day of fist light the moon may become visible
|
3240
|
+
* already during day. It also may appear during day, disappear again
|
3241
|
+
* and then reappear after sunset */
|
3242
|
+
direct = 1;
|
3243
|
+
if (TypeEvent == 4)
|
3244
|
+
direct = -1;
|
3245
|
+
retval = time_limit_invisible(tjd, dgeo, datm, dobs, ObjectName, helflag, direct, &tjd, serr);
|
3246
|
+
if (retval == ERR) goto moon_event_err;
|
3247
|
+
dret[2] = tjd;
|
3248
|
+
/* find moment of end of visibility */
|
3249
|
+
direct *= -1;
|
3250
|
+
retval = time_limit_invisible(dret[1], dgeo, datm, dobs, ObjectName, helflag, direct, &tjd, serr);
|
3251
|
+
dret[0] = tjd;
|
3252
|
+
if (retval == ERR) goto moon_event_err;
|
3253
|
+
/* if the moon is visible before sunset, we return sunset as start time */
|
3254
|
+
if (TypeEvent == 3) {
|
3255
|
+
if ((retval = my_rise_trans(tjd, SE_SUN, "", SE_CALC_SET, helflag, dgeo, datm, &trise, serr)) == ERR)
|
3256
|
+
return ERR;
|
3257
|
+
if (trise < dret[1]) {
|
3258
|
+
dret[0] = trise;
|
3259
|
+
/* do not warn, it happens too often */
|
3260
|
+
/*strcpy(serr, "start time given is sunset, but moon is observable before that");*/
|
3261
|
+
}
|
3262
|
+
/* if the moon is visible after sunrise, we return sunrise as end time */
|
3263
|
+
} else {
|
3264
|
+
if ((retval = my_rise_trans(dret[1], SE_SUN, "", SE_CALC_RISE, helflag, dgeo, datm, &trise, serr)) == ERR)
|
3265
|
+
return ERR;
|
3266
|
+
if (dret[0] > trise) {
|
3267
|
+
dret[0] = trise;
|
3268
|
+
/* do not warn, it happens too often */
|
3269
|
+
/*strcpy(serr, "end time given is sunrise, but moon is observable after that");*/
|
3270
|
+
}
|
3271
|
+
}
|
3272
|
+
/* correct order of the three times: */
|
3273
|
+
if (TypeEvent == 4) {
|
3274
|
+
tjd = dret[0];
|
3275
|
+
dret[0] = dret[2];
|
3276
|
+
dret[2] = tjd;
|
3277
|
+
}
|
3278
|
+
moon_event_err:
|
3279
|
+
if (serr_ret != NULL && *serr != '\0')
|
3280
|
+
strcpy(serr_ret, serr);
|
3281
|
+
return retval;
|
3282
|
+
}
|
3283
|
+
|
3284
|
+
static int32 MoonEventJDut(double JDNDaysUTStart, double *dgeo, double *datm, double *dobs, int32 TypeEvent, int32 helflag, double *dret, char *serr)
|
3285
|
+
{
|
3286
|
+
int32 avkind = helflag & SE_HELFLAG_AVKIND;
|
3287
|
+
if (avkind)
|
3288
|
+
return moon_event_arc_vis(JDNDaysUTStart, dgeo, datm, dobs, TypeEvent, helflag, dret, serr);
|
3289
|
+
else
|
3290
|
+
return moon_event_vis_lim(JDNDaysUTStart, dgeo, datm, dobs, TypeEvent, helflag, dret, serr);
|
3291
|
+
}
|
3292
|
+
|
3293
|
+
static int32 heliacal_ut(double JDNDaysUTStart, double *dgeo, double *datm, double *dobs, char *ObjectName, int32 TypeEventIn, int32 helflag, double *dret, char *serr_ret)
|
3294
|
+
{
|
3295
|
+
int32 avkind = helflag & SE_HELFLAG_AVKIND;
|
3296
|
+
if (avkind)
|
3297
|
+
return heliacal_ut_arc_vis(JDNDaysUTStart, dgeo, datm, dobs, ObjectName, TypeEventIn, helflag, dret, serr_ret);
|
3298
|
+
else
|
3299
|
+
return heliacal_ut_vis_lim(JDNDaysUTStart, dgeo, datm, dobs, ObjectName, TypeEventIn, helflag, dret, serr_ret);
|
3300
|
+
}
|
3301
|
+
|
3302
|
+
/*' Magn [-]
|
3303
|
+
' tjd_ut start date (JD) for event search
|
3304
|
+
' dgeo[3] geogr. longitude, latitude, eye height (m above sea level)
|
3305
|
+
' datm[4] atm. pressure, temperature, RH, and VR
|
3306
|
+
' - pressure atmospheric pressure (mbar, =hPa) default 1013.25hPa
|
3307
|
+
' - temperature deg C, default 15 deg C (if at
|
3308
|
+
' If both attemp and atpress are 0, a temperature and
|
3309
|
+
' atmospheric pressure are estimated from the above-mentioned
|
3310
|
+
' default values and the height above sea level.
|
3311
|
+
' - RH relative humidity in %
|
3312
|
+
' - VR VR>=1: the Meteorological range: default 40 km
|
3313
|
+
' 1>VR>0: the ktot (so the total atmospheric coefficient):
|
3314
|
+
' a good default would be 0.25
|
3315
|
+
' VR=-1: the ktot is calculated from the other atmospheric
|
3316
|
+
' constants.
|
3317
|
+
' age [Year] default 36, experienced sky observer in ancient times
|
3318
|
+
' optimum age is 23
|
3319
|
+
' SN Snellen factor of the visual aquity of the observer
|
3320
|
+
' default 1
|
3321
|
+
' see: http://www.i-see.org/eyecharts.html#make-your-own
|
3322
|
+
' TypeEvent 1 morning first
|
3323
|
+
' 2 evening last
|
3324
|
+
' 3 evening first
|
3325
|
+
' 4 morning last
|
3326
|
+
' dret output: time (tjd_ut) of heliacal event
|
3327
|
+
' see http://www.iol.ie/~geniet/eng/atmoastroextinction.htm
|
3328
|
+
*/
|
3329
|
+
int32 FAR PASCAL_CONV swe_heliacal_ut(double JDNDaysUTStart, double *dgeo, double *datm, double *dobs, char *ObjectNameIn, int32 TypeEvent, int32 helflag, double *dret, char *serr_ret)
|
3330
|
+
{
|
3331
|
+
int32 retval, Planet, itry;
|
3332
|
+
char ObjectName[AS_MAXCH], serr[AS_MAXCH], s[AS_MAXCH];
|
3333
|
+
double tjd0 = JDNDaysUTStart, tjd, dsynperiod, tjdmax, tadd;
|
3334
|
+
int32 MaxCountSynodicPeriod = MAX_COUNT_SYNPER;
|
3335
|
+
char *sevent[7] = {"", "morning first", "evening last", "evening first", "morning last", "acronychal rising", "acronychal setting"};
|
3336
|
+
if (helflag & SE_HELFLAG_LONG_SEARCH)
|
3337
|
+
MaxCountSynodicPeriod = MAX_COUNT_SYNPER_MAX;
|
3338
|
+
/* if (helflag & SE_HELFLAG_SEARCH_1_PERIOD)
|
3339
|
+
MaxCountSynodicPeriod = 1; */
|
3340
|
+
*serr = '\0';
|
3341
|
+
if (serr_ret != NULL)
|
3342
|
+
*serr_ret = '\0';
|
3343
|
+
/* note, the fixed stars functions rewrite the star name. The input string
|
3344
|
+
may be too short, so we have to make sure we have enough space */
|
3345
|
+
strcpy_VBsafe(ObjectName, ObjectNameIn);
|
3346
|
+
default_heliacal_parameters(datm, dgeo, dobs, helflag);
|
3347
|
+
swe_set_topo(dgeo[0], dgeo[1], dgeo[2]);
|
3348
|
+
Planet = DeterObject(ObjectName);
|
3349
|
+
/*
|
3350
|
+
* Moon events
|
3351
|
+
*/
|
3352
|
+
if (Planet == SE_MOON) {
|
3353
|
+
if (TypeEvent == 1 || TypeEvent == 2) {
|
3354
|
+
if (serr_ret != NULL)
|
3355
|
+
sprintf(serr_ret, "%s (event type %d) does not exist for the moon\n", sevent[TypeEvent], TypeEvent);
|
3356
|
+
return ERR;
|
3357
|
+
}
|
3358
|
+
tjd = tjd0;
|
3359
|
+
retval = MoonEventJDut(tjd, dgeo, datm, dobs, TypeEvent, helflag, dret, serr);
|
3360
|
+
while (retval != -2 && *dret < tjd0) {
|
3361
|
+
tjd += 15;
|
3362
|
+
*serr = '\0';
|
3363
|
+
retval = MoonEventJDut(tjd, dgeo, datm, dobs, TypeEvent, helflag, dret, serr);
|
3364
|
+
}
|
3365
|
+
if (serr_ret != NULL && *serr != '\0')
|
3366
|
+
strcpy(serr_ret, serr);
|
3367
|
+
return retval;
|
3368
|
+
}
|
3369
|
+
/*
|
3370
|
+
* planets and fixed stars
|
3371
|
+
*/
|
3372
|
+
if (!(helflag & SE_HELFLAG_AVKIND)) {
|
3373
|
+
if (Planet == -1 || Planet >= SE_MARS) {
|
3374
|
+
if (TypeEvent == 3 || TypeEvent == 4) {
|
3375
|
+
if (serr_ret != NULL) {
|
3376
|
+
if (Planet == -1)
|
3377
|
+
strcpy(s, ObjectName);
|
3378
|
+
else
|
3379
|
+
swe_get_planet_name(Planet, s);
|
3380
|
+
sprintf(serr_ret, "%s (event type %d) does not exist for %s\n", sevent[TypeEvent], TypeEvent, s);
|
3381
|
+
}
|
3382
|
+
return ERR;
|
3383
|
+
}
|
3384
|
+
}
|
3385
|
+
}
|
3386
|
+
/* arcus visionis method: set the TypeEvent for acronychal events */
|
3387
|
+
if (helflag & SE_HELFLAG_AVKIND) {
|
3388
|
+
if (Planet == -1 || Planet >= SE_MARS) {
|
3389
|
+
if (TypeEvent == SE_ACRONYCHAL_RISING)
|
3390
|
+
TypeEvent = 3;
|
3391
|
+
if (TypeEvent == SE_ACRONYCHAL_SETTING)
|
3392
|
+
TypeEvent = 4;
|
3393
|
+
}
|
3394
|
+
/* acronychal rising and setting (cosmic setting) are ill-defined.
|
3395
|
+
* We do not calculate them with the "visibility limit method" */
|
3396
|
+
} else if (1) {
|
3397
|
+
if (TypeEvent == SE_ACRONYCHAL_RISING || TypeEvent == SE_ACRONYCHAL_SETTING) {
|
3398
|
+
if (serr_ret != NULL) {
|
3399
|
+
if (Planet == -1)
|
3400
|
+
strcpy(s, ObjectName);
|
3401
|
+
else
|
3402
|
+
swe_get_planet_name(Planet, s);
|
3403
|
+
sprintf(serr_ret, "%s (event type %d) is not provided for %s\n", sevent[TypeEvent], TypeEvent, s);
|
3404
|
+
}
|
3405
|
+
return ERR;
|
3406
|
+
}
|
3407
|
+
}
|
3408
|
+
dsynperiod = get_synodic_period(Planet);
|
3409
|
+
tjdmax = tjd0 + dsynperiod * MaxCountSynodicPeriod;
|
3410
|
+
tadd = dsynperiod * 0.6;
|
3411
|
+
if (Planet == SE_MERCURY)
|
3412
|
+
tadd = 30;
|
3413
|
+
/*
|
3414
|
+
* this is the outer loop over n synodic periods
|
3415
|
+
*/
|
3416
|
+
tjd = tjd0;
|
3417
|
+
retval = -2; /* indicates that another synodic period has to be done */
|
3418
|
+
for (itry = 0;
|
3419
|
+
tjd < tjdmax && retval == -2;
|
3420
|
+
itry++, tjd += tadd) {
|
3421
|
+
*serr = '\0';
|
3422
|
+
retval = heliacal_ut(tjd, dgeo, datm, dobs, ObjectName, TypeEvent, helflag, dret, serr);
|
3423
|
+
/* if resulting event date < start date for search (tjd0): retry starting
|
3424
|
+
* from half a period later. The event must be found now, unless there
|
3425
|
+
* is none, as is often the case with Mercury */
|
3426
|
+
while (retval != -2 && *dret < tjd0) {
|
3427
|
+
tjd += tadd;
|
3428
|
+
*serr = '\0';
|
3429
|
+
retval = heliacal_ut(tjd, dgeo, datm, dobs, ObjectName, TypeEvent, helflag, dret, serr);
|
3430
|
+
}
|
3431
|
+
}
|
3432
|
+
/*
|
3433
|
+
* no event was found within MaxCountSynodicPeriod, return error
|
3434
|
+
*/
|
3435
|
+
if ((helflag & SE_HELFLAG_SEARCH_1_PERIOD) && (retval == -2 || dret[0] > tjd0 + dsynperiod * 1.5)) {
|
3436
|
+
strcpy(serr, "no heliacal date found within this synodic period");
|
3437
|
+
retval = -2;
|
3438
|
+
} else if (retval == -2) {
|
3439
|
+
sprintf(serr, "no heliacal date found within %d synodic periods", MaxCountSynodicPeriod);
|
3440
|
+
retval = ERR;
|
3441
|
+
}
|
3442
|
+
if (serr_ret != NULL && *serr != '\0')
|
3443
|
+
strcpy(serr_ret, serr);
|
3444
|
+
return retval;
|
3445
|
+
}
|