7

trying to compute moon illumination percent from moon day.

To get moon day in pseudo code I do:

LUNAR_MONTH = 29.530588853
KNOWN_NEW_MOON = JulianDay("2000-01-06 06:14")
age = (julian_day_now - KNOWN_NEW_MOON).abs % LUNAR_MONTH

So that shows me right now an age of 10.9 days. How do I tell percent illumination?

akostadinov
  • 235
  • 1
  • 4
  • The Moon's angular speed varies a fair bit, so that age calculation is just a rough approximation. – PM 2Ring Jan 02 '23 at 23:57
  • 2
    This computes the moon illumination given a date: https://celestialprogramming.com/meeus-illuminated_fraction_of_the_moon.html – Greg Miller Jan 03 '23 at 00:18
  • There is a related question, but I hesitate to mark as duplicate, since the answer their depends on external spreadsheets that are no longer available. This rough and ready estimation of the phase can be done by simple trig, assuming (as you do) that the moon/s orbit is simple and circular. https://astronomy.stackexchange.com/questions/1709/formulas-to-determine-the-illuminated-phase-and-orientation-of-the-moon – James K Jan 03 '23 at 08:58
  • 1
    @GregMiller, glad that you see my question! I would be happy if you can answer my question on stackoverflow. I saw your page but I have no idea what it does. const T=(jd-2451545)/36525.0; - what is this? Lets assume I don't care so much to understand all other constants but I'd like to calculate this according to the method I use to get julian day. Otherwise I'm not sure whether my julian day is same as yours. – akostadinov Jan 03 '23 at 10:35
  • 1
    @akostadinov, that line computes the number of Julian centuries since J2000. The "jd" is the standard Julian date, and the big number is the Julian date for Jan 1, 2000. The linked page also has routines for computing the Julian date, so you can use those if you're concerned. – Greg Miller Jan 03 '23 at 17:22
  • 1
    Thank you @GregMiller! You can see my stackoverflow question for my implementation. I see that full moon is given on Jan 6 23:09 on mooninfo.org while my computation returns at 11:05. Is this an expected margin of error or do you think I messed up something? – akostadinov Jan 04 '23 at 01:03
  • 1
    Actually around 12 hours difference from mooninfo.org, also for 2000-08-15. Either I have someting wrong, or algorithm is a little off or mooninfo.org are off. – akostadinov Jan 04 '23 at 01:11
  • 1
    You probably didn't account for a Julian day starting an 12:00 noon rather than midnight. – Greg Miller Jan 04 '23 at 05:30
  • 1
    @GregMiller, that's true! I get it at 00:00, not noon. Now I'm within 4 minutes accuracy compared with mooninfo.org for the next full moon. While this accounts for the inaccuracy, there is still something unclear about your jd calculation for me. DateTime.new(2000, 1, 1, 12, 0, 0).ajd.to_f => 2451545.0 as in your code. But if I get a unix timestamp of it, then use your formula I get a very different result: DateTime.new(2000, 1, 1, 12, 0, 0).to_time.to_i / 86400000 + 2440587.5 => 2440597.5. Do you have an explanation to this? – akostadinov Jan 04 '23 at 10:55
  • 1
    @GregMiller, also if you post an answer, I will be glad to accept it because basically that did the job for me. – akostadinov Jan 04 '23 at 11:31
  • @GregMiller, another question. You perform angle = num % 360 then angle += 360 if angle.negative?. Which definition of modulo should be used? Ruby has a floored modulo and it seems to be what we need here. But wanted to double check as I'm not familiar with the math you're using. – akostadinov Mar 28 '23 at 13:15
  • @akostadinov, I'm not familiar with Ruby's floor modulo, so can't say for sure. The goal there is just to make sure the value is in the range from 0 to 360. For your question about the timestamp above, it looks like the function you're using isn't returning a Unix timestamp, so you can't use that method. – Greg Miller Mar 28 '23 at 15:27
  • @GregMiller, it is returning a unix timestamp. DateTime.new(2000, 1, 1, 12, 0, 0).to_time.to_i => 946728000, then in shell $ TZ=UTC date -d "@946728000" => 1.01.2000 (сб) 12:00:00 UTC. – akostadinov Mar 28 '23 at 16:44
  • Ok, got it. Need to divide by float 86400.0, then I get 2451545.0. Maybe in your code the timestamp is milliseconds and not seconds like in my case. Good that things are cleared up. That was interesting. Sad only in comments. – akostadinov Mar 28 '23 at 16:49
  • 2
    @akostadinov I added a bounty to attract an answer. If it turns out you've solved the problem and feel up to writing it up as an answer, please feel free to do so. – uhoh Apr 05 '23 at 03:31
  • 1
    How about the Daft Moon application? It does it for free hour-by-hour – Geographos Apr 05 '23 at 09:12
  • 2
    @uhoh, I didn't post a solution here because I've got (and needed) a computer algorithm. That I've got and posted to stackoverflow. Also Greg has such in another language. I think an answer worth this site would be more theoretical math how to do it and not just pasting a magic algorithm that works reasonably well. I will be interested to see such an answer. Also referring to some app and not explaining how it works is also a non-answer imho. – akostadinov Apr 05 '23 at 14:17

1 Answers1

8

The algorithm below produces the fraction of moon illumination based on the Julian Day (rather than the moon age). It is from Meeus' Astronomical Algorithms Second Edition chapter 48.

$$ \begin{align} D &= 297.8501921 + 445267.1114034T - 0.0018819T^2 + \frac{1}{545868.0}T^3 - \frac{1}{113065000.0}T^4 \\ M &= 357.5291092 + 35999.0502909T - 0.0001536T^2 + \frac{1}{24490000.0}T^3 \\ M' &= 134.9633964 + 477198.8675055T + 0.0087414T^2 + \frac{1}{69699}T^3 - \frac{1}{14712000.0}T^4 \\ i &= 180 - D - 6.289 \sin M' + 2.1 \sin M -1.274 \sin(2D - M') -0.658 \sin 2D -0.214 \sin 2M' -0.11 \sin D \\ k &= \frac{1 + \cos i}{2} \end{align} $$

Where $T$ is the number of Julian centuries since J2000: $T=(jd-2451545)/36525.0$. And $k$ is the fraction (from 0.0 to 1.0) of the moon (approximated as a perfect sphere) which is illuminated as viewed from the Geocenter.

$D$, $M$, $M'$ are the Delaunay arguments. Respectively the Moon's mean elongation, the Sun's mean anomaly, and the Moon's mean anomaly.

Here is an example implementation in JavaScript.

As far as an explanation of what all of the contants, etc mean... Sadly there is no deep dark secret explanation guarded by mythical creatures in funny hats who require you to solve puzzles to enter their chamber. Rather, they're just a least squares fit to observations to find the coefficients $a_i$ of a function of the form: $$ f(x) = a_1f_1(x) + a_2f_2(x) + a_2f_2(x) + ... a_if_i(x) $$

For the Delaunay arguments, $f_i(x)$ are just the powers of $T$.

For $i$ the $f_i(x)$ are trig functions of integer multiples of the Delaunay arguments. This method has been used in many ephemeris algorithms, most notably VSOP87. Again, it might seem like there's a deep scientific method involved in figuring out which ones to use. But as described in "Synthetic representation of the Galilean satellites' orbital motions from L1 ephemerides", it's largely a matter of performing a Fourier transform to find good candidates, then trying almost every integer multiple of each argument and just picking the one which fits the observations best. Which solution to pick is largely a balance between computational complexity and accuracy over a desired time frame.

Greg Miller
  • 5,857
  • 1
  • 14
  • 31
  • 2
    Despite being disappointed by the lack of involvement of mythical creatures, thank you very much for the explanation! And for adding some more info on your web site. It would have taken me enormous amout of time to implement based on the theory. – akostadinov Apr 06 '23 at 17:58
  • 2
    Can I check - the T³ and T⁴ I would expect them to be in the numerator of the fractions, not the denominator. Are the formulas correct? Is that a typo? – James K Apr 07 '23 at 08:23
  • 2
    @JamesK You're correct, thanks. I have edited the post. – Greg Miller Apr 07 '23 at 13:21
  • 2
    Well pointed out! Jean Meeus's clever shortcut formulae for the illuminated fraction of the moon's disk deserve to be better known, I think. It might also be worth mentioning (because occasionally people express doubts about it), that the illuminated fraction of the diameter (taken to cut the crescent etc halfway between the moon's 'horns') is the same as the illuminated fraction of the disk area because the crescent is of ellipse form and the projection of circle on to ellipse preserves such area-ratios. It's a good algorithm. – terry-s Apr 07 '23 at 23:09