Skip to content

Instantly share code, notes, and snippets.

@jem
Forked from nofxx/moon.rb
Created November 8, 2022 04:59
Show Gist options
  • Save jem/3c1e3a33527c75eb7799609e8907f945 to your computer and use it in GitHub Desktop.
Save jem/3c1e3a33527c75eb7799609e8907f945 to your computer and use it in GitHub Desktop.
#
# Lunar/Moon phases ruby class
#
# Code is based upon Bradley E. Schaefer''s moon phase algorithm.
# Ruby version based on JavaScript Phase Calculator by Stephen R. Schmitt
class Moon
attr_reader :epoch, :phase, :days, :icon, :dist, :ll, :emoji
# Return the current (or input a date) moon.
# Moon.new
# Moon.new(some_day)
#
# Methods available:
# phase => Phase of the moon as a sym
# days => Moon days
# icon => An integer from 0 to 29
# dist => Distance in earth radii
# ll => Moon ecliptic lat/lon
#
def initialize(epoch=Time.now)
@epoch = epoch
do_calc
end
private
def calc_phase(p)
case p
when 0 then :new
when 1..6 then :waxing_crescent
when 7..9 then :first_quarter
when 10..12 then :waxing_gibbous
when 13..16 then :full
when 17..20 then :waning_gibbous
when 21..24 then :last_quarter
when 25..28 then :waning_crescent
else :new
end
end
def calc_emoji(p)
case p
when 0 then "πŸŒ‘"
when 1..6 then "πŸŒ’"
when 7..9 then "πŸŒ“"
when 10..12 then "πŸŒ”"
when 13..16 then "πŸŒ•"
when 17..20 then "πŸŒ–"
when 21..24 then "πŸŒ—"
when 25..28 then "🌘"
else "πŸŒ‘"
end
end
def calc_coords(inter, phase)
phase = phase * 2 * Math::PI
dp = 2 * Math::PI * normalize((inter - 2451562.2 ) / 27.55454988)
@dist = 60.4 - 3.3 * Math.cos(dp) - 0.6 * Math.cos(2 * phase - dp) - 0.5 * Math.cos(2 * phase)
np = 2 * Math::PI * normalize((inter - 2451565.2) / 27.212220817)
la = 5.1 * Math.sin(np)
rp = normalize((inter - 2451555.8 ) / 27.321582241)
lo = 360 * rp + 6.3 * Math.sin(dp) + 1.3 * Math.sin(2 * phase - dp) + 0.7 * Math.sin(2 * phase)
@ll = [la, lo]
end
def do_calc
c_phase = 29.530588853
t_year = @epoch.year - ((12 - @epoch.month)/10).to_i
t_month = (@epoch.month + 9) % 12
t1 = (365.25 * (t_year + 4712)).to_i
t2 = (30.6 * t_month + 0.5).to_i
t3 = (((t_year / 100.0) + 49.0) * 0.75).to_i - 38
inter = t1 + t2 + @epoch.day + 59
inter -= t3 if inter > 2299160
phase = normalize((inter - 2451550.1) / c_phase)
res = phase * c_phase;
@days = (res * 100).to_i / 100
@icon = res.to_i % 30
@phase = calc_phase(@icon)
@emoji = calc_emoji(@icon)
calc_coords(inter, phase)
end
def normalize(x)
x %= 1
x += 1 if x < 0
x
end
end
@jem
Copy link
Author

jem commented Nov 8, 2022

Added emoji symbol

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment