diff options
Diffstat (limited to 'src/calendar.cpp')
-rw-r--r-- | src/calendar.cpp | 120 |
1 files changed, 90 insertions, 30 deletions
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 | // 常量 |
8 | double day = 86400; | 9 | #define day_secs 86400 |
9 | double delta = 1e-11; | 10 | #define delta_time 1e-11 |
11 | |||
12 | /* calendar.h规定之量 */ | ||
10 | Julian julian; | 13 | Julian julian; |
11 | parameter p; | 14 | parameter p; |
15 | double epsilon; | ||
12 | 16 | ||
13 | pair<double, double> getSunPos(time_t time) { | 17 | FILE *fp; |
14 | double t = julian.getJulianKiloYear(time); | ||
15 | 18 | ||
19 | pair<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 | ||
46 | int main(int argc, char *argv[]) { | 48 | void 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 | |||
74 | void getSunTime(Date date) { | ||
75 | time_t time = mktime(&date); | ||
76 | binarySearch("Sunrize", time, date); | ||
77 | binarySearch("Sunset", time + day_secs / 2, date); | ||
78 | } | ||
79 | |||
80 | void 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 | |||
103 | int 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 |