2016-01-22 3 views
3

Je travaille sur un projet d'animal de compagnie qui implique le calcul des données de lever/coucher du soleil. Je me bats avec la mise en œuvre de la formule suivante à Swift:Calcul de l'équation du centre dans Swift

équation du centre:

C = (1,9148 * sin (meanSolarAnomaly)) + (0,0200 * sin (2 * meanSolarAnomaly)) + (0,0003 * sin (3 * meanSolarAnomaly))

Voici la réponse que je devrais obtenir mon Lat/Lon donné:

C = 1,9148 * sin (18,30143135945) + 0,0200 * sin (2 * 18,30143135945) + 0,0003 * sin (3 * 18,30143135945) = 0,61344892821988

Voici mon code, ce qui ne donne pas la valeur correcte que la valeur finale:

// meanSolarAnomaly has a value of 18.30143135945036 at this point 
let center = (1.9148 * sin(meanSolarAnomaly)) + (0.0200 * sin(2*meanSolarAnomaly)) + (0.0003 * sin(3*meanSolarAnomaly)) 

Mon code dit centre = -1.015867439183884 tandis que le centre correct = 0.61344892821988

J'ai double et triple vérifié l'équation, mais je ne peux pas sembler repérer mon erreur. J'espère que c'est une erreur de syntaxe simple mais sera embarrassée si elle est ...

Je travaille à partir de l'équation et les réponses fournies here.

EDIT Voici le code complet:

//: Playground - noun: a place where people can play 

import UIKit 
//calculator to determine what time of day Sunset/Sunrise will occur 
func jdFromDate(date : NSDate) -> Double { 
    let JD_JAN_1_1970_0000GMT = 2440587.5 
    return JD_JAN_1_1970_0000GMT + date.timeIntervalSince1970/86400 
} 

func dateFromJd(jd : Double) -> NSDate { 
    let JD_JAN_1_1970_0000GMT = 2440587.5 
    return NSDate(timeIntervalSince1970: (jd - JD_JAN_1_1970_0000GMT) * 86400) 
} 
let julianOffset = 2451545 as Double 
let refDateFormatter = NSDateFormatter() 
refDateFormatter.dateFormat = "MM-dd-yyyy" 

let today = NSDate() 

let julianDaysToToday = round(jdFromDate(today)) 

//get the lat/lon variables set (Tampa in example) 
let lat = 27.9681 
let lon = 82.4764 

//now we need to calculate julian cycle 
let nRaw = (julianDaysToToday - julianOffset - 0.0009) - (lon/360) 
let n = round(nRaw) 

//n now contains the julian cycle 
//next we must calculate the julian date of solar noon (approximately) 
//J* = 2451545 + 0.0009 + (lw/360) + n 

let jSolarNoon = julianOffset + 0.0009 + (lon/360) + n 

//next calculate the mean solar anomaly 
//M = [357.5291 + 0.98560028 * (J* - 2451545)] mod 360 
let meanSolarAnomaly = (357.5291 + 0.98560028 * (jSolarNoon - julianOffset)) % 360 

//next calculate the equation of center 

let center = (1.9148 * sin(meanSolarAnomaly)) + (0.0200 * sin(2*meanSolarAnomaly)) + (0.0003 * sin(3*meanSolarAnomaly)) 

//Now, using Center and Mean, calculate the ecliptical longitude of the sun. 
//λ = (M + 102.9372 + C + 180) mod 360 
let eclLonOfSun = (meanSolarAnomaly + 102.9372 + center + 180) % 360 

//now we can finally get an accurate julian date for solar noon 
let jTransit = jSolarNoon + (0.0053 * sin(meanSolarAnomaly)) - (0.0069 * sin(2 * eclLonOfSun)) 

//To calculate the hour angle we need to find the declination of the sun 
//δ = arcsin(sin(λ) * sin(23.45)) 
let declinationOfSun = asin(sin(eclLonOfSun) * sin(23.45)) 

//now calculate the hour angle 
//H = arccos([sin(-0.83) - sin(ln) * sin(δ)]/[cos(ln) * cos(δ)]) 
let hourCosNum = sin(-0.83) - sin(lat) * sin(declinationOfSun) 
let hourDenom = cos(lat)*cos(declinationOfSun) 
let hourAngle = acos(hourCosNum)/hourDenom 

//time to go back through the approximation again using the hour angle 
let finalJulianApproximation = 2451545 + 0.0009 + ((hourAngle + lon)/360) + n 

//The values of M and λ from above don't really change from solar noon to sunset, so there is no need to recalculate them before calculating sunset. 
let jSet = finalJulianApproximation + (0.0053 * sin(meanSolarAnomaly)) - (0.0069 * sin(2*eclLonOfSun)) 

let sunset = dateFromJd(jSet) 
+4

Est-ce que 18.3 est un degré? Je pense que vous devez d'abord le convertir en radians. – kennytm

+0

J'ai mis à jour ma réponse avec le code complet pour vous permettre de voir la dérivation de meanSolarAnomaly (le 18.3) – Charlie

Répondre

4

Comme @kennytm a suggéré, l'anomalie moyenne (du soleil ou quoi que ce soit d'autre) est un angle. Les angles dans Swift (et C, d'où viennent les bibliothèques de maths) sont tous radians, tandis que les astronomes parlent en degrés. Voici votre code dans le terrain de jeu:

var meanSolarAnomaly = 18.30143135945036 
var c = (1.9148 * sin(meanSolarAnomaly)) + (0.0200 * sin(2 * meanSolarAnomaly)) + (0.0003 * sin(3 * meanSolarAnomaly)) 
// = -1.01586743918389 - wrong answer 

meanSolarAnomaly = meanSolarAnomaly * M_PI/180.0 
// Convert it to radians 

c = (1.9148 * sin(meanSolarAnomaly)) + (0.0200 * sin(2 * meanSolarAnomaly)) + (0.0003 * sin(3 * meanSolarAnomaly)) 
// = 0.6134489282198807 - right answer 
+0

Merci @kennytm et Grimxn pour vos réponses et vos commentaires. Cela aurait dû être évident mais c'est à coup sûr ma réponse! Merci beaucoup!! – Charlie

+0

N'hésitez pas à accepter la réponse! Le site que vous référence est vraiment en faute pour ne pas spécifier d'unités, bien que 18.xxx ne soit pas significativement un angle en radians de toute façon (significativement ils sont entre 0 et 2 pi, ou -pi et pi). – Grimxn

+0

Je vais accepter dès que possible. Je rencontre un problème similaire en calculant declinationOfSun mais ce n'était pas la question originale! :) Appliquera vos commentaires et voir si c'est la même erreur – Charlie