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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2671 - (hide annotations) (download)
Tue Aug 25 18:15:15 2015 UTC (8 years, 10 months ago) by torben
File size: 22930 byte(s)
Added tpsystools component
1 torben 2671 // 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