/** * Calculates all sun-related important times * depending on time of year and location * @param Location Location to be used in calculation * @param Basic NMEA_INFO for current date * @param Calculated DERIVED_INFO (not yet used) * @param TimeZone The timezone * @return Sunset time */ void SunEphemeris::CalcSunTimes(const GeoPoint &Location, const BrokenDateTime &date_time, const fixed TimeZone) { fixed DaysToJ2000 = FNday(date_time); Angle L = GetMeanSunLongitude(DaysToJ2000); // Use GetEclipticLongitude to find the ecliptic longitude of the Sun Angle Lambda = GetEclipticLongitude(DaysToJ2000, L); // Obliquity of the ecliptic Angle Obliquity = Angle::degrees(fixed(23.439) - fixed(.0000004) * DaysToJ2000); // Find the RA and DEC of the Sun Angle Alpha = Angle::radians(atan2(Obliquity.cos() * Lambda.sin(), Lambda.cos())); Angle Delta = Angle::radians(asin(Obliquity.sin() * Lambda.sin())); // Find the Equation of Time in minutes // Correction suggested by David Smith fixed LL = (L - Alpha).value_radians(); if (L.value_radians() < fixed_pi) LL += fixed_two_pi; fixed equation = fixed(1440) * (fixed_one - LL / fixed_two_pi); Angle HourAngle = GetHourAngle(Location.Latitude, Delta); Angle HourAngleTwilight = GetHourAngleTwilight(Location.Latitude, Delta); // length of twilight in hours fixed TwilightHours = (HourAngleTwilight - HourAngle).value_hours(); // Conversion of angle to hours and minutes DayLength = HourAngle.value_hours() * fixed_two; if (DayLength < fixed(0.0001)) // arctic winter DayLength = fixed_zero; TimeOfSunRise = fixed(12) - HourAngle.value_hours() + TimeZone - Location.Longitude.value_degrees() / 15 + equation / 60; if (TimeOfSunRise > fixed(24)) TimeOfSunRise -= fixed(24); TimeOfSunSet = TimeOfSunRise + DayLength; TimeOfNoon = TimeOfSunRise + HourAngle.value_hours(); // morning twilight begin MorningTwilight = TimeOfSunRise - TwilightHours; // evening twilight end EveningTwilight = TimeOfSunSet + TwilightHours; }
// 黄道座標から時角を取得. IZ_FLOAT CEphemeris::GetHourAngleByEliptic( const SUniversalTime& ut, IZ_FLOAT longitude, const SPolarCoord& eliptic) { izanagi::math::SVector4 equatorial; ConvertElipticToEquatorial(eliptic, equatorial); SPolarCoord polarEquatorial; ConvertRectangularToPolar(equatorial, polarEquatorial); IZ_FLOAT hourAngle = GetHourAngle(ut, longitude, polarEquatorial.longitude); return hourAngle; }
void SClock::OnPaint(SOUI::IRenderTarget * pRT) { SWindow::OnPaint(pRT); CRect rcClient; GetClientRect(&rcClient); CPoint center = rcClient.CenterPoint(); // 计算矩形 // 35 * 16 CRect rcDraw(center, SOUI::CPoint(center.x + 200, center.y + 32)); rcDraw.OffsetRect(-35, -16); CRect rcSrc(0, 0, 200, 32); SYSTEMTIME last_refresh_time; ::GetLocalTime(&last_refresh_time); { double angle = GetHourAngle(last_refresh_time.wHour,last_refresh_time.wMinute); SMatrix form = InitMatrix(angle, center); pRT->SetTransform(&form, NULL); pRT->DrawBitmapEx(rcDraw, pointer_hour, &rcSrc, EM_STRETCH, 255); } { double angle = GetMinuteSecondAngle(last_refresh_time.wMinute); SMatrix form = InitMatrix(angle, center); pRT->SetTransform(&form, NULL); pRT->DrawBitmapEx(rcDraw, pointer_minute, &rcSrc, EM_STRETCH, 255); } { double angle = GetMinuteSecondAngle(last_refresh_time.wSecond); SMatrix form = InitMatrix(angle, center); pRT->SetTransform(&form, NULL); pRT->DrawBitmapEx(rcDraw, pointer_second, &rcSrc, EM_STRETCH, 255); } pRT->SetTransform(&SMatrix()); }
SunEphemeris::Result SunEphemeris::CalcSunTimes(const GeoPoint &location, const BrokenDateTime &date_time, const fixed time_zone) { Result result; assert(date_time.Plausible()); fixed days_to_j2000 = FNday(date_time); Angle l = GetMeanSunLongitude(days_to_j2000); // Use GetEclipticLongitude to find the ecliptic longitude of the Sun Angle lambda = GetEclipticLongitude(days_to_j2000, l); // Obliquity of the ecliptic Angle obliquity = Angle::Degrees(fixed(23.439) - fixed(.0000004) * days_to_j2000); // Find the RA and DEC of the Sun Angle alpha = Angle::FromXY(lambda.cos(), obliquity.cos() * lambda.sin()); Angle delta = Angle::asin(obliquity.sin() * lambda.sin()); // Find the Equation of Time in minutes // Correction suggested by David Smith fixed ll = (l - alpha).Radians(); if (l.Radians() < fixed_pi) ll += fixed_two_pi; fixed equation = fixed(1440) * (fixed(1) - ll / fixed_two_pi); Angle hour_angle = GetHourAngle(location.latitude, delta); Angle hour_angle_twilight = GetHourAngleTwilight(location.latitude, delta); result.azimuth = CalculateAzimuth(location, date_time, time_zone, delta); // length of twilight in hours fixed twilight_hours = (hour_angle_twilight - hour_angle).Hours(); // Conversion of angle to hours and minutes result.day_length = Double(hour_angle.Hours()); if (result.day_length < fixed(0.0001)) // arctic winter result.day_length = fixed(0); result.time_of_sunrise = fixed(12) - hour_angle.Hours() + time_zone - location.longitude.Degrees() / 15 + equation / 60; if (result.time_of_sunrise > fixed(24)) result.time_of_sunrise -= fixed(24); result.time_of_sunset = result.time_of_sunrise + result.day_length; result.time_of_noon = result.time_of_sunrise + hour_angle.Hours(); // morning twilight begin result.morning_twilight = result.time_of_sunrise - twilight_hours; // evening twilight end result.evening_twilight = result.time_of_sunset + twilight_hours; return result; }