summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/CMakeLists.txt6
-rw-r--r--src/Julian.cpp3
-rw-r--r--src/calendar.cpp120
-rw-r--r--src/calendar.h42
-rw-r--r--src/parameters.cpp56
5 files changed, 107 insertions, 120 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 53ddadc..14401b8 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -5,10 +5,6 @@ add_definitions(-w)
5message("Project root: ${PROJECT_SOURCE_DIR}") 5message("Project root: ${PROJECT_SOURCE_DIR}")
6 6
7set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin) 7set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
8set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
9 8
10# 将Julian.cpp与parameters.cpp编译为一个动态库
11add_library(parameters SHARED Julian.cpp parameters.cpp)
12# 将calendar.cpp与List.cpp编译为可执行文件,链接动态库 9# 将calendar.cpp与List.cpp编译为可执行文件,链接动态库
13add_executable(calendar calendar.cpp) 10add_executable(calendar calendar.cpp Julian.cpp parameters.cpp) \ No newline at end of file
14target_link_libraries(calendar PRIVATE parameters)
diff --git a/src/Julian.cpp b/src/Julian.cpp
index 5a0522b..ecfe391 100644
--- a/src/Julian.cpp
+++ b/src/Julian.cpp
@@ -86,6 +86,5 @@ double Julian::getJulianKiloYear(time_t time) {
86//儒略千年数转时间戳 86//儒略千年数转时间戳
87time_t Julian::kiloYearToTime(double t, int year) { 87time_t Julian::kiloYearToTime(double t, int year) {
88 double jd = t * 365250.0 + 2451545.0; 88 double jd = t * 365250.0 + 2451545.0;
89 time_t time = (time_t)((jd - 2440587.5) * 86400.0 - delta_t(year)); 89 return (time_t)((jd - 2440587.5) * 86400.0 - delta_t(year));
90 return time;
91} 90}
diff --git a/src/calendar.cpp b/src/calendar.cpp
index 6731692..7e04857 100644
--- a/src/calendar.cpp
+++ b/src/calendar.cpp
@@ -1,64 +1,124 @@
1// Encoding: UTF-8 1// Encoding: UTF-8
2#include "calendar.h" 2#include "calendar.h"
3#include <cstdio> 3#include <cstdio>
4#include <cstdlib>
4#include <ctime> 5#include <ctime>
5#include <iomanip> 6#include <iomanip>
6 7
7/*以下为"calendar.h规定之量*/ 8// 常量
8double day = 86400; 9#define day_secs 86400
9double delta = 1e-11; 10#define delta_time 1e-11
11
12/* calendar.h规定之量 */
10Julian julian; 13Julian julian;
11parameter p; 14parameter p;
15double epsilon;
12 16
13pair<double, double> getSunPos(time_t time) { 17FILE *fp;
14 double t = julian.getJulianKiloYear(time);
15 18
19pair<double, double> getSunPos(double t, double flag = false) {
16 pair<double, double> sun = p.sun_longitude(t); 20 pair<double, double> sun = p.sun_longitude(t);
17 radToDMS("Sun longitude:\t\t", 0, 360, sun.first);
18 radToDMS("Sun latitude:\t\t", -90, 90, sun.second);
19 21
20 double alpha, delta; // 太阳赤经赤纬 22 double alpha, delta; // 太阳赤经赤纬
21 double lambda = sun.first, beta = sun.second; // 太阳黄经黄纬 23 double lambda = sun.first, beta = sun.second; // 太阳黄经黄纬
22 // 黄赤交角epsilon 24 // 黄赤交角epsilon
23 double epsilon = p.get_epsilon(t); 25 epsilon = p.get_epsilon(t);
24 radToDMS("Ecliptic Obliquity:\t\t", 0, 90, epsilon);
25 26
26 delta = 27 delta =
27 asin(sin(epsilon) * sin(lambda) * cos(beta) + cos(epsilon) * sin(beta)); 28 asin(sin(epsilon) * sin(lambda) * cos(beta) + cos(epsilon) * sin(beta));
28 alpha = atan2( 29 alpha = atan2(
29 (cos(epsilon) * sin(lambda) * cos(beta) - sin(epsilon) * sin(beta)), 30 (cos(epsilon) * sin(lambda) * cos(beta) - sin(epsilon) * sin(beta)),
30 (cos(lambda) * cos(beta))); 31 (cos(lambda) * cos(beta)));
31 radToDMS("Sun right ascension:\t\t", 0, 360, alpha);
32 radToDMS("Sun declination:\t\t", -90, 90, delta);
33 // 时角 32 // 时角
34 double H = p.getHourAngle(t, LONGITUDE, LATITUDE, alpha); 33 double H = p.getHourAngle(t, LONGITUDE, LATITUDE, alpha);
35 double A, h; //方位角和高度角 34 double A, h; //方位角和高度角
36 h = asin(sin(LATITUDE) * sin(delta) + cos(LATITUDE) * cos(delta) * cos(H)); 35 h = asin(sin(LATITUDE) * sin(delta) + cos(LATITUDE) * cos(delta) * cos(H));
37 A = atan2(-cos(delta) * sin(H), 36 A = atan2(-cos(delta) * sin(H),
38 cos(LATITUDE) * sin(delta) - sin(LATITUDE) * cos(delta) * cos(H)); 37 cos(LATITUDE) * sin(delta) - sin(LATITUDE) * cos(delta) * cos(H));
39 A += M_PI; 38 if (flag) {
40 // 转换为角度制输出 39 fprintf(
41 radToDMS("Hour angle:\t\t", 0, 360, H); 40 fp, "%s\t%s\t%s\t%s\t%s\t%s\n", radToDMS(0, 360, lambda).c_str(),
42 radToDMS("Azimuth:\t\t", 0, 360, A); 41 radToDMS(-90, 90, beta).c_str(), radToDMS(0, 360, alpha).c_str(),
43 radToDMS("Elevation:\t\t", -90, 90, h); 42 radToDMS(-90, 90, delta).c_str(), radToDMS(0, 360, A).c_str(),
43 radToDMS(-90, 90, h).c_str());
44 }
45 return make_pair(A, h + M_PI / 216);
44} 46}
45 47
46int main(int argc, char *argv[]) { 48void binarySearch(string message, time_t begin, Date date) {
47 Date date; 49 double t = julian.getJulianKiloYear(begin);
48 if (argc != 2) { 50 double t_end = julian.getJulianKiloYear(begin + day_secs / 2);
49 printf("Input the time you want to calculate in <YYYY-MM-DD,HH:MM:SS> " 51 double middle;
50 "format:\t\t"); 52 time_t res;
51 scanf("%d-%d-%d,%d:%d:%d", &date.tm_year, &date.tm_mon, &date.tm_mday, 53 pair<double, double> sunPos;
52 &date.tm_hour, &date.tm_min, &date.tm_sec); 54 while (t_end - t >= delta_time) {
53 } else { 55 middle = (t + t_end) / 2;
54 sscanf(argv[1], "%d-%d-%d,%d:%d:%d", &date.tm_year, &date.tm_mon, 56 sunPos = getSunPos(middle, false);
55 &date.tm_mday, &date.tm_hour, &date.tm_min, &date.tm_sec); 57 if (sunPos.second * getSunPos(t).second > 0) {
58 t = middle;
59 } else {
60 t_end = middle;
61 }
62 }
63 res = julian.kiloYearToTime(middle, date.tm_year + 1900);
64 Date *tm = localtime(&res);
65 printf("%s\t%4d-%02d-%02d %02d:%02d:%02d\tAzimuth\t%s\n", message.c_str(),
66 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour,
67 tm->tm_min, tm->tm_sec, radToDMS(0, 360, sunPos.first).c_str());
68 fprintf(fp, "%s\t%4d-%02d-%02d %02d:%02d:%02d\tAzimuth\t%s\n",
69 message.c_str(), tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
70 tm->tm_hour, tm->tm_min, tm->tm_sec,
71 radToDMS(0, 360, sunPos.first).c_str());
72}
73
74void getSunTime(Date date) {
75 time_t time = mktime(&date);
76 binarySearch("Sunrize", time, date);
77 binarySearch("Sunset", time + day_secs / 2, date);
78}
79
80void showSunPos(Date date) {
81 time_t time = mktime(&date);
82 double t;
83 fprintf(fp, "\n\nSun Trace Table\n\n");
84 fprintf(fp, "--------------------------------------------------------------"
85 "--------------------------------------------------------------"
86 "----------\n");
87 fprintf(fp, "Time |\tlongitude\t\tlatitude\t\tright "
88 "ascension\tdeclination\tAzimuth\t\tAltitude\n");
89 fprintf(fp, "--------------------------------------------------------------"
90 "--------------------------------------------------------------"
91 "----------\n");
92 for (int i = 0; i < 24; i++, time += 3600, date.tm_hour++) {
93 t = julian.getJulianKiloYear(time);
94 fprintf(fp, "%02d:%02d:%02d |\t", date.tm_hour, date.tm_min,
95 date.tm_sec);
96 getSunPos(t, true);
56 } 97 }
98 fprintf(fp, "--------------------------------------------------------------"
99 "--------------------------------------------------------------"
100 "----------\n");
101}
102
103int main() {
104 Date date;
105 cout << "Input a day you want(in YYYY-MM-DD): ";
106 scanf("%d-%d-%d", &date.tm_year, &date.tm_mon, &date.tm_mday);
57 date.tm_year -= 1900; 107 date.tm_year -= 1900;
58 date.tm_mon -= 1; 108 date.tm_mon -= 1;
59 date.tm_isdst = -1; 109 date.tm_hour = date.tm_min = date.tm_sec = 0;
110
111 fp = fopen("sunPos.txt", "w");
112 if (fp == NULL) {
113 printf("File open failed\n");
114 exit(1);
115 }
116 fprintf(fp, "Sun trace File (Date: %4d-%02d-%02d)\n\n\n",
117 date.tm_year + 1900, date.tm_mon + 1, date.tm_mday);
118 getSunTime(date);
119
120 showSunPos(date);
121 fclose(fp);
60 122
61 time_t time = mktime(&date);
62 getSunPos(time);
63 return 0; 123 return 0;
64} 124} \ No newline at end of file
diff --git a/src/calendar.h b/src/calendar.h
index 248026f..87ca413 100644
--- a/src/calendar.h
+++ b/src/calendar.h
@@ -10,43 +10,13 @@
10using namespace std; 10using namespace std;
11 11
12// 哈尔滨南岗地方经纬度 12// 哈尔滨南岗地方经纬度
13#define LONGITUDE 126.533 * M_PI / 180 13#define M_PI 3.14159265358979323846
14#define LATITUDE 45.800 * M_PI / 180 14#define LONGITUDE 126.66854 * M_PI / 180
15 15#define LATITUDE 45.75996 * M_PI / 180
16extern double delta;
17extern char jieqi[25][10];
18 16
19typedef struct tm Date; 17typedef struct tm Date;
20struct point {
21 int year, mon, day, hour, min, sec;
22 bool isShuo, isJieqi, isZhongqi;
23 int JieqiIndex, MonthIndex;
24 bool RunYue;
25 double time;
26 point *next;
27
28 point(int year, int mon, int day, int hour, int min, int sec, bool isShuo,
29 bool isJieqi, bool isZhongqi, int JieqiIndex, int MonthIndex,
30 bool RunYue, double time) {
31 this->year = year;
32 this->mon = mon;
33 this->day = day;
34 this->hour = hour;
35 this->min = min;
36 this->sec = sec;
37 this->isShuo = isShuo;
38 this->isJieqi = isJieqi;
39 this->isZhongqi = isZhongqi;
40 this->JieqiIndex = JieqiIndex;
41 this->MonthIndex = MonthIndex;
42 this->RunYue = RunYue;
43 this->time = time;
44 this->next = NULL;
45 }
46};
47 18
48void radToDMS(const char *message, int lowerBound, int upperBound, 19string radToDMS(int lowerBound, int upperBound, double radians);
49 double radians);
50 20
51class Julian { 21class Julian {
52 private: 22 private:
@@ -96,8 +66,6 @@ class parameter {
96 public: 66 public:
97 pair<double, double> sun_longitude(double t); 67 pair<double, double> sun_longitude(double t);
98 68
99 double moon_longitude(double t);
100
101 double get_epsilon(double T); 69 double get_epsilon(double T);
102 70
103 // 计算时角,返回弧度制 71 // 计算时角,返回弧度制
@@ -107,4 +75,6 @@ class parameter {
107 75
108extern Julian julian; 76extern Julian julian;
109extern parameter p; 77extern parameter p;
78extern double epsilon;
79
110#endif \ No newline at end of file 80#endif \ No newline at end of file
diff --git a/src/parameters.cpp b/src/parameters.cpp
index fdcefd1..ff57305 100644
--- a/src/parameters.cpp
+++ b/src/parameters.cpp
@@ -5,8 +5,7 @@
5#include <utility> 5#include <utility>
6using namespace std; 6using namespace std;
7 7
8void radToDMS(const char *message, int lowerBound, int upperBound, 8string radToDMS(int lowerBound, int upperBound, double radians) {
9 double radians) {
10 // Convert radians to degrees 9 // Convert radians to degrees
11 double degrees = radians * 180.0 / M_PI; 10 double degrees = radians * 180.0 / M_PI;
12 11
@@ -15,17 +14,19 @@ void radToDMS(const char *message, int lowerBound, int upperBound,
15 while (degrees >= upperBound) 14 while (degrees >= upperBound)
16 degrees -= (upperBound - lowerBound); 15 degrees -= (upperBound - lowerBound);
17 16
18 bool flag = degrees < 0;
19 if (flag)
20 degrees = -degrees;
21 // Calculate degrees, minutes, and seconds 17 // Calculate degrees, minutes, and seconds
22 int deg = static_cast<int>(degrees); 18 int deg = static_cast<int>(degrees);
23 double min_sec = (degrees - deg) * 60.0; 19 double min_sec = (degrees - deg) * 60.0;
24 int min = static_cast<int>(min_sec); 20 int min = static_cast<int>(min_sec);
25 double sec = (min_sec - min) * 60.0; 21 double sec = (min_sec - min) * 60.0;
22 if (degrees < 0) {
23 min = -min;
24 sec = -sec;
25 }
26 26
27 // Output the result 27 char buf[100];
28 printf("%s: %c%d°%d'%06.3f''\n", message, flag ? '-' : ' ', deg, min, sec); 28 sprintf(buf, "%4d°%2d'%06.3f''", deg, min, sec);
29 return string(buf);
29} 30}
30 31
31// 计算地球日心黄经 32// 计算地球日心黄经
@@ -205,51 +206,12 @@ pair<double, double> parameter::sun_longitude(double t) {
205 return make_pair(L, -B); 206 return make_pair(L, -B);
206} 207}
207 208
208// 计算月球地心黄经,外部调用,返回角度制
209double parameter::moon_longitude(double t) {
210 double T = 10 * t;
211 vector<double> angles = get_angle(T);
212 double a, b, c, d, moon_longitude_a;
213
214 double L = 218.3164591 + 481267.88134236 * T - 0.0013268 * T * T +
215 T * T * T / 538841 - T * T * T * T / 65194000; //月球平黄经
216 double EI = 0, sita = 0;
217 double E = 1 - 0.002516 * T - 0.0000074 * T * T; //地球离心率
218
219 for (int i = 0; i < moon_size; i++) {
220 sita = moon_longitude_parameters[i][0] * angles[0] +
221 moon_longitude_parameters[i][1] * angles[1] +
222 moon_longitude_parameters[i][2] * angles[2] +
223 moon_longitude_parameters[i][3] * angles[3];
224 sita *= M_PI / 180;
225 EI += moon_longitude_parameters[i][4] * sin(sita) *
226 pow(E, fabs(moon_longitude_parameters[i][1]));
227 }
228
229 //地外行星影响月球地心黄经修正项
230 double a1, a2;
231 a1 = 119.75 + 131.849 * T;
232 a2 = 53.09 + 479264.290 * T;
233
234 EI += 3958.0 * sin(a1 * M_PI / 180);
235 EI += 1962.0 * sin((L - angles[3]) * M_PI / 180);
236 EI += 318.0 * sin(a2 * M_PI / 180);
237
238 L += EI / 1000000;
239 L += 180 / M_PI * nutation(T); //地球章动修正
240
241 while (L < 0)
242 L += 360;
243 while (L >= 360)
244 L -= 360;
245 return L;
246}
247
248double parameter::getHourAngle(double julianKiloYear, double longitude, 209double parameter::getHourAngle(double julianKiloYear, double longitude,
249 double latitude, double alpha) { 210 double latitude, double alpha) {
250 double T = julianKiloYear * 10; 211 double T = julianKiloYear * 10;
251 double GST = 280.46061837 + 360.98564736629 * 36525 * T + 212 double GST = 280.46061837 + 360.98564736629 * 36525 * T +
252 0.000387933 * T * T - T * T * T / 38710000; 213 0.000387933 * T * T - T * T * T / 38710000;
214 GST += nutation(T) * cos(epsilon);
253 GST *= M_PI / 180; 215 GST *= M_PI / 180;
254 return GST + longitude - alpha; // 返回弧度制 216 return GST + longitude - alpha; // 返回弧度制
255} 217}