astro-algo 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README +23 -0
- data/bin/equinox +19 -0
- data/bin/lunarcalendar +38 -0
- data/bin/moon_clock.rb +184 -0
- data/bin/moons +31 -0
- data/lib/astro-algo.rb +846 -0
- data/lib/lunaryear.rb +91 -0
- metadata +65 -0
data/README
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
= Astronomical Algorithms
|
2
|
+
|
3
|
+
This library implements algorithms from Jean Meeus, <i>Astronomical Algorithms</i>,
|
4
|
+
2nd English Edition, Willmann-Bell, Inc., Richmond, Virginia, 1999, with corrections
|
5
|
+
as of June 15, 2005.
|
6
|
+
|
7
|
+
Gem astro-algo provides two modules:
|
8
|
+
|
9
|
+
* Astro which implements algorithms from the book. (require 'astro-algo')
|
10
|
+
* LunarYear which implements helper routines for calculating lunar years. (require 'lunaryear')
|
11
|
+
|
12
|
+
This gem also comes with several command line scripts.
|
13
|
+
equinox:: prints the date and time of the vernal equinox for the given year.
|
14
|
+
lunarcalendar:: prints a conversion chart between the customary Gregarian
|
15
|
+
calendar and a lunar year beginning with the full moon on or before
|
16
|
+
the vernal equinox.
|
17
|
+
moon_clock.rb:: a Tk GUI application which displays information about the current
|
18
|
+
lunation.
|
19
|
+
moons:: prints the phases of the moon for the given year.
|
20
|
+
|
21
|
+
This is a work in progress. Only the algorithms from <i>Astronomical Algorithms</i>
|
22
|
+
needed to support my hobby in the LunarYear have been implemented. I will add more
|
23
|
+
algorithms from the book in time.
|
data/bin/equinox
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# equinox.rb
|
3
|
+
|
4
|
+
# Compute the date of the vernal equinox for a given year (default current year).
|
5
|
+
#
|
6
|
+
# Example: compute the date and time of the vernal equinox for 2008.
|
7
|
+
# $ equinox 2008 => Thu Mar 20 05:48:18 2008
|
8
|
+
|
9
|
+
require File.join(File.dirname(__FILE__), '../lib/astro-algo')
|
10
|
+
|
11
|
+
|
12
|
+
if ARGV.length == 0
|
13
|
+
year = Time.now.year
|
14
|
+
else
|
15
|
+
year = ARGV[0].to_i
|
16
|
+
end
|
17
|
+
|
18
|
+
puts Astro.date_of_vernal_equinox(year).to_utc.asctime
|
19
|
+
|
data/bin/lunarcalendar
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# lunarcalendar.rb
|
3
|
+
|
4
|
+
# Print a lunar calendar for the given year (default current year).
|
5
|
+
|
6
|
+
require File.join(File.dirname(__FILE__), '../lib/lunaryear')
|
7
|
+
|
8
|
+
|
9
|
+
|
10
|
+
if ARGV.length == 0
|
11
|
+
year = Time.now.year
|
12
|
+
else
|
13
|
+
year = ARGV[0].to_i
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
|
18
|
+
lunation = LunarYear.new_moon_before_vernal_equinox(year)
|
19
|
+
next_years_lunation = LunarYear.new_moon_before_vernal_equinox(year + 1)
|
20
|
+
vernal_equinox = Astro.date_of_vernal_equinox(year).to_utc
|
21
|
+
vemonth = vernal_equinox.month
|
22
|
+
veday = vernal_equinox.day
|
23
|
+
|
24
|
+
moonth = 0
|
25
|
+
while lunation < next_years_lunation
|
26
|
+
moon_date = Astro.date_of_moon(lunation, Astro::PhaseNew).to_utc
|
27
|
+
next_moon = Astro.date_of_moon(lunation + 1, Astro::PhaseNew).to_utc
|
28
|
+
moon_day = 0
|
29
|
+
until moon_date.month == next_moon.month && moon_date.day == next_moon.day
|
30
|
+
ve = vemonth == moon_date.month && veday == moon_date.day ? '*' : ' '
|
31
|
+
puts '%2d-%02d %s%s' % [moonth, moon_day, moon_date.strftime('%b %d'), ve]
|
32
|
+
moon_day += 1
|
33
|
+
moon_date += 1
|
34
|
+
end
|
35
|
+
puts '--------------'
|
36
|
+
lunation += 1
|
37
|
+
moonth += 1
|
38
|
+
end
|
data/bin/moon_clock.rb
ADDED
@@ -0,0 +1,184 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# moon_clock.rb
|
3
|
+
#
|
4
|
+
# A clock application which displays the current local time,
|
5
|
+
# Universal time, time since the previous new and full moons,
|
6
|
+
# and time until the next new and full moons.
|
7
|
+
#
|
8
|
+
# Copyright (c) 2007 John Powers
|
9
|
+
|
10
|
+
require 'tk'
|
11
|
+
require File.join(File.dirname(__FILE__), '../lib/lunaryear')
|
12
|
+
|
13
|
+
|
14
|
+
DateTimeFormat = '%Y-%m-%d %H:%M:%S'
|
15
|
+
|
16
|
+
|
17
|
+
# Format number of days.
|
18
|
+
# +days+ is a rational number of days.
|
19
|
+
# Return days formatted like 28d 14:59:11
|
20
|
+
def format_days(days)
|
21
|
+
d, r = days.divmod(1)
|
22
|
+
h, r = (24*r).divmod(1)
|
23
|
+
m, r = (60*r).divmod(1)
|
24
|
+
s = (60*r).floor
|
25
|
+
'%dd %d:%02d:%02d' % [d, h, m, s] # 28d 14:59:11
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
# Set local and universal clocks to current time.
|
30
|
+
def set_clocks
|
31
|
+
now = DateTime.now
|
32
|
+
$current_time.value = now.strftime(DateTimeFormat)
|
33
|
+
$universal_time.value = now.new_offset.strftime(DateTimeFormat)
|
34
|
+
$lunar_date.value = '%4d\'%02d\'%02d' % LunarYear.lunar_date(now.to_date)
|
35
|
+
now
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
# Update moon times
|
40
|
+
$tnew0 = DateTime.jd(1)
|
41
|
+
$tnew1 = DateTime.jd(1)
|
42
|
+
$tfull0 = DateTime.jd(1)
|
43
|
+
$tfull1 = DateTime.jd(1)
|
44
|
+
|
45
|
+
|
46
|
+
# Set all moon clocks relative to the current time -- the
|
47
|
+
# number of days since the last moon or until the next moon.
|
48
|
+
def set_moon_clocks
|
49
|
+
now = set_clocks
|
50
|
+
|
51
|
+
# Has new or full moon expired?
|
52
|
+
if now > $tnew1 || now > $tfull1
|
53
|
+
$tnew0, $tnew1, $tfull0, $tfull1 = LunarYear.date_of_moons(now)
|
54
|
+
end
|
55
|
+
|
56
|
+
$last_new_moon.value = format_days(now - $tnew0)
|
57
|
+
$next_new_moon.value = format_days($tnew1 - now)
|
58
|
+
$last_full_moon.value = format_days(now - $tfull0)
|
59
|
+
$next_full_moon.value = format_days($tfull1 - now)
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
# Periodically update moon clocks. Reschedules itself to run
|
64
|
+
# again in 1000 milliseconds.
|
65
|
+
def update
|
66
|
+
set_moon_clocks
|
67
|
+
Tk.after(1000) {update}
|
68
|
+
end
|
69
|
+
|
70
|
+
|
71
|
+
|
72
|
+
|
73
|
+
$root = TkRoot.new { title 'Moon Clock' }
|
74
|
+
top = TkFrame.new($root)
|
75
|
+
|
76
|
+
# Local time
|
77
|
+
$current_time = TkVariable.new
|
78
|
+
TkLabel.new(top) {
|
79
|
+
font 'Courier 48 bold'
|
80
|
+
textvariable $current_time
|
81
|
+
grid(:row => 0, :column => 0, :columnspan => 2, :sticky => 'ew')
|
82
|
+
}
|
83
|
+
TkLabel.new(top) {
|
84
|
+
font 'Palatino 18 italic'
|
85
|
+
text 'Local Time'
|
86
|
+
grid(:row => 1, :column => 0, :columnspan => 2, :sticky => 'ew')
|
87
|
+
}
|
88
|
+
|
89
|
+
|
90
|
+
# Universal time
|
91
|
+
$universal_time = TkVariable.new
|
92
|
+
TkLabel.new(top) {
|
93
|
+
font 'Courier 36 bold'
|
94
|
+
textvariable $universal_time
|
95
|
+
grid(:row => 2, :column => 0, :columnspan => 2, :sticky => 'ew')
|
96
|
+
}
|
97
|
+
TkLabel.new(top) {
|
98
|
+
font 'Palatino 18 italic'
|
99
|
+
text 'Universal Time'
|
100
|
+
grid(:row => 3, :column => 0, :columnspan => 2, :sticky => 'ew')
|
101
|
+
}
|
102
|
+
|
103
|
+
|
104
|
+
# Lunar date
|
105
|
+
$lunar_date = TkVariable.new
|
106
|
+
TkLabel.new(top) {
|
107
|
+
font 'Courier 36 bold'
|
108
|
+
textvariable $lunar_date
|
109
|
+
grid(:row => 4, :column => 0, :columnspan => 2, :sticky => 'ew')
|
110
|
+
}
|
111
|
+
TkLabel.new(top) {
|
112
|
+
font 'Palatino 18 italic'
|
113
|
+
text 'Lunar Date'
|
114
|
+
grid(:row => 5, :column => 0, :columnspan => 2, :sticky => 'ew')
|
115
|
+
}
|
116
|
+
|
117
|
+
|
118
|
+
# Time since last new moon
|
119
|
+
$last_new_moon = TkVariable.new
|
120
|
+
TkLabel.new(top) {
|
121
|
+
font 'Courier 36 bold'
|
122
|
+
textvariable $last_new_moon
|
123
|
+
grid(:row => 6, :column => 0, :sticky => 'e')
|
124
|
+
}
|
125
|
+
TkLabel.new(top) {
|
126
|
+
font 'Palatino 18 italic'
|
127
|
+
text 'Last New Moon'
|
128
|
+
grid(:row => 7, :column => 0)
|
129
|
+
}
|
130
|
+
|
131
|
+
# Time until next new moon
|
132
|
+
$next_new_moon = TkVariable.new
|
133
|
+
TkLabel.new(top) {
|
134
|
+
font 'Courier 36 bold'
|
135
|
+
textvariable $next_new_moon
|
136
|
+
grid(:row => 6, :column => 1, :sticky => 'e')
|
137
|
+
}
|
138
|
+
TkLabel.new(top) {
|
139
|
+
font 'Palatino 18 italic'
|
140
|
+
text 'Next New Moon'
|
141
|
+
grid(:row => 7, :column => 1)
|
142
|
+
}
|
143
|
+
|
144
|
+
# Time since last full moon
|
145
|
+
$last_full_moon = TkVariable.new
|
146
|
+
TkLabel.new(top) {
|
147
|
+
font 'Courier 36 bold'
|
148
|
+
textvariable $last_full_moon
|
149
|
+
grid(:row => 8, :column => 0, :sticky => 'e')
|
150
|
+
}
|
151
|
+
TkLabel.new(top) {
|
152
|
+
font 'Palatino 18 italic'
|
153
|
+
text 'Last Full Moon'
|
154
|
+
grid(:row => 9, :column => 0)
|
155
|
+
}
|
156
|
+
|
157
|
+
# Time until next full moon
|
158
|
+
$next_full_moon = TkVariable.new
|
159
|
+
TkLabel.new(top) {
|
160
|
+
font 'Courier 36 bold'
|
161
|
+
textvariable $next_full_moon
|
162
|
+
grid(:row => 8, :column => 1, :sticky => 'e')
|
163
|
+
}
|
164
|
+
TkLabel.new(top) {
|
165
|
+
font 'Palatino 18 italic'
|
166
|
+
text 'Next Full Moon'
|
167
|
+
grid(:row => 9, :column => 1)
|
168
|
+
}
|
169
|
+
|
170
|
+
|
171
|
+
TkButton.new(top) {
|
172
|
+
text ' Quit '
|
173
|
+
command {exit}
|
174
|
+
grid(:row => 10, :column => 1)
|
175
|
+
}
|
176
|
+
|
177
|
+
|
178
|
+
top.pack(:fill => 'both')
|
179
|
+
|
180
|
+
|
181
|
+
# Start clock display
|
182
|
+
update
|
183
|
+
|
184
|
+
Tk.mainloop
|
data/bin/moons
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# moons
|
3
|
+
|
4
|
+
# Print a list of dates and times for phases of the moon for given
|
5
|
+
# year (default current year).
|
6
|
+
|
7
|
+
require File.join(File.dirname(__FILE__), '../lib/astro-algo')
|
8
|
+
|
9
|
+
|
10
|
+
|
11
|
+
if ARGV.length == 0
|
12
|
+
year = DateTime.now.year
|
13
|
+
else
|
14
|
+
year = ARGV[0].to_i
|
15
|
+
end
|
16
|
+
|
17
|
+
DateFormat = '%Y-%m-%d %H:%M:%S '
|
18
|
+
|
19
|
+
#puts ' ' + date.year.to_s
|
20
|
+
lunation = Astro.first_lunation_of_year(year)
|
21
|
+
next_year = DateTime.new(year + 1, 1, 1)
|
22
|
+
|
23
|
+
loop do
|
24
|
+
new_moon = Astro.date_of_moon(lunation, Astro::PhaseNew).to_utc
|
25
|
+
break if new_moon >= next_year
|
26
|
+
print new_moon.strftime(DateFormat)
|
27
|
+
print Astro.date_of_moon(lunation, Astro::PhaseFirstQuarter).to_utc.strftime(DateFormat)
|
28
|
+
print Astro.date_of_moon(lunation, Astro::PhaseFull).to_utc.strftime(DateFormat)
|
29
|
+
puts Astro.date_of_moon(lunation, Astro::PhaseLastQuarter).to_utc.strftime(DateFormat)
|
30
|
+
lunation += 1
|
31
|
+
end
|
data/lib/astro-algo.rb
ADDED
@@ -0,0 +1,846 @@
|
|
1
|
+
# astro.rb
|
2
|
+
# Implementation of astronomical calculations from
|
3
|
+
# Jean Meuss, <i>Astronomical Algorithms</i>, 2nd English Edition,
|
4
|
+
# Willmann-Bell, Inc., Richmond, Virginia, 1999, with corrections as of June 15, 2005.
|
5
|
+
|
6
|
+
|
7
|
+
require 'date'
|
8
|
+
|
9
|
+
# Augment several classes with new methods.
|
10
|
+
|
11
|
+
class Numeric
|
12
|
+
|
13
|
+
# Convert from degrees to radians.
|
14
|
+
def to_rad
|
15
|
+
self * Math::PI / 180.0
|
16
|
+
end
|
17
|
+
|
18
|
+
# Convert from radians to degrees.
|
19
|
+
def to_deg
|
20
|
+
self * 180.0 / Math::PI
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
class Float
|
27
|
+
|
28
|
+
# Convert Float to Rational.
|
29
|
+
# Algorithm from Dave Burt: http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/142199
|
30
|
+
def to_r
|
31
|
+
return Rational(0, 1) if self == 0.0
|
32
|
+
x = self
|
33
|
+
negative = false
|
34
|
+
if x < 0.0
|
35
|
+
x = -x
|
36
|
+
negative = true
|
37
|
+
end
|
38
|
+
f, e = Math.frexp(x)
|
39
|
+
# raise unless 0.5 <= f and f < 1.0
|
40
|
+
# x = f * 2**e exactly
|
41
|
+
|
42
|
+
# Suck up _chunk_ bits at a time; 28 is enough so that we suck
|
43
|
+
# up all bits in 2 iterations for all known binary double-
|
44
|
+
# precision formats, and small enough to fit in an int.
|
45
|
+
chunk = 28
|
46
|
+
top = 0
|
47
|
+
# invariant: x = (top + f) * 2**e exactly
|
48
|
+
while f > 0.0
|
49
|
+
f = Math.ldexp(f, chunk)
|
50
|
+
digit = f.to_i
|
51
|
+
raise unless digit >> chunk == 0
|
52
|
+
top = (top << chunk) | digit
|
53
|
+
f -= digit
|
54
|
+
# raise unless 0.0 <= f and f < 1.0
|
55
|
+
e -= chunk
|
56
|
+
end
|
57
|
+
# raise if top == 0
|
58
|
+
|
59
|
+
# now x = top * 2**e exactly; fold in 2**e
|
60
|
+
r = Rational(top, 1)
|
61
|
+
if e > 0
|
62
|
+
r *= 2**e
|
63
|
+
else
|
64
|
+
r /= 2**-e
|
65
|
+
end
|
66
|
+
negative ? -r : r
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
|
71
|
+
class Array
|
72
|
+
|
73
|
+
# Evaluate polynomial using Horner's method.
|
74
|
+
# Array consists of coefficients of a polynomial, the
|
75
|
+
# coefficient of the highest order term first, the
|
76
|
+
# constant coefficient last.
|
77
|
+
# Returns evaluation of polynomial at +x+.
|
78
|
+
#
|
79
|
+
# Example: evaluate the polynomial x**2 - 0.5*x + 3.0 where x = 2.0
|
80
|
+
# [1.0, -0.5, 3.0].poly_eval(2.0) # => 6.0
|
81
|
+
def poly_eval(x)
|
82
|
+
self.inject(0.0) {|p, a| p*x + a}
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
|
88
|
+
class DateTime
|
89
|
+
|
90
|
+
# Adjust dynamical time to UTC.
|
91
|
+
# Returns rational number of seconds.
|
92
|
+
def to_utc
|
93
|
+
self - Astro.delta_T(self).to_r / 86400 # convert from seconds to days
|
94
|
+
end
|
95
|
+
|
96
|
+
# Truncate date/time to date.
|
97
|
+
# Returns a Date object for the given DateTime.
|
98
|
+
def to_date
|
99
|
+
Date.new(year, month, day)
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
|
105
|
+
module Astro
|
106
|
+
|
107
|
+
VERSION = '0.0.1'
|
108
|
+
|
109
|
+
# Compute difference between dynamical time and UTC in seconds.
|
110
|
+
# See http://sunearth.gsfc.nasa.gov/eclipse/SEcat5/deltatpoly.html.
|
111
|
+
# Good from -1999 to +3000.
|
112
|
+
#
|
113
|
+
# Example: compute the difference between dynamical time and UTC for January 1, 2007.
|
114
|
+
# Astro.delta_T(DateTime.new(2007, 1, 1)) # => 65.465744703125
|
115
|
+
def Astro.delta_T(date)
|
116
|
+
|
117
|
+
year = date.year.to_f
|
118
|
+
y = year + (date.month.to_f - 0.5) / 12.0
|
119
|
+
|
120
|
+
case
|
121
|
+
when year < -500.0
|
122
|
+
u = (year - 1820.0) / 100.0
|
123
|
+
-20.0 + 32.0*u*u
|
124
|
+
when year < 500.0
|
125
|
+
u = y / 100.0
|
126
|
+
[0.0090316521, 0.022174192, -0.1798452, -5.952053, 33.78311, -1014.41, 10583.6].poly_eval(u)
|
127
|
+
when year < 1600.0
|
128
|
+
u = (y - 1000.0) / 100.0
|
129
|
+
[0.0083572073, -0.005050998, -0.8503463, 0.319781, 71.23472, -556.01, 1574.2].poly_eval(u)
|
130
|
+
when year < 1700.0
|
131
|
+
t = y - 1600.0
|
132
|
+
[1.0/7129.0, -0.01532, -0.9808, 120.0].poly_eval(t)
|
133
|
+
when year < 1800.0
|
134
|
+
t = y - 1700.0
|
135
|
+
[-1.0/1174000.0, 0.00013336, -0.0059285, 0.1603, 8.83].poly_eval(t)
|
136
|
+
when year < 1860.0
|
137
|
+
t = y - 1800.0
|
138
|
+
[0.000000000875, -0.0000001699, 0.0000121272, -0.00037436, 0.0041116, 0.0068612, -0.332447, 13.72].poly_eval(t)
|
139
|
+
when year < 1900.0
|
140
|
+
t = y - 1860.0
|
141
|
+
[1.0/233174.0, -0.0004473624, 0.01680668, -0.251754, 0.5737, 7.62].poly_eval(t)
|
142
|
+
when year < 1920.0
|
143
|
+
t = y - 1900.0
|
144
|
+
[-0.000197, 0.0061966, -0.0598939, 1.494119, -2.79].poly_eval(t)
|
145
|
+
when year < 1941.0
|
146
|
+
t = y - 1920.0
|
147
|
+
[0.0020936, -0.076100, 0.84493, 21.20].poly_eval(t)
|
148
|
+
when year < 1961.0
|
149
|
+
t = y - 1950.0
|
150
|
+
[1.0/2547.0, -1.0/233.0, 0.407, 29.07].poly_eval(t)
|
151
|
+
when year < 1986.0
|
152
|
+
t = y - 1975.0
|
153
|
+
[-1.0/718.0, -1.0/260.0, 1.067, 45.45].poly_eval(t)
|
154
|
+
when year < 2005.0
|
155
|
+
t = y - 2000.0
|
156
|
+
[0.00002373599, 0.000651814, 0.0017275, -0.060374, 0.3345, 63.86].poly_eval(t)
|
157
|
+
when year < 2050.0
|
158
|
+
t = y - 2000.0
|
159
|
+
[0.005589, 0.32217, 62.92].poly_eval(t)
|
160
|
+
when year < 2150.0
|
161
|
+
-20.0 + 32.0*((y - 1820.0)/100.0)**2 - 0.5628*(2150.0 - y)
|
162
|
+
else
|
163
|
+
u = (year - 1820.0) / 100.0
|
164
|
+
-20.0 + 32*u*u
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
# =Phases of the Moon
|
169
|
+
|
170
|
+
# :stopdoc:
|
171
|
+
# New and Old Moon
|
172
|
+
Table_49B = [ # page 351
|
173
|
+
# new moon full moon E F M M' O
|
174
|
+
[ 0.00002, 0.00002, 0, 0.0, 0.0, 4.0, 0.0],
|
175
|
+
[-0.00002, -0.00002, 0, 0.0, 1.0, 3.0, 0.0],
|
176
|
+
[-0.00002, -0.00002, 0, -2.0, -1.0, 1.0, 0.0],
|
177
|
+
[ 0.00003, 0.00003, 0, 2.0, -1.0, 1.0, 0.0],
|
178
|
+
[-0.00003, -0.00003, 0, 2.0, 1.0, 1.0, 0.0],
|
179
|
+
[ 0.00003, 0.00003, 0, 2.0, 0.0, 2.0, 0.0],
|
180
|
+
[ 0.00003, 0.00003, 0, -2.0, 1.0, 1.0, 0.0],
|
181
|
+
[ 0.00004, 0.00004, 0, 0.0, 3.0, 0.0, 0.0],
|
182
|
+
[ 0.00004, 0.00004, 0, -2.0, 0.0, 2.0, 0.0],
|
183
|
+
[-0.00007, -0.00007, 0, 0.0, 2.0, 1.0, 0.0],
|
184
|
+
[-0.00017, -0.00017, 0, 0.0, 0.0, 0.0, 1.0],
|
185
|
+
[-0.00024, -0.00024, 1, 0.0, -1.0, 2.0, 0.0],
|
186
|
+
[ 0.00038, 0.00038, 1, -2.0, 1.0, 0.0, 0.0],
|
187
|
+
[ 0.00042, 0.00042, 1, 2.0, 1.0, 0.0, 0.0],
|
188
|
+
[-0.00042, -0.00042, 0, 0.0, 0.0, 3.0, 0.0],
|
189
|
+
[ 0.00056, 0.00056, 1, 0.0, 1.0, 2.0, 0.0],
|
190
|
+
[-0.00057, -0.00057, 0, 2.0, 0.0, 1.0, 0.0],
|
191
|
+
[-0.00111, -0.00111, 0, -2.0, 0.0, 1.0, 0.0],
|
192
|
+
[ 0.00208, 0.00209, 2, 0.0, 2.0, 0.0, 0.0],
|
193
|
+
[-0.00514, -0.00515, 1, 0.0, 1.0, 1.0, 0.0],
|
194
|
+
[ 0.00739, 0.00734, 1, 0.0, -1.0, 1.0, 0.0],
|
195
|
+
[ 0.01039, 0.01043, 0, 2.0, 0.0, 0.0, 0.0],
|
196
|
+
[ 0.01608, 0.01614, 0, 0.0, 0.0, 2.0, 0.0],
|
197
|
+
[ 0.17241, 0.17302, 1, 0.0, 1.0, 0.0, 0.0],
|
198
|
+
[-0.40720, -0.40614, 0, 0.0, 0.0, 1.0, 0.0]
|
199
|
+
]
|
200
|
+
|
201
|
+
# Planetary arguments
|
202
|
+
Table_49A = [ # page 351
|
203
|
+
# k T^2
|
204
|
+
[299.77, 0.107408, 0.000325, -0.009173],
|
205
|
+
[251.88, 0.016321, 0.000165, 0.0 ],
|
206
|
+
[251.83, 26.651886, 0.000164, 0.0 ],
|
207
|
+
[349.42, 36.412478, 0.000126, 0.0 ],
|
208
|
+
[ 84.66, 18.206239, 0.000110, 0.0 ],
|
209
|
+
[141.74, 53.303771, 0.000062, 0.0 ],
|
210
|
+
[207.14, 2.453732, 0.000060, 0.0 ],
|
211
|
+
[154.84, 7.306860, 0.000056, 0.0 ],
|
212
|
+
[ 34.52, 27.261239, 0.000047, 0.0 ],
|
213
|
+
[207.19, 0.121824, 0.000042, 0.0 ],
|
214
|
+
[291.34, 1.844379, 0.000040, 0.0 ],
|
215
|
+
[161.72, 24.198154, 0.000037, 0.0 ],
|
216
|
+
[239.56, 25.513099, 0.000035, 0.0 ],
|
217
|
+
[331.55, 3.592518, 0.000023, 0.0 ]
|
218
|
+
]
|
219
|
+
|
220
|
+
# First and last quarter
|
221
|
+
Table_49C = [ # page 352
|
222
|
+
# E F M M' O
|
223
|
+
[-0.00002, 0, 0.0, 1.0, 3.0, 0.0],
|
224
|
+
[ 0.00002, 0, 2.0, -1.0, 1.0, 0.0],
|
225
|
+
[ 0.00002, 0, -2.0, 0.0, 2.0, 0.0],
|
226
|
+
[ 0.00003, 0, 0.0, 3.0, 0.0, 0.0],
|
227
|
+
[ 0.00003, 0, -2.0, 1.0, 1.0, 0.0],
|
228
|
+
[ 0.00004, 0, 0.0, -2.0, 1.0, 0.0],
|
229
|
+
[-0.00004, 0, 2.0, 1.0, 1.0, 0.0],
|
230
|
+
[ 0.00004, 0, 2.0, 0.0, 2.0, 0.0],
|
231
|
+
[-0.00005, 0, -2.0, -1.0, 1.0, 0.0],
|
232
|
+
[-0.00017, 0, 0.0, 0.0, 0.0, 1.0],
|
233
|
+
[ 0.00027, 1, 0.0, 1.0, 2.0, 0.0],
|
234
|
+
[-0.00028, 2, 0.0, 2.0, 1.0, 0.0],
|
235
|
+
[ 0.00032, 1, -2.0, 1.0, 0.0, 0.0],
|
236
|
+
[ 0.00032, 1, 2.0, 1.0, 0.0, 0.0],
|
237
|
+
[-0.00034, 1, 0.0, -1.0, 2.0, 0.0],
|
238
|
+
[-0.00040, 0, 0.0, 0.0, 3.0, 0.0],
|
239
|
+
[-0.00070, 0, 2.0, 0.0, 1.0, 0.0],
|
240
|
+
[-0.00180, 0, -2.0, 0.0, 1.0, 0.0],
|
241
|
+
[ 0.00204, 2, 0.0, 2.0, 0.0, 0.0],
|
242
|
+
[ 0.00454, 1, 0.0, -1.0, 1.0, 0.0],
|
243
|
+
[ 0.00804, 0, 2.0, 0.0, 0.0, 0.0],
|
244
|
+
[ 0.00862, 0, 0.0, 0.0, 2.0, 0.0],
|
245
|
+
[-0.01183, 1, 0.0, 1.0, 1.0, 0.0],
|
246
|
+
[ 0.17172, 1, 0.0, 1.0, 0.0, 0.0],
|
247
|
+
[-0.62801, 0, 0.0, 0.0, 1.0, 0.0]
|
248
|
+
]
|
249
|
+
# :startdoc:
|
250
|
+
|
251
|
+
PhaseNew = 0
|
252
|
+
PhaseFirstQuarter = 1
|
253
|
+
PhaseFull = 2
|
254
|
+
PhaseLastQuarter = 3
|
255
|
+
|
256
|
+
# Returns DateTime for phase of Moon.
|
257
|
+
# Implementation of algorithm in chapter 49.
|
258
|
+
# k:: number of Moon. k = 0 is first New Moon in the year 2000.
|
259
|
+
# phase:: Astro::PhaseNew, Astro::PhaseFirstQuarter, Astro::PhaseFull, Astro::PhaseLastQuarter
|
260
|
+
#
|
261
|
+
# Example: compute the date and time of New Moon #87 (first lunation in 2007).
|
262
|
+
# Astro.date_of_moon(87, Astro::PhaseNew).asctime # => "Fri Jan 19 04:01:45 2007"
|
263
|
+
def Astro.date_of_moon(k, phase)
|
264
|
+
|
265
|
+
k += phase / 4.0
|
266
|
+
|
267
|
+
# t = Julian centuries
|
268
|
+
t = k / 1236.85
|
269
|
+
|
270
|
+
# Julian Ephemeris Days
|
271
|
+
jde = 2_451_550.097_66 +
|
272
|
+
29.530_588_861 * k +
|
273
|
+
[0.000_000_000_73, -0.000_000_150, 0.000_154_37, 0.0, 0.0].poly_eval(t)
|
274
|
+
|
275
|
+
# Eccentricity of Earth's orbit
|
276
|
+
e = [-0.000_0074, -0.002_516, 1.0].poly_eval(t)
|
277
|
+
|
278
|
+
# Sun's mean anomaly
|
279
|
+
m = 2.5534 +
|
280
|
+
29.105_356_70 * k +
|
281
|
+
[-0.000_000_11, -0.000_0014, 0.0, 0.0].poly_eval(t)
|
282
|
+
|
283
|
+
# Moon's mean anomaly
|
284
|
+
m_lun = 201.5643 +
|
285
|
+
385.816_935_28 * k +
|
286
|
+
[-0.000_000_058, 0.000_012_38, 0.010_7582, 0.0, 0.0].poly_eval(t)
|
287
|
+
|
288
|
+
# Moon's argument of latitude
|
289
|
+
f = 160.7108 +
|
290
|
+
390.670_502_84 * k +
|
291
|
+
[0.000_000_011, -0.000_002_27, -0.001_6118, 0.0, 0.0].poly_eval(t)
|
292
|
+
|
293
|
+
# omega = longitude of the ascending node of the lunar orbit
|
294
|
+
o = 124.7746 -
|
295
|
+
1.563_755_88 * k +
|
296
|
+
[0.000_002_15, 0.002_0672, 0.0, 0.0].poly_eval(t)
|
297
|
+
|
298
|
+
if phase == PhaseNew || phase == PhaseFull # new moon or full moon
|
299
|
+
|
300
|
+
col = phase == PhaseNew ? 0 : 1 # choose column of coefficient
|
301
|
+
corr1 = 0.0
|
302
|
+
for term in Table_49B do
|
303
|
+
t1 = term[col]
|
304
|
+
term[2].times {t1 *= e}
|
305
|
+
t2 = term[3] * f
|
306
|
+
t2 += term[4] * m
|
307
|
+
t2 += term[5] * m_lun
|
308
|
+
t2 += term[6] * o
|
309
|
+
t2 = Math.sin((t2 % 360.0).to_rad)
|
310
|
+
corr1 += t1 * t2
|
311
|
+
end
|
312
|
+
|
313
|
+
jde += corr1
|
314
|
+
|
315
|
+
else # first or last quarter
|
316
|
+
corr1 = 0.0
|
317
|
+
for term in Table_49C do
|
318
|
+
t1 = term[0]
|
319
|
+
term[1].times {t1 *= e}
|
320
|
+
t2 = term[2] * f
|
321
|
+
t2 += term[3] * m
|
322
|
+
t2 += term[4] * m_lun
|
323
|
+
t2 += term[5] * o
|
324
|
+
t2 = Math.sin((t2 % 360.0).to_rad)
|
325
|
+
corr1 += t1 * t2
|
326
|
+
end
|
327
|
+
jde += corr1
|
328
|
+
|
329
|
+
w = 0.00002 * Math.cos((2.0*f).to_rad) +
|
330
|
+
0.00002 * Math.cos((m_lun + m).to_rad) -
|
331
|
+
0.00002 * Math.cos((m_lun - m).to_rad) +
|
332
|
+
0.00026 * Math.cos(m_lun.to_rad) -
|
333
|
+
0.00038 * e * Math.cos(m.to_rad) +
|
334
|
+
0.00306
|
335
|
+
|
336
|
+
if phase == PhaseFirstQuarter
|
337
|
+
jde += w # first quarter
|
338
|
+
else
|
339
|
+
jde -= w # last quarter
|
340
|
+
end
|
341
|
+
end
|
342
|
+
|
343
|
+
# correction for all phases
|
344
|
+
corr2 = 0.0
|
345
|
+
t2 = t*t
|
346
|
+
for term in Table_49A do
|
347
|
+
a = term[0]
|
348
|
+
a += term[1] * k
|
349
|
+
a += term[3] * t2
|
350
|
+
corr2 += Math.sin((a % 360.0).to_rad) * term[2]
|
351
|
+
end
|
352
|
+
|
353
|
+
DateTime.jd((jde + corr2).to_r, 12)
|
354
|
+
end
|
355
|
+
|
356
|
+
# Find number of first lunation (New Moon) for a given year.
|
357
|
+
# Lunation 0 is the first New Moon in the year 2000.
|
358
|
+
# Returns an integer lunation number.
|
359
|
+
#
|
360
|
+
# Example: find first lunation of 1776.
|
361
|
+
# Astro.first_lunation_of_year(1776) # => -2770
|
362
|
+
def Astro.first_lunation_of_year(year)
|
363
|
+
k = ((year - 2000)*12.3685).floor
|
364
|
+
k += 1 while date_of_moon(k, PhaseNew).year < year
|
365
|
+
k
|
366
|
+
end
|
367
|
+
|
368
|
+
|
369
|
+
# :stopdoc:
|
370
|
+
# Vernal Equinox
|
371
|
+
Table_27C = [ # page 179
|
372
|
+
# sum(A cos (B + C*t))
|
373
|
+
# A B C
|
374
|
+
[ 8.0, 15.45, 16_859.074],
|
375
|
+
[ 9.0, 227.73, 1_222.114],
|
376
|
+
[ 12.0, 320.81, 34_777.259],
|
377
|
+
[ 12.0, 287.11, 31_931.756],
|
378
|
+
[ 12.0, 95.39, 14_577.848],
|
379
|
+
[ 14.0, 199.76, 31_436.921],
|
380
|
+
[ 16.0, 198.04, 62_894.029],
|
381
|
+
[ 17.0, 288.79, 4_562.452],
|
382
|
+
[ 18.0, 155.12, 67_555.328],
|
383
|
+
[ 29.0, 60.93, 4_443.417],
|
384
|
+
[ 44.0, 325.15, 31_555.956],
|
385
|
+
[ 45.0, 247.54, 29_929.562],
|
386
|
+
[ 50.0, 21.02, 2_281.226],
|
387
|
+
[ 52.0, 297.17, 150.678],
|
388
|
+
[ 58.0, 119.81, 33_718.147],
|
389
|
+
[ 70.0, 243.58, 9_037.513],
|
390
|
+
[ 74.0, 296.72, 3_034.906],
|
391
|
+
[ 77.0, 222.54, 65_928.934],
|
392
|
+
[136.0, 171.52, 22_518.443],
|
393
|
+
[156.0, 73.14, 45_036.886],
|
394
|
+
[182.0, 27.85, 445_267.112],
|
395
|
+
[199.0, 342.08, 20.186],
|
396
|
+
[203.0, 337.23, 32_964.467],
|
397
|
+
[485.0, 324.96, 1_934.136]
|
398
|
+
]
|
399
|
+
# :startdoc:
|
400
|
+
|
401
|
+
# Compute date and time of Vernal Equinox for given year.
|
402
|
+
# Implementation of low accuracy algorithm in chapter 27.
|
403
|
+
# Good from about -1000 to +3000.
|
404
|
+
# Returns DateTime of Vernal Equinox.
|
405
|
+
#
|
406
|
+
# Example: date of Vernal Equinox of 1999.
|
407
|
+
# Astro.date_of_vernal_equinox_low_accuracy(1999).asctime # => "Sun Mar 21 01:46:59 1999"
|
408
|
+
def Astro.date_of_vernal_equinox_low_accuracy(year)
|
409
|
+
if year >= 1000 # +1000 to +3000
|
410
|
+
y = (year - 2000.0) / 1000.0
|
411
|
+
|
412
|
+
# Julian day of March mean equinox
|
413
|
+
jdme = [-0.000_57, -0.004_11, 0.051_69, 365_242.374_04, 2_451_623.809_84].poly_eval(y)
|
414
|
+
|
415
|
+
else # -1000 to +1000
|
416
|
+
y = year/1000.0
|
417
|
+
|
418
|
+
# Julian day of March mean equinox
|
419
|
+
jdme = [-0.000_71, 0.001_11, 0.061_34, 365_242.137_40, 1_721_139.291_89].poly_eval(y)
|
420
|
+
|
421
|
+
end
|
422
|
+
|
423
|
+
# Julian centuries from 2000
|
424
|
+
t = (jdme - 2_451_545.0) / 36525.0
|
425
|
+
|
426
|
+
w = (35_999.373 * t - 2.47).to_rad
|
427
|
+
lambda = 1.0 + 0.0334*Math.cos(w) + 0.0007 * Math.cos(2.0 * w)
|
428
|
+
s = Table_27C.inject(0.0) {|accum, (a, b, c)| accum + a * Math.cos((b + c*t).to_rad)}
|
429
|
+
|
430
|
+
ve = jdme + 0.000_01 * s / lambda
|
431
|
+
|
432
|
+
DateTime.jd(ve.to_r, 12)
|
433
|
+
end
|
434
|
+
|
435
|
+
# Compute date and time of Vernal Equinox for given year.
|
436
|
+
# Implementation of higher accuracy algorithm in chapter 27.
|
437
|
+
# Returns DateTime of Vernal Equinox.
|
438
|
+
#
|
439
|
+
# Example: date of Vernal Equinox of 1999.
|
440
|
+
# Astro.date_of_vernal_equinox(1999).asctime # => "Sun Mar 21 01:46:56 1999"
|
441
|
+
def Astro.date_of_vernal_equinox(year)
|
442
|
+
est_date = date_of_vernal_equinox_low_accuracy(year)
|
443
|
+
|
444
|
+
5.times do |i|
|
445
|
+
sol_long = solar_longitude(est_date)
|
446
|
+
sol_long -= 360.0 if sol_long > 180.0
|
447
|
+
break if sol_long.abs < 0.000001
|
448
|
+
est_date += (58 * Math.sin(-sol_long.to_rad)).to_r
|
449
|
+
end
|
450
|
+
|
451
|
+
est_date
|
452
|
+
end
|
453
|
+
|
454
|
+
|
455
|
+
# :stopdoc:
|
456
|
+
# Solar Coordinates
|
457
|
+
Table_22A = [
|
458
|
+
# D M M' F omega coef of sin
|
459
|
+
[ 2, -1, 0, 2, 2, -3, 0],
|
460
|
+
[ 0, 0, 3, 2, 2, -3, 0],
|
461
|
+
[ 2, -1, -1, 2, 2, -3, 0],
|
462
|
+
[ 0, -1, 1, 2, 2, -3, 0],
|
463
|
+
[ 0, 1, 1, 0, 0, -3, 0],
|
464
|
+
[-1, -1, 1, 0, 0, -3, 0],
|
465
|
+
[ 0, 0, -2, 2, 2, -3, 0],
|
466
|
+
[ 0, 0, 1, 2, 0, 3, 0],
|
467
|
+
[ 1, 0, 0, 0, 0, -4, 0],
|
468
|
+
[-2, 1, 0, 0, 0, -4, 0],
|
469
|
+
[-1, 0, 1, 0, 0, -4, 0],
|
470
|
+
[ 0, 0, 1, -2, 0, 4, 0],
|
471
|
+
[-2, 1, 0, 2, 1, 4, 0],
|
472
|
+
[-2, 0, 2, 0, 1, 4, 0],
|
473
|
+
[ 0, 0, 2, 2, 1, -5, 0],
|
474
|
+
[-2, 0, 0, 0, 1, -5, 0],
|
475
|
+
[-2, -1, 0, 2, 1, -5, 0],
|
476
|
+
[ 0, -1, 1, 0, 0, 5, 0],
|
477
|
+
[ 2, 0, 0, 0, 1, -6, 0],
|
478
|
+
[ 2, 0, -2, 0, 1, -6, 0],
|
479
|
+
[-2, 0, 1, 2, 1, 6, 0],
|
480
|
+
[-2, 0, 2, 2, 2, 6, 0],
|
481
|
+
[ 2, 0, 1, 0, 0, 6, 0],
|
482
|
+
[ 2, 0, 0, 2, 1, -7, 0],
|
483
|
+
[ 0, -1, 0, 2, 2, -7, 0],
|
484
|
+
[-2, 1, 1, 0, 0, -7, 0],
|
485
|
+
[ 0, 1, 0, 2, 2, 7, 0],
|
486
|
+
[ 2, 0, 1, 2, 2, -8, 0],
|
487
|
+
[ 2, 0, -1, 2, 1, -10, 0],
|
488
|
+
[ 0, 0, 2, -2, 0, 11, 0],
|
489
|
+
[ 0, -1, 0, 0, 1, -12, 0],
|
490
|
+
[-2, 0, 1, 0, 1, -13, 0],
|
491
|
+
[ 0, 1, 0, 0, 1, -15, 0],
|
492
|
+
[-2, 2, 0, 2, 2, -16, 0.1],
|
493
|
+
[ 2, 0, -1, 0, 1, 16, 0],
|
494
|
+
[ 0, 2, 0, 0, 0, 17, -0.1],
|
495
|
+
[ 0, 0, -1, 2, 1, 21, 0],
|
496
|
+
[-2, 0, 0, 2, 0, -22, 0],
|
497
|
+
[ 0, 0, 0, 2, 0, 26, 0],
|
498
|
+
[-2, 0, 1, 2, 2, 29, 0],
|
499
|
+
[ 0, 0, 2, 0, 0, 29, 0],
|
500
|
+
[ 0, 0, 2, 2, 2, -31, 0],
|
501
|
+
[ 2, 0, 0, 2, 2, -38, 0],
|
502
|
+
[ 0, 0, -2, 2, 1, 46, 0],
|
503
|
+
[-2, 0, 2, 0, 0, 48, 0],
|
504
|
+
[ 0, 0, 1, 2, 1, -51, 0],
|
505
|
+
[ 0, 0, -1, 0, 1, -58, -0.1],
|
506
|
+
[ 2, 0, -1, 2, 2, -59, 0],
|
507
|
+
[ 0, 0, 1, 0, 1, 63, 0.1],
|
508
|
+
[ 2, 0, 0, 0, 0, 63, 0],
|
509
|
+
[ 0, 0, -1, 2, 2, 123, 0],
|
510
|
+
[-2, 0, 0, 2, 1, 129, 0.1],
|
511
|
+
[-2, 0, 1, 0, 0, -158, 0],
|
512
|
+
[-2, -1, 0, 2, 2, 217, -0.5],
|
513
|
+
[ 0, 0, 1, 2, 2, -301, 0],
|
514
|
+
[ 0, 0, 0, 2, 1, -386, -0.4],
|
515
|
+
[-2, 1, 0, 2, 2, -517, 1.2],
|
516
|
+
[ 0, 0, 1, 0, 0, 712, 0.1],
|
517
|
+
[ 0, 1, 0, 0, 0, 1426, -3.4],
|
518
|
+
[ 0, 0, 0, 0, 2, 2062, 0.2],
|
519
|
+
[ 0, 0, 0, 2, 2, -2274, -0.2],
|
520
|
+
[-2, 0, 0, 2, 2, -13187, -1.6],
|
521
|
+
[ 0, 0, 0, 0, 1, -171996, -174.2]
|
522
|
+
]
|
523
|
+
# :startdoc:
|
524
|
+
|
525
|
+
# Compute nutation in longitude of Earth's pole for the given DateTime.
|
526
|
+
# Implementation of algorithm in chapter 22.
|
527
|
+
# Returns nutation in degrees.
|
528
|
+
def Astro.nutation_in_longitude(date)
|
529
|
+
|
530
|
+
# Julian centuries from the epoch J2000.0
|
531
|
+
t = (date.ajd.to_f - 2451545.0)/36525.0
|
532
|
+
|
533
|
+
# Mean elongation of the Moon from the Sun
|
534
|
+
d = [1.0/189_474.0, -0.001_9142, 445_267.111_480, 297.85036].poly_eval(t) % 360.0
|
535
|
+
|
536
|
+
# Mean anomaly of the Sun (Earth)
|
537
|
+
m = [-1.0/300_000.0, -0.000_1603, 35_999.050_340, 357.52772].poly_eval(t) % 360.0
|
538
|
+
|
539
|
+
# Mean anomaly of the Moon
|
540
|
+
m_lun = [1.0/56_250.0, 0.008_6972, 477_198.867_398, 134.96298].poly_eval(t) %360.0
|
541
|
+
|
542
|
+
# Moon's argument of latitude
|
543
|
+
f = [1.0/327_270.0, -0.003_6825, 483_202.017_538, 93.27191].poly_eval(t) % 360.0
|
544
|
+
|
545
|
+
# Longitude of the ascending node of the Moon's mean orbit on the ecliptic
|
546
|
+
omega = [1.0/450_000.0, 0.002_0708, -1934.136_261, 125.04452].poly_eval(t) % 360.0
|
547
|
+
|
548
|
+
nutation = 0.0
|
549
|
+
for term in Table_22A do
|
550
|
+
nutation += (term[5] + term[6]*t) *
|
551
|
+
Math.sin((term[0]*d + term[1]*m + term[2]*m_lun + term[3]*f + term[4]*omega).to_rad) / 36_000_000.0
|
552
|
+
end
|
553
|
+
|
554
|
+
nutation
|
555
|
+
|
556
|
+
end
|
557
|
+
|
558
|
+
# Compute longitude of the Sun for the given DateTime.
|
559
|
+
# Implementation of low accuracy algorithm in chapter 25.
|
560
|
+
# Returns longitude in degrees.
|
561
|
+
def Astro.solar_longitude_low_accuracy(date)
|
562
|
+
|
563
|
+
# t = Julian centuries from the epoch J2000.0 (2000 January 1.5 TD)
|
564
|
+
t = (date.ajd.to_f - 2451545.0)/36525.0
|
565
|
+
|
566
|
+
# Mean longitude of the Sun
|
567
|
+
mean_long = [0.000_3032, 36_000.769_83, 280.46646].poly_eval(t) % 360.0
|
568
|
+
|
569
|
+
# Mean anomaly of the Sun
|
570
|
+
mean_anomaly = [-0.000_1537, 35_999.050_29, 357.52911].poly_eval(t) % 360.0
|
571
|
+
|
572
|
+
# Center of the sun
|
573
|
+
m_rad = mean_anomaly.to_rad
|
574
|
+
c = [-0.000_014, -0.004_817, 1.914_602].poly_eval(t) * Math.sin(m_rad) +
|
575
|
+
[-0.000_101, 0.019_993].poly_eval(t) * Math.sin(2.0 * m_rad) +
|
576
|
+
0.000_289 * Math.sin(3.0 * m_rad)
|
577
|
+
|
578
|
+
# True longitude
|
579
|
+
true_long = (mean_long + c) % 360.0
|
580
|
+
|
581
|
+
# Longitude corrected for nutation and the aberration
|
582
|
+
omega = (125.04 - 1934.136*t) % 360.0
|
583
|
+
apparent_long = (true_long - 0.00569 - 0.00478 * Math.sin(omega.to_rad)) % 360.0
|
584
|
+
apparent_long
|
585
|
+
end
|
586
|
+
|
587
|
+
|
588
|
+
# :stopdoc:
|
589
|
+
# Helio-centric coordinates of Earth
|
590
|
+
EarthL0 = [
|
591
|
+
# A B C
|
592
|
+
[ 25.0, 3.16, 4_690.48 ],
|
593
|
+
[ 30.0, 2.74, 1_349.87 ],
|
594
|
+
[ 30.0, 0.44, 83_996.85 ],
|
595
|
+
[ 33.0, 0.59, 17_789.85 ],
|
596
|
+
[ 36.0, 1.78, 6_812.77 ],
|
597
|
+
[ 36.0, 1.71, 2_352.87 ],
|
598
|
+
[ 37.0, 2.57, 1_059.38 ],
|
599
|
+
[ 37.0, 6.04, 10_213.29 ],
|
600
|
+
[ 39.0, 6.17, 10_447.39 ],
|
601
|
+
[ 41.0, 2.40, 19_651.05 ],
|
602
|
+
[ 41.0, 5.37, 8_429.24 ],
|
603
|
+
[ 49.0, 0.49, 1_194.45 ],
|
604
|
+
[ 51.0, 0.28, 5_856.48 ],
|
605
|
+
[ 52.0, 1.33, 1_748.02 ],
|
606
|
+
[ 52.0, 0.19, 12_139.55 ],
|
607
|
+
[ 56.0, 3.47, 6_279.55 ],
|
608
|
+
[ 56.0, 4.39, 14_143.50 ],
|
609
|
+
[ 57.0, 2.78, 6_286.60 ],
|
610
|
+
[ 61.0, 1.82, 7_084.90 ],
|
611
|
+
[ 62.0, 3.98, 8_827.39 ],
|
612
|
+
[ 70.0, 0.83, 9_437.76 ],
|
613
|
+
[ 74.0, 4.68, 801.82 ],
|
614
|
+
[ 74.0, 3.50, 3_154.69 ],
|
615
|
+
[ 75.0, 1.76, 5_088.63 ],
|
616
|
+
[ 79.0, 3.04, 12_036.46 ],
|
617
|
+
[ 80.0, 1.81, 17_260.15 ],
|
618
|
+
[ 85.0, 3.67, 71_430.70 ],
|
619
|
+
[ 85.0, 1.30, 6_275.96 ],
|
620
|
+
[ 86.0, 5.98, 161_000.69 ],
|
621
|
+
[ 98.0, 0.68, 155.42 ],
|
622
|
+
[ 99.0, 6.21, 2_146.17 ],
|
623
|
+
[ 102.0, 4.267, 7.114 ],
|
624
|
+
[ 102.0, 0.976, 15_720.839 ],
|
625
|
+
[ 103.0, 0.636, 4_694.003 ],
|
626
|
+
[ 115.0, 0.645, 0.980 ],
|
627
|
+
[ 126.0, 1.083, 20.775 ],
|
628
|
+
[ 132.0, 3.411, 2_942.463 ],
|
629
|
+
[ 156.0, 0.833, 213.299 ],
|
630
|
+
[ 202.0, 2.458, 6_069.777 ],
|
631
|
+
[ 205.0, 1.869, 5_573.143 ],
|
632
|
+
[ 206.0, 4.806, 2_544.314 ],
|
633
|
+
[ 243.0, 0.345, 5_486.778 ],
|
634
|
+
[ 271.0, 0.315, 10_977.079 ],
|
635
|
+
[ 284.0, 1.899, 796.298 ],
|
636
|
+
[ 317.0, 5.849, 11_790.629 ],
|
637
|
+
[ 357.0, 2.920, 0.067 ],
|
638
|
+
[ 492.0, 4.205, 775.523 ],
|
639
|
+
[ 505.0, 4.583, 18_849.228 ],
|
640
|
+
[ 753.0, 2.533, 5_507.553 ],
|
641
|
+
[ 780.0, 1.179, 5_223.694 ],
|
642
|
+
[ 857.0, 3.508, 398.149 ],
|
643
|
+
[ 902.0, 2.045, 26.298 ],
|
644
|
+
[ 990.0, 5.233, 5_884.927 ],
|
645
|
+
[ 1_199.0, 1.109_6, 1_577.343_5 ],
|
646
|
+
[ 1_273.0, 2.037_1, 529.691_0 ],
|
647
|
+
[ 1_324.0, 0.742_5, 11_506.769_8 ],
|
648
|
+
[ 2_343.0, 6.135_2, 3_930.209_7 ],
|
649
|
+
[ 2_676.0, 4.418_1, 7_860.419_4 ],
|
650
|
+
[ 3_136.0, 3.627_7, 77_713.771_5 ],
|
651
|
+
[ 3_418.0, 2.828_9, 3.523_1 ],
|
652
|
+
[ 3_497.0, 2.744_1, 5_753.384_9 ],
|
653
|
+
[ 34_894.0, 4.626_10, 12_566.151_70 ],
|
654
|
+
[ 3_341_656.0, 4.669_256_8, 6_283.075_850_0 ],
|
655
|
+
[175_347_046.0, 0.0, 0.0 ]
|
656
|
+
]
|
657
|
+
|
658
|
+
EarthL1 = [
|
659
|
+
[ 6.0, 4.67, 4_690.48 ],
|
660
|
+
[ 6.0, 2.65, 9_437.76 ],
|
661
|
+
[ 8.0, 5.30, 2_352.87 ],
|
662
|
+
[ 9.0, 5.64, 951.72 ],
|
663
|
+
[ 9.0, 2.70, 242.73 ],
|
664
|
+
[ 10.0, 4.24, 1_349.87 ],
|
665
|
+
[ 10.0, 1.30, 6_286.60 ],
|
666
|
+
[ 11.0, 0.77, 553.57 ],
|
667
|
+
[ 12.0, 2.08, 4_694.00 ],
|
668
|
+
[ 12.0, 5.27, 1_194.45 ],
|
669
|
+
[ 12.0, 3.26, 5_088.63 ],
|
670
|
+
[ 12.0, 2.83, 1_748.02 ],
|
671
|
+
[ 15.0, 1.21, 10_977.08 ],
|
672
|
+
[ 16.0, 1.43, 2_146.17 ],
|
673
|
+
[ 16.0, 0.03, 2_544.31 ],
|
674
|
+
[ 17.0, 2.99, 6_275.96 ],
|
675
|
+
[ 19.0, 4.97, 213.30 ],
|
676
|
+
[ 19.0, 1.85, 5_486.78 ],
|
677
|
+
[ 21.0, 5.34, 0.98 ],
|
678
|
+
[ 29.0, 2.65, 7.11 ],
|
679
|
+
[ 36.0, 0.47, 775.52 ],
|
680
|
+
[ 45.0, 0.40, 796.30 ],
|
681
|
+
[ 56.0, 2.17, 155.42 ],
|
682
|
+
[ 59.0, 2.89, 5_223.69 ],
|
683
|
+
[ 67.0, 4.41, 5_507.55 ],
|
684
|
+
[ 68.0, 1.87, 398.15 ],
|
685
|
+
[ 72.0, 1.14, 529.69 ],
|
686
|
+
[ 93.0, 2.59, 18_849.23 ],
|
687
|
+
[ 109.0, 2.966, 1_577.344 ],
|
688
|
+
[ 119.0, 5.796, 26.298 ],
|
689
|
+
[ 425.0, 1.590, 3.523 ],
|
690
|
+
[ 4_303.0, 2.635_1, 12_566.151_7 ],
|
691
|
+
[ 206_059.0, 2.678_235, 6_283.075_850],
|
692
|
+
[628_331_966_747.0, 0.0, 0.0 ]
|
693
|
+
]
|
694
|
+
|
695
|
+
EarthL2 = [
|
696
|
+
[ 2.0, 3.75, 0.98 ],
|
697
|
+
[ 2.0, 4.38, 5_233.69 ],
|
698
|
+
[ 3.0, 2.28, 553.57 ],
|
699
|
+
[ 3.0, 0.31, 398.15 ],
|
700
|
+
[ 3.0, 6.12, 529.69 ],
|
701
|
+
[ 3.0, 1.19, 242.73 ],
|
702
|
+
[ 3.0, 6.05, 5_507.55 ],
|
703
|
+
[ 3.0, 5.14, 796.30 ],
|
704
|
+
[ 4.0, 3.44, 5_573.14 ],
|
705
|
+
[ 4.0, 1.03, 7.11 ],
|
706
|
+
[ 5.0, 4.66, 1_577.34 ],
|
707
|
+
[ 7.0, 0.83, 775.52 ],
|
708
|
+
[ 9.0, 2.06, 77_713.77 ],
|
709
|
+
[ 10.0, 0.76, 18_849.23 ],
|
710
|
+
[ 16.0, 3.68, 155.42 ],
|
711
|
+
[ 16.0, 5.19, 26.30 ],
|
712
|
+
[ 27.0, 0.05, 3.52 ],
|
713
|
+
[ 309.0, 0.867, 12_566.152 ],
|
714
|
+
[ 8_720.0, 1.072_1, 6_283.075_8],
|
715
|
+
[52_919.0, 0.0, 0.0 ]
|
716
|
+
]
|
717
|
+
|
718
|
+
EarthL3 = [
|
719
|
+
[ 1.0, 5.97, 242.73 ],
|
720
|
+
[ 1.0, 5.30, 18_849.23 ],
|
721
|
+
[ 1.0, 4.72, 3.52 ],
|
722
|
+
[ 3.0, 5.20, 155.42 ],
|
723
|
+
[ 17.0, 5.49, 12_566.15 ],
|
724
|
+
[ 35.0, 0.0, 0.0 ],
|
725
|
+
[289.0, 5.844, 6_283.076]
|
726
|
+
]
|
727
|
+
|
728
|
+
EarthL4 = [
|
729
|
+
[ 1.0, 3.84, 12_566.15],
|
730
|
+
[ 8.0, 4.13, 6_283.08],
|
731
|
+
[114.0, 3.142, 0.0 ]
|
732
|
+
]
|
733
|
+
|
734
|
+
EarthL5 = [
|
735
|
+
[ 1.0, 3.14, 0.0]
|
736
|
+
]
|
737
|
+
|
738
|
+
EarthR0 = [
|
739
|
+
[ 26, 4.59, 10_447.39 ],
|
740
|
+
[ 28, 1.90, 6_279.55 ],
|
741
|
+
[ 28, 1.21, 6_286.60 ],
|
742
|
+
[ 32, 1.78, 398.15 ],
|
743
|
+
[ 32, 0.18, 5_088.63 ],
|
744
|
+
[ 33, 0.24, 7_084.90 ],
|
745
|
+
[ 35, 1.84, 2_942.46 ],
|
746
|
+
[ 36, 1.67, 12_036.46 ],
|
747
|
+
[ 37, 4.90, 12_139.55 ],
|
748
|
+
[ 37, 0.83, 19_651.05 ],
|
749
|
+
[ 38, 2.39, 8_827.39 ],
|
750
|
+
[ 39, 5.36, 4_694.00 ],
|
751
|
+
[ 43, 6.01, 6_275.96 ],
|
752
|
+
[ 45, 5.54, 9_437.76 ],
|
753
|
+
[ 47, 2.58, 775.52 ],
|
754
|
+
[ 49, 3.25, 2_544.31 ],
|
755
|
+
[ 56, 5.24, 71_430.70 ],
|
756
|
+
[ 57, 2.01, 83_996.85 ],
|
757
|
+
[ 63, 0.92, 529.69 ],
|
758
|
+
[ 65, 0.27, 17_260.15 ],
|
759
|
+
[ 86, 1.27, 161_000.69 ],
|
760
|
+
[ 86, 5.69, 15_720.84 ],
|
761
|
+
[ 98, 0.89, 6_069.78 ],
|
762
|
+
[ 110, 5.055, 5_486.778 ],
|
763
|
+
[ 175, 3.012, 18_849.228 ],
|
764
|
+
[ 186, 5.022, 10_977.079 ],
|
765
|
+
[ 212, 5.847, 1_577.344 ],
|
766
|
+
[ 243, 4.273, 11_790.629 ],
|
767
|
+
[ 307, 0.299, 5_573.143 ],
|
768
|
+
[ 329, 5.900, 5_223.694 ],
|
769
|
+
[ 346, 0.964, 5_507.553 ],
|
770
|
+
[ 472, 3.661, 5_884.927 ],
|
771
|
+
[ 542, 4.564, 3_930.210 ],
|
772
|
+
[ 925, 5.453, 11_506.770 ],
|
773
|
+
[ 1_576, 2.846_9, 7_860.419_4 ],
|
774
|
+
[ 1_628, 1.173_9, 5_753.384_9 ],
|
775
|
+
[ 3_084, 5.198_5, 77_713.771_5 ],
|
776
|
+
[ 13_956, 3.055_25, 12_566.151_70 ],
|
777
|
+
[ 1_670_700, 3.098_463_5, 6_283.075_850_0],
|
778
|
+
[100_013_989, 0, 0 ]
|
779
|
+
]
|
780
|
+
|
781
|
+
EarthR1 = [
|
782
|
+
[ 9, 0.27, 5_486.78 ],
|
783
|
+
[ 9, 1.42, 6_275.96 ],
|
784
|
+
[ 10, 5.91, 10_977.08 ],
|
785
|
+
[ 18, 1.42, 1_577.34 ],
|
786
|
+
[ 25, 1.32, 5_223.69 ],
|
787
|
+
[ 31, 2.84, 5_507.55 ],
|
788
|
+
[ 32, 1.02, 18_849.23 ],
|
789
|
+
[ 702, 3.142, 0 ],
|
790
|
+
[ 1_721, 1.064_4, 12_566.151_7 ],
|
791
|
+
[103_019, 1.107_490, 6_283.075_850]
|
792
|
+
]
|
793
|
+
|
794
|
+
EarthR2 = [
|
795
|
+
[ 3, 5.47, 18_849.23 ],
|
796
|
+
[ 6, 1.87, 5_573.14 ],
|
797
|
+
[ 9, 3.63, 77_713.77 ],
|
798
|
+
[ 12, 3.14, 0 ],
|
799
|
+
[ 124, 5.579, 12_566.152 ],
|
800
|
+
[4_359, 5.784_6, 6_283.075_8]
|
801
|
+
]
|
802
|
+
|
803
|
+
EarthR3 = [
|
804
|
+
[ 7, 3.92, 12_566.15 ],
|
805
|
+
[145, 4.273, 6_283.076]
|
806
|
+
]
|
807
|
+
|
808
|
+
EarthR4 = [
|
809
|
+
[4, 2.56, 6_283.08]
|
810
|
+
]
|
811
|
+
# :startdoc:
|
812
|
+
|
813
|
+
|
814
|
+
# Compute longitude of Sun for given DateTime.
|
815
|
+
# Implementation of higher accuracy algorithm in chapter 25.
|
816
|
+
# Accurate to within 1" between the years -2000 and +6000.
|
817
|
+
# Returns longitude in degrees.
|
818
|
+
def Astro.solar_longitude(date)
|
819
|
+
|
820
|
+
# t = Julian millennia from the epoch J2000.0 (2000 January 1.5 TD)
|
821
|
+
t = (date.ajd.to_f - 2451545.0)/365250.0
|
822
|
+
|
823
|
+
l0 = EarthL0.inject(0.0) {|accum, (a, b, c)| accum + a * Math.cos(b + c*t)}
|
824
|
+
l1 = EarthL1.inject(0.0) {|accum, (a, b, c)| accum + a * Math.cos(b + c*t)}
|
825
|
+
l2 = EarthL2.inject(0.0) {|accum, (a, b, c)| accum + a * Math.cos(b + c*t)}
|
826
|
+
l3 = EarthL3.inject(0.0) {|accum, (a, b, c)| accum + a * Math.cos(b + c*t)}
|
827
|
+
l4 = EarthL4.inject(0.0) {|accum, (a, b, c)| accum + a * Math.cos(b + c*t)}
|
828
|
+
l5 = EarthL5.inject(0.0) {|accum, (a, b, c)| accum + a * Math.cos(b + c*t)}
|
829
|
+
long = (([l5, l4, l3, l2, l1, l0].poly_eval(t) * 1e-8).to_deg) % 360.0
|
830
|
+
|
831
|
+
r0 = EarthR0.inject(0.0) {|accum, (a, b, c)| accum + a * Math.cos(b + c*t)}
|
832
|
+
r1 = EarthR1.inject(0.0) {|accum, (a, b, c)| accum + a * Math.cos(b + c*t)}
|
833
|
+
r2 = EarthR2.inject(0.0) {|accum, (a, b, c)| accum + a * Math.cos(b + c*t)}
|
834
|
+
r3 = EarthR3.inject(0.0) {|accum, (a, b, c)| accum + a * Math.cos(b + c*t)}
|
835
|
+
r4 = EarthR4.inject(0.0) {|accum, (a, b, c)| accum + a * Math.cos(b + c*t)}
|
836
|
+
radius = [r4, r3, r2, r1, r0].poly_eval(t) * 1e-8
|
837
|
+
aberration = -0.0056916111/radius
|
838
|
+
|
839
|
+
long -= 180.0 # switch to Earth's perspective
|
840
|
+
long += -2.509167e-5 # convert to FK5 system
|
841
|
+
long += nutation_in_longitude(date)
|
842
|
+
long += aberration # correct for aberration
|
843
|
+
long % 360.0
|
844
|
+
end
|
845
|
+
|
846
|
+
end
|
data/lib/lunaryear.rb
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
# lunaryear.rb
|
2
|
+
# Lunar calendar library.
|
3
|
+
#
|
4
|
+
# Lunar months (or moonths) begin on the day of the New Moon in Coordinated
|
5
|
+
# Universal Time.
|
6
|
+
#
|
7
|
+
# The lunar year begins at the beginning of the moonth during which the
|
8
|
+
# Vernal Equinox occurs, usually March 20 or 21. Twelve moonths fall short
|
9
|
+
# of the Solar year by about 10 or 11 days, so an additional thirteenth
|
10
|
+
# moonth occurs every two or three years.
|
11
|
+
|
12
|
+
require File.join(File.dirname(__FILE__), 'astro-algo')
|
13
|
+
|
14
|
+
module LunarYear
|
15
|
+
|
16
|
+
# Calculate the lunar calendar date for the given DateTime.
|
17
|
+
# Returns [year, moonth, day].
|
18
|
+
def LunarYear.lunar_date(date)
|
19
|
+
year = date.year
|
20
|
+
lun0 = LunarYear.new_moon_before_vernal_equinox(year) # Year begins at Vernal Equinox
|
21
|
+
if date < Astro.date_of_moon(lun0, Astro::PhaseNew).to_date
|
22
|
+
year -= 1
|
23
|
+
lun0 = new_moon_before_vernal_equinox(year)
|
24
|
+
end
|
25
|
+
prev_moon = Astro.date_of_moon(lun0, Astro::PhaseNew).to_date
|
26
|
+
lun = lun0
|
27
|
+
loop do
|
28
|
+
lun += 1
|
29
|
+
new_moon = Astro.date_of_moon(lun, Astro::PhaseNew).to_date
|
30
|
+
break if new_moon > date
|
31
|
+
prev_moon = new_moon
|
32
|
+
end
|
33
|
+
moonth = lun - lun0 - 1
|
34
|
+
day = (date - prev_moon).to_i
|
35
|
+
[year, moonth, day]
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
# Find number of lunation (New Moon) just before Vernal Equinox for a given year.
|
40
|
+
# Lunation 0 is the first New Moon in the year 2000.
|
41
|
+
# Returns an integer lunation number.
|
42
|
+
#
|
43
|
+
# Example: first lunation before Vernal Equinox of the year 1984.
|
44
|
+
# LunarYear.new_moon_before_vernal_equinox(1984) # => -196
|
45
|
+
def LunarYear.new_moon_before_vernal_equinox(year)
|
46
|
+
equ = Astro.date_of_vernal_equinox(year)
|
47
|
+
lunation = Astro.first_lunation_of_year(year)
|
48
|
+
new_moon = Astro.date_of_moon(lunation, Astro::PhaseNew)
|
49
|
+
loop do
|
50
|
+
previous_new_moon = new_moon
|
51
|
+
lunation += 1
|
52
|
+
new_moon = Astro.date_of_moon(lunation, Astro::PhaseNew)
|
53
|
+
return lunation-1 if new_moon > equ
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
# Calculate the DateTime of the previous New and Full Moons
|
59
|
+
# and the DateTime of the next New and Full moons.
|
60
|
+
# Returns [previous New Moon, next New Moon, previous Full Moon, next Full Moon]
|
61
|
+
#
|
62
|
+
# Example: For November 18, 2007, calculate the date and time of the previous New Moon,
|
63
|
+
# the next New Moon, the previous Full Moon, and the next Full Moon.
|
64
|
+
# LunarYear.date_of_moons(DateTime.civil(2007, 11, 18)).collect {|d| d.asctime}
|
65
|
+
# #=> ["Fri Nov 9 23:03:07 2007", "Sun Dec 9 17:40:21 2007", "Fri Oct 26 04:51:33 2007", "Sat Nov 24 14:29:47 2007"]
|
66
|
+
def LunarYear.date_of_moons(date)
|
67
|
+
next_new_moon = nil
|
68
|
+
next_full_moon = nil
|
69
|
+
|
70
|
+
k = ((date.year - 2000)*12.3685).floor - 1
|
71
|
+
prev_new_moon = Astro.date_of_moon(k, Astro::PhaseNew).to_utc
|
72
|
+
lun = k
|
73
|
+
loop do
|
74
|
+
lun += 1
|
75
|
+
next_new_moon = Astro.date_of_moon(lun, Astro::PhaseNew).to_utc
|
76
|
+
break if next_new_moon > date
|
77
|
+
prev_new_moon = next_new_moon
|
78
|
+
end
|
79
|
+
|
80
|
+
lun = k
|
81
|
+
prev_full_moon = Astro.date_of_moon(k, Astro::PhaseFull).to_utc
|
82
|
+
loop do
|
83
|
+
lun += 1
|
84
|
+
next_full_moon = Astro.date_of_moon(lun, Astro::PhaseFull).to_utc
|
85
|
+
break if next_full_moon > date
|
86
|
+
prev_full_moon = next_full_moon
|
87
|
+
end
|
88
|
+
|
89
|
+
[prev_new_moon, next_new_moon, prev_full_moon, next_full_moon]
|
90
|
+
end
|
91
|
+
end
|
metadata
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: astro-algo
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ""
|
6
|
+
authors:
|
7
|
+
- John P. Powers
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2007-11-27 00:00:00 -06:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: This library implements algorithms from Jean Meeus, Astronomical Algorithms, 2nd English Edition, Willmann-Bell, Inc., Richmond, Virginia, 1999, with corrections as of June 15, 2005.
|
17
|
+
email: john@jppowers.net
|
18
|
+
executables:
|
19
|
+
- equinox
|
20
|
+
- lunarcalendar
|
21
|
+
- moon_clock.rb
|
22
|
+
- moons
|
23
|
+
extensions: []
|
24
|
+
|
25
|
+
extra_rdoc_files: []
|
26
|
+
|
27
|
+
files:
|
28
|
+
- bin/moon_clock.rb
|
29
|
+
- lib/astro-algo.rb
|
30
|
+
- lib/lunaryear.rb
|
31
|
+
- README
|
32
|
+
- bin/equinox
|
33
|
+
- bin/lunarcalendar
|
34
|
+
- bin/moons
|
35
|
+
has_rdoc: true
|
36
|
+
homepage: http://astro-algo.rubyforge.org/astro-algo
|
37
|
+
post_install_message:
|
38
|
+
rdoc_options:
|
39
|
+
- --title
|
40
|
+
- Astro API documentation
|
41
|
+
- --main
|
42
|
+
- README
|
43
|
+
require_paths:
|
44
|
+
- lib
|
45
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: "0"
|
50
|
+
version:
|
51
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: "0"
|
56
|
+
version:
|
57
|
+
requirements: []
|
58
|
+
|
59
|
+
rubyforge_project: astro-algo
|
60
|
+
rubygems_version: 0.9.5
|
61
|
+
signing_key:
|
62
|
+
specification_version: 2
|
63
|
+
summary: Implementation of algorithms in _Astronomical Algorithms_. Useful for computing phases of the moon.
|
64
|
+
test_files: []
|
65
|
+
|