Saturday, December 16, 2017

#1 2015-10-09 06:46:26 am

Joseph25b
Member
Registered: 2015-08-31
Posts: 31

Moon eclipses calculator

An AppleScript script predicting Moon eclipses on a wide range of years.
The script provided is based on Jean MEEUS works published in his book:
Astronomical Formulae for Calculators © 1979 Willmann-Bell Editions.

Results are given with the date and time of the eclipse event, its type and magnitude.
The average precision for eclipses time calculated with this program is 2 minutes, maximum imprecision could reach  5 minutes.
Results will look like to this:
{"2017 08 07", "Partial E. @ UTC 18 h 19 min / M: 0,256"}
Where date  is YYYY MM dd; the type of eclipse can be "Penumbral", "Partial" or "Total" ; "M" magnitude is, here, relative to the only Earth's deep shadow (for partial and total eclipse), not its whole extent including the penumbra cone.
The time represents the moment of eclipse at its maximum. 

Keep in mind that this script will give only a fast and rather precise reminder for interesting lunar event, not a reference tool.
For very accurate and extended informations about eclipses, please look at the master work by Fred ESPENAK on NASA site:
http://eclipse.gsfc.nasa.gov/lunar.html

Script tested and running OK from Lion up to El Capitan.
The script is ready to run in Applescript Editor, no need of Satimage or such "scripting addition". Nonetheless, if you have a trigonometric osax installed, you can use it by getting rid of the pipes around |sin| and |cos| in formulae and commenting out or deleting the two functions provided at the bottom of the script.
Feel free to point out and correct any error encountered in the script or it's results.

Enjoy!

Applescript:


(*Written by Joseph25b / oct 2015. Moon's eclipses calculator based on Jean MEEUS algorithms*)

set allMoonEclipses to yearMoonEclipses(2013, 2018) --Here, set the range of needed years

on yearMoonEclipses(Year1, Year2)
   set Refdate to my makeASDateFrom(1900, 1, 1, 6, 13, 26) --(1st january 1900 06:13:26 AM):DO NOT modify the Refdate!!
   set rad to pi / 180
   set moonEclipsesList to {}
   (*After Jean Meeus's algorithms published in "Astronomical Formulae for Calculators" - 1979*)
   repeat with aYear from Year1 to Year2
       set JJD to {}
       set iQ0 to 0
       set floorDate to my JJulien(31.99999, 12, (aYear - 1))
       set ceilingDate to my JJulien(1, 1, aYear + 1)
       set calendarCible to my makeASDateFrom(aYear, 1, 1, 0, 0, 0) -- (1st january aYear 0:0:0:)
       set Ktest to ((calendarCible - Refdate) / 29.53058868) / 86400
       set entierK to Ktest div 1
       set resteK to Ktest mod 1
       if resteK <= 0.5 then
           set K1 to entierK + 0.5
       else
           set K1 to entierK + 1.5
       end if
       repeat with i from 0 to 12 --
           set typeEclipse to ""
           set K to K1 + i
           set T to K / 1236.85
           set T2 to T * T
           set T3 to T2 * T
           set JJm to (2.41502075933E+6 + 29.53058832 * K + 1.337E-4 * T2 - 1.5E-7 * T3 + 3.3E-4 * (|sin|(rad * (166.56 + 132.87 * T - 0.009173 * T2))))
           set M to (359.2242 + 29.10535608 * K - 3.33E-5 * T2 - 3.47E-6 * T3)
           set M to (M mod 360) * rad
           set N to (306.0253 + 385.81691806 * K + 0.0107306 * T2 + 1.236E-5 * T3)
           set N to (N mod 360) * rad
           set F to (21.2964 + 390.67050646 * K - 0.0016528 * T2 - 2.39E-6 * T3)
           set F to (F mod 360) * rad
           set testEclipse to (|sin|(F))
           if testEclipse > -0.3584 and testEclipse < 0.3584 then -- If it can ever be an eclipse, the Moon's latitude must be under 21° modulo 180°
               set corr to ((0.1734 - 3.93E-4 * T) * (|sin|(M))) + (0.0021 * (|sin|(2 * M))) - (0.4068 * (|sin|(N))) + (0.0161 * (|sin|(2 * N))) - (0.0051 * (|sin|(M + N))) - (0.0074 * (|sin|(M - N))) - (0.0104 * (|sin|(2 * F)))
               set JJ to (JJm + corr) --the date and time of the maximum of eclipse, if any...
               --log JJ
               set S to my calculationOfS(M, N)
               set C to my calculationOfC(M, N, F)
               set Mu to my calculationOfMu(M, N)
               set gama to (S * (|sin|(F)) + C * (|cos|(F)))
               if gama < 0 then set gama to (-1 * gama)
               set grandeurPenombre to (1.5572 + Mu - gama) / 0.545
               set Magn to ((1.0129 - Mu - gama) / 0.545) + 0.009
               set Magn to ((Magn * 1000) div 1) / 1000
               if grandeurPenombre > 0 then -- a negative value means that there is no eclipse
                   set typeEclipse to 1 -- at least a penumbral eclipse
                   if Magn >= 1 then --Total Moon's eclipse in Earth's shadow cone
                       set typeEclipse to 3
                   else if Magn > 0 then -- only a part of the Moon shadowed by Earth's shadow cone
                       set typeEclipse to 2
                   end if
                   if JJ >= ceilingDate then exit repeat -- avoid last item's belonging to next year
                   if JJ <= floorDate then "nothing" -- avoid first item's belonging to previous year
                   if JJ > floorDate then copy {JJ, typeEclipse, Magn} as list to end of JJD -- lets'go
               end if
           end if
       end repeat
       repeat with nbEclipse from 1 to (count items in JJD)
           set tempEclipseDate to my (JJUlToCalendar(JJD's item nbEclipse)) as list
           set moonEclipsesList to moonEclipsesList & (tempEclipseDate)
       end repeat
   end repeat
   return moonEclipsesList
end yearMoonEclipses

on calculationOfS(M, N) -- part of J Meeus algorithms
   set tempVal to 5.19595 - (0.0048 * (|cos|(M))) + (0.002 * (|cos|(2 * M))) - (0.3283 * (|cos|(N))) - (0.006 * (|cos|(M + N))) + (0.0041 * (|cos|(M - N)))
   return tempVal
end calculationOfS

on calculationOfC(M, N, F) -- part of J Meeus algorithms
   set tempVal to (0.207 * (|sin|(M))) + (0.0024 * (|sin|(2 * M))) - (0.039 * (|sin|(N))) + (0.0115 * (|sin|(2 * N))) - (0.0073 * (|sin|(M + N))) - (0.0067 * (|sin|(M - N))) + (0.0117 * (|sin|(2 * F)))
   return tempVal
end calculationOfC

on calculationOfMu(M, N) -- part of J Meeus algorithms
   set tempVal to 0.0059 + (0.0046 * (|cos|(M))) - (0.0182 * (|cos|(N))) + (4.0E-4 * (|cos|(2 * N))) - (5.0E-4 * (|cos|(M + N)))
   return tempVal
end calculationOfMu

on JJUlToCalendar(JJeclipse) -- after J Meeus's algorithms
   set tEclipses to {"Penumbral E. ", "Partial E. ", "Total E. "}
   set eclipsindex to item 2 of JJeclipse
   set typEclp to (tEclipses's item eclipsindex)
   set magnit to "M: " & JJeclipse's item 3
   set JJul to (item 1 of JJeclipse) + 0.5
   set Z to (JJul div 1)
   set HMS to (JJul mod 1) * 86400
   set Fh to HMS div 3600
   set Fh to nb00j(Fh)
   set Fmn to (HMS mod 3600) div 60
   set Fmn to nb00j(Fmn)
   if Z >= 2299161 then -- Gregorian calendar
       copy ((Z - 1.86721625E+6) / 3.652425E+4) div 1 to alpha
       copy Z + 1 + alpha - ((alpha / 4) div 1) to A
   else -- Julian calendar
       copy Z to A
   end if
   copy A + 1524 to B
   copy ((B - 122.1) / 365.25) div 1 to C
   copy (365.25 * C) div 1 to D
   copy ((B - D) / 30.6001) div 1 to E
   copy B - D - ((30.6001 * E) div 1) to DD
   set DD to nb00j(DD)
   copy E - 1 to MM
   if E > 13.5 then copy E - 13 to MM
   copy nb00j(MM) to MMft
   copy C - 4716 to YYYY
   if MM < 2.5 then copy C - 4715 to YYYY --Year
   set ref_J_Eclipse to (YYYY & " " & MMft & " " & DD) as string
   return {((ref_J_Eclipse) as list) & (typEclp & "@ UTC " & Fh & " h " & Fmn & " min / " & magnit)} as list
end JJUlToCalendar

on JJulien(DD, MM, YY) -- J Meeus's algorithm
   copy YY + (MM / 100) + (DD / 10000) to Gregor
   if MM < 3 then
       copy MM + 12 to MM
       copy YY - 1 to YY
   end if
   copy (365.25 * YY) div 1 + (30.6001 * (MM + 1)) div 1 + DD + (1.7209945E+6) to JourJulien
   if Gregor > 1582.1015 then -- Step from julian to gregorian calendar
       copy (YY div 100) to K
       set JourJulien to JourJulien + (2 - K) + (K div 4)
   end if
   return JourJulien
end JJulien

--*********** Annexes handlers *******************************************
(*NB: Rather than unpredictable result from AS when making a "date" from a string, Shane Stanley suggests this function below*)
on makeASDateFrom(theYear, theMonth, theDay, theHours, theMinutes, theSeconds)
   tell (current date) to set {theASDate, year, day, its month, day, time} to {it, theYear, 1, theMonth, theDay, theHours * hours + theMinutes * minutes + theSeconds}
   return theASDate
end makeASDateFrom

on nb00j(val) -- returning two digits dates as string
   set temp to (100 + val) --as string
   return items 2 thru -1 of (temp as string) as text
end nb00j

on Bissextile(YY)
   if YY mod 4 is not  0 then return 0
   if YY mod 100 = 0 and YY mod 400 is not  0 then return 0
   return 1
end Bissextile

on |sin|(X) -- x en radian
   set loopList to {3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27} --enough iterations
   set X to (X as real) mod (2 * pi)
   set snus to X as real
   set Z to 1
   set X2 to X * X
   repeat with j in loopList
       set Z to Z * (j - 1) * j --factorial loop
       set X to X * X2 -- increment x^3, x^5, x^7, etc.
       set pow to (j / 2) - 0.5
       set snus to snus + ((-1) ^ pow) * (X / Z)
   end repeat
   set ctrl to snus
   if ctrl < 0 then set ctrl to ctrl * (-1)
   if ctrl < 9.999999999999E-14 then set snus to 0.0
   return snus
end |sin|

on |cos|(X) -- x en radian
   set loopList to {2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26} --enough iterations
   set X to (X as real) mod (2 * pi)
   set cosnus to 1 as real
   set Z to 1
   set X2 to X * X
   set X to 1
   repeat with j in loopList
       set X to X * X2 -- increment x^2, x^4, x^6, etc.
       set Z to Z * (j - 1) * j --factorial loop
       set pow to (j / 2)
       set cosnus to cosnus + ((-1) ^ pow) * (X / Z)
   end repeat
   set ctrl to cosnus
   if ctrl < 0 then set ctrl to ctrl * (-1)
   if ctrl < 9.9999999999E-14 then set cosnus to 0.0
   return cosnus
end |cos|

Last edited by Joseph25b (2017-07-28 06:13:29 am)


Joseph from France
MacPro 10.7.5 - XCode 4.6.3


Filed under: eclipse, Moon

Offline

 

Board footer

Powered by FluxBB

RSS (new topics) RSS (active topics)