/[projects]/dao/DelphiScanner/Components/tpsystools_4.04/source/StEclpse.pas
ViewVC logotype

Contents of /dao/DelphiScanner/Components/tpsystools_4.04/source/StEclpse.pas

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2671 - (show annotations) (download)
Tue Aug 25 18:15:15 2015 UTC (8 years, 9 months ago) by torben
File size: 22930 byte(s)
Added tpsystools component
1 // Upgraded to Delphi 2009: Sebastian Zierer
2
3 (* ***** BEGIN LICENSE BLOCK *****
4 * Version: MPL 1.1
5 *
6 * The contents of this file are subject to the Mozilla Public License Version
7 * 1.1 (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 * http://www.mozilla.org/MPL/
10 *
11 * Software distributed under the License is distributed on an "AS IS" basis,
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 * for the specific language governing rights and limitations under the
14 * License.
15 *
16 * The Original Code is TurboPower SysTools
17 *
18 * The Initial Developer of the Original Code is
19 * TurboPower Software
20 *
21 * Portions created by the Initial Developer are Copyright (C) 1996-2002
22 * the Initial Developer. All Rights Reserved.
23 *
24 * Contributor(s):
25 *
26 * ***** END LICENSE BLOCK ***** *)
27
28 {*********************************************************}
29 {* SysTools: StEclpse.pas 4.04 *}
30 {*********************************************************}
31 {* SysTools: Lunar/Solar Eclipses *}
32 {*********************************************************}
33
34 {$I StDefine.inc}
35
36 { ************************************************************** }
37 { Sources: }
38 { 1. Astronomical Algorithms, Jean Meeus, Willmann-Bell, 1991. }
39 { }
40 { 2. Planetary and Lunar Coordinates (1984-2000), U.S. Govt, }
41 { 1983. }
42 { }
43 { 3. Supplement to the American Ephemeris and Nautical Almanac,}
44 { U.S. Govt, 1964. }
45 { }
46 { 4. MPO96-98 source files, Brian D. Warner, 1995-98. }
47 { }
48 { ************************************************************** }
49
50
51 unit StEclpse;
52
53 interface
54
55 uses
56 {$IFDEF UseMathUnit} Math, {$ENDIF}
57 StBase, StList, StDate, StAstro, StMath;
58
59 type
60 TStEclipseType = (etLunarPenumbral, etLunarPartial, etLunarTotal,
61 etSolarPartial, etSolarAnnular, etSolarTotal,
62 etSolarAnnularTotal);
63
64 TStHemisphereType = (htNone, htNorthern, htSouthern);
65
66 TStContactTimes = packed record
67 UT1, {start of lunar penumbral phase}
68 UT2, {end of lunar penumbral phase}
69 FirstContact, {start of partial eclipse}
70 SecondContact, {start of totality}
71 MidEclipse, {mid-eclipse}
72 ThirdContact, {end of totality}
73 FourthContact : TDateTime; {end of partial phase}
74 end;
75
76 TStLongLat = packed record
77 JD : TDateTime;
78 Longitude,
79 Latitude,
80 Duration : Double;
81 end;
82 PStLongLat = ^TStLongLat;
83
84 TStEclipseRecord = packed record
85 EType : TStEclipseType; {type of Eclipse}
86 Magnitude : Double; {magnitude of eclipse}
87 Hemisphere : TStHemisphereType; {favored hemisphere - solar}
88 LContacts : TStContactTimes; {Universal Times of critical points}
89 { in lunar eclipses}
90 Path : TStList; {longitude/latitude of moon's shadow}
91 end; { during solar eclipse}
92 PStEclipseRecord = ^TStEclipseRecord;
93
94 TStBesselianRecord = packed record
95 JD : TDateTime;
96 Delta,
97 Angle,
98 XAxis,
99 YAxis,
100 L1,
101 L2 : Double;
102 end;
103
104 TStEclipses = class(TStList)
105 {.Z+}
106 protected {private}
107 FBesselianElements : array[1..25] of TStBesselianRecord;
108 F0,
109 FUPrime,
110 FDPrime : Double;
111
112 function GetEclipse(Idx : longint) : PStEclipseRecord;
113 procedure CentralEclipseTime(JD, K, J2,
114 SunAnom, MoonAnom,
115 ArgLat, AscNode, EFac : Double;
116 var F1, A1, CentralTime : Double);
117 procedure CheckForEclipse(K : Double);
118 procedure TotalLunarEclipse(CentralJD, MoonAnom, Mu,
119 PMag, UMag, Gamma : Double);
120 procedure PartialLunarEclipse(CentralJD, MoonAnom, Mu,
121 PMag, UMag, Gamma : Double);
122 procedure PenumbralLunarEclipse(CentralJD, MoonAnom, Mu,
123 PMag, UMag, Gamma : Double);
124
125 procedure GetBesselianElements(CentralJD : Double);
126 procedure GetShadowPath(I1, I2 : Integer; Path : TStList);
127 procedure NonPartialSolarEclipse(CentralJD, Mu, Gamma : Double);
128 procedure PartialSolarEclipse(CentralJD, Mu, Gamma : Double);
129 {.Z-}
130 public
131 constructor Create(NodeClass : TStNodeClass);
132 override;
133 procedure FindEclipses(Year : integer);
134
135 property Eclipses[Idx : longint] : PStEclipseRecord
136 read GetEclipse;
137 end;
138
139
140 implementation
141
142 procedure DisposePathData(Data : Pointer); far;
143 begin
144 Dispose(PStLongLat(Data));
145 end;
146
147 procedure DisposeEclipseRecord(Data : Pointer); far;
148 var
149 EcData : TStEclipseRecord;
150 begin
151 EcData := TStEclipseRecord(Data^);
152 if (Assigned(EcData.Path)) then
153 EcData.Path.Free;
154 Dispose(PStEclipseRecord(Data));
155 end;
156
157 constructor TStEclipses.Create(NodeClass : TStNodeClass);
158 begin
159 inherited Create(NodeClass);
160
161 DisposeData := DisposeEclipseRecord;
162 end;
163
164 function TStEclipses.GetEclipse(Idx : longint) : PStEclipseRecord;
165 begin
166 if (Idx < 0) or (Idx > pred(Count)) then
167 Result := nil
168 else
169 Result := PStEclipseRecord(Items[Idx].Data);
170 end;
171
172 procedure TStEclipses.FindEclipses(Year : integer);
173 var
174 K,
175 MeanJD,
176 JDofFirst,
177 JDofLast : Double;
178
179 begin
180 JDofFirst := AstJulianDatePrim(Year, 1, 1, 0);
181 JDofLast := AstJulianDatePrim(Year, 12, 31, pred(SecondsInDay));
182 K := Int((Year - 2000) * 12.3685 - 1);
183 repeat
184 MeanJD := 2451550.09765 + 29.530588853 * K;
185 if (MeanJD < JDofFirst) then
186 K := K + 0.5;
187 until (MeanJD >= JDofFirst);
188
189 while (MeanJD < JDofLast) do begin
190 CheckForEclipse(K);
191 K := K + 0.5;
192 MeanJD := 2451550.09765 + 29.530588853 * K;
193 end;
194 end;
195
196 procedure TStEclipses.CentralEclipseTime(JD, K, J2,
197 SunAnom, MoonAnom,
198 ArgLat, AscNode, EFac : Double;
199 var F1, A1, CentralTime : Double);
200 {the mean error of this routine is 0.36 minutes in a test between}
201 {1951 through 2050 with a maximum of 1.1 - Meeus}
202 begin
203 F1 := ArgLat - (0.02665/radcor) * sin(AscNode);
204 A1 := (299.77/radcor)
205 + (0.107408/radcor) * K
206 - (0.009173/radcor) * J2;
207
208 if (Frac(K) > 0.1) then
209 {correction at Full Moon - Lunar eclipse}
210 CentralTime := JD
211 - 0.4065 * sin(MoonAnom)
212 + 0.1727 * EFac * sin(SunAnom)
213 else
214 {correction at New Moon - solar eclipse}
215 CentralTime := JD
216 - 0.4075 * sin(MoonAnom)
217 + 0.1721 * EFac * sin(SunAnom);
218
219 CentralTime := CentralTime
220 + 0.0161 * sin(2 * MoonAnom)
221 - 0.0097 * sin(2 * F1)
222 + 0.0073 * sin(MoonAnom - SunAnom) * EFac
223 - 0.0050 * sin(MoonAnom + SunAnom) * EFac
224 - 0.0023 * sin(MoonAnom - 2*F1)
225 + 0.0021 * sin(2*SunAnom) * EFac
226 + 0.0012 * sin(MoonAnom + 2*F1)
227 + 0.0006 * sin(2*MoonAnom + SunAnom) * EFac
228 - 0.0004 * sin(3*MoonAnom)
229 - 0.0003 * sin(SunAnom + 2*F1) * EFac
230 + 0.0003 * sin(A1)
231 - 0.0002 * sin(SunAnom - 2*F1) * EFac
232 - 0.0002 * sin(2*MoonAnom - SunAnom) * EFac
233 - 0.0002 * sin(AscNode);
234 end;
235
236 procedure TStEclipses.CheckForEclipse(K : Double);
237 var
238 MeanJD,
239 J1, J2, J3,
240 PMag, UMag,
241 CentralJD,
242 SunAnom,
243 MoonAnom,
244 ArgLat,
245 AscNode,
246 EFac,
247 DeltaT,
248 F1, A1,
249 P, Q, W,
250 Gamma, Mu : Double;
251 begin
252 {compute Julian Centuries}
253 J1 := K / 1236.85;
254 J2 := Sqr(J1);
255 J3 := J2 * J1;
256
257 {mean Julian Date for phase}
258 MeanJD := 2451550.09765
259 + 29.530588853 * K
260 + 0.0001337 * J2
261 - 0.000000150 * J3
262 + 0.00000000073 * J2 * J2;
263
264 {solar mean anomaly}
265 SunAnom := 2.5534
266 + 29.1053569 * K
267 - 0.0000218 * J2
268 - 0.00000011 * J3;
269 SunAnom := Frac(SunAnom / 360.0) * 360;
270 if (SunAnom < 0) then
271 SunAnom := SunAnom + 360.0;
272
273 {lunar mean anomaly}
274 MoonAnom := 201.5643
275 + 385.81693528 * K
276 + 0.0107438 * J2
277 + 0.00001239 * J3
278 - 0.000000058 * J2 * J2;
279 MoonAnom := Frac(MoonAnom / 360.0) * 360;
280 if (MoonAnom < 0) then
281 MoonAnom := MoonAnom + 360.0;
282
283 {lunar argument of latitude}
284 ArgLat := 160.7108
285 + 390.67050274 * K
286 - 0.0016341 * J2
287 - 0.00000227 * J3
288 + 0.000000011 * J2 * J2;
289 ArgLat := Frac(ArgLat / 360.0) * 360;
290 if (ArgLat < 0) then
291 ArgLat := ArgLat + 360.0;
292
293 {lunar ascending node}
294 AscNode := 124.7746
295 - 1.56375580 * K
296 + 0.0020691 * J2
297 + 0.00000215 * J3;
298 AscNode := Frac(AscNode / 360.0) * 360;
299 if (AscNode < 0) then
300 AscNode := AscNode + 360.0;
301
302 {convert to radians}
303 SunAnom := SunAnom/radcor;
304 MoonAnom := MoonAnom/radcor;
305 ArgLat := ArgLat/radcor;
306 AscNode := AscNode/radcor;
307
308 {correction factor}
309 EFac := 1.0 - 0.002516 * J1 - 0.0000074 * J2;
310
311 {if AscNode > 21 deg. from 0 or 180 then no eclipse}
312 if (abs(sin(ArgLat)) > (sin(21.0/radcor))) then Exit;
313
314 {there is probably an eclipse - what kind? when?}
315
316 CentralEclipseTime(MeanJD, K, J2, SunAnom, MoonAnom,
317 ArgLat, AscNode, EFac,
318 F1, A1, CentralJD);
319
320 {Central JD is in Dynamical Time. Sun/Moon Positions are based on UT}
321 {An APPROXIMATE conversion is made to UT. This has limited accuracy}
322
323 DeltaT := (-15 + (sqr(CentralJD - 2382148) / 41048480)) / 86400;
324 CentralJD := CentralJD - DeltaT;
325
326 P := 0.2070 * sin(SunAnom) * EFac
327 + 0.0024 * sin(2*SunAnom) * EFac
328 - 0.0392 * sin(MoonAnom)
329 + 0.0116 * sin(2*MoonAnom)
330 - 0.0073 * sin(SunAnom + MoonAnom) * EFac
331 + 0.0067 * sin(MoonAnom - SunAnom) * EFac
332 + 0.0118 * sin(2*F1);
333
334 Q := 5.2207
335 - 0.0048 * cos(SunAnom) * EFac
336 + 0.0020 * cos(2*SunAnom) * EFac
337 - 0.3299 * cos(MoonAnom)
338 - 0.0060 * cos(SunAnom + MoonAnom) * EFac
339 + 0.0041 * cos(MoonAnom - SunAnom) * EFac;
340
341 W := abs(cos(F1));
342
343 Gamma := (P * cos(F1) + Q * sin(F1)) * (1 - 0.0048 * W);
344
345 Mu := 0.0059
346 + 0.0046 * cos(SunAnom) * EFac
347 - 0.0182 * cos(MoonAnom)
348 + 0.0004 * cos(2*MoonAnom)
349 - 0.0005 * cos(SunAnom + MoonAnom);
350
351 if (Frac(abs(K)) > 0.1) then begin
352 {Check for Lunar Eclipse possibilities}
353 PMag := (1.5573 + Mu - abs(Gamma)) / 0.5450;
354 UMag := (1.0128 - Mu - abs(Gamma)) / 0.5450;
355
356 if (UMag >= 1.0) then
357 TotalLunarEclipse(CentralJD, MoonAnom, Mu, PMag, UMag, Gamma)
358 else if (UMag > 0) then
359 PartialLunarEclipse(CentralJD, MoonAnom, Mu, PMag, UMag, Gamma)
360 else if ((UMag < 0) and (PMag > 0)) then
361 PenumbralLunarEclipse(CentralJD, MoonAnom, Mu, PMag, UMag, Gamma);
362 end else begin
363 {Check for Solar Eclipse possibilities}
364 {
365 Non-partial eclipses
366 --------------------
367 central Axis of moon's umbral shadow touches earth's surface
368 Can be total, annular, or both
369
370 non-central Axis of moon's umbral shadow does not touch earth's surface
371 Eclipse is usually partial but can be one of possibilities
372 for central eclipse if very near one of the earth's poles
373
374 Partial eclipses
375 ----------------
376 partial None of the moon's umbral shadow touches the earth's surface
377 }
378
379 if (abs(Gamma) <= (0.9972 + abs(Mu))) then
380 NonPartialSolarEclipse(CentralJD, Mu, Gamma)
381 else begin
382 if (abs(Gamma) < 1.5433 + Mu) then
383 PartialSolarEclipse(CentralJD, Mu, Gamma);
384 end;
385 end;
386 end;
387
388 procedure TStEclipses.TotalLunarEclipse(CentralJD, MoonAnom, Mu,
389 PMag, UMag, Gamma : Double);
390 var
391 TLE : PStEclipseRecord;
392 PartialSemiDur,
393 TotalSemiDur,
394 Dbl1 : Double;
395 begin
396 New(TLE);
397 TLE^.Magnitude := UMag;
398 TLE^.Hemisphere := htNone;
399 TLE^.EType := etLunarTotal;
400 TLE^.Path := nil;
401 CentralJD := AJDToDateTime(CentralJD);
402
403 PartialSemiDur := 1.0128 - Mu;
404 TotalSemiDur := 0.4678 - Mu;
405 Dbl1 := 0.5458 + 0.0400 * cos(MoonAnom);
406
407 PartialSemiDur := 60/Dbl1 * sqrt(sqr(PartialSemiDur) - sqr(Gamma)) / 1440;
408 TotalSemiDur := 60/Dbl1 * sqrt(sqr(TotalSemiDur) - sqr(Gamma)) / 1440;
409
410 TLE^.LContacts.FirstContact := CentralJD - PartialSemiDur;
411 TLE^.LContacts.SecondContact := CentralJD - TotalSemiDur;
412 TLE^.LContacts.MidEclipse := CentralJD;
413 TLE^.LContacts.ThirdContact := CentralJD + TotalSemiDur;
414 TLE^.LContacts.FourthContact := CentralJD + PartialSemiDur;
415
416 PartialSemiDur := 60/Dbl1 * sqrt(sqr(1.5573 + Mu) - sqr(Gamma)) / 1440;
417 TLE^.LContacts.UT1 := CentralJD - PartialSemiDur;
418 TLE^.LContacts.UT2 := CentralJD + PartialSemiDur;
419
420 Self.Append(TLE);
421 end;
422
423 procedure TStEclipses.PartialLunarEclipse(CentralJD, MoonAnom, Mu,
424 PMag, UMag, Gamma : Double);
425 var
426 TLE : PStEclipseRecord;
427 PartialSemiDur,
428 Dbl1 : Double;
429 begin
430 New(TLE);
431 TLE^.Magnitude := UMag;
432 TLE^.Hemisphere := htNone;
433 TLE^.EType := etLunarPartial;
434 TLE^.Path := nil;
435 CentralJD := AJDToDateTime(CentralJD);
436
437 PartialSemiDur := 1.0128 - Mu;
438 Dbl1 := 0.5458 + 0.0400 * cos(MoonAnom);
439
440 PartialSemiDur := 60/Dbl1 * sqrt(sqr(PartialSemiDur) - sqr(Gamma)) / 1440;
441
442 TLE^.LContacts.FirstContact := CentralJD - PartialSemiDur;
443 TLE^.LContacts.SecondContact := 0;
444 TLE^.LContacts.MidEclipse := CentralJD;
445 TLE^.LContacts.ThirdContact := 0;
446 TLE^.LContacts.FourthContact := CentralJD + PartialSemiDur;
447
448 PartialSemiDur := 60/Dbl1 * sqrt(sqr(1.5573 + Mu) - sqr(Gamma)) / 1440;
449 TLE^.LContacts.UT1 := CentralJD - PartialSemiDur;
450 TLE^.LContacts.UT2 := CentralJD + PartialSemiDur;
451
452 Self.Append(TLE);
453 end;
454
455 procedure TStEclipses.PenumbralLunarEclipse(CentralJD, MoonAnom, Mu,
456 PMag, UMag, Gamma : Double);
457 var
458 TLE : PStEclipseRecord;
459 PartialSemiDur,
460 Dbl1 : Double;
461 begin
462 New(TLE);
463 TLE^.Magnitude := PMag;
464 TLE^.Hemisphere := htNone;
465 TLE^.EType := etLunarPenumbral;
466 TLE^.Path := nil;
467 CentralJD := AJDToDateTime(CentralJD);
468
469 TLE^.LContacts.FirstContact := 0;
470 TLE^.LContacts.SecondContact := 0;
471 TLE^.LContacts.MidEclipse := CentralJD;
472 TLE^.LContacts.ThirdContact := 0;
473 TLE^.LContacts.FourthContact := 0;
474
475 Dbl1 := 0.5458 + 0.0400 * cos(MoonAnom);
476 PartialSemiDur := 60/Dbl1 * sqrt(sqr(1.5573 + Mu) - sqr(Gamma)) / 1440;
477 TLE^.LContacts.UT1 := CentralJD - PartialSemiDur;
478 TLE^.LContacts.UT2 := CentralJD + PartialSemiDur;
479
480 Self.Append(TLE);
481 end;
482
483 procedure TStEclipses.GetBesselianElements(CentralJD : Double);
484 var
485 I,
486 Mins : LongInt;
487 CurJD,
488 SidTime,
489 SunDist,
490 MoonDist,
491 DistRatio,
492 Alpha,
493 Theta,
494 Sun1,
495 Sun2,
496 Moon1,
497 Moon2,
498 Dbl3,
499 F1, F2 : Double;
500 DTRec : TStDateTimeRec;
501 SunXYZ : TStSunXYZRec;
502 Sun : TStPosRec;
503 Moon : TStMoonPosRec;
504 begin
505 {compute BesselianElements every 10 minutes starting 2 hours prior to CentralJD}
506 {but forcing positions to be at multiple of ten minutes}
507 for I := 1 to 25 do begin
508 CurJD := CentralJD + ((I-13) * (10/1440));
509 DTRec.D := AstJulianDateToStDate(CurJD, True);
510 if ((Frac(CurJD) + 0.5) >= 1) then
511 Mins := Trunc(((Frac(CurJD) + 0.5)-1) * 1440)
512 else
513 Mins := Trunc((Frac(CurJD) + 0.5) * 1440);
514 {changed because, for example, both 25 and 35 rounded to 30}
515 Mins := ((Mins + 5) div 10) * 10;
516 if (Mins = 1440) then
517 Mins := 0;
518 DTRec.T := Mins * 60;
519
520 SidTime := SiderealTime(DTRec) / radcor;
521 SunXYZ := SunPosPrim(DTRec);
522 Sun := SunPos(DTRec);
523 Moon := MoonPos(DTRec);
524
525 Sun1 := Sun.RA/radcor;
526 Sun2 := Sun.DC/radcor;
527 Moon1 := Moon.RA/radcor;
528 Moon2 := Moon.DC/radcor;
529
530 FBesselianElements[I].JD := StDateToDateTime(DTRec.D)
531 + StTimeToDateTime(DTRec.T);
532
533 SunDist := 1.0 / sin(8.794/SunXYZ.RV/3600.0/radcor);
534 MoonDist := 1.0 / sin(Moon.Plx/radcor);
535 DistRatio := MoonDist / SunDist;
536
537 Theta := DistRatio/cos(Sun2) * cos(Moon2) * (Moon1 - Sun1);
538 Theta := Theta/(1.0-DistRatio);
539 Alpha := Sun1 - Theta;
540
541 Theta := DistRatio/(1.0 - DistRatio) * (Moon2 - Sun2);
542
543 FBesselianElements[I].Delta := Sun2 - Theta;
544 FBesselianElements[I].Angle := SidTime - Alpha;
545 FBesselianElements[I].XAxis := MoonDist * cos(Moon2) * (sin(Moon1 - Alpha));
546
547 Dbl3 := FBesselianElements[I].Delta;
548 FBesselianElements[I].YAxis := MoonDist * (sin(Moon2) * cos(Dbl3)
549 - cos(Moon2) * sin(Dbl3) * cos(Moon1 - Alpha));
550
551 Theta := DistRatio * SunXYZ.RV;
552 Theta := SunXYZ.RV - Theta;
553 F1 := StInvSin(0.004664012/Theta);
554 F2 := StInvSin(0.004640787/Theta);
555
556 Theta := MoonDist * (sin(Moon2) * sin(Dbl3) + cos(Moon2)
557 * cos(Dbl3) * cos(Moon1 - Alpha));
558 FBesselianElements[I].L1 := (Theta + 0.272453/sin(F1)) * StTan(F1);
559 FBesselianElements[I].L2 := (Theta - 0.272453/sin(F2)) * StTan(F2);
560
561 if (I = 13) then
562 F0 := StTan(F2);
563
564 if (I = 16) then begin
565 FUPrime := FBesselianElements[16].Angle - FBesselianElements[10].Angle;
566 FDPrime := FBesselianElements[16].Delta - FBesselianElements[10].Delta;
567 end;
568 end;
569 end;
570
571 procedure TStEclipses.GetShadowPath(I1, I2 : Integer; Path : TStList);
572 var
573 J,
574 I3, I4,
575 I5, I6 : integer;
576
577 Delta,
578 Dbl1,
579 Dbl2,
580 P1,
581 XAxis,
582 YAxis,
583 Eta,
584 R1, R2,
585 D1, D2,
586 D3, D4,
587 V3, V4,
588 V5, V6, V7,
589 XPrime,
590 YPrime : Double;
591
592 Position : PStLongLat;
593 begin
594 for J := I1 to I2 do begin
595 Eta := 0.00669454;
596 Delta := FBesselianElements[J].Delta;
597 XAxis := FBesselianElements[J].XAxis;
598 YAxis := FBesselianElements[J].YAxis;
599
600 R1 := sqrt(1.0 - Eta * sqr(cos(Delta)));
601 R2 := sqrt(1.0 - Eta * sqr(sin(Delta)));
602
603 D1 := sin(Delta) / R1;
604 D2 := sqrt(1.0 - Eta) * cos(Delta) / R1;
605 D3 := Eta * sin(Delta) * cos(Delta) / R1 / R2;
606 D4 := sqrt(1.0 - Eta) / R1 / R2;
607
608 V3 := YAxis / R1;
609 V4 := sqrt(1.0 - sqr(XAxis) - sqr(V3));
610 V5 := R2 * (V4 * D4 - V3 * D3);
611 V6 := FUPrime * (-YAxis * sin(Delta) + V5 * cos(Delta));
612 V7 := FUPrime * XAxis * sin(Delta) - FDPrime * V5;
613
614 if ((I2-I1) div 2) >= 4 then begin
615 I3 := (I2-I1) div 2;
616 I4 := I1 + I3;
617 I5 := I4 - 3;
618 I6 := I4 + 3;
619 XPrime := FBesselianElements[I6].XAxis
620 - FBesselianElements[I5].XAxis;
621 YPrime := FBesselianElements[I6].YAxis
622 - FBesselianElements[I5].YAxis;
623 end else begin
624 XPrime := (FBesselianElements[J+1].XAxis -
625 FBesselianElements[J-1].XAxis) * 3;
626 YPrime := (FBesselianElements[J+1].YAxis -
627 FBesselianElements[J-1].YAxis) * 3;
628 end;
629
630 New(Position);
631 Dbl1 := sqrt(sqr(XPrime - V6) + sqr(YPrime - V7));
632 Position^.JD := FBesselianElements[J].JD;
633
634 Dbl2 := (FBesselianElements[J].L2 - V5 * F0) / Dbl1;
635 Dbl2 := abs(Dbl2 * 120);
636 Position^.Duration := int(Dbl2) + frac(Dbl2) * 0.6;
637
638 Dbl1 := -V3 * D1 + V4 * D2;
639 P1 := StInvTan2(Dbl1, XAxis);
640
641 Dbl2 := (FBesselianElements[J].Angle - P1) * radcor;
642 Dbl2 := frac(Dbl2 / 360.0) * 360;
643 if (Dbl2 < 0) then
644 Dbl2 := Dbl2 + 360.0;
645 if (Dbl2 > 180.0) and (Dbl2 < 360.0) then
646 Dbl2 := Dbl2 - 360.0;
647 Position^.Longitude := Dbl2;
648
649 Dbl1 := StInvSin(V3 * D2 + V4 * D1);
650 Dbl2 := ArcTan(1.003364 * StTan(Dbl1)) * radcor;
651 Position^.Latitude := Dbl2;
652
653 Path.Append(Position);
654 end;
655 end;
656
657 procedure TStEclipses.NonPartialSolarEclipse(CentralJD, Mu, Gamma : Double);
658 var
659 SolEc : PStEclipseRecord;
660 I1, I2 : Integer;
661 begin
662 New(SolEc);
663 if (Mu < 0) then
664 SolEc^.EType := etSolarTotal
665 else if (Mu > 0.0047) then
666 SolEc^.EType := etSolarAnnular
667 else begin
668 if (Mu < (0.00464 * sqrt(1 - sqr(Gamma)))) then
669 SolEc^.EType := etSolarAnnularTotal
670 else
671 SolEc^.EType := etSolarTotal;
672 end;
673
674 SolEc^.Magnitude := -1;
675 if (Gamma > 0) then
676 SolEc^.Hemisphere := htNorthern
677 else
678 SolEc^.Hemisphere := htSouthern;
679 FillChar(SolEc^.LContacts, SizeOf(TStContactTimes), #0);
680 SolEc^.LContacts.MidEclipse := AJDtoDateTime(CentralJD);
681
682 GetBesselianElements(CentralJD);
683
684 {find limits - then go one step inside at each end}
685 I1 := 1;
686 while (sqr(FBesselianElements[I1].XAxis) +
687 sqr(FBesselianElements[I1].YAxis) >= 1.0) and (I1 < 25) do
688 Inc(I1);
689 Inc(I1);
690
691 I2 := I1;
692 repeat
693 if (I2 < 25) then begin
694 if (sqr(FBesselianElements[I2+1].XAxis) +
695 sqr(FBesselianElements[I2+1].YAxis) < 1) then
696 Inc(I2)
697 else
698 break;
699 end;
700 until (sqr(FBesselianElements[I2].XAxis) +
701 sqr(FBesselianElements[I2].YAxis) >= 1) or (I2 >= 25);
702 Dec(I2);
703
704 {this test accounts for non-central eclipses, i.e., those that are total}
705 {and/or annular but the axis of the moon's shadow does not touch the earth}
706 if (I1 <> I2) and (I1 < 26) and (I2 < 26) then begin
707 SolEc^.Path := TStList.Create(TStListNode);
708 SolEc^.Path.DisposeData := DisposePathData;
709 GetShadowPath(I1, I2, SolEc^.Path);
710 end else
711 SolEc^.Path := nil;
712 Self.Append(SolEc);
713 end;
714
715 procedure TStEclipses.PartialSolarEclipse(CentralJD, Mu, Gamma : Double);
716 var
717 SolEc : PStEclipseRecord;
718 begin
719 New(SolEc);
720 SolEc^.EType := etSolarPartial;
721 SolEc^.Magnitude := (1.5433 + Mu - abs(Gamma)) / (0.5461 + 2*Mu);
722 if (Gamma > 0) then
723 SolEc^.Hemisphere := htNorthern
724 else
725 SolEc^.Hemisphere := htSouthern;
726 FillChar(SolEc^.LContacts, SizeOf(TStContactTimes), #0);
727 SolEc^.LContacts.MidEclipse := AJDToDateTime(CentralJD);
728 SolEc^.Path := nil;
729 Self.Append(SolEc);
730 end;
731
732
733 end.

  ViewVC Help
Powered by ViewVC 1.1.20