1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
|
# -*- python -*-
'''
xpybar – xmobar replacement written in python
Copyright © 2014, 2015, 2016 Mattias Andrée (maandree@member.fsf.org)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
'''
import math
import time
class Lunar:
'''
Lunar observation
@variable fraction:float The phase of the moon increasing linearly. 0 on new moon, 0,5 on
full moon. ]0, 0,5[ when waxing and ]0m5, 1[ when waning.
@variable waxing:bool `True` when moon is waxing (increasing illumination) and `False`
when waning (decreasing). Not well defined on new moon (fraction = 0,
illumination = 0) and full moon (fraction = 0,5, illumination = 1).
@variable terminator:float The latitude, as seen from the northern hemisphere on Earth, of the
terminator. The terminator is the line delimiting the sunlit area
and the dark area.
@variable illumination:float The illumnation of the moon, the fraction of the visible side's
area that is sunlit
'''
REFERENCE_NEW_MOON = 934329600 # 11 August 1999 00:00:00 UTC
'''
:float Time of last known new moon, in POSIX time
'''
SYNODIC_MONTH = 29.530588853
'''
:float The length of a lunar month, in days
'''
def __init__(self):
'''
Constructor
'''
julian_day = lambda t : t / 86400.0 + 2440587.5
radians = lambda deg : deg * math.pi / 180
hacoversin = lambda deg : 0.5 - math.sin(radians(deg)) / 2
ref = julian_day(Lunar.REFERENCE_NEW_MOON)
now = julian_day(time.time())
# TODO how to we calculate the Moon's apparent geocentric celestial longitude
self.fraction = ((now - ref) / Lunar.SYNODIC_MONTH) % 1
self.waxing = self.fraction <= 0.5 # we get an off by one without equality
self.terminator = 90 - 360 * self.fraction # sunlit trailing
if self.terminator < -90:
self.terminator += 180 # visible side
inverted = self.terminator < 0
self.illumination = hacoversin(abs(self.terminator))
if (not self.waxing) != inverted:
self.illumination = 1 - self.illumination
# TODO add libration
# TODO add phase names
# TODO add solar and lunar eclipses
# TODO add position of sunlit area
# TODO add tides
# TODO add blue moon
# TODO add black moon
# TODO add moon colour
# TODO add altitude
# TODO add azimuth
# TODO add zodiac sign
# TODO add distances
# TODO add angular diameters
|