⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 astronomicalmath.cpp

📁 一个基于BREW上的电子时钟程序,通过太阳历计算当前时间,并有闹铃和日志功能.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//
//      AstronomicalMath.cpp
//
//      Copyright (C) 2006 Sophia Cradle Incorporated

#include "AstronomicalMath.hpp"

Void AstronomicalMath::Date::Set(UInt16 year, UInt16 month, UInt16 day, UInt16 hour, UInt16 minute, UInt16 second)
{
	SInt32 yyyy(static_cast<SInt32>(year)), mm(static_cast<SInt32>(month)), dd(static_cast<SInt32>(day)), dayCount;
		
	// Fairfield 偺岞幃傪巊偭偰丄0001/01/01 偐傜偺擔悢傪媮傔傞
	if (mm < 3) {
		--yyyy;
		mm += 12;
	}
	dayCount = 365 * yyyy + yyyy / 4 - yyyy / 100 + yyyy / 400 + 306 * (mm + 1) / 10 - 428 + dd;

	// 2001/01/01 偐傜偺宱夁擔悢傪媮傔傞
	_days = static_cast<Float64>(dayCount) - 730486.0;
	_days += static_cast<Float64>(hour) / 24.0;
	_days += static_cast<Float64>(minute) / 1440.0;
	_days += static_cast<Float64>(second) / 86400.0;

	_dateUpdated = false;
	_j2000Updated = false;
}

Void AstronomicalMath::Date::Set(SFXDateConstRef date)
{
	SFXDateConst dateOrigin(2001, 1, 1, 0, 0, 0);
	SFXDateDurationConst span(date - dateOrigin);

	_days = static_cast<Float64>(span.ToSInt32()) / 86400.0;
	_year = date.GetYear();
	_month = date.GetMonth();
	_day = date.GetDay();
	_hour = date.GetHour();
	_minute = date.GetMinute();
	_second = date.GetSecond();

	_dateUpdated = true;
	_j2000Updated = false;
}

Void AstronomicalMath::Date::Set(DateConstRef ob)
{
	_year = ob._year;
	_month = ob._month;
	_day = ob._day;
	_hour = ob._hour;
	_minute = ob._minute;
	_second = ob._second;
	_days = ob._days;
	_j2000 = ob._j2000;
	_dateUpdated = ob._dateUpdated;
	_j2000Updated = ob._j2000Updated;
}

AstronomicalMath::Date::Date(Void) : _year(0), _month(0), _day(0), _hour(0), _minute(0), _second(0), _days(0.0), _j2000(0.0), _dateUpdated(false), _j2000Updated(false)
{
}

AstronomicalMath::Date::Date(UInt16 year, UInt16 month, UInt16 day, UInt16 hour, UInt16 minute, UInt16 second) : _year(0), _month(0), _day(0), _hour(0), _minute(0), _second(0), _days(0.0), _j2000(0.0), _dateUpdated(false), _j2000Updated(false)
{
	Set(year, month, day, hour, minute, second);
}

AstronomicalMath::Date::Date(SFXDateConstRef date)
{
	Set(date);
}

AstronomicalMath::Date::Date(Float64 days) : _year(0), _month(0), _day(0), _hour(0), _minute(0), _second(0), _days(0.0), _j2000(0.0), _dateUpdated(false), _j2000Updated(false)
{
	Set(days);
}

AstronomicalMath::Date::Date(DateConstRef ob)
{
	Set(ob);
}

AstronomicalMath::Date::~Date(Void)
{
}

// 2001/01/01 00:00:00 偐傜偺宱夁擔悢傪擔晅偵捈偡
Void AstronomicalMath::Date::CalcDate(Void) const
{
	SInt32 days, k, l, m, n, d, yyyy, mm, dd;
	Float64 t, u;

	if (_dateUpdated) {
		return;
	}

	t = floor(_days);
	days = static_cast<SInt32>(t) + 730486;		// 0001/01/01 傪 1 偲偡傞捠嶼偺擔悢
	t = _days - t;

	d = days + 305;
	k = d / 146097;
	d -= k * 146097;
	l = d / 36524;
	d -= l * 36524;
	m = d / 1461;
	d -= m * 1461;
	n = d / 365;
	yyyy = 400 * k + 100 * l + 4 * m + n;
	d = days - (365 * (yyyy - 1) + yyyy / 4 - yyyy / 100 + yyyy / 400 + 60);
	if (d == -1) {
		--yyyy;
		d = 365;
	}
	for (mm = 3; mm < 15; ++mm) {
		if (d >= 306 * (mm + 1) / 10 - 122 && d < 306 * (mm + 2) / 10 - 122) {
			break;
		}
	}
	dd = d - (306 * (mm + 1) / 10 - 123);
	if (mm > 12) {
		++yyyy;
		mm -= 12;
	}

	_year = static_cast<UInt16>(yyyy);
	_month = static_cast<UInt16>(mm);
	_day = static_cast<UInt16>(dd);

	t *= 24.0;
	u = floor(t);
	_hour = static_cast<UInt16>(u);
	t = (t - u) * 60.0;
	u = floor(t);
	_minute = static_cast<UInt16>(u);
	t = (t - u) * 60.0;
	u = floor(t + 0.5);
	_second = static_cast<UInt16>(u);

	_dateUpdated = true;
}

// J2000.0 (2000/01/01 00:00 (GMT)) 偐傜偺宱夁儐儕僂僗擭傪寁嶼偡傞
Void AstronomicalMath::Date::CalcJ2000Year(Void) const
{
	SInt32 y, m, d;
	Float64 k, k2, dk, dt;

	if (_j2000Updated) {
		return;
	}
	CalcDate();

	d = _day;
	if (_month < 3) {
		y = _year - 2001;
		m = _month + 12;
	}
	else {
		y = _year - 2000;
		m = _month;
	}

	k2 = static_cast<Float64>(365 * y + 30 * m + d) - 33.5 + floor(static_cast<Float64>(3 * (m + 1)) / 5.0) + floor(static_cast<Float64>(y) / 4.0);
	dt = floor(0.707018 * static_cast<Float64>(_year) - 1349.54);		// 抧媴偺帺揮偵傛傞曗惓
	dk = _days - floor(_days);
	k = k2 + dk + dt / 86400.0;
	_j2000 = k / 365.25;

	_j2000Updated = true;
}

AstronomicalMath::DateDuration::DateDuration(Void) : _duration(0.0)
{
}

AstronomicalMath::DateDuration::DateDuration(SInt32 days, UInt16 hour, UInt16 minute, UInt16 second)
{
	Set(days, hour, minute, second);
}

AstronomicalMath::DateDuration::DateDuration(Float64 days)
{
	Set(days);
}

AstronomicalMath::DateDuration::DateDuration(SFXDateDurationConstRef duration)
{
	Set(duration);
}

AstronomicalMath::DateDuration::DateDuration(DateDurationConstRef ob)
{
	Set(ob);
}

AstronomicalMath::DateDuration::~DateDuration(Void)
{
}

Void AstronomicalMath::Star::Set(DateConstRef gmtDate)
{
	_gmtDate = gmtDate;
	_eclipticPosition.Longitude = CalcEclipticLongitude(_gmtDate.GetJ2000Year());
	_eclipticPosition.Latitude = CalcEclipticLatitude(_gmtDate.GetJ2000Year());
	_PI = CalcParallax(_gmtDate.GetJ2000Year());
}

AstronomicalMath::Star::Star(Void) : _PI(0.0)
{
	_eclipticPosition.Longitude = 0.0;
	_eclipticPosition.Latitude = 0.0;
}

AstronomicalMath::Star::Star(DateConstRef gmtDate)
{
	Set(gmtDate);
}

// 惎偺愒摴嵗昗傪庢摼偡傞
AstronomicalMath::AstronomicalPoint AstronomicalMath::Star::GetEquatorialPosition(Void) const
{
	Float64Const beta(DegreeToRadian(_eclipticPosition.Latitude));
	Float64Const lambda(DegreeToRadian(_eclipticPosition.Longitude));
	Float64Const eps(DegreeToRadian(CalcObliquityOfTheEcliptic(_gmtDate.GetJ2000Year())));
	Float64 u, v, w, alpha, delta;
	AstronomicalPoint result;

	u = cos(beta) * cos(lambda);
	v = - sin(beta) * sin(eps) + cos(beta) * sin(lambda) * cos(eps);
	w = sin(beta) * cos(eps) + cos(beta) * sin(lambda) * sin(eps);
	alpha = atan2(v, u);
	delta = atan(w / sqrt(u * u + v * v));
	if (alpha < 0.0) {
		alpha += 2.0 * ASTRONOMICALMATH_PI;
	}

	result.Longitude = RadianToDegree(alpha);
	result.Latitude = RadianToDegree(delta);
	return result;
}

Void AstronomicalMath::Sun::Set(DateConstRef gmtDate)
{
	Float64 r;

	_gmtDate = gmtDate;
	_eclipticPosition.Longitude = CalcEclipticLongitude(_gmtDate.GetJ2000Year());
	_eclipticPosition.Latitude = 0.0;

	r = CalcDistance(_gmtDate.GetJ2000Year());
	_S = 0.266994 / r;
	_PI = 0.00244282 / r;
}

AstronomicalMath::Sun::Sun(Void) : _S(0.0)
{
}

AstronomicalMath::Sun::Sun(DateConstRef gmtDate)
{
	Set(gmtDate);
}

// 懢梲偺墿宱傪寁嶼偡傞
// T : 宱夁儐儕僂僗擭
Float64 AstronomicalMath::Sun::CalcEclipticLongitude(Float64 T) const
{
	Float64 lambdaS;
	
	lambdaS = 280.4603 + 360.00769 * T
				+ (1.9146 - 0.00005 * T) * sin(DegreeToRadian(357.538 + 359.991 * T))
				+ 0.0200 * sin(DegreeToRadian(355.05 + 719.981 * T))
				+ 0.0048 * sin(DegreeToRadian(234.95 + 19.341 * T))
				+ 0.0020 * sin(DegreeToRadian(247.1 + 329.64 * T))
				+ 0.0018 * sin(DegreeToRadian(297.8 + 4452.67 * T))
				+ 0.0018 * sin(DegreeToRadian(251.3 + 0.20 * T))
				+ 0.0015 * sin(DegreeToRadian(343.2 + 450.37 * T))
				+ 0.0013 * sin(DegreeToRadian(81.4 * 225.18 * T))
				+ 0.0008 * sin(DegreeToRadian(132.5 + 659.29 * T))
				+ 0.0007 * sin(DegreeToRadian(153.3 + 90.38 * T))
				+ 0.0007 * sin(DegreeToRadian(206.8 + 30.35 * T))
				+ 0.0006 * sin(DegreeToRadian(29.8 + 337.18 * T))
				+ 0.0005 * sin(DegreeToRadian(207.4 + 1.50 * T))
				+ 0.0005 * sin(DegreeToRadian(291.2 + 22.81 * T))
				+ 0.0004 * sin(DegreeToRadian(234.9 + 315.56 * T))
				+ 0.0004 * sin(DegreeToRadian(157.3 + 299.30 * T))
				+ 0.0004 * sin(DegreeToRadian(21.1 * 720.02 * T))
				+ 0.0003 * sin(DegreeToRadian(352.5 + 1079.97 * T))
				+ 0.0003 * sin(DegreeToRadian(329.7 + 44.43 * T));
	lambdaS = fmod(lambdaS, 360.0);
	return (lambdaS >= 0.0) ? lambdaS : (lambdaS + 360.0);
}

// 懢梲偲抧媴偺娫偺嫍棧傪媮傔傞
// T : 宱夁儐儕僂僗擭
Float64 AstronomicalMath::Sun::CalcDistance(Float64 T) const
{
	Float64 q;

	q = (0.007256 - 0.0000002 * T) * sin(DegreeToRadian(267.54 + 359.991 * T))
			+ 0.000091 * sin(DegreeToRadian(265.1 + 719.98 * T))
			+ 0.000030 * sin(DegreeToRadian(90.0))
			+ 0.000013 * sin(DegreeToRadian(27.8 + 4452.67 * T))
			+ 0.000007 * sin(DegreeToRadian(254.0 + 450.4 * T))
			+ 0.000007 * sin(DegreeToRadian(156.0 + 329.6 * T));
	return pow(10.0, q);
}

AstronomicalMath::Moon::Moon(DateConstRef gmtDate)
{
	Set(gmtDate);
}

// 寧偺墿宱傪寁嶼偡傞
// T : 宱夁儐儕僂僗擭
Float64 AstronomicalMath::Moon::CalcEclipticLongitude(Float64 T) const
{
	Float64 Am, lambda_m;

	Am = 0.0040 * sin(DegreeToRadian(119.5 + 1.33 * T))
		+ 0.0020 * sin(DegreeToRadian(55.0 + 19.34 * T))
		+ 0.0006 * sin(DegreeToRadian(71.0 + 0.2 * T))
		+ 0.0006 * sin(DegreeToRadian(54.0 + 19.3 * T));

	lambda_m = 218.3161 + 4812.67881 * T
				+ 6.2887 * sin(DegreeToRadian(134.961 + 4771.9886 * T + Am))
				+ 1.2740 * sin(DegreeToRadian(100.738 + 4133.3536 * T))
				+ 0.6583 * sin(DegreeToRadian(235.700 + 8905.3422 * T))
				+ 0.2136 * sin(DegreeToRadian(269.926 + 9543.9773 * T))
				+ 0.1856 * sin(DegreeToRadian(177.525 + 359.9905 * T))
				+ 0.1143 * sin(DegreeToRadian(6.546 + 9664.0404 * T))
				+ 0.0588 * sin(DegreeToRadian(214.22 + 638.635 * T))
				+ 0.0572 * sin(DegreeToRadian(103.21 + 3773.363 * T))
				+ 0.0533 * sin(DegreeToRadian(10.66 + 13677.331 * T))
				+ 0.0459 * sin(DegreeToRadian(238.18 + 8545.352 * T))
				+ 0.0410 * sin(DegreeToRadian(137.43 + 4411.998 * T))
				+ 0.0348 * sin(DegreeToRadian(117.84 + 4452.671 * T))
				+ 0.0305 * sin(DegreeToRadian(312.49 + 5131.979 * T))
				+ 0.0153 * sin(DegreeToRadian(130.84 + 758.698 * T))
				+ 0.0125 * sin(DegreeToRadian(141.51 + 14436.029 * T))
				+ 0.0110 * sin(DegreeToRadian(231.59 + 4892.052 * T))
				+ 0.0107 * sin(DegreeToRadian(336.44 + 13038.696 * T))
				+ 0.0100 * sin(DegreeToRadian(44.89 + 14315.966 * T))
				+ 0.0085 * sin(DegreeToRadian(201.5 + 8266.71 * T))
				+ 0.0079 * sin(DegreeToRadian(278.2 + 4493.34 * T))
				+ 0.0068 * sin(DegreeToRadian(53.2 + 9265.33 * T))
				+ 0.0052 * sin(DegreeToRadian(197.2 + 319.32 * T))
				+ 0.0050 * sin(DegreeToRadian(295.4 + 4812.66 * T))
				+ 0.0048 * sin(DegreeToRadian(235.0 + 19.34 * T))
				+ 0.0040 * sin(DegreeToRadian(13.2 + 13317.34 * T))
				+ 0.0040 * sin(DegreeToRadian(145.6 + 18449.32 * T))
				+ 0.0040 * sin(DegreeToRadian(119.5 + 1.33 * T))
				+ 0.0039 * sin(DegreeToRadian(111.3 + 17810.68 * T))
				+ 0.0037 * sin(DegreeToRadian(349.1 + 5410.62 * T))
				+ 0.0027 * sin(DegreeToRadian(272.5 + 9183.99 * T))
				+ 0.0026 * sin(DegreeToRadian(107.2 + 13797.39 * T))
				+ 0.0024 * sin(DegreeToRadian(211.9 + 988.63 * T))
				+ 0.0024 * sin(DegreeToRadian(252.8 + 9224.66 * T))
				+ 0.0022 * sin(DegreeToRadian(240.6 + 8185.36 * T))
				+ 0.0021 * sin(DegreeToRadian(87.5 + 9903.97 * T))
				+ 0.0021 * sin(DegreeToRadian(175.1 + 719.98 * T))
				+ 0.0021 * sin(DegreeToRadian(105.6 + 3413.37 * T))
				+ 0.0020 * sin(DegreeToRadian(55.0 + 19.34 * T))

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -