summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--info/blueshift.texinfo32
-rw-r--r--src/solar.py117
2 files changed, 134 insertions, 15 deletions
diff --git a/info/blueshift.texinfo b/info/blueshift.texinfo
index 23d810e..a19d0f4 100644
--- a/info/blueshift.texinfo
+++ b/info/blueshift.texinfo
@@ -216,11 +216,11 @@ high night and 6500 K during the high day.
Specify your geographical coordinates. This
is used to determine how dark it is outside.
@env{LAT} is the latitude, floating point
-measured in degrees from the equator to the
-north. It is negative if you are on the
+measured in degrees celestial northwards from
+the equator. It is negative if you are on the
southern hemisphere. @env{LON} is the
longitude, floating point measured in degrees
-from Greenwich to the east. Negative if you
+eastwards from Greenwich. Negative if you
are on the west side of the Earth.
@item -r
@@ -753,12 +753,12 @@ point. It has three optional parameters:
The time in Julian Centuries.
@item low = -6.0
-The suns elevation at the limit to high night, that
+The Suns elevation at the limit to high night, that
is, the highest possible position (measured in degrees)
-of the sun before it becomes visible.
+of the Sun before it becomes visible.
@item high = 3.0
-The suns elevation at the limit to high day, that is,
+The Suns elevation at the limit to high day, that is,
the lowest possible position (measured in degrees) of
the before it starts becoming less visible (twilight.)
@end table
@@ -817,13 +817,27 @@ Converts from radians to degrees.
@item corrected_mean_ecliptic_obliquity(t)
@item solar_declination(t)
@item equation_of_time(t)
-@item hour_angle_from_elevation(latitude, declinaton, elevation)
-@item elevation_from_hour_angle(latitude, declinaton, hour_angle)
+@item hour_angle_from_elevation(latitude, declination, elevation)
+Calculates the solar hour angle from the Sun's elevation.
+
+@item elevation_from_hour_angle(latitude, declination, hour_angle)
+Calculates the Sun's elevation from the solar hour angle.
+
@item time_of_solar_noon(t, longitude)
+Calculates the time of the closest solar noon.
+
@item time_of_solar_elevation(t, noon, latitude, longitude, elevation)
+Calculates the time the Sun has the apparent elevation
+@code{elevation}, in degrees, at the geographical position
+(@code{latitude}, @code{longitude}). @code{noon} is the
+time the closest the solar noon.
+
@item solar_elevation_from_time(t, latitude, longitude)
+Calculates the Suns elevation, in degrees, as apparent from the
+geographical position (@code{latitude}, @code{longitude}).
+
@item solar_elevation(latitude, longitude, t = None)
-Does the same thing as @code{solar_elevation_from_time},
+Calculates the same thing as @code{solar_elevation_from_time},
except the time is optional and defaults to the current time.
@end table
diff --git a/src/solar.py b/src/solar.py
index c8d7677..b418b41 100644
--- a/src/solar.py
+++ b/src/solar.py
@@ -44,45 +44,99 @@ def sun(latitude, longitude, t = None, low = -6.0, high = 3.0):
def julian_day_to_epoch(t):
+ '''
+ Converts a Julian Day timestamp to a POSIX time timestamp
+
+ @param t:float The time in Julian Days
+ @return :float The time in POSIX time
+ '''
return (jd - 2440587.5) * 86400.0
def epoch_to_julian_day(t):
+ '''
+ Converts a POSIX time timestamp to a Julian Day timestamp
+
+ @param t:float The time in POSIX time
+ @return :float The time in Julian Days
+ '''
return t / 86400.0 + 2440587.5
def julian_day_to_julian_centuries(t):
+ '''
+ Converts a Julian Day timestamp to a Julian Centuries timestamp
+
+ @param t:float The time in Julian Days
+ @return :float The time in Julian Centuries
+ '''
return (t - 2451545.0) / 36525.0
def julian_centuries_to_julian_day(t):
+ '''
+ Converts a Julian Centuries timestamp to a Julian Day timestamp
+
+ @param t:float The time in Julian Centuries
+ @return :float The time in Julian Days
+ '''
return t * 36525.0 + 2451545.0
def epoch_to_julian_centuries(t):
+ '''
+ Converts a POSIX time timestamp to a Julian Centuries timestamp
+
+ @param t:float The time in POSIX time
+ @return :float The time in Julian Centuries
+ '''
return julian_day_to_julian_centuries(epoch_to_julian_day(t))
def julian_centuries_to_epoch(t):
+ '''
+ Converts a Julian Centuries timestamp to a POSIX time timestamp
+
+ @param t:float The time in Julian Centuries
+ @return :float The time in POSIX time
+ '''
return julian_day_to_epoch(julian_centuries_to_julian_day(t))
def epoch():
'''
Get current POSIX time
+
+ @return :float The current POSIX time
'''
return time.time()
def julian_day():
'''
Get current Julian Day time
+
+ @return :float The current Julian Day time
'''
return epoch_to_julian_day(epoch())
def julian_centuries():
'''
Get current Julian Centuries time
+
+ @return :float The current Julian Centuries time
'''
return epoch_to_julian_centuries(epoch())
def radians(deg):
+ '''
+ Convert an angle from degrees to radians
+
+ @param deg:float The angle in degrees
+ @return :float The angle in radians
+ '''
return deg * math.pi / 180
def degrees(rad):
+ '''
+ Convert an angle from radians to degrees
+
+ @param rad:float The angle in radians
+ @return :float The angle in degrees
+ '''
return rad * 180 / math.pi
def sun_geometric_mean_longitude(t):
@@ -139,22 +193,45 @@ def equation_of_time(t):
rc -= 1.25 * e ** 2 * math.sin(2 * m)
return 4 * degrees(rc)
-def hour_angle_from_elevation(latitude, declinaton, elevation):
+def hour_angle_from_elevation(latitude, declination, elevation):
+ '''
+ Calculates the solar hour angle from the Sun's elevation
+
+ @param longitude:float The longitude in degrees eastwards from Greenwich, negative for westwards
+ @param declination:float The declination, in degrees
+ @param hour_angle:float The suns elevation, in degrees
+ @return :float The solar hour angle, in degrees
+ '''
if elevation == 0:
return 0
rc = math.cos(abs(elevation))
- rc -= math.sin(radians(latitude)) * math.sin(declinaton)
- rc /= math.cos(radians(latitude)) * math.cos(declinaton)
+ rc -= math.sin(radians(latitude)) * math.sin(declination)
+ rc /= math.cos(radians(latitude)) * math.cos(declination)
rc = math.acos(rc)
return -rc if (rc < 0) == (elevation < 0) else rc;
-def elevation_from_hour_angle(latitude, declinaton, hour_angle):
+def elevation_from_hour_angle(latitude, declination, hour_angle):
+ '''
+ Calculates the Sun's elevation from the solar hour angle
+
+ @param longitude:float The longitude in degrees eastwards from Greenwich, negative for westwards
+ @param declination:float The declination, in degrees
+ @param hour_angle:float The solar hour angle, in degrees
+ @return :float The suns elevation, in degrees
+ '''
rc = math.cos(radians(latitude))
- rc *= math.cos(hour_angle) * math.cos(declinaton)
- rc += math.sin(radians(latitude)) * math.sin(declinaton)
+ rc *= math.cos(hour_angle) * math.cos(declination)
+ rc += math.sin(radians(latitude)) * math.sin(declination)
return math.asin(rc)
def time_of_solar_noon(t, longitude):
+ '''
+ Calculates the time of the closest solar noon
+
+ @param t:float A time close to the seeked time, in Julian Centuries
+ @param longitude:float The longitude in degrees eastwards from Greenwich, negative for westwards
+ @return :float The time, in Julian Centuries, of the closest solar noon
+ '''
t, rc = julian_centuries_to_julian_day(t), longitude
for (k, m) in ((-360, 0), (1440, -0.5)):
rc = julian_day_to_julian_centuries(t + m + rc / k)
@@ -162,6 +239,16 @@ def time_of_solar_noon(t, longitude):
return rc
def time_of_solar_elevation(t, noon, latitude, longitude, elevation):
+ '''
+ Calculates the time the Sun has a specified apparent elevation at a geographical position
+
+ @param t:float A time close to the seeked time, in Julian Centuries
+ @param noon:float The time of the closest solar noon
+ @param latitude:float The latitude in degrees northwards from the equator, negative for southwards
+ @param longitude:float The longitude in degrees eastwards from Greenwich, negative for westwards
+ @param elevation:float The solar elevation, in degrees
+ @return :float The time, in Julian Centuries, of the specified elevation
+ '''
rc = noon
rc, et = solar_declination(rc), equation_of_time(rc)
rc = hour_angle_from_elevation(latitude, rc, elevation)
@@ -174,6 +261,15 @@ def time_of_solar_elevation(t, noon, latitude, longitude, elevation):
return rc
def solar_elevation_from_time(t, latitude, longitude):
+ '''
+ Calculates the Suns elevation as apparent from a geographical position
+
+ @param t:float The time in Julian Centuries
+ @param latitude:float The latitude in degrees northwards from the equator, negative for southwards
+ @param longitude:float The longitude in degrees eastwards from Greenwich, negative for westwards
+ @return :float The suns apparent at the specified time as seen from the specified position,
+ measured in degrees
+ '''
rc = julian_centuries_to_julian_day(t)
rc = (rc - float(int(rc + 0.5)) - 0.5) * 1440
rc = 720 - rc - equation_of_time(t)
@@ -181,6 +277,15 @@ def solar_elevation_from_time(t, latitude, longitude):
return elevation_from_hour_angle(latitude, solar_declination(t), rc)
def solar_elevation(latitude, longitude, t = None):
+ '''
+ Calculates the Suns elevation as apparent from a geographical position
+
+ @param latitude:float The latitude in degrees northwards from the equator, negative for southwards
+ @param longitude:float The longitude in degrees eastwards from Greenwich, negative for westwards
+ @param t:float? The time in Julian Centuries, `None` for the current time
+ @return :float The suns apparent at the specified time as seen from the specified position,
+ measured in degrees
+ '''
rc = julian_centuries() if t is None else t
rc = solar_elevation_from_time(rc, latitude, longitude)
return degrees(rc)