Positie van de zon, tijdsverhouding: VERKEERD 27 DAGEN

Ik probeer het algoritme van het US Naval Observatory voor het berekenen van de positie van de zon , door het op een eenvoudigere manier te schrijven waar alle gebruikte nummers correct zijn geïdentificeerd - dus normale mensen kunnen het ook begrijpen.

Maar op de een of andere manier is de vergelijking van de tijd 27 dagen voorbij. Misschien kan iemand hier zien wat er mis is?

Testrun:

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.

Nieuw algoritme:

# 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

Bedankt!

Mats

1
Zou je de oude code kunnen posten, die (ik veronderstel) werkt?
toegevoegd de auteur Beta, de bron
@ ja72: ziet eruit als Ruby.
toegevoegd de auteur Mechanical snail, de bron
Markeer de gebruikte taal en overweeg over te stappen naar codereview.stackexchange.com .
toegevoegd de auteur ja72, de bron
@ ja72 codereview is voor werkende code, toch?
toegevoegd de auteur AakashM, de bron
Ik denk dat je code op de een of andere manier wordt gemengd: de waarde van de eccentriciteit van de aarde is 0.01671 (zie Wikipedia). U gebruikt exact deze waarde voor atmosferische breking en converteert deze van graden naar radialen. Dat is onzin.
toegevoegd de auteur Curd, de bron
@ ja72: Dit is echter niet echt een Ruby-vraag.
toegevoegd de auteur Molvær, de bron

3 antwoord

Een deel van mijn code.

# From angles.rb:
# eccentricity of elliptical Earth orbit around Sun # Horner calculation method def eccentricity_Earth( ta = A2000 ) ta = check_jct_zero( ta ) # 0.016708617 - ta[ 0 ] * ( 0.000042037 + ta[ 0 ] * 0.0000001235 ) [-0.0000001235, -0.000042037, 0.016708617].inject(0.0) {|p, a| p * ta[0] + a} end alias_method :eccentricity_earth_orbit, :eccentricity_Earth

From: Equation of Time ruby gem

Waar wordt het gebruikt?

# From angles.rb:
# equation of centre # added to mean anomaly to get true anomaly. def center( ta = A2000) ta = check_jct_zero( ta ) sine_1M = sin( 1.0 * deg_to_rad( @ma ) ) sine_2M = sin( 2.0 * deg_to_rad( @ma ) ) sine_3M = sin( 3.0 * deg_to_rad( @ma ) ) sine_4M = sin( 4.0 * deg_to_rad( @ma ) ) sine_5M = sin( 5.0 * deg_to_rad( @ma ) ) e = eccentricity_Earth( ta ) rad_to_deg( sine_1M * ( 2.0 * e - e**3/4.0 + 5/96.0 * e**5 ) + sine_2M * ( 5/4.0 * e**2 - 11/24.0 * e**4 ) + sine_3M * ( 13/12.0 * e**3 - 43/64.0 * e**5 ) + sine_4M * 103/96.0 * e**4 + sine_5M * 1097/960.0 * e**5 ) # sine_1M *( 1.914602 - ta[ 0 ] * ( 0.004817 + ta[ 0 ] * 0.000014 )) + # sine_2M *( 0.019993 - ta[ 0 ] * 0.000101 ) + # sine_3M * 0.000289 end alias_method :equation_of_center, :center
1
toegevoegd

Hier:

def suns_apparent_ecliptic_longitude
  suns_mean_longitude 
  + SUNS_GEODETIC_PRECESSION * sin(suns_mean_anomaly) 
  + EARTHS_ORBITAL_ECCENTRICITY * sin(2 * suns_mean_anomaly)
end

je bent eenheden aan het mixen. suns_mean_longitude is radialen, net als SUNS_GEODETIC_PRECESSION (en dus is dit de tweede term), maar EARTHS_ORBITAL_ECCENTRICITY is 0.020 < strong> graden .

Bovendien:

EARTHS_APPROXIMATE_ATMOSPHERIC_REFRACTION = degrees_to_radians 0.01671

zou gewoon moeten zijn

EARTHS_APPROXIMATE_ATMOSPHERIC_REFRACTION = 0.01671

Ik denk dat dit wordt gebruikt in een formule die een afstand bepaalt.

Bijkomend bovendien

def suns_right_ascension
  atan2(cos(suns_apparent_ecliptic_longitude) * sin(suns_apparent_ecliptic_longitude), cos(suns_apparent_ecliptic_longitude))/15
end

Ik heb niet gecontroleerd welke eenheden deze atan2 functie teruggeeft - weet je zeker dat het graden zijn, wat het zou moeten zijn om te delen door 15 om zin te geven?

Er kunnen andere problemen zijn; dit zijn alleen die ik kan zien.

1
toegevoegd
Correct! ruby-doc.org/core-1.9.3/Math.html#method-c-atan2 Wanneer ooit het retourbereik wordt uitgedrukt als PI-waarden, zorg er dan voor dat ze in radialen zijn. Overweeg het gebruik van dit type formule ook y0 = sine_al_Sun (ta) * cosine_to_Earth (ta) al is suns_apparent_ecliptic_longitude en to is true obliquity not longitude. Het is de hoek van de aardbeweging ten opzichte van de hemelpool. 180.0 + rad_to_deg (atan2 (-y0, -cosine_al_Sun (ta))) Het helpt de retourwaarde binnen het juiste bereik te houden. Zoals de man zei, meng geen appels met sinaasappels. deg rad
toegevoegd de auteur Douglas G. Allen, de bron

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

Volgens de post moet u mogelijk de BigDecimal-klasse gebruiken voor uw drijvende-kommabewerkingen. Ik heb je programma niet echt doorlopen, dit is maar een gok.

0
toegevoegd