I'm trying to improve the U.S. Naval Observatory's algorithm for calculating the position of the sun, by writing it in a simpler way where all the numbers used have been properly identified - so normal people can understand it as well.
But somehow, the equation of time is off by 27 days. Maybe someone here can spot what's wrong?
Test run:
1) Failure:
test_equation_of_time(TestSolarCalculations):
Expected 2011-10-01 10:23:00 UTC, not 2011-10-28 10:59:31 UTC.
2) Failure:
test_suns_declination(TestSolarCalculations):
Expected -3.18, not -3.2087920449753007.
New algorithm:
# Constants for J2000.0 / 1 Jan 2000 12:00Z:
#
EPOCHS_JULIAN_DATE = 2451545
ANOMALISTIC_YEAR_IN_DAYS = 365.259636
TROPICAL_YEAR_IN_DAYS = 365.2421897
SUNS_MEAN_ANOMALY_AT_EPOCH = degrees_to_radians 357.5291
SUNS_MEAN_LONGITUDE_AT_EPOCH = degrees_to_radians 280.459
SUNS_GEODETIC_PRECESSION = degrees_to_radians 1.915
EARTHS_ORBITAL_ECCENTRICITY = 0.020
EARTHS_ADJUSTED_AVERAGE_RADIUS_IN_AU = 1.00014
EARTHS_APPROXIMATE_ATMOSPHERIC_REFRACTION = degrees_to_radians 0.01671
EARTHS_ECLIPTIC_MEAN_OBLIQUITY = degrees_to_radians 23.439
EARTHS_ECLIPTIC_OBLIQUITY_CHANGE_RATE = degrees_to_radians 0.00000036
def days_from_epoch
@todays_julian_date - EPOCHS_JULIAN_DATE
end
def suns_daily_mean_anomaly_change_rate
degrees_to_radians(360 / ANOMALISTIC_YEAR_IN_DAYS)
end
def suns_mean_anomaly
SUNS_MEAN_ANOMALY_AT_EPOCH + suns_daily_mean_anomaly_change_rate * days_from_epoch
end
def suns_daily_mean_longitude_change_rate
degrees_to_radians(360 / TROPICAL_YEAR_IN_DAYS)
end
def suns_mean_longitude
SUNS_MEAN_LONGITUDE_AT_EPOCH + suns_daily_mean_longitude_change_rate * days_from_epoch
end
def suns_apparent_ecliptic_longitude
suns_mean_longitude + SUNS_GEODETIC_PRECESSION * sin(suns_mean_anomaly) + EARTHS_ORBITAL_ECCENTRICITY * sin(2 * suns_mean_anomaly)
end
def suns_distance_from_earth_in_au
EARTHS_ADJUSTED_AVERAGE_RADIUS_IN_AU - EARTHS_APPROXIMATE_ATMOSPHERIC_REFRACTION * cos(suns_mean_anomaly) - (EARTHS_APPROXIMATE_ATMOSPHERIC_REFRACTION ^ 2 / 2) * cos(2 * suns_mean_anomaly)
end
def earths_ecliptic_mean_obliquity
EARTHS_ECLIPTIC_MEAN_OBLIQUITY - EARTHS_ECLIPTIC_OBLIQUITY_CHANGE_RATE * days_from_epoch
end
def suns_right_ascension
atan2(cos(suns_apparent_ecliptic_longitude) * sin(suns_apparent_ecliptic_longitude), cos(suns_apparent_ecliptic_longitude)) / 15
end
# Time.utc(Time.now.year) => 2011-01-01 00:00:00 UTC
#
def equation_of_time
Time.utc(Time.now.year) + (radians_to_degrees(suns_mean_longitude) / 15 - suns_right_ascension) * 60 * 60 * 24
end
def suns_declination
radians_to_degrees(asin(sin(earths_ecliptic_mean_obliquity) * sin(suns_apparent_ecliptic_longitude)))
end
Thanks!
Mats
May be it is an issue with the precision of Ruby floating point numbers, not an issue with your program's logic? I haven't used ruby, but it seems there are some issues in ruby floating point operations exists according to thisposts. Issue with precision of Ruby math operations
According to the post, you may need to use BigDecimal class for your floating point operations. I actually didn't go through your program, this is just a guess.