计算 Swift 中的中心方程
Calculating Equation of Center in Swift
我正在从事一个涉及计算日出/日落数据的宠物项目。我正在努力在 Swift:
中实现以下公式
Equation of Center:
C = (1.9148 * sin(meanSolarAnomaly)) + (0.0200 *
sin(2 * meanSolarAnomaly)) + (0.0003 * sin(3 * meanSolarAnomaly))
这是我应该得到的答案 Lat/Lon:
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
我对方程式进行了双重和三次检查,但我似乎无法发现我的错误。我希望这是一个简单的语法错误,但如果它是......
我正在根据提供的等式和答案计算 here。
编辑这是完整的代码:
//: 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)
正如@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
我正在从事一个涉及计算日出/日落数据的宠物项目。我正在努力在 Swift:
中实现以下公式Equation of Center:
C = (1.9148 * sin(meanSolarAnomaly)) + (0.0200 * sin(2 * meanSolarAnomaly)) + (0.0003 * sin(3 * meanSolarAnomaly))
这是我应该得到的答案 Lat/Lon:
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
我对方程式进行了双重和三次检查,但我似乎无法发现我的错误。我希望这是一个简单的语法错误,但如果它是......
我正在根据提供的等式和答案计算 here。
编辑这是完整的代码:
//: 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)
正如@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