Вычисление уравнения центра в Swift

Я работаю над домашним проектом, который включает в себя расчет данных о восходе/заходе солнца. Я борюсь с реализацией следующей формулы в Swift:

Уравнение центра:

C = (1,9148 * sin(средняя солнечная аномалия)) + (0,0200 * sin(2 * средняя солнечная аномалия)) + (0,0003 * sin(3 * средняя солнечная аномалия))

Вот ответ, который я должен получить для заданной широты/долготы:

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

Вот мой код, который не дает правильное значение в качестве окончательного значения:

// 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))

Мой код говорит, что центр = -1,015867439183884, а правильный центр = 0,61344892821988

Я дважды и трижды проверял уравнение, но, кажется, не могу обнаружить свою ошибку. Я надеюсь, что это простая синтаксическая ошибка, но мне будет неловко, если это так...

Я работаю с уравнением и ответами, предоставленными здесь< /а>.

РЕДАКТИРОВАТЬ Вот полный код:

//: 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)

person Charlie    schedule 22.01.2016    source источник
comment
18.3 это градус? Я думаю, вам нужно сначала преобразовать его в радианы.   -  person kennytm    schedule 22.01.2016
comment
Я обновил свой ответ полным кодом, чтобы вы могли увидеть вывод meanSolarAnomaly (18.3)   -  person Charlie    schedule 22.01.2016


Ответы (1)


Как предположил @kennytm, средняя аномалия (солнца или чего-то еще) - это угол. Углы в Swift (и C, откуда взялись математические библиотеки) — это все радианы, в то время как астрономы говорят о градусах. Вот ваш код в Playground:

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
person Grimxn    schedule 22.01.2016
comment
Спасибо @kennytm и Grimxn за ваши ответы и отзывы. Это должно было быть очевидно, но это точно мой ответ! Большое спасибо!! - person Charlie; 22.01.2016
comment
Не стесняйтесь принять ответ! Сайт, на который вы ссылаетесь, действительно виноват в том, что не указывает единицы измерения, хотя 18.xxx в любом случае не является осмысленным углом в радианах (по смыслу они находятся между 0 и 2 пи или -пи и пи). - person Grimxn; 22.01.2016
comment
Я приму как можно скорее. Я столкнулся с аналогичной проблемой при вычислении склонения Солнца, но это был не первоначальный вопрос! :) Применю ваш отзыв и посмотрю, та же ли это ошибка - person Charlie; 22.01.2016