solunar 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/ext/solunar/DST_Files/Test.txt +11 -0
- data/ext/solunar/DST_Files/USA.txt +11 -0
- data/ext/solunar/Data_Files/Test.bin +0 -0
- data/ext/solunar/Data_Files/USA.bin +0 -0
- data/ext/solunar/Source_Files/Moon.txt +4019 -0
- data/ext/solunar/Source_Files/Phase.TXT +545 -0
- data/ext/solunar/Source_Files/Sun.txt +3729 -0
- data/ext/solunar/Source_Files/ilum_2016.txt +31 -0
- data/ext/solunar/Source_Files/ilum_2017.txt +31 -0
- data/ext/solunar/Source_Files/ilum_2018.txt +32 -0
- data/ext/solunar/Source_Files/ilum_2019.txt +31 -0
- data/ext/solunar/Source_Files/ilum_2020.txt +31 -0
- data/ext/solunar/Source_Files/ilum_2021.txt +31 -0
- data/ext/solunar/Source_Files/ilum_2022.txt +31 -0
- data/ext/solunar/Source_Files/ilum_2023.txt +31 -0
- data/ext/solunar/Source_Files/ilum_2024.txt +31 -0
- data/ext/solunar/Source_Files/ilum_2025.txt +31 -0
- data/ext/solunar/Source_Files/ilum_2026.txt +32 -0
- data/ext/solunar/astrocon.h +61 -0
- data/ext/solunar/extconf.rb +14 -0
- data/ext/solunar/solunar.c +1959 -0
- data/lib/solunar.rb +79 -0
- metadata +71 -0
@@ -0,0 +1,31 @@
|
|
1
|
+
01 055 044 052 039 033 016 010 002 000 001 004 005
|
2
|
+
02 045 035 042 028 023 008 004 000 002 003 008 010
|
3
|
+
03 036 026 033 019 014 003 001 001 006 007 014 016
|
4
|
+
04 027 017 023 011 006 000 000 004 011 012 021 024
|
5
|
+
05 019 010 015 004 002 001 002 009 017 019 030 033
|
6
|
+
06 012 005 008 001 000 004 006 015 025 027 039 043
|
7
|
+
07 006 001 003 000 002 009 013 023 034 036 049 054
|
8
|
+
08 002 000 000 003 006 017 020 031 043 046 060 065
|
9
|
+
09 000 002 001 008 012 025 029 041 053 056 070 075
|
10
|
+
10 001 006 004 016 021 035 038 050 062 066 080 085
|
11
|
+
11 004 013 010 025 030 044 047 059 072 075 088 092
|
12
|
+
12 009 022 019 035 040 054 057 069 081 084 095 097
|
13
|
+
13 016 033 029 046 051 063 066 077 088 092 099 100
|
14
|
+
14 026 044 040 056 060 072 075 085 094 097 100 099
|
15
|
+
15 036 055 051 066 070 080 083 092 099 100 098 096
|
16
|
+
16 048 066 061 075 078 087 089 097 100 099 093 090
|
17
|
+
17 059 076 071 083 085 093 095 099 099 096 086 082
|
18
|
+
18 070 084 080 090 091 097 098 100 095 090 077 073
|
19
|
+
19 079 091 087 095 096 099 100 098 088 082 067 063
|
20
|
+
20 088 096 093 098 099 100 099 093 079 072 056 053
|
21
|
+
21 094 099 097 100 100 098 096 086 069 062 046 044
|
22
|
+
22 098 100 099 100 099 094 091 077 058 051 036 034
|
23
|
+
23 100 099 100 098 097 089 084 066 046 040 027 026
|
24
|
+
24 099 096 099 094 092 081 074 055 036 030 019 018
|
25
|
+
25 097 092 095 089 086 072 064 043 026 021 012 011
|
26
|
+
26 093 086 091 082 078 061 053 032 017 014 007 006
|
27
|
+
27 087 079 085 074 069 050 041 022 010 008 003 002
|
28
|
+
28 080 071 077 065 058 039 030 014 005 004 001 000
|
29
|
+
29 072 062 069 054 047 028 020 007 002 001 000 000
|
30
|
+
30 063 *** 059 044 036 018 012 003 000 000 002 002
|
31
|
+
31 054 *** 049 *** 026 *** 006 000 *** 001 *** 006
|
@@ -0,0 +1,31 @@
|
|
1
|
+
01 012 024 012 028 035 052 057 070 080 083 092 094
|
2
|
+
02 019 034 021 039 046 063 067 078 087 090 097 099
|
3
|
+
03 028 045 031 050 057 072 075 085 093 095 100 100
|
4
|
+
04 038 057 042 061 067 080 083 091 097 099 099 098
|
5
|
+
05 049 068 053 071 076 087 090 096 100 100 096 093
|
6
|
+
06 061 078 064 080 084 093 095 099 100 099 091 086
|
7
|
+
07 071 087 075 088 091 097 098 100 097 095 083 077
|
8
|
+
08 081 094 084 094 096 099 100 099 093 088 073 067
|
9
|
+
09 090 098 091 098 099 100 100 096 086 080 062 056
|
10
|
+
10 096 100 096 100 100 099 098 091 077 070 051 046
|
11
|
+
11 099 099 099 100 099 096 094 084 067 059 040 035
|
12
|
+
12 100 097 100 098 097 091 088 075 056 047 030 026
|
13
|
+
13 098 092 099 094 093 085 081 065 045 036 021 018
|
14
|
+
14 093 085 095 089 087 077 072 054 033 026 013 011
|
15
|
+
15 087 078 090 082 080 068 062 042 023 017 007 006
|
16
|
+
16 079 069 084 075 072 058 051 031 014 010 003 002
|
17
|
+
17 071 060 076 066 063 047 040 021 007 005 001 000
|
18
|
+
18 061 051 068 057 053 036 029 012 003 001 000 000
|
19
|
+
19 052 041 059 047 043 026 019 005 000 000 002 002
|
20
|
+
20 042 032 049 037 032 016 010 001 000 001 005 005
|
21
|
+
21 033 024 040 027 022 009 004 000 003 004 010 010
|
22
|
+
22 025 016 030 018 014 003 001 001 007 009 016 017
|
23
|
+
23 017 009 022 010 007 000 000 005 013 015 023 025
|
24
|
+
24 010 004 014 005 002 001 003 010 020 022 031 034
|
25
|
+
25 005 001 007 001 000 004 007 018 028 030 041 044
|
26
|
+
26 002 000 003 000 002 010 014 026 037 039 051 054
|
27
|
+
27 000 002 000 003 006 018 022 035 047 048 061 064
|
28
|
+
28 001 006 001 008 013 027 032 044 056 058 071 075
|
29
|
+
29 003 *** 004 015 021 037 041 054 065 068 080 084
|
30
|
+
30 008 *** 010 025 031 047 051 063 074 077 088 092
|
31
|
+
31 015 *** 018 *** 042 *** 061 072 *** 085 *** 097
|
@@ -0,0 +1,32 @@
|
|
1
|
+
01 100 098 100 098 097 091 089 079 065 058 038 031
|
2
|
+
02 099 093 099 094 093 085 083 071 054 046 028 022
|
3
|
+
03 096 087 096 089 087 078 075 061 043 035 018 013
|
4
|
+
04 090 078 091 082 080 069 066 050 032 024 010 007
|
5
|
+
05 082 069 084 073 072 060 056 039 022 015 005 003
|
6
|
+
06 072 059 076 065 063 050 046 029 013 008 001 000
|
7
|
+
07 062 049 066 055 053 040 035 019 006 003 000 000
|
8
|
+
08 052 040 057 046 044 031 025 010 002 000 001 002
|
9
|
+
09 042 031 047 037 034 021 016 004 000 001 005 006
|
10
|
+
10 032 022 038 028 025 013 008 001 002 003 010 011
|
11
|
+
11 024 015 029 019 017 006 003 000 006 008 017 018
|
12
|
+
12 016 009 021 012 010 002 000 003 012 015 024 025
|
13
|
+
13 010 004 014 006 004 000 001 008 020 023 033 034
|
14
|
+
14 005 001 008 002 001 001 004 015 029 031 042 043
|
15
|
+
15 002 000 003 000 000 006 010 024 038 041 051 053
|
16
|
+
16 000 001 001 001 002 012 018 034 048 050 061 062
|
17
|
+
17 000 004 000 004 007 021 028 044 058 060 070 072
|
18
|
+
18 002 008 002 009 014 031 039 054 067 069 078 081
|
19
|
+
19 006 015 006 017 024 042 049 064 075 077 086 088
|
20
|
+
20 012 023 012 026 034 053 060 073 083 085 092 095
|
21
|
+
21 019 033 020 037 046 064 069 081 089 091 097 099
|
22
|
+
22 028 044 029 048 057 074 078 088 095 096 100 100
|
23
|
+
23 038 055 040 060 067 082 086 093 098 099 100 099
|
24
|
+
24 048 066 051 070 077 089 092 097 100 100 097 094
|
25
|
+
25 059 076 063 080 085 094 096 099 099 099 092 087
|
26
|
+
26 070 086 073 088 092 098 099 100 097 095 084 079
|
27
|
+
27 080 093 083 094 096 100 100 098 093 089 075 068
|
28
|
+
28 089 098 091 098 099 100 099 095 086 081 064 057
|
29
|
+
29 095 *** 096 100 100 098 097 090 078 072 053 046
|
30
|
+
30 099 *** 099 099 099 094 093 083 068 061 042 036
|
31
|
+
31 100 *** 100 *** 096 *** 087 074 *** 049 *** 026
|
32
|
+
|
@@ -0,0 +1,31 @@
|
|
1
|
+
01 017 009 020 012 010 003 002 001 008 013 025 027
|
2
|
+
02 010 004 013 007 005 001 000 004 016 021 034 036
|
3
|
+
03 005 001 007 003 002 000 001 010 025 030 044 045
|
4
|
+
04 002 000 003 001 000 002 005 019 035 041 053 054
|
5
|
+
05 000 001 001 000 001 007 012 028 046 051 063 064
|
6
|
+
06 000 003 000 002 004 014 021 039 057 060 071 073
|
7
|
+
07 003 007 001 006 009 023 031 050 066 070 079 081
|
8
|
+
08 006 013 004 012 016 033 042 061 075 078 087 088
|
9
|
+
09 012 020 009 019 025 044 053 071 083 085 092 093
|
10
|
+
10 019 029 015 028 035 056 064 080 090 091 097 098
|
11
|
+
11 026 038 023 039 047 067 074 087 095 096 099 100
|
12
|
+
12 035 048 033 050 058 077 083 093 098 099 100 100
|
13
|
+
13 045 059 043 061 069 086 090 097 100 100 098 097
|
14
|
+
14 055 069 054 072 079 092 095 099 100 099 095 093
|
15
|
+
15 065 079 065 082 088 097 099 100 098 097 090 086
|
16
|
+
16 075 088 075 090 094 100 100 099 094 092 082 077
|
17
|
+
17 084 095 084 096 098 100 099 095 089 086 073 066
|
18
|
+
18 091 099 092 099 100 098 097 091 082 078 063 055
|
19
|
+
19 097 100 097 100 099 094 093 085 074 069 052 044
|
20
|
+
20 100 098 100 098 096 089 087 077 064 059 040 033
|
21
|
+
21 100 093 099 093 091 082 080 068 054 048 029 023
|
22
|
+
22 096 086 096 087 084 074 072 059 043 037 019 014
|
23
|
+
23 091 078 090 079 077 066 063 049 033 026 011 007
|
24
|
+
24 082 068 083 071 068 056 053 038 022 016 005 003
|
25
|
+
25 073 058 074 061 059 047 043 028 013 008 001 000
|
26
|
+
26 062 047 064 052 050 037 033 019 006 003 000 000
|
27
|
+
27 052 038 054 042 040 028 024 011 002 000 002 003
|
28
|
+
28 041 028 045 033 031 019 015 004 000 001 005 007
|
29
|
+
29 031 *** 035 025 022 012 008 001 002 004 011 013
|
30
|
+
30 022 *** 026 017 015 006 003 000 006 009 018 020
|
31
|
+
31 015 *** 019 *** 008 *** 000 003 *** 016 *** 028
|
@@ -0,0 +1,31 @@
|
|
1
|
+
01 037 047 039 054 060 079 086 096 100 100 099 098
|
2
|
+
02 046 057 049 064 071 087 093 099 100 099 096 095
|
3
|
+
03 055 066 059 074 081 094 097 100 098 097 091 089
|
4
|
+
04 065 076 070 084 089 098 100 099 094 093 085 082
|
5
|
+
05 074 084 079 092 096 100 100 095 089 087 078 074
|
6
|
+
06 082 091 087 097 099 099 097 091 082 080 069 064
|
7
|
+
07 089 097 094 100 100 095 093 084 074 072 059 053
|
8
|
+
08 095 099 098 099 098 090 087 077 066 063 048 042
|
9
|
+
09 099 100 100 096 093 082 079 068 056 053 037 031
|
10
|
+
10 100 097 098 090 086 074 071 059 047 043 027 021
|
11
|
+
11 099 091 094 082 077 065 062 050 037 032 017 012
|
12
|
+
12 095 083 087 073 068 055 052 040 027 022 009 005
|
13
|
+
13 089 074 078 063 058 046 043 031 018 014 003 001
|
14
|
+
14 080 063 068 052 049 036 034 022 010 007 000 000
|
15
|
+
15 070 052 057 042 039 027 025 014 004 002 000 002
|
16
|
+
16 059 041 046 033 030 019 017 007 001 000 003 006
|
17
|
+
17 048 031 036 024 022 012 010 003 000 001 009 012
|
18
|
+
18 037 022 027 016 014 007 005 000 003 006 017 020
|
19
|
+
19 026 014 019 010 008 002 001 001 008 013 026 029
|
20
|
+
20 018 008 012 005 004 000 000 004 016 021 036 038
|
21
|
+
21 010 003 006 002 001 000 001 010 025 031 046 048
|
22
|
+
22 005 001 003 000 000 002 005 018 036 042 056 057
|
23
|
+
23 001 000 001 001 001 007 012 028 047 052 065 067
|
24
|
+
24 000 001 000 003 004 014 020 039 057 062 074 075
|
25
|
+
25 001 004 002 007 009 022 030 050 068 072 082 083
|
26
|
+
26 003 009 005 012 016 032 041 061 077 080 088 089
|
27
|
+
27 008 015 010 020 025 043 053 071 085 087 094 095
|
28
|
+
28 014 022 016 028 035 055 064 081 091 093 097 098
|
29
|
+
29 021 030 024 038 046 066 074 088 096 097 100 100
|
30
|
+
30 029 *** 033 049 057 077 083 094 099 099 100 100
|
31
|
+
31 038 *** 043 *** 068 *** 091 098 *** 100 *** 097
|
@@ -0,0 +1,31 @@
|
|
1
|
+
01 093 082 092 079 072 056 051 039 028 025 013 010
|
2
|
+
02 086 072 085 068 062 046 042 030 019 017 007 004
|
3
|
+
03 078 061 075 058 051 036 032 022 012 009 002 001
|
4
|
+
04 068 050 065 046 040 027 024 014 006 004 000 000
|
5
|
+
05 057 039 054 036 031 019 016 008 002 001 001 003
|
6
|
+
06 046 028 042 026 022 012 010 004 000 000 005 009
|
7
|
+
07 035 019 032 018 014 006 005 001 001 002 012 017
|
8
|
+
08 024 011 022 011 008 003 002 000 004 007 021 026
|
9
|
+
09 015 005 014 005 004 000 000 002 009 015 031 036
|
10
|
+
10 008 001 008 002 001 000 001 006 017 024 042 047
|
11
|
+
11 003 000 003 000 000 002 003 012 027 035 052 057
|
12
|
+
12 000 001 001 000 001 005 008 020 038 046 063 067
|
13
|
+
13 000 004 000 003 003 010 014 029 049 057 073 076
|
14
|
+
14 003 009 002 006 008 017 022 040 060 067 081 083
|
15
|
+
15 008 016 005 012 014 025 032 051 071 077 088 090
|
16
|
+
16 014 023 010 018 021 035 043 063 080 085 094 095
|
17
|
+
17 022 031 017 026 030 046 054 073 088 092 098 098
|
18
|
+
18 030 040 024 035 039 057 065 083 094 096 100 100
|
19
|
+
19 040 050 033 045 050 068 076 091 098 099 100 100
|
20
|
+
20 049 059 042 055 060 078 085 096 100 100 098 098
|
21
|
+
21 058 069 051 065 071 087 092 099 099 099 095 094
|
22
|
+
22 067 077 061 075 081 094 097 100 097 096 090 089
|
23
|
+
23 076 085 071 084 089 098 100 098 092 091 084 082
|
24
|
+
24 084 092 080 092 095 100 099 094 087 085 076 074
|
25
|
+
25 090 097 088 097 099 099 096 089 080 078 068 064
|
26
|
+
26 095 099 094 100 100 094 091 082 071 070 058 054
|
27
|
+
27 099 100 098 099 098 088 084 073 063 061 048 043
|
28
|
+
28 100 097 100 096 092 080 076 065 053 051 037 032
|
29
|
+
29 099 *** 099 090 085 071 067 055 044 041 027 022
|
30
|
+
30 095 *** 094 082 076 061 058 046 034 031 018 013
|
31
|
+
31 089 *** 088 *** 066 *** 048 037 *** 022 *** 006
|
@@ -0,0 +1,31 @@
|
|
1
|
+
01 002 001 001 000 001 005 006 015 029 036 056 063
|
2
|
+
02 000 003 000 002 003 010 012 023 039 047 067 073
|
3
|
+
03 002 008 001 006 008 016 019 032 050 059 077 082
|
4
|
+
04 006 015 005 012 014 023 027 042 061 070 085 089
|
5
|
+
05 012 024 010 019 021 032 036 053 072 080 092 094
|
6
|
+
06 021 033 017 027 029 041 047 064 082 088 097 098
|
7
|
+
07 030 042 025 036 038 051 057 075 090 094 099 100
|
8
|
+
08 040 052 034 045 048 062 068 084 096 098 100 100
|
9
|
+
09 050 061 044 055 057 072 078 092 099 100 098 098
|
10
|
+
10 060 070 053 064 067 081 087 097 100 099 095 094
|
11
|
+
11 069 078 062 073 077 089 094 100 098 096 090 089
|
12
|
+
12 077 085 071 082 085 095 098 099 093 091 083 082
|
13
|
+
13 085 091 079 089 092 099 100 096 087 085 075 074
|
14
|
+
14 091 096 087 095 097 100 098 090 079 077 067 066
|
15
|
+
15 095 099 093 099 100 097 094 083 070 068 058 056
|
16
|
+
16 098 100 097 100 100 092 087 074 061 059 048 046
|
17
|
+
17 100 099 099 099 096 085 079 064 052 050 039 036
|
18
|
+
18 099 095 100 095 090 075 069 054 042 040 029 027
|
19
|
+
19 097 090 097 088 082 065 059 045 033 031 020 018
|
20
|
+
20 093 083 093 080 072 054 049 035 024 023 013 010
|
21
|
+
21 086 074 086 070 062 044 039 027 017 015 006 004
|
22
|
+
22 079 063 077 059 050 034 029 019 010 008 002 001
|
23
|
+
23 069 052 067 047 040 024 021 012 005 003 000 000
|
24
|
+
24 059 041 056 036 029 017 014 007 002 001 001 003
|
25
|
+
25 048 030 044 026 020 010 008 003 000 000 005 008
|
26
|
+
26 037 020 033 017 013 005 004 001 001 002 011 016
|
27
|
+
27 026 012 023 010 007 002 001 000 004 007 019 025
|
28
|
+
28 017 005 014 005 003 000 000 002 009 014 030 036
|
29
|
+
29 009 *** 007 001 000 000 001 006 016 023 040 047
|
30
|
+
30 003 *** 003 000 000 003 004 012 025 033 052 058
|
31
|
+
31 001 *** 000 *** 002 *** 009 019 *** 044 *** 068
|
@@ -0,0 +1,31 @@
|
|
1
|
+
01 077 086 073 082 084 093 096 100 096 093 083 081
|
2
|
+
02 084 092 080 089 091 097 099 098 090 086 074 073
|
3
|
+
03 091 096 087 094 096 100 100 094 082 077 065 064
|
4
|
+
04 096 099 093 098 099 099 097 087 072 068 056 055
|
5
|
+
05 099 100 097 100 100 096 092 078 062 058 046 045
|
6
|
+
06 100 099 099 100 099 091 085 068 052 048 037 036
|
7
|
+
07 099 096 100 097 095 083 075 057 042 039 028 027
|
8
|
+
08 097 092 099 093 089 073 065 047 032 030 020 019
|
9
|
+
09 093 086 095 086 081 062 054 037 024 022 013 012
|
10
|
+
10 088 078 090 078 071 051 043 027 016 014 007 006
|
11
|
+
11 081 070 083 068 060 040 032 019 010 008 003 002
|
12
|
+
12 073 060 075 057 048 029 023 012 005 004 000 000
|
13
|
+
13 064 049 065 046 037 020 015 006 002 001 000 001
|
14
|
+
14 054 038 054 035 026 012 009 003 000 000 002 004
|
15
|
+
15 043 028 043 024 017 006 004 001 000 001 006 010
|
16
|
+
16 033 018 032 015 010 002 001 000 003 004 013 018
|
17
|
+
17 023 010 021 008 004 000 000 002 007 009 021 028
|
18
|
+
18 014 004 012 003 001 000 001 005 012 016 031 039
|
19
|
+
19 007 001 006 000 000 003 004 010 020 025 042 050
|
20
|
+
20 002 000 001 000 001 006 008 016 029 035 054 061
|
21
|
+
21 000 003 000 003 005 012 014 024 039 046 065 072
|
22
|
+
22 001 009 001 008 010 019 021 033 049 057 075 081
|
23
|
+
23 006 016 005 014 016 026 029 043 061 068 084 089
|
24
|
+
24 012 025 011 022 024 035 039 054 071 078 092 094
|
25
|
+
25 021 034 019 030 033 045 048 064 081 087 097 098
|
26
|
+
26 031 044 028 039 042 054 059 075 090 094 099 100
|
27
|
+
27 041 054 037 049 051 064 069 084 096 098 100 099
|
28
|
+
28 051 064 047 058 061 074 078 092 099 100 098 097
|
29
|
+
29 061 *** 056 067 070 082 087 097 100 099 094 093
|
30
|
+
30 071 *** 066 076 079 090 094 100 097 095 088 087
|
31
|
+
31 079 *** 074 *** 087 *** 098 099 *** 090 *** 080
|
@@ -0,0 +1,31 @@
|
|
1
|
+
01 072 062 069 054 047 027 020 008 002 001 000 000
|
2
|
+
02 063 052 059 043 036 018 012 003 000 000 001 002
|
3
|
+
03 054 042 049 032 025 010 006 001 000 001 005 007
|
4
|
+
04 044 032 038 022 016 004 002 000 003 003 010 013
|
5
|
+
05 035 023 028 013 008 001 000 002 006 008 017 020
|
6
|
+
06 026 014 018 006 003 000 001 005 012 014 025 030
|
7
|
+
07 017 007 010 002 000 002 004 010 018 021 034 040
|
8
|
+
08 010 002 004 000 001 006 008 016 026 030 045 051
|
9
|
+
09 004 000 001 001 004 012 014 024 035 039 056 063
|
10
|
+
10 001 001 000 006 009 019 022 032 045 050 067 073
|
11
|
+
11 000 005 003 012 016 027 030 042 055 060 077 083
|
12
|
+
12 002 011 008 020 024 036 039 051 065 071 086 091
|
13
|
+
13 007 020 016 030 033 046 048 061 075 081 093 096
|
14
|
+
14 015 030 025 040 043 055 058 071 084 089 098 099
|
15
|
+
15 024 041 035 050 053 064 067 080 092 096 100 100
|
16
|
+
16 034 051 046 059 062 073 076 088 097 099 099 097
|
17
|
+
17 046 062 056 069 071 081 084 094 100 100 095 093
|
18
|
+
18 057 072 066 077 079 088 091 098 099 097 089 087
|
19
|
+
19 067 080 075 084 086 094 096 100 096 092 081 079
|
20
|
+
20 077 087 083 091 092 098 099 099 090 085 072 070
|
21
|
+
21 085 093 089 095 097 100 100 094 081 076 063 061
|
22
|
+
22 091 097 094 099 099 099 098 087 072 066 053 052
|
23
|
+
23 096 099 098 100 100 096 093 079 061 056 044 042
|
24
|
+
24 099 100 100 099 098 091 085 068 050 046 034 033
|
25
|
+
25 100 099 100 097 095 083 076 057 040 036 026 025
|
26
|
+
26 099 096 098 092 089 074 066 046 030 027 018 017
|
27
|
+
27 096 091 095 086 081 063 054 036 022 019 011 010
|
28
|
+
28 092 085 089 078 072 052 043 026 014 012 006 005
|
29
|
+
29 086 077 082 069 061 041 032 017 008 007 002 002
|
30
|
+
30 079 *** 074 058 050 030 023 010 004 003 000 000
|
31
|
+
31 071 *** 065 *** 038 *** 014 005 *** 001 *** 001
|
@@ -0,0 +1,31 @@
|
|
1
|
+
01 004 013 004 016 021 036 040 052 064 067 081 085
|
2
|
+
02 009 022 010 025 031 046 050 062 073 077 089 093
|
3
|
+
03 017 032 019 036 042 056 059 071 082 085 095 098
|
4
|
+
04 026 043 029 046 052 065 068 079 089 092 099 100
|
5
|
+
05 036 055 040 057 062 074 077 086 095 097 100 099
|
6
|
+
06 047 066 051 067 071 082 084 093 099 100 098 095
|
7
|
+
07 059 076 062 076 080 089 090 097 100 099 093 089
|
8
|
+
08 070 084 072 084 087 094 095 100 099 096 085 081
|
9
|
+
09 079 091 081 091 092 098 099 100 095 090 076 071
|
10
|
+
10 088 096 088 095 097 100 100 098 088 082 066 061
|
11
|
+
11 094 099 094 099 099 100 099 093 079 072 055 051
|
12
|
+
12 098 100 098 100 100 098 096 086 069 061 045 041
|
13
|
+
13 100 099 100 099 099 094 091 077 058 050 035 032
|
14
|
+
14 099 095 100 097 096 088 084 067 047 039 026 024
|
15
|
+
15 096 091 098 093 091 081 075 055 036 029 018 016
|
16
|
+
16 092 084 095 088 085 072 064 044 026 020 011 010
|
17
|
+
17 085 077 090 081 077 062 053 033 017 013 006 005
|
18
|
+
18 078 069 083 073 068 051 042 023 010 007 002 002
|
19
|
+
19 069 059 075 063 058 039 031 014 004 003 000 000
|
20
|
+
20 060 050 067 053 047 029 021 007 001 001 000 001
|
21
|
+
21 051 040 057 043 036 019 012 003 000 000 002 003
|
22
|
+
22 042 031 047 032 026 010 006 000 001 002 006 007
|
23
|
+
23 032 022 037 022 016 004 002 000 004 005 011 013
|
24
|
+
24 024 014 027 013 008 001 000 002 008 009 017 020
|
25
|
+
25 016 007 018 006 003 000 001 006 014 016 025 029
|
26
|
+
26 009 002 010 002 000 002 005 012 021 023 034 039
|
27
|
+
27 004 000 004 000 001 007 010 019 029 031 044 050
|
28
|
+
28 001 001 001 001 004 014 017 027 038 041 055 061
|
29
|
+
29 000 *** 000 006 010 022 025 036 048 051 066 071
|
30
|
+
30 002 *** 003 013 017 030 033 045 058 061 076 081
|
31
|
+
31 006 *** 008 *** 026 *** 043 055 *** 071 *** 090
|
@@ -0,0 +1,32 @@
|
|
1
|
+
01 096 100 096 100 100 098 097 090 078 070 051 045
|
2
|
+
02 099 099 099 099 099 095 093 083 068 059 040 034
|
3
|
+
03 100 096 100 097 096 090 087 075 057 048 030 025
|
4
|
+
04 097 091 098 093 092 083 080 065 045 037 020 017
|
5
|
+
05 093 084 094 087 086 076 071 054 034 026 013 010
|
6
|
+
06 086 076 089 081 079 067 061 043 023 017 007 005
|
7
|
+
07 078 067 082 073 070 057 051 032 014 010 003 002
|
8
|
+
08 069 058 074 064 061 047 040 021 007 004 000 000
|
9
|
+
09 059 048 065 054 051 036 029 012 002 001 000 001
|
10
|
+
10 049 039 056 045 041 026 019 006 000 000 002 003
|
11
|
+
11 040 030 047 035 031 016 011 001 000 001 006 007
|
12
|
+
12 031 021 037 026 022 009 004 000 003 005 011 012
|
13
|
+
13 022 014 028 017 013 003 001 001 008 010 018 019
|
14
|
+
14 015 008 020 010 006 000 000 005 014 016 025 027
|
15
|
+
15 009 003 012 004 002 001 003 011 022 024 034 036
|
16
|
+
16 004 001 006 001 000 004 008 019 030 032 043 045
|
17
|
+
17 001 000 002 000 001 010 015 028 040 041 053 055
|
18
|
+
18 000 002 000 002 006 018 023 037 049 051 062 066
|
19
|
+
19 001 006 001 008 013 028 033 047 058 060 072 076
|
20
|
+
20 004 012 004 015 021 038 043 056 068 070 081 085
|
21
|
+
21 009 021 010 024 032 048 053 065 076 078 089 092
|
22
|
+
22 016 030 018 035 042 059 063 074 084 086 095 097
|
23
|
+
23 024 041 027 046 053 068 072 082 091 093 099 100
|
24
|
+
24 034 053 038 057 063 077 080 089 096 097 100 099
|
25
|
+
25 045 064 050 068 073 084 087 094 099 100 098 096
|
26
|
+
26 056 075 061 077 081 091 092 098 100 099 093 089
|
27
|
+
27 068 084 071 085 088 095 097 100 099 096 086 081
|
28
|
+
28 078 091 081 092 094 098 099 100 095 091 077 072
|
29
|
+
29 087 *** 088 096 097 100 100 097 088 083 067 061
|
30
|
+
30 094 *** 094 099 099 099 099 093 080 073 056 051
|
31
|
+
31 098 *** 098 *** 100 *** 096 086 *** 063 *** 040
|
32
|
+
|
@@ -0,0 +1,61 @@
|
|
1
|
+
#ifndef _CONSTS_
|
2
|
+
#define _CONSTS_
|
3
|
+
|
4
|
+
/* Gaussian gravitational constant */
|
5
|
+
#define GAUSSK (0.01720209895)
|
6
|
+
|
7
|
+
/* values related to PI */
|
8
|
+
#ifndef PI
|
9
|
+
#define PI (139755218526789.0 / 44485467702853.0)
|
10
|
+
#endif
|
11
|
+
|
12
|
+
#define TWOPI (2.0 * PI)
|
13
|
+
#define PIDIV2 (0.5 * PI)
|
14
|
+
|
15
|
+
/* degrees to radians and radians to degrees */
|
16
|
+
#define D2R (PI / 180.0)
|
17
|
+
#define R2D (180.0 / PI)
|
18
|
+
|
19
|
+
/* hours to radians and radians to hours */
|
20
|
+
#define H2R (PI / 12.0)
|
21
|
+
#define R2H (12.0 / PI)
|
22
|
+
|
23
|
+
/* arcseconds to radians and radians to arcseconds */
|
24
|
+
#define A2R (PI / 648000.0)
|
25
|
+
#define R2A (648000.0 / PI)
|
26
|
+
|
27
|
+
/* AU to km and km to AU */
|
28
|
+
#define AU2KM (149597870.66)
|
29
|
+
#define KM2AU (1.0 / 149597870.66)
|
30
|
+
|
31
|
+
/* speed of light in km/s and AU/day */
|
32
|
+
#define CKMS (299792.458)
|
33
|
+
#define CAUD (CKMS * 86400.0 * KM2AU)
|
34
|
+
|
35
|
+
/* Earth's angular velocity in rad/s */
|
36
|
+
#define EarAngVelRD (6.30038748685432)
|
37
|
+
|
38
|
+
/* Earth's equatorial radius in km and AU */
|
39
|
+
#define EarthRadKM (6378.137)
|
40
|
+
#define EarthRadAU (EarthRadKM * KM2AU)
|
41
|
+
|
42
|
+
/* Earth's flattening factor */
|
43
|
+
#define EFlat (1.0 / 298.257)
|
44
|
+
|
45
|
+
/* JED of standard epoch */
|
46
|
+
#define J2000 (2451545.0)
|
47
|
+
|
48
|
+
/* days in a Julian century */
|
49
|
+
#define JulCty (36525.0)
|
50
|
+
|
51
|
+
/* Earth's gravitational constant */
|
52
|
+
#define MUC (2.0 * GAUSSK * GAUSSK / (CAUD * CAUD))
|
53
|
+
|
54
|
+
/* global state vector variable */
|
55
|
+
extern double StateVector[15][15][2][6];
|
56
|
+
|
57
|
+
extern double obsr_lon;
|
58
|
+
extern double obsr_lat;
|
59
|
+
extern double obsr_ele;
|
60
|
+
|
61
|
+
#endif /* _CONSTS_ */
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'mkmf'
|
2
|
+
|
3
|
+
# have_func returns false if a C function cannot be found. Sometimes this
|
4
|
+
# will be OK (the function changed names between versions) and sometimes it is
|
5
|
+
# not so you need to exit without creating the Makefile.
|
6
|
+
|
7
|
+
abort 'missing malloc()' unless have_func 'malloc'
|
8
|
+
abort 'missing free()' unless have_func 'free'
|
9
|
+
|
10
|
+
# Now we create the Makefile that will install the extension as
|
11
|
+
# lib/my_malloc/my_malloc.so.
|
12
|
+
|
13
|
+
create_makefile 'solunar/solunar'
|
14
|
+
|
@@ -0,0 +1,1959 @@
|
|
1
|
+
/*********************** include files ******************************************************/
|
2
|
+
#include <ruby.h>
|
3
|
+
#include <astrocon.h>
|
4
|
+
#include "stdio.h"
|
5
|
+
#include "stdlib.h"
|
6
|
+
#include <math.h>
|
7
|
+
#include <string.h>
|
8
|
+
#include <stdbool.h>
|
9
|
+
|
10
|
+
/*********************** macro definitions **************************************************/
|
11
|
+
|
12
|
+
#define SUN 0
|
13
|
+
#define MOON 1
|
14
|
+
#define RA 23
|
15
|
+
#define DEC 33
|
16
|
+
#define DATA_NAME "USA"
|
17
|
+
#define CLUB_NAME "club"
|
18
|
+
#define CLUB_EXT ".txt"
|
19
|
+
#define DATA_EXT ".bin"
|
20
|
+
#define DST_NAME "USA"
|
21
|
+
#define DST_EXT ".txt"
|
22
|
+
#define DATA_PATH "./ext/solunar/Data_Files/"
|
23
|
+
#define CLUB_PATH "./ext/solunar/Club_Files/"
|
24
|
+
#define DST_PATH "./ext/solunar/DST_Files/"
|
25
|
+
#define SUN_FILE "./ext/solunar/Source_Files/sun.txt"
|
26
|
+
#define MOON_FILE "./ext/solunar/Source_Files/moon.txt"
|
27
|
+
#define PHASE_FILE "./ext/solunar/Source_Files/phase.txt"
|
28
|
+
#define ILLUM_16_FILE "./ext/solunar/Source_Files/ilum_2016.txt"
|
29
|
+
#define ILLUM_17_FILE "./ext/solunar/Source_Files/ilum_2017.txt"
|
30
|
+
#define ILLUM_18_FILE "./ext/solunar/Source_Files/ilum_2018.txt"
|
31
|
+
#define ILLUM_19_FILE "./ext/solunar/Source_Files/ilum_2019.txt"
|
32
|
+
#define ILLUM_20_FILE "./ext/solunar/Source_Files/ilum_2020.txt"
|
33
|
+
#define ILLUM_21_FILE "./ext/solunar/Source_Files/ilum_2021.txt"
|
34
|
+
#define ILLUM_22_FILE "./ext/solunar/Source_Files/ilum_2022.txt"
|
35
|
+
#define ILLUM_23_FILE "./ext/solunar/Source_Files/ilum_2023.txt"
|
36
|
+
#define ILLUM_24_FILE "./ext/solunar/Source_Files/ilum_2024.txt"
|
37
|
+
#define ILLUM_25_FILE "./ext/solunar/Source_Files/ilum_2025.txt"
|
38
|
+
#define ILLUM_26_FILE "./ext/solunar/Source_Files/ilum_2026.txt"
|
39
|
+
|
40
|
+
#define CLUB_FAIL 1
|
41
|
+
#define DATA_FAIL 2
|
42
|
+
#define SUN_FAIL 3
|
43
|
+
#define MOON_FAIL 4
|
44
|
+
#define DTS_FAIL 5
|
45
|
+
#define PHASE_FAIL 6
|
46
|
+
#define ILLUM_16_FAIL 7
|
47
|
+
#define ILLUM_17_FAIL 8
|
48
|
+
#define ILLUM_18_FAIL 9
|
49
|
+
#define ILLUM_19_FAIL 10
|
50
|
+
#define ILLUM_20_FAIL 11
|
51
|
+
#define ILLUM_21_FAIL 12
|
52
|
+
#define ILLUM_22_FAIL 13
|
53
|
+
#define ILLUM_23_FAIL 14
|
54
|
+
#define ILLUM_24_FAIL 15
|
55
|
+
#define ILLUM_25_FAIL 16
|
56
|
+
#define ILLUM_26_FAIL 17
|
57
|
+
#define ARG_ERROR 99
|
58
|
+
//file information
|
59
|
+
#define DATA_FILE_SIZE 4018
|
60
|
+
#define JPL_DATE_SIZE 12
|
61
|
+
#define PHASE_FILE_SIZE 544
|
62
|
+
#define DST_FILE_SIZE 11
|
63
|
+
#define RST_MAX_TRIES 50
|
64
|
+
#define JDATE_BASE 2457388.5 // January 1, 2016
|
65
|
+
#define YES 1
|
66
|
+
#define NO 0
|
67
|
+
#define MINUTES_PER_DAY (24 * 60)
|
68
|
+
//exceptions
|
69
|
+
#define NEXT_DAY 1
|
70
|
+
#define PREV_DAY 2
|
71
|
+
#define NONE_TODAY 3
|
72
|
+
#define ROUTINE 4
|
73
|
+
#define NEVER_RISE 5
|
74
|
+
#define NEVER_SET 6
|
75
|
+
#define ERROR 7
|
76
|
+
#define RST_ERROR 8
|
77
|
+
#define RST_FAIL 9
|
78
|
+
//phases
|
79
|
+
#define NEW_MOON 1
|
80
|
+
#define WAX_CRES 2
|
81
|
+
#define FIRST_QTR 3
|
82
|
+
#define WAX_GIBB 4
|
83
|
+
#define FULL_MOON 5
|
84
|
+
#define WAN_GIBB 6
|
85
|
+
#define LAST_QTR 7
|
86
|
+
#define WAN_CRES 8
|
87
|
+
|
88
|
+
/*********************** typedefs ***********************************************************/
|
89
|
+
|
90
|
+
typedef struct {
|
91
|
+
double ra;
|
92
|
+
double dec;
|
93
|
+
} jpl_data;
|
94
|
+
typedef struct {
|
95
|
+
char date[JPL_DATE_SIZE];
|
96
|
+
jpl_data sun;
|
97
|
+
jpl_data moon;
|
98
|
+
bool dst;
|
99
|
+
int phase;
|
100
|
+
int phase_time;
|
101
|
+
int illum;
|
102
|
+
} jpl_type;
|
103
|
+
typedef struct {
|
104
|
+
int minute;
|
105
|
+
int second;
|
106
|
+
int exception;
|
107
|
+
} time_type;
|
108
|
+
typedef struct {
|
109
|
+
time_type ris;
|
110
|
+
time_type set;
|
111
|
+
time_type trn;
|
112
|
+
time_type tru;
|
113
|
+
} rst_type;
|
114
|
+
typedef struct {
|
115
|
+
char date[JPL_DATE_SIZE];
|
116
|
+
int gmt_offset;
|
117
|
+
rst_type sun;
|
118
|
+
rst_type moon;
|
119
|
+
int moon_phase;
|
120
|
+
int phase_time;
|
121
|
+
int moon_illum;
|
122
|
+
} sol_type;
|
123
|
+
typedef struct {
|
124
|
+
double start;
|
125
|
+
double stop;
|
126
|
+
} dst_type;
|
127
|
+
|
128
|
+
/*********************** constant arrays ****************************************************/
|
129
|
+
|
130
|
+
const int year_days[11] = {
|
131
|
+
0, // 2016
|
132
|
+
366, // 2017
|
133
|
+
731, // 2018
|
134
|
+
1096, // 2019
|
135
|
+
1461, // 2020
|
136
|
+
1827, // 2021
|
137
|
+
2192, // 2022
|
138
|
+
2557, // 2023
|
139
|
+
2922, // 2024
|
140
|
+
3288, // 2025
|
141
|
+
3653, // 2026
|
142
|
+
};
|
143
|
+
const int month_days[12] = {
|
144
|
+
0, // JAN
|
145
|
+
31, // FEB
|
146
|
+
59, // MAR
|
147
|
+
90, // APR
|
148
|
+
120, // MAY
|
149
|
+
151, // JUN
|
150
|
+
181, // JUL
|
151
|
+
212, // AUG
|
152
|
+
243, // SEP
|
153
|
+
273, // OCT
|
154
|
+
304, // NOV
|
155
|
+
334, // DEC
|
156
|
+
};
|
157
|
+
const int leap_days[12] = {
|
158
|
+
0, // JAN
|
159
|
+
31, // FEB
|
160
|
+
60, // MAR
|
161
|
+
91, // APR
|
162
|
+
121, // MAY
|
163
|
+
152, // JUN
|
164
|
+
182, // JUL
|
165
|
+
213, // AUG
|
166
|
+
244, // SEP
|
167
|
+
274, // OCT
|
168
|
+
305, // NOV
|
169
|
+
335, // DEC
|
170
|
+
};
|
171
|
+
char error_msg[][36] = {
|
172
|
+
"Operation Successful",
|
173
|
+
"Cannot open Club file",
|
174
|
+
"Cannot open Data file",
|
175
|
+
"Cannot open Sun file",
|
176
|
+
"Cannot open Moon file",
|
177
|
+
"Cannot open DST file",
|
178
|
+
"Cannot open Phase file",
|
179
|
+
"Cannot open 2016 Illumination file",
|
180
|
+
"Cannot open 2017 Illumination file",
|
181
|
+
"Cannot open 2018 Illumination file",
|
182
|
+
"Cannot open 2019 Illumination file",
|
183
|
+
"Cannot open 2020 Illumination file",
|
184
|
+
"Cannot open 2021 Illumination file",
|
185
|
+
"Cannot open 2022 Illumination file",
|
186
|
+
"Cannot open 2023 Illumination file",
|
187
|
+
"Cannot open 2024 Illumination file",
|
188
|
+
"Cannot open 2025 Illumination file",
|
189
|
+
"Cannot open 2026 Illumination file"
|
190
|
+
};
|
191
|
+
|
192
|
+
/*********************** function prototypes ************************************************/
|
193
|
+
|
194
|
+
int TestBuildDataFile(void);
|
195
|
+
int BuildDataFile(char*);
|
196
|
+
int TestSummary(void);
|
197
|
+
int Summary(char*, double, double, int, int, int, char*);
|
198
|
+
int TestClubFile(void);
|
199
|
+
char* ClubFile(char*, char*, int, double, double, int, int, int, char*, char*);
|
200
|
+
double ConvertDate(char*);
|
201
|
+
int GetSunData(void);
|
202
|
+
int GetMoonData(void);
|
203
|
+
int GetDateData(void);
|
204
|
+
int GetDstData(char*);
|
205
|
+
int GetIllumData(void);
|
206
|
+
int GetPhaseData(void);
|
207
|
+
int SaveDataFile(char*);
|
208
|
+
int Solunar(sol_type*, double, double, double, int, int, char*);
|
209
|
+
int GetIllumYear(const char*, int*);
|
210
|
+
time_type FmtTime(double);
|
211
|
+
void FmtTimeStr(char*, time_type, int);
|
212
|
+
time_type AdjustTimes(time_type, time_type, time_type, int);
|
213
|
+
// original Heafner functions with some changes
|
214
|
+
rst_type RST(FILE*, int, double, double, double);
|
215
|
+
static int RST_Interpolate(int, double, double, double, double, double*, double*, double,
|
216
|
+
double, double, double, double, double, double, double, double*);
|
217
|
+
double deg(double x);
|
218
|
+
void GetGST(double, int, double*);
|
219
|
+
double amodulo(double, double);
|
220
|
+
|
221
|
+
/*********************** variable delarations ***********************************************/
|
222
|
+
|
223
|
+
jpl_type jpl_temp[DATA_FILE_SIZE];
|
224
|
+
dst_type dst[DST_FILE_SIZE];
|
225
|
+
|
226
|
+
/*********************** mode selection *****************************************************/
|
227
|
+
/*
|
228
|
+
Uuncomment one of these to control whether the executable will enter the Console Mode, to display
|
229
|
+
a one cay summary, the Club Mode, to porepare the Club File, or the build Mode, to build a new
|
230
|
+
data file from a revised DST file. */
|
231
|
+
|
232
|
+
//define CONSOLE_MODE
|
233
|
+
#define CLUB_MODE
|
234
|
+
//#define BUILD_MODE
|
235
|
+
|
236
|
+
/*********************** Main
|
237
|
+
|
238
|
+
This is the entry point for the program.
|
239
|
+
|
240
|
+
RETURN VALUE: EXIT_SUCCESS or Error Code
|
241
|
+
|
242
|
+
PARAMETERS: Varies depending on mode
|
243
|
+
*/
|
244
|
+
/*#ifdef CONSOLE_MODE
|
245
|
+
int main()
|
246
|
+
{
|
247
|
+
enum { BUILD = 'B', CLUB = 'C', DISPLAY = 'D' };
|
248
|
+
int task;
|
249
|
+
char line[100];
|
250
|
+
|
251
|
+
printf("Enter: Club File, Display Summary, Build Data File: ");
|
252
|
+
fgets(line, sizeof line, stdin);
|
253
|
+
if (line[0] == '\n') strcpy(line, "Club");
|
254
|
+
task = line[0];
|
255
|
+
switch (task)
|
256
|
+
{
|
257
|
+
case BUILD:
|
258
|
+
case BUILD + 32:
|
259
|
+
printf("\nBUILD DATA FILE\n\n");
|
260
|
+
TestBuildDataFile();
|
261
|
+
break;
|
262
|
+
case DISPLAY:
|
263
|
+
case DISPLAY + 32:
|
264
|
+
printf("\nDISPLAY SUMMARY\n\n");
|
265
|
+
TestSummary();
|
266
|
+
break;
|
267
|
+
default:
|
268
|
+
printf("\nCLUB FILE\n\n");
|
269
|
+
TestClubFile();
|
270
|
+
break;
|
271
|
+
}
|
272
|
+
return 0;
|
273
|
+
}
|
274
|
+
#endif*/
|
275
|
+
|
276
|
+
static VALUE generate(VALUE self, VALUE r_date_str, VALUE r_count, VALUE r_lat,
|
277
|
+
VALUE r_lon, VALUE r_gmt_offset, VALUE r_dst_offset, VALUE r_military_time)
|
278
|
+
{
|
279
|
+
char* result;
|
280
|
+
int gmt_offset;
|
281
|
+
int dst_time;
|
282
|
+
int am_pm;
|
283
|
+
int count;
|
284
|
+
double lat;
|
285
|
+
double lon;
|
286
|
+
char *club_name;
|
287
|
+
char *date_str;
|
288
|
+
char *data_name;
|
289
|
+
VALUE ret_v;
|
290
|
+
|
291
|
+
club_name = "club"; //Constant, as this isn't really used for anything
|
292
|
+
date_str = RSTRING_PTR(r_date_str);
|
293
|
+
count = NUM2INT(r_count);
|
294
|
+
lat = NUM2DBL(r_lat);
|
295
|
+
lon = NUM2DBL(r_lon);
|
296
|
+
gmt_offset = NUM2INT(r_gmt_offset);
|
297
|
+
dst_time = NUM2INT(r_dst_offset);
|
298
|
+
am_pm = NUM2INT(r_military_time);
|
299
|
+
data_name = "USA"; //Constant, for now
|
300
|
+
int outputLength;
|
301
|
+
outputLength = count*251;
|
302
|
+
char output[outputLength];
|
303
|
+
result = ClubFile( club_name, date_str, count, lat, lon,
|
304
|
+
gmt_offset, dst_time, am_pm, data_name, output);
|
305
|
+
ret_v = rb_str_new2(result);
|
306
|
+
|
307
|
+
return ret_v;
|
308
|
+
}
|
309
|
+
|
310
|
+
/*#ifdef BUILD_MODE
|
311
|
+
int main(int argc, char *argv[])
|
312
|
+
{
|
313
|
+
return argc < 2? ARG_ERROR : BuildDataFile(argv[1]);
|
314
|
+
|
315
|
+
}
|
316
|
+
#endif*/
|
317
|
+
|
318
|
+
/*********************** Build Data File Test
|
319
|
+
|
320
|
+
This function exercises BuildDataFile(). It is used for testing.
|
321
|
+
|
322
|
+
RETURN VALUE: EXIT_SUCCESS or Error Code
|
323
|
+
|
324
|
+
PARAMETERS: none
|
325
|
+
*/
|
326
|
+
int TestBuildDataFile()
|
327
|
+
{
|
328
|
+
int success;
|
329
|
+
char line[100];
|
330
|
+
char file_name[100];
|
331
|
+
|
332
|
+
printf("Enter DST/Data File Name: ");
|
333
|
+
fgets(line, sizeof line, stdin);
|
334
|
+
if (line[0] == '\n') strcpy(file_name, DST_NAME);
|
335
|
+
else
|
336
|
+
{
|
337
|
+
line[strlen(line) - 1] = '\0';
|
338
|
+
strcpy(file_name, line);
|
339
|
+
}
|
340
|
+
success = BuildDataFile(file_name);
|
341
|
+
printf("\n%s", error_msg[success]);
|
342
|
+
printf("\n\nOK? ");
|
343
|
+
fgets(line, sizeof line, stdin);
|
344
|
+
return success;
|
345
|
+
}
|
346
|
+
/*********************** Build Data File
|
347
|
+
|
348
|
+
This function prepares a the Data file from a number of source data files. If one of the files
|
349
|
+
cannot be opened, the program stops there and returns a number indicating the failure.
|
350
|
+
|
351
|
+
RETURN VALUE: EXIT_SUCCESS or Error Code
|
352
|
+
|
353
|
+
PARAMETERS: name of DST file and resultant Data File
|
354
|
+
|
355
|
+
*/
|
356
|
+
int BuildDataFile(char *file_name)
|
357
|
+
{
|
358
|
+
int success;
|
359
|
+
char data_filename[32];
|
360
|
+
char dst_filename[32];
|
361
|
+
|
362
|
+
strcpy(data_filename, DATA_PATH);
|
363
|
+
strcat(data_filename, file_name);
|
364
|
+
strcat(data_filename, DATA_EXT);
|
365
|
+
strcpy(dst_filename, DST_PATH);
|
366
|
+
strcat(dst_filename, file_name);
|
367
|
+
strcat(dst_filename, DST_EXT);
|
368
|
+
|
369
|
+
success = 0;
|
370
|
+
if (success == EXIT_SUCCESS) success = GetSunData();
|
371
|
+
if (success == EXIT_SUCCESS) success = GetMoonData();
|
372
|
+
if (success == EXIT_SUCCESS) success = GetDateData();
|
373
|
+
if (success == EXIT_SUCCESS) success = GetDstData(dst_filename);
|
374
|
+
if (success == EXIT_SUCCESS) success = GetIllumData();
|
375
|
+
if (success == EXIT_SUCCESS) success = GetPhaseData();
|
376
|
+
if (success == EXIT_SUCCESS) success = SaveDataFile(data_filename);
|
377
|
+
return success;
|
378
|
+
}
|
379
|
+
|
380
|
+
/*********************** Display Summary Test
|
381
|
+
|
382
|
+
This function exercises Summary(). It is used for testing.
|
383
|
+
|
384
|
+
RETURN VALUE: EXIT_SUCCESS or Error Code
|
385
|
+
|
386
|
+
PARAMETERS: none
|
387
|
+
*/
|
388
|
+
int TestSummary(void)
|
389
|
+
{
|
390
|
+
int dst_time;
|
391
|
+
int am_pm;
|
392
|
+
char date_str[100];
|
393
|
+
char file_name[100];
|
394
|
+
char line[1024];
|
395
|
+
double lat;
|
396
|
+
double lon;
|
397
|
+
int gmt_offset;
|
398
|
+
int success;
|
399
|
+
|
400
|
+
printf("Enter Data File name: ");
|
401
|
+
fgets(line, sizeof line, stdin);
|
402
|
+
if (line[0] == '\n') strcpy(file_name, DATA_NAME);
|
403
|
+
else
|
404
|
+
{
|
405
|
+
line[strlen(line) - 1] = '\0';
|
406
|
+
strcpy(file_name, line);
|
407
|
+
}
|
408
|
+
|
409
|
+
printf("Enter latitude (+N/-S, dd.dddd): ");
|
410
|
+
fgets(line, sizeof line, stdin);
|
411
|
+
if (line[0] == '\n') lat = 34.5082;
|
412
|
+
else sscanf(line, "%lf", &lat);
|
413
|
+
|
414
|
+
printf("Enter longitude (+W/-E, dd.dddd): ");
|
415
|
+
fgets(line, sizeof line, stdin);
|
416
|
+
if (line[0] == '\n') lon = 82.6500;
|
417
|
+
else sscanf(line, "%lf", &lon);
|
418
|
+
|
419
|
+
printf("Enter offset minutes from GMT (+W/-E): ");
|
420
|
+
fgets(line, sizeof line, stdin);
|
421
|
+
if (line[0] == '\n') gmt_offset = 5 * 60;
|
422
|
+
else sscanf(line, "%i", &gmt_offset);
|
423
|
+
|
424
|
+
printf("Enter DST time in minutes: ");
|
425
|
+
fgets(line, sizeof line, stdin);
|
426
|
+
if (line[0] == '\n') dst_time = 60;
|
427
|
+
else sscanf(line, "%i", &dst_time);
|
428
|
+
|
429
|
+
printf("Enter Date - YYYY/MM/DD: ");
|
430
|
+
fgets(line, sizeof line, stdin);
|
431
|
+
if (line[0] == '\n') strcpy(date_str, "2016/07/04");
|
432
|
+
else
|
433
|
+
{
|
434
|
+
line[strlen(line) - 1] = '\0';
|
435
|
+
strcpy(date_str, line);
|
436
|
+
}
|
437
|
+
printf("24 Hour Format (YES/NO): ");
|
438
|
+
fgets(line, sizeof line, stdin);
|
439
|
+
am_pm = ((line[0] == 'Y') || (line[0] == 'y')) ? NO : YES;
|
440
|
+
|
441
|
+
success = Summary(date_str, lat, lon, gmt_offset, dst_time, am_pm, file_name);
|
442
|
+
|
443
|
+
printf("\n%s", error_msg[success]);
|
444
|
+
|
445
|
+
printf("\n\nOK? ");
|
446
|
+
|
447
|
+
fgets(line, sizeof line, stdin);
|
448
|
+
return success;
|
449
|
+
}
|
450
|
+
/*********************** Display Summary
|
451
|
+
|
452
|
+
This function displays all data for the parameters specified.
|
453
|
+
|
454
|
+
RETURN VALUE: EXIT_SUCCESS or Error Code
|
455
|
+
|
456
|
+
PARAMETERS: date (string)
|
457
|
+
latitude (+ is north)
|
458
|
+
longitude (+ is west)
|
459
|
+
offset from GMT in minutes (+ is west)
|
460
|
+
daylight savings time change in minutes
|
461
|
+
time format desired
|
462
|
+
name of the data file
|
463
|
+
*/
|
464
|
+
int Summary(char *date_str, double lat, double lon, int gmt_offset, int dst_time,
|
465
|
+
int am_pm, char *data_file)
|
466
|
+
{
|
467
|
+
sol_type solunar;
|
468
|
+
time_type temp;
|
469
|
+
double jdate;
|
470
|
+
int n;
|
471
|
+
int success;
|
472
|
+
char s_ris[10];
|
473
|
+
char s_trn[10];
|
474
|
+
char s_set[10];
|
475
|
+
char s_tru[10];
|
476
|
+
char m_ris[10];
|
477
|
+
char m_trn[10];
|
478
|
+
char m_set[10];
|
479
|
+
char m_tru[10];
|
480
|
+
char p_tim[10];
|
481
|
+
char filename[100];
|
482
|
+
const char phase[9][16] =
|
483
|
+
{ "*** ERROR *** ",
|
484
|
+
"NEW_MOON ",
|
485
|
+
"Waxing Crescent",
|
486
|
+
"FIRST QUARTER ",
|
487
|
+
"Waxing Gibbous ",
|
488
|
+
"FULL MOON ",
|
489
|
+
"Waning Gibbous ",
|
490
|
+
"LAST QUARTER ",
|
491
|
+
"Waning Cescent " };
|
492
|
+
|
493
|
+
lat *= D2R;
|
494
|
+
lon *= D2R;
|
495
|
+
|
496
|
+
strcpy(filename, DATA_PATH);
|
497
|
+
strcat(filename, data_file);
|
498
|
+
strcat(filename, DATA_EXT);
|
499
|
+
jdate = ConvertDate(date_str);
|
500
|
+
|
501
|
+
success = Solunar(&solunar, jdate, lat, lon, gmt_offset, dst_time, filename);
|
502
|
+
if (success == EXIT_SUCCESS)
|
503
|
+
{
|
504
|
+
FmtTimeStr(s_ris, solunar.sun.ris, am_pm);
|
505
|
+
FmtTimeStr(s_trn, solunar.sun.trn, am_pm);
|
506
|
+
FmtTimeStr(s_set, solunar.sun.set, am_pm);
|
507
|
+
FmtTimeStr(s_tru, solunar.sun.tru, am_pm);
|
508
|
+
FmtTimeStr(m_ris, solunar.moon.ris, am_pm);
|
509
|
+
FmtTimeStr(m_trn, solunar.moon.trn, am_pm);
|
510
|
+
FmtTimeStr(m_set, solunar.moon.set, am_pm);
|
511
|
+
FmtTimeStr(m_tru, solunar.moon.tru, am_pm);
|
512
|
+
|
513
|
+
printf("\n%s SUN local times (GMT - %i)\n", solunar.date, solunar.gmt_offset);
|
514
|
+
printf(" Rise = %s\n", s_ris);
|
515
|
+
printf(" Transit = %s\n", s_trn);
|
516
|
+
printf(" Set = %s\n", s_set);
|
517
|
+
printf(" Tran Under = %s\n", s_tru);
|
518
|
+
printf("\n%s MOON local times (GMT - %i)\n", solunar.date, solunar.gmt_offset);
|
519
|
+
printf(" Rise = %s\n", m_ris);
|
520
|
+
printf(" Transit = %s\n", m_trn);
|
521
|
+
printf(" Set = %s\n", m_set);
|
522
|
+
printf(" Tran Under = %s\n", m_tru);
|
523
|
+
|
524
|
+
for (n = 0; n < 8; n++)
|
525
|
+
{
|
526
|
+
p_tim[n] = ' ';
|
527
|
+
}
|
528
|
+
p_tim[n] = '\0';
|
529
|
+
if (solunar.phase_time != 0)
|
530
|
+
{
|
531
|
+
temp.minute = solunar.phase_time;
|
532
|
+
temp.second = 0;
|
533
|
+
temp.exception = 0;
|
534
|
+
FmtTimeStr(p_tim, temp, am_pm);
|
535
|
+
}
|
536
|
+
printf( " %s %s\n %d%% Illuminated\n",
|
537
|
+
phase[solunar.moon_phase], p_tim, solunar.moon_illum);
|
538
|
+
}
|
539
|
+
return success;
|
540
|
+
}
|
541
|
+
|
542
|
+
/*********************** Club File Test
|
543
|
+
|
544
|
+
This function exercises ClubFile(). It is used for testing.
|
545
|
+
|
546
|
+
RETURN VALUE: EXIT_SUCCESS or Error Code
|
547
|
+
|
548
|
+
PARAMETERS: none
|
549
|
+
*/
|
550
|
+
int TestClubFile(void)
|
551
|
+
{
|
552
|
+
int success;
|
553
|
+
int dst_time;
|
554
|
+
int am_pm;
|
555
|
+
char club_name[100];
|
556
|
+
char data_name[100];
|
557
|
+
char start_date[100];
|
558
|
+
char line[1024];
|
559
|
+
double lat;
|
560
|
+
double lon;
|
561
|
+
int count;
|
562
|
+
int gmt_offset;
|
563
|
+
|
564
|
+
printf("Enter Club Name: ");
|
565
|
+
fgets(line, sizeof line, stdin);
|
566
|
+
if (line[0] == '\n') strcpy(club_name, CLUB_NAME);
|
567
|
+
else
|
568
|
+
{
|
569
|
+
line[strlen(line) - 1] = '\0';
|
570
|
+
strcpy(club_name, line);
|
571
|
+
}
|
572
|
+
printf("Enter Data File Name: ");
|
573
|
+
fgets(line, sizeof line, stdin);
|
574
|
+
if (line[0] == '\n') strcpy(data_name, DATA_NAME);
|
575
|
+
else
|
576
|
+
{
|
577
|
+
line[strlen(line) - 1] = '\0';
|
578
|
+
strcpy(data_name, line);
|
579
|
+
}
|
580
|
+
printf("Enter latitude (+N/-S, dd.dddd): ");
|
581
|
+
fgets(line, sizeof line, stdin);
|
582
|
+
if (line[0] == '\n') lat = 34.5082;
|
583
|
+
else sscanf(line, "%lf", &lat);
|
584
|
+
|
585
|
+
printf("Enter longitude (+W/-E, dd.dddd): ");
|
586
|
+
fgets(line, sizeof line, stdin);
|
587
|
+
if (line[0] == '\n') lon = 82.6500;
|
588
|
+
else sscanf(line, "%lf", &lon);
|
589
|
+
|
590
|
+
printf("Enter offset minutes from GMT (+W/-E): ");
|
591
|
+
fgets(line, sizeof line, stdin);
|
592
|
+
if (line[0] == '\n') gmt_offset = 5 * 60;
|
593
|
+
else sscanf(line, "%i", &gmt_offset);
|
594
|
+
|
595
|
+
printf("Enter DST time in minutes: ");
|
596
|
+
fgets(line, sizeof line, stdin);
|
597
|
+
if (line[0] == '\n') dst_time = 60;
|
598
|
+
else sscanf(line, "%i", &dst_time);
|
599
|
+
|
600
|
+
printf("Enter Starting Date - YYYY/MM/DD: ");
|
601
|
+
fgets(line, sizeof line, stdin);
|
602
|
+
if (line[0] == '\n') strcpy(start_date, "2016/07/04");
|
603
|
+
else
|
604
|
+
{
|
605
|
+
line[strlen(line) - 1] = '\0';
|
606
|
+
strcpy(start_date, line);
|
607
|
+
}
|
608
|
+
|
609
|
+
printf("Enter number of days to be listed: ");
|
610
|
+
fgets(line, sizeof line, stdin);
|
611
|
+
if (line[0] == '\n') count = 1;
|
612
|
+
else sscanf(line, "%i", &count);
|
613
|
+
|
614
|
+
printf("24 Hour Format (YES/NO): ");
|
615
|
+
fgets(line, sizeof line, stdin);
|
616
|
+
am_pm = ((line[0] == 'Y') || (line[0] == 'y')) ? NO : YES;
|
617
|
+
|
618
|
+
//success = ClubFile(club_name, start_date, count, lat, lon, gmt_offset, dst_time, am_pm, data_name);
|
619
|
+
|
620
|
+
printf("\n%s", error_msg[success]);
|
621
|
+
printf("\n\nOK? ");
|
622
|
+
fgets(line, sizeof line, stdin);
|
623
|
+
|
624
|
+
return success;
|
625
|
+
}
|
626
|
+
/*********************** Prepare Club Data File
|
627
|
+
|
628
|
+
This function prepares a text file with a list of values for the date range specified.
|
629
|
+
|
630
|
+
RETURN VALUE: EXIT_SUCCESS or Error Code
|
631
|
+
|
632
|
+
PARAMETERS: name of Club File
|
633
|
+
starting date (string)
|
634
|
+
number of days to be listed
|
635
|
+
latitude (+ is north)
|
636
|
+
longitude (+ is weast)
|
637
|
+
offset from GMT in minutes (+ is west)
|
638
|
+
daylight savings time change in minutes
|
639
|
+
name of Data File
|
640
|
+
*/
|
641
|
+
char* ClubFile(char *club_name, char *start_date, int count, double lat, double lon,
|
642
|
+
int gmt_offset, int dst_time, int am_pm, char *data_name, char *output)
|
643
|
+
{
|
644
|
+
FILE *file;
|
645
|
+
int i;
|
646
|
+
int n;
|
647
|
+
int success;
|
648
|
+
double jdate;
|
649
|
+
time_type temp;
|
650
|
+
sol_type solunar;
|
651
|
+
char s_ris[10];
|
652
|
+
char s_trn[10];
|
653
|
+
char s_set[10];
|
654
|
+
char s_tru[10];
|
655
|
+
char m_ris[10];
|
656
|
+
char m_trn[10];
|
657
|
+
char m_set[10];
|
658
|
+
char m_tru[10];
|
659
|
+
char p_tim[10];
|
660
|
+
char data_filename[100];
|
661
|
+
char club_filename[100];
|
662
|
+
const char phase[9][16] =
|
663
|
+
{ "*** ERROR *** ",
|
664
|
+
"New Moon ",
|
665
|
+
"Waxing Crescent",
|
666
|
+
"First Quarter ",
|
667
|
+
"Waxing Gibbous ",
|
668
|
+
"Full Moon ",
|
669
|
+
"Waning Gibbous ",
|
670
|
+
"Last Quarter ",
|
671
|
+
"Waning Crescent" };
|
672
|
+
|
673
|
+
lat *= D2R;
|
674
|
+
lon *= D2R;
|
675
|
+
|
676
|
+
strcpy(club_filename, CLUB_PATH);
|
677
|
+
strcat(club_filename, club_name);
|
678
|
+
strcat(club_filename, CLUB_EXT);
|
679
|
+
strcpy(data_filename, DATA_PATH);
|
680
|
+
strcat(data_filename, data_name);
|
681
|
+
strcat(data_filename, DATA_EXT);
|
682
|
+
jdate = ConvertDate(start_date);
|
683
|
+
|
684
|
+
for (i = 0; i < count; i++)
|
685
|
+
{
|
686
|
+
success = Solunar(&solunar, jdate + i, lat, lon, gmt_offset, dst_time, data_filename);
|
687
|
+
if (success == EXIT_SUCCESS)
|
688
|
+
{
|
689
|
+
FmtTimeStr(s_ris, solunar.sun.ris, am_pm);
|
690
|
+
FmtTimeStr(s_trn, solunar.sun.trn, am_pm);
|
691
|
+
FmtTimeStr(s_set, solunar.sun.set, am_pm);
|
692
|
+
FmtTimeStr(s_tru, solunar.sun.tru, am_pm);
|
693
|
+
FmtTimeStr(m_ris, solunar.moon.ris, am_pm);
|
694
|
+
FmtTimeStr(m_trn, solunar.moon.trn, am_pm);
|
695
|
+
FmtTimeStr(m_set, solunar.moon.set, am_pm);
|
696
|
+
FmtTimeStr(m_tru, solunar.moon.tru, am_pm);
|
697
|
+
|
698
|
+
for (n = 0; n < 8; n ++)
|
699
|
+
{
|
700
|
+
p_tim[n] = ' ';
|
701
|
+
}
|
702
|
+
p_tim[n] = '\0';
|
703
|
+
if (solunar.phase_time != 0)
|
704
|
+
{
|
705
|
+
temp.minute = solunar.phase_time;
|
706
|
+
temp.second = 0;
|
707
|
+
temp.exception = 0;
|
708
|
+
|
709
|
+
FmtTimeStr(p_tim, temp, am_pm);
|
710
|
+
}
|
711
|
+
char charout[250];
|
712
|
+
sprintf(charout,"%s, %s, %s, %s, %s, %s, %s, %s, %s, %i, %s, %s, %i%%\n",
|
713
|
+
solunar.date, s_ris, s_trn, s_set, s_tru, m_ris, m_trn, m_set, m_tru,
|
714
|
+
solunar.gmt_offset, phase[solunar.moon_phase], p_tim, solunar.moon_illum);
|
715
|
+
if(strlen(output) == 0){
|
716
|
+
strcpy(output,charout);
|
717
|
+
}
|
718
|
+
else{
|
719
|
+
strcat(output,";");
|
720
|
+
strcat(output,charout);
|
721
|
+
}
|
722
|
+
}
|
723
|
+
}
|
724
|
+
|
725
|
+
return output;
|
726
|
+
|
727
|
+
}
|
728
|
+
/*********************** Convert Date
|
729
|
+
|
730
|
+
This function returns the jdate from a string containing the desired date in a YYYY-MM-DD format.
|
731
|
+
|
732
|
+
RETURN VALUE: jdate
|
733
|
+
0.0 if text date is not valid
|
734
|
+
|
735
|
+
PARAMETERS: pointer to date string (yyyy/mm/dd
|
736
|
+
*/
|
737
|
+
double ConvertDate(char* string)
|
738
|
+
{
|
739
|
+
int m[] = {31,28,31,30,31,30,31,31,30,31,30,31};
|
740
|
+
int l[] = {31,29,31,30,31,30,31,31,30,31,30,31};
|
741
|
+
int year;
|
742
|
+
int month;
|
743
|
+
int day;
|
744
|
+
int error;
|
745
|
+
double result;
|
746
|
+
|
747
|
+
error = NO;
|
748
|
+
year = atoi(string);
|
749
|
+
month = atoi(string + 5);
|
750
|
+
day = atoi(string + 8);
|
751
|
+
if ((year < 2016) || (year > 2026)) error = YES;
|
752
|
+
if ((month < 1) || (month > 12)) error = YES;
|
753
|
+
if ((day < 1) || ((year % 4 == 0) && (day > l[month - 1]))) error = YES;
|
754
|
+
if ((day < 1) || ((year % 4 != 0) && (day > m[month - 1]))) error = YES;
|
755
|
+
if (error == NO)
|
756
|
+
{
|
757
|
+
result = JDATE_BASE;
|
758
|
+
result += year_days[year - 2016];
|
759
|
+
result += year % 4 == 0? leap_days[month - 1]: month_days[month - 1];
|
760
|
+
result += day - 1;
|
761
|
+
}
|
762
|
+
else
|
763
|
+
{
|
764
|
+
result = 0.0;
|
765
|
+
}
|
766
|
+
return result;
|
767
|
+
}
|
768
|
+
/*********************** Get Sun Data
|
769
|
+
|
770
|
+
This function gets the sun's JPL values for right ascension and declination values from the JPL
|
771
|
+
data in sun.txt and puts them into jpl_temp[].
|
772
|
+
|
773
|
+
RETURN VALUE: EXIT_SUCCESS or Error Code
|
774
|
+
|
775
|
+
PARAMETERS: none
|
776
|
+
*/
|
777
|
+
int GetSunData(void)
|
778
|
+
{
|
779
|
+
FILE *file;
|
780
|
+
int n;
|
781
|
+
int success;
|
782
|
+
char buffer[100];
|
783
|
+
|
784
|
+
file = fopen(SUN_FILE, "r");
|
785
|
+
if (file != NULL)
|
786
|
+
{
|
787
|
+
for (n = 0; n < DATA_FILE_SIZE; n++)
|
788
|
+
{
|
789
|
+
fgets(buffer, 100, file);
|
790
|
+
jpl_temp[n].sun.ra = atof(buffer + RA);
|
791
|
+
jpl_temp[n].sun.dec = atof(buffer + DEC);
|
792
|
+
}
|
793
|
+
fclose(file);
|
794
|
+
success = EXIT_SUCCESS;
|
795
|
+
}
|
796
|
+
else
|
797
|
+
{
|
798
|
+
success = SUN_FAIL;
|
799
|
+
}
|
800
|
+
return success;
|
801
|
+
}
|
802
|
+
|
803
|
+
/*********************** Get Moon Data
|
804
|
+
|
805
|
+
This function gets the moon's JPL values for right ascension and declination values from the JPL
|
806
|
+
data in sun.txt and puts them into jpl_temp[].
|
807
|
+
|
808
|
+
RETURN VALUE: EXIT_SUCCESS or Error Code
|
809
|
+
|
810
|
+
PARAMETERS: none
|
811
|
+
*/
|
812
|
+
int GetMoonData(void)
|
813
|
+
{
|
814
|
+
FILE* file;
|
815
|
+
int n;
|
816
|
+
int success;
|
817
|
+
char buffer[100];
|
818
|
+
|
819
|
+
file = fopen(MOON_FILE, "r");
|
820
|
+
if (file != NULL)
|
821
|
+
{
|
822
|
+
for (n = 0; n < DATA_FILE_SIZE; n++)
|
823
|
+
{
|
824
|
+
fgets(buffer, 100, file);
|
825
|
+
jpl_temp[n].moon.ra = atof(buffer + RA);
|
826
|
+
jpl_temp[n].moon.dec = atof(buffer + DEC);
|
827
|
+
}
|
828
|
+
fclose(file);
|
829
|
+
success = EXIT_SUCCESS;
|
830
|
+
}
|
831
|
+
else
|
832
|
+
{
|
833
|
+
success = MOON_FAIL;
|
834
|
+
}
|
835
|
+
return success;
|
836
|
+
}
|
837
|
+
|
838
|
+
/*********************** Get Date String
|
839
|
+
|
840
|
+
This function gets the date string from the JPL data in moon.txt and puts it into jpl_temp[].
|
841
|
+
This operation could have been done as part of GetMoonData() or GetSunData(), but is separated
|
842
|
+
for clarity.
|
843
|
+
|
844
|
+
RETURN VALUE: EXIT_SUCCESS or Error Code
|
845
|
+
|
846
|
+
PARAMETERS: none
|
847
|
+
*/
|
848
|
+
int GetDateData(void)
|
849
|
+
{
|
850
|
+
FILE* file;
|
851
|
+
int n;
|
852
|
+
int i;
|
853
|
+
int success;
|
854
|
+
char buffer[100];
|
855
|
+
|
856
|
+
file = fopen(MOON_FILE, "r");
|
857
|
+
if (file != NULL)
|
858
|
+
{
|
859
|
+
for (n = 0; n < DATA_FILE_SIZE; n++)
|
860
|
+
{
|
861
|
+
fgets(buffer, 100, file);
|
862
|
+
for (i = 0; i < JPL_DATE_SIZE - 1; i++)
|
863
|
+
{
|
864
|
+
jpl_temp[n].date[i] = buffer[i + 1];
|
865
|
+
}
|
866
|
+
jpl_temp[n].date[i] = '\0';
|
867
|
+
}
|
868
|
+
fclose(file);
|
869
|
+
success = EXIT_SUCCESS;
|
870
|
+
}
|
871
|
+
else
|
872
|
+
{
|
873
|
+
success = MOON_FAIL;
|
874
|
+
}
|
875
|
+
return success;
|
876
|
+
}
|
877
|
+
|
878
|
+
/*********************** Get Daylight Savings Time Data
|
879
|
+
|
880
|
+
For every element of the jpl_temp[] array, this function determines whether or not the associated
|
881
|
+
date is subject to daylight savinhgs time and the dst member is updated.
|
882
|
+
|
883
|
+
RETURN VALUE: EXIT_SUCCESS or Error Code
|
884
|
+
|
885
|
+
PARAMETERS: none
|
886
|
+
*/
|
887
|
+
int GetDstData(char *filename)
|
888
|
+
{
|
889
|
+
FILE* file;
|
890
|
+
char buffer[100];
|
891
|
+
int n;
|
892
|
+
int y;
|
893
|
+
int success;
|
894
|
+
double jdate;
|
895
|
+
|
896
|
+
file = fopen(filename, "r");
|
897
|
+
if (file != NULL)
|
898
|
+
{
|
899
|
+
for (y = 0; y < DST_FILE_SIZE; y++)
|
900
|
+
{
|
901
|
+
fgets(buffer, 100, file);
|
902
|
+
dst[y].start = ConvertDate(buffer);
|
903
|
+
dst[y].stop = ConvertDate(buffer + 12);
|
904
|
+
}
|
905
|
+
for (n = 0; n < DATA_FILE_SIZE; n++)
|
906
|
+
{
|
907
|
+
jdate = JDATE_BASE + n;
|
908
|
+
jpl_temp[n].dst = NO;
|
909
|
+
for (y = 0; y < (sizeof dst / sizeof(dst_type)); y++)
|
910
|
+
{
|
911
|
+
if (jdate < dst[y].stop)
|
912
|
+
{
|
913
|
+
if (jdate >= dst[y].start)
|
914
|
+
{
|
915
|
+
jpl_temp[n].dst = YES;
|
916
|
+
}
|
917
|
+
break;
|
918
|
+
}
|
919
|
+
}
|
920
|
+
}
|
921
|
+
fclose(file);
|
922
|
+
success = EXIT_SUCCESS;
|
923
|
+
}
|
924
|
+
else
|
925
|
+
{
|
926
|
+
success = DTS_FAIL;
|
927
|
+
}
|
928
|
+
return success;
|
929
|
+
}
|
930
|
+
/*********************** Get Moon Phase Data
|
931
|
+
|
932
|
+
This function gets the moon's phase data from the phase.txt file and puts it into jpl_temp[].
|
933
|
+
|
934
|
+
RETURN VALUE: EXIT_SUCCESS or Error Code
|
935
|
+
|
936
|
+
PARAMETERS: none
|
937
|
+
*/
|
938
|
+
int GetPhaseData(void)
|
939
|
+
{
|
940
|
+
FILE* file;
|
941
|
+
bool match;
|
942
|
+
int c;
|
943
|
+
int j;
|
944
|
+
int i;
|
945
|
+
int n;
|
946
|
+
int phase;
|
947
|
+
int success;
|
948
|
+
char date[11];
|
949
|
+
int minute;
|
950
|
+
char buffer[100];
|
951
|
+
|
952
|
+
j = 0;
|
953
|
+
for (n = 0; n < DATA_FILE_SIZE; n++)
|
954
|
+
{
|
955
|
+
jpl_temp[n].phase = 0;
|
956
|
+
jpl_temp[n].phase_time = 0;
|
957
|
+
}
|
958
|
+
file = fopen(PHASE_FILE, "r");
|
959
|
+
if (file != NULL)
|
960
|
+
{
|
961
|
+
for (n = 0; n < PHASE_FILE_SIZE; n++)
|
962
|
+
{
|
963
|
+
fgets(buffer, 100, file);
|
964
|
+
i = 0;
|
965
|
+
while (buffer[i++] != '\t');
|
966
|
+
for (c = 0; c < 11; c++)
|
967
|
+
{
|
968
|
+
date[c] = buffer[i] == ' ' ? '-' : buffer[i];
|
969
|
+
i++;
|
970
|
+
}
|
971
|
+
i ++;
|
972
|
+
minute = atoi(buffer + i) * 60;
|
973
|
+
minute += atoi(buffer + i + 3);
|
974
|
+
if (minute == 0)
|
975
|
+
{
|
976
|
+
minute = 24 * 60;
|
977
|
+
}
|
978
|
+
match = NO;
|
979
|
+
while (match == NO)
|
980
|
+
{
|
981
|
+
for (c = 0; c < 11; c++)
|
982
|
+
{
|
983
|
+
if (date[c] != jpl_temp[j].date[c])
|
984
|
+
{
|
985
|
+
break;
|
986
|
+
}
|
987
|
+
}
|
988
|
+
if (c == 11)
|
989
|
+
{
|
990
|
+
match = YES;
|
991
|
+
}
|
992
|
+
else
|
993
|
+
{
|
994
|
+
j++;
|
995
|
+
}
|
996
|
+
}
|
997
|
+
if (buffer[2] == 'w') jpl_temp[j].phase = NEW_MOON;
|
998
|
+
else if (buffer[2] == 'r') jpl_temp[j].phase = FIRST_QTR;
|
999
|
+
else if (buffer[2] == 'l') jpl_temp[j].phase = FULL_MOON;
|
1000
|
+
else jpl_temp[j].phase = LAST_QTR;
|
1001
|
+
jpl_temp[j].phase_time = minute;
|
1002
|
+
}
|
1003
|
+
fclose(file);
|
1004
|
+
success = EXIT_SUCCESS;
|
1005
|
+
|
1006
|
+
// for each element of the jpl array:
|
1007
|
+
// record the phase based on the last major phases
|
1008
|
+
// record the the time of the last major phase
|
1009
|
+
phase = FULL_MOON; // 12/25/2015 phase
|
1010
|
+
minute = (11 * 60)+ 11; // 12/25/2015 Full Moon time
|
1011
|
+
for (n = 0; n < DATA_FILE_SIZE; n++)
|
1012
|
+
{
|
1013
|
+
if (jpl_temp[n].phase == 0)
|
1014
|
+
{
|
1015
|
+
jpl_temp[n].phase = phase + 1;
|
1016
|
+
}
|
1017
|
+
else
|
1018
|
+
{
|
1019
|
+
phase = jpl_temp[n].phase;
|
1020
|
+
}
|
1021
|
+
}
|
1022
|
+
}
|
1023
|
+
else
|
1024
|
+
{
|
1025
|
+
success = PHASE_FAIL;
|
1026
|
+
}
|
1027
|
+
return success;
|
1028
|
+
}
|
1029
|
+
|
1030
|
+
/*********************** Get Moon Illumination Percentage Data
|
1031
|
+
|
1032
|
+
This function gets the moon's percent illumination data from Ilum 20xx.txt files and puts it
|
1033
|
+
into jpl_temp[].
|
1034
|
+
|
1035
|
+
RETURN VALUE: EXIT_SUCCESS or Error Code
|
1036
|
+
|
1037
|
+
PARAMETERS: none
|
1038
|
+
*/
|
1039
|
+
int GetIllumData(void)
|
1040
|
+
{
|
1041
|
+
int index;
|
1042
|
+
int success;
|
1043
|
+
|
1044
|
+
index = 0;
|
1045
|
+
success = EXIT_SUCCESS;
|
1046
|
+
if (success == EXIT_SUCCESS) success = GetIllumYear(ILLUM_16_FILE, &index);
|
1047
|
+
if (success == EXIT_SUCCESS) success = GetIllumYear(ILLUM_17_FILE, &index);
|
1048
|
+
if (success == EXIT_SUCCESS) success = GetIllumYear(ILLUM_18_FILE, &index);
|
1049
|
+
if (success == EXIT_SUCCESS) success = GetIllumYear(ILLUM_19_FILE, &index);
|
1050
|
+
if (success == EXIT_SUCCESS) success = GetIllumYear(ILLUM_20_FILE, &index);
|
1051
|
+
if (success == EXIT_SUCCESS) success = GetIllumYear(ILLUM_21_FILE, &index);
|
1052
|
+
if (success == EXIT_SUCCESS) success = GetIllumYear(ILLUM_22_FILE, &index);
|
1053
|
+
if (success == EXIT_SUCCESS) success = GetIllumYear(ILLUM_23_FILE, &index);
|
1054
|
+
if (success == EXIT_SUCCESS) success = GetIllumYear(ILLUM_24_FILE, &index);
|
1055
|
+
if (success == EXIT_SUCCESS) success = GetIllumYear(ILLUM_25_FILE, &index);
|
1056
|
+
if (success == EXIT_SUCCESS) success = GetIllumYear(ILLUM_26_FILE, &index);
|
1057
|
+
return success;
|
1058
|
+
}
|
1059
|
+
|
1060
|
+
/*********************** Save Data File
|
1061
|
+
|
1062
|
+
After the daylight savings data, date string and the right ascension and declination values for
|
1063
|
+
the sun and moon plus mone phase and illumination have been placed in jpl.temp[], this function
|
1064
|
+
writes the jpl data to the Data File.
|
1065
|
+
|
1066
|
+
RETURN VALUE: EXIT_SUCCESS or Error Code
|
1067
|
+
|
1068
|
+
PARAMETERS: filepath of Data File
|
1069
|
+
*/
|
1070
|
+
int SaveDataFile(char *filename)
|
1071
|
+
{
|
1072
|
+
FILE *file;
|
1073
|
+
int success;
|
1074
|
+
|
1075
|
+
file = fopen(filename, "wb");
|
1076
|
+
if (file != NULL)
|
1077
|
+
{
|
1078
|
+
fwrite(jpl_temp, sizeof(jpl_type), DATA_FILE_SIZE, file);
|
1079
|
+
fclose(file);
|
1080
|
+
success = EXIT_SUCCESS;
|
1081
|
+
}
|
1082
|
+
else
|
1083
|
+
{
|
1084
|
+
success = DATA_FAIL;
|
1085
|
+
}
|
1086
|
+
return success;
|
1087
|
+
}
|
1088
|
+
|
1089
|
+
/*********************** Solunar
|
1090
|
+
|
1091
|
+
This function returns all the informatin required by the Knockdown program.
|
1092
|
+
|
1093
|
+
As to the phases of the moon:
|
1094
|
+
|
1095
|
+
The JPL file stores all data by GMT date. Unless the GMT offset time is 0, the local date
|
1096
|
+
overlaps parts of two GMT dates:
|
1097
|
+
|
1098
|
+
East of Greenwich, the local date overlaps that part of the previous GMT date where the
|
1099
|
+
GMT time is within [gmt_offset] minutes before midnight; the local date overlaps the current
|
1100
|
+
GMT date the rest of the day.
|
1101
|
+
|
1102
|
+
West of Greenwich, the local date overlaps that part of the following GMT date where the
|
1103
|
+
GMT time is within [gmt_offset] minutes after midnight; the local date overlaps the current
|
1104
|
+
GMT date the rest of the day.
|
1105
|
+
|
1106
|
+
The Primary moon phases are reported in local time and date. Use the GMT date where the
|
1107
|
+
time of the moon phase overlaps the current local date.
|
1108
|
+
|
1109
|
+
|
1110
|
+
RETURN VALUE: EXIT_SUCCESS or Error Code
|
1111
|
+
|
1112
|
+
PARAMETERS: sol_type structure with sun, moon, date, and DST adjusted GME offset information
|
1113
|
+
julian date
|
1114
|
+
latitude (+ is north)
|
1115
|
+
longitude (+ is west)
|
1116
|
+
minutes easr or west of GMT (+ is west)
|
1117
|
+
DST time in minutes
|
1118
|
+
filepath of Data File
|
1119
|
+
*/
|
1120
|
+
int Solunar(sol_type *result, double jdate, double lat, double lon,
|
1121
|
+
int gmt_offset, int dst_time, char *filename)
|
1122
|
+
{
|
1123
|
+
enum {p_day, c_day, f_day};
|
1124
|
+
int n;
|
1125
|
+
int index;
|
1126
|
+
int success;
|
1127
|
+
FILE *file;
|
1128
|
+
jpl_type jpl[3];
|
1129
|
+
rst_type times_p;
|
1130
|
+
rst_type times;
|
1131
|
+
rst_type times_f;
|
1132
|
+
int phase_time;
|
1133
|
+
int months[13][5] = {
|
1134
|
+
{ 'J', 'a', 'n', '0', '1' },
|
1135
|
+
{ 'F', 'e', 'b', '0', '2' },
|
1136
|
+
{ 'M', 'a', 'r', '0', '3' },
|
1137
|
+
{ 'A', 'p', 'r', '0', '4' },
|
1138
|
+
{ 'M', 'a', 'y', '0', '5' },
|
1139
|
+
{ 'J', 'u', 'n', '0', '6' },
|
1140
|
+
{ 'J', 'u', 'l', '0', '7' },
|
1141
|
+
{ 'A', 'u', 'g', '0', '8' },
|
1142
|
+
{ 'S', 'e', 'p', '0', '9' },
|
1143
|
+
{ 'O', 'c', 't', '1', '0' },
|
1144
|
+
{ 'N', 'o', 'v', '1', '1' },
|
1145
|
+
{ 'D', 'e', 'c', '1', '2' },
|
1146
|
+
{ 0, 0, 0, '?', '?' } };
|
1147
|
+
|
1148
|
+
//lon = -lon;
|
1149
|
+
|
1150
|
+
// get date
|
1151
|
+
index = (int)(floor(jdate) - floor(JDATE_BASE));
|
1152
|
+
file = fopen(filename, "rb");
|
1153
|
+
if (file != NULL)
|
1154
|
+
{
|
1155
|
+
fseek(file, ((index - 1) * sizeof(jpl_type)), SEEK_SET);
|
1156
|
+
fread(&jpl[0], sizeof(jpl_type), 3, file);
|
1157
|
+
for (n = 0; n < 12; n++)
|
1158
|
+
{
|
1159
|
+
if ( (jpl[c_day].date[5] == months[n][0])
|
1160
|
+
&& (jpl[c_day].date[6] == months[n][1])
|
1161
|
+
&& (jpl[c_day].date[7] == months[n][2]) )
|
1162
|
+
{
|
1163
|
+
break;
|
1164
|
+
}
|
1165
|
+
}
|
1166
|
+
result->date[0] = jpl[c_day].date[0];
|
1167
|
+
result->date[1] = jpl[c_day].date[1];
|
1168
|
+
result->date[2] = jpl[c_day].date[2];
|
1169
|
+
result->date[3] = jpl[c_day].date[3];
|
1170
|
+
result->date[4] = '-';
|
1171
|
+
result->date[5] = months[n][3];
|
1172
|
+
result->date[6] = months[n][4];
|
1173
|
+
result->date[7] = '-';
|
1174
|
+
result->date[8] = jpl[c_day].date[9];
|
1175
|
+
result->date[9] = jpl[c_day].date[10];
|
1176
|
+
result->date[10] = '\0';
|
1177
|
+
|
1178
|
+
// adjust gmt offset for dst
|
1179
|
+
if ((dst_time != 0) && (jpl[c_day].dst == YES))
|
1180
|
+
{
|
1181
|
+
gmt_offset -= dst_time;
|
1182
|
+
}
|
1183
|
+
result->gmt_offset = gmt_offset;
|
1184
|
+
|
1185
|
+
// get values for the sun
|
1186
|
+
times_p = RST(file, SUN, jdate - 1, lat, lon);
|
1187
|
+
times = RST(file, SUN, jdate, lat, lon);
|
1188
|
+
times_f = RST(file, SUN, jdate + 1, lat, lon);
|
1189
|
+
result->sun.ris = AdjustTimes(times_p.ris, times.ris, times_f.ris, gmt_offset);
|
1190
|
+
result->sun.trn = AdjustTimes(times_p.trn, times.trn, times_f.trn, gmt_offset);
|
1191
|
+
result->sun.set = AdjustTimes(times_p.set, times.set, times_f.set, gmt_offset);
|
1192
|
+
|
1193
|
+
// get values for the moon
|
1194
|
+
times_p = RST(file, MOON, jdate - 1, lat, lon);
|
1195
|
+
times = RST(file, MOON, jdate, lat, lon);
|
1196
|
+
times_f = RST(file, MOON, jdate + 1, lat, lon);
|
1197
|
+
result->moon.ris = AdjustTimes(times_p.ris, times.ris, times_f.ris, gmt_offset);
|
1198
|
+
result->moon.trn = AdjustTimes(times_p.trn, times.trn, times_f.trn, gmt_offset);
|
1199
|
+
result->moon.set = AdjustTimes(times_p.set, times.set, times_f.set, gmt_offset);
|
1200
|
+
|
1201
|
+
// get value for sun and moon transit underfoot ...
|
1202
|
+
if (lon < 0) lon += PI;
|
1203
|
+
else lon -= PI;
|
1204
|
+
|
1205
|
+
// ... sun
|
1206
|
+
times_p = RST(file, SUN, jdate - 1, lat, lon);
|
1207
|
+
times = RST(file, SUN, jdate, lat, lon);
|
1208
|
+
times_f = RST(file, SUN, jdate + 1, lat, lon);
|
1209
|
+
result->sun.tru = AdjustTimes(times_p.trn, times.trn, times_f.trn, gmt_offset);
|
1210
|
+
|
1211
|
+
// ... moon
|
1212
|
+
times_p = RST(file, MOON, jdate - 1, lat, lon);
|
1213
|
+
times = RST(file, MOON, jdate, lat, lon);
|
1214
|
+
times_f = RST(file, MOON, jdate + 1, lat, lon);
|
1215
|
+
result->moon.tru = AdjustTimes(times_p.trn, times.trn, times_f.trn, gmt_offset);
|
1216
|
+
|
1217
|
+
fclose(file);
|
1218
|
+
|
1219
|
+
// if western hemisphere or Britian Summer Time
|
1220
|
+
if (gmt_offset > 0)
|
1221
|
+
{
|
1222
|
+
// if the following Greenwich day has a primary phase at a time that is during the
|
1223
|
+
// current local day, use the phase from the following Greenwich day
|
1224
|
+
if ( (jpl[f_day].phase_time != 0)
|
1225
|
+
&& (jpl[f_day].phase_time <= abs(gmt_offset)) )
|
1226
|
+
{
|
1227
|
+
result->moon_phase = jpl[f_day].phase;
|
1228
|
+
phase_time = jpl[f_day].phase_time;
|
1229
|
+
}
|
1230
|
+
// if the current Greenwich day has a primary phase at a time that is not during the
|
1231
|
+
// current local day, use the phase from the following Greenwich day
|
1232
|
+
else if ( (jpl[c_day].phase_time != 0)
|
1233
|
+
&& (jpl[c_day].phase_time <= abs(gmt_offset)) )
|
1234
|
+
{
|
1235
|
+
result->moon_phase = jpl[f_day].phase;
|
1236
|
+
phase_time = jpl[f_day].phase_time;
|
1237
|
+
}
|
1238
|
+
// if it is not necessary to use the phase from the following GMT day, use the phase
|
1239
|
+
// from the current GMT day
|
1240
|
+
else
|
1241
|
+
{
|
1242
|
+
result->moon_phase = jpl[c_day].phase;
|
1243
|
+
phase_time = jpl[c_day].phase_time;
|
1244
|
+
}
|
1245
|
+
if (phase_time != 0.0)
|
1246
|
+
{
|
1247
|
+
phase_time += 24 * 60;
|
1248
|
+
phase_time -= abs(gmt_offset);
|
1249
|
+
if (phase_time > MINUTES_PER_DAY)
|
1250
|
+
{
|
1251
|
+
phase_time -= 24 * 60;
|
1252
|
+
}
|
1253
|
+
}
|
1254
|
+
result->phase_time = phase_time;
|
1255
|
+
}
|
1256
|
+
// if eastern hemisphere
|
1257
|
+
else if (gmt_offset < 0)
|
1258
|
+
{
|
1259
|
+
// if the previous Greenwich day has a primary phase at a time that is during the
|
1260
|
+
// current local day, use the phase from the following Greenwich day
|
1261
|
+
if ( (jpl[p_day].phase_time != 0)
|
1262
|
+
&& ((MINUTES_PER_DAY - jpl[p_day].phase_time) <= abs(gmt_offset)))
|
1263
|
+
{
|
1264
|
+
result->moon_phase = jpl[p_day].phase;
|
1265
|
+
phase_time = jpl[p_day].phase_time;
|
1266
|
+
}
|
1267
|
+
// if the current Greenwich day has a primary phase at a time that is not during the
|
1268
|
+
// current local day, use the hase from the previous Greenwich day
|
1269
|
+
else if ( (jpl[c_day].phase_time != 0)
|
1270
|
+
&& ((MINUTES_PER_DAY - jpl[c_day].phase_time) <= abs(gmt_offset)))
|
1271
|
+
{
|
1272
|
+
result->moon_phase = jpl[p_day].phase;
|
1273
|
+
phase_time = jpl[p_day].phase_time;
|
1274
|
+
}
|
1275
|
+
// if it is not necessary to use the phase from the previous GMT day, use the phase
|
1276
|
+
// from the current GMT day
|
1277
|
+
else
|
1278
|
+
{
|
1279
|
+
result->moon_phase = jpl[c_day].phase;
|
1280
|
+
phase_time = jpl[c_day].phase_time;
|
1281
|
+
}
|
1282
|
+
if (phase_time != 0.0)
|
1283
|
+
{
|
1284
|
+
phase_time += abs(gmt_offset);
|
1285
|
+
{
|
1286
|
+
if (phase_time > MINUTES_PER_DAY)
|
1287
|
+
{
|
1288
|
+
phase_time -= MINUTES_PER_DAY;
|
1289
|
+
}
|
1290
|
+
}
|
1291
|
+
}
|
1292
|
+
result->phase_time = phase_time;
|
1293
|
+
}
|
1294
|
+
// if the gmt offset is 0, use the phase from the current Greenwich day
|
1295
|
+
else
|
1296
|
+
{
|
1297
|
+
result->moon_phase = jpl[c_day].phase;
|
1298
|
+
phase_time = jpl[c_day].phase_time;
|
1299
|
+
result->phase_time = phase_time;
|
1300
|
+
}
|
1301
|
+
result->moon_illum = jpl[c_day].illum;
|
1302
|
+
success = EXIT_SUCCESS;
|
1303
|
+
}
|
1304
|
+
else
|
1305
|
+
{
|
1306
|
+
//rb_eval_string("puts 'No file found at: '+`pwd`");
|
1307
|
+
success = DATA_FAIL;
|
1308
|
+
}
|
1309
|
+
return success;
|
1310
|
+
}
|
1311
|
+
|
1312
|
+
/*********************** Get Moon Illumination Percentage Data for One Year
|
1313
|
+
|
1314
|
+
This function processes the moon's percent illumination data from the specified file and places
|
1315
|
+
it into jpl_temp[] for one year. Parameter index is kept up to date as this function is called
|
1316
|
+
multiple times - one for each year.
|
1317
|
+
|
1318
|
+
RETURN VALUE: EXIT_SUCCESS or Error Code
|
1319
|
+
|
1320
|
+
PARAMETERS: current file
|
1321
|
+
index into jpl_temp[]
|
1322
|
+
*/
|
1323
|
+
int GetIllumYear(const char *filename, int *index)
|
1324
|
+
{
|
1325
|
+
FILE* file;
|
1326
|
+
char buffer[31][102];
|
1327
|
+
int col[] = { 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96 };
|
1328
|
+
int m;
|
1329
|
+
int d;
|
1330
|
+
int n;
|
1331
|
+
int success;
|
1332
|
+
|
1333
|
+
file = fopen(filename, "r");
|
1334
|
+
if (file != NULL)
|
1335
|
+
{
|
1336
|
+
for (n = 0; n < 31; n++)
|
1337
|
+
{
|
1338
|
+
fgets(buffer[n], 102, file);
|
1339
|
+
}
|
1340
|
+
fclose(file);
|
1341
|
+
for (m = 0; m < 12; m++)
|
1342
|
+
{
|
1343
|
+
for (d = 0; d < 31; d++)
|
1344
|
+
{
|
1345
|
+
if (buffer[d][col[m]] == '*')
|
1346
|
+
{
|
1347
|
+
break;
|
1348
|
+
}
|
1349
|
+
else
|
1350
|
+
{
|
1351
|
+
jpl_temp[*index].illum = atoi(buffer[d] + col[m]);
|
1352
|
+
(*index) ++;
|
1353
|
+
}
|
1354
|
+
}
|
1355
|
+
}
|
1356
|
+
success = EXIT_SUCCESS;
|
1357
|
+
}
|
1358
|
+
else
|
1359
|
+
{
|
1360
|
+
success = EXIT_FAILURE;
|
1361
|
+
}
|
1362
|
+
return success;
|
1363
|
+
}
|
1364
|
+
|
1365
|
+
/*********************** Format the Time Structure
|
1366
|
+
|
1367
|
+
This function formats a decimal time (H.hhhh) into minutes and seconds. Internal to the
|
1368
|
+
program, time of day is kept in interger munites. To avoid floating point, seconds are a
|
1369
|
+
separate field and is used only for development and desting.
|
1370
|
+
|
1371
|
+
RETURN VALUE: formated time structure
|
1372
|
+
|
1373
|
+
PARAMETERS: decimal time
|
1374
|
+
*/
|
1375
|
+
time_type FmtTime(double d_time)
|
1376
|
+
{
|
1377
|
+
time_type result;
|
1378
|
+
double d_minute;
|
1379
|
+
double d_second;
|
1380
|
+
double i_minute;
|
1381
|
+
double i_second;
|
1382
|
+
double temp;
|
1383
|
+
|
1384
|
+
d_minute = d_time * 60;
|
1385
|
+
i_minute = floor(d_minute);
|
1386
|
+
d_second = (d_minute - i_minute) * 60;
|
1387
|
+
i_second = floor(d_second);
|
1388
|
+
temp = (d_second - i_second);
|
1389
|
+
if (temp >= 0.5)
|
1390
|
+
{
|
1391
|
+
i_second += 1.0;
|
1392
|
+
}
|
1393
|
+
if (i_second == 60)
|
1394
|
+
{
|
1395
|
+
i_second = 0;
|
1396
|
+
i_minute += 1;
|
1397
|
+
}
|
1398
|
+
result.minute = (int)d_minute;
|
1399
|
+
result.second = (int)d_second;
|
1400
|
+
result.exception = NULL;
|
1401
|
+
|
1402
|
+
return result;
|
1403
|
+
}
|
1404
|
+
|
1405
|
+
/*********************** Format a Time String
|
1406
|
+
|
1407
|
+
This function formats a string in the format hh:mm:ss from a time_type structure.
|
1408
|
+
|
1409
|
+
RETURN VALUE: none
|
1410
|
+
|
1411
|
+
PARAMETERS: pointer to destination string
|
1412
|
+
time-type structure to be formatted
|
1413
|
+
flag indicating whether format should 24 hour (with seconds) or am/pm
|
1414
|
+
*/
|
1415
|
+
void FmtTimeStr(char *string, time_type times, int am_pm)
|
1416
|
+
{
|
1417
|
+
int n;
|
1418
|
+
int hour;
|
1419
|
+
int min;
|
1420
|
+
char a_p;
|
1421
|
+
const char exception[9][9] = {
|
1422
|
+
" ",
|
1423
|
+
" ",
|
1424
|
+
" NONE ",
|
1425
|
+
" ",
|
1426
|
+
" DARK ",
|
1427
|
+
" BRIGHT ",
|
1428
|
+
" ",
|
1429
|
+
"ERROR 1",
|
1430
|
+
"ERROR 2" };
|
1431
|
+
|
1432
|
+
if (times.exception >= NONE_TODAY)
|
1433
|
+
{
|
1434
|
+
sprintf(string, "%s", exception[times.exception - 1]);
|
1435
|
+
}
|
1436
|
+
else
|
1437
|
+
{
|
1438
|
+
if (am_pm == YES)
|
1439
|
+
{
|
1440
|
+
if (times.second >= 30) times.minute += 1;
|
1441
|
+
if (times.minute >= MINUTES_PER_DAY) times.minute = MINUTES_PER_DAY - 1;
|
1442
|
+
hour = times.minute / 60;
|
1443
|
+
a_p = hour >= 12? 'p': 'a';
|
1444
|
+
if (hour > 12) hour -= 12;
|
1445
|
+
if (hour == 0) hour = 12;
|
1446
|
+
min = times.minute % 60;
|
1447
|
+
sprintf(string, "%2d:%2d %cm", hour, min, a_p);
|
1448
|
+
if (string[3] == ' ') string[3] = '0';
|
1449
|
+
}
|
1450
|
+
else
|
1451
|
+
{
|
1452
|
+
hour = times.minute / 60;
|
1453
|
+
min = times.minute % 60;
|
1454
|
+
sprintf(string, "%2d:%2d:%2d", hour, min, times.second);
|
1455
|
+
for (n = 0; n < 8; n++)
|
1456
|
+
{
|
1457
|
+
if (string[n] == ' ') string[n] = '0';
|
1458
|
+
}
|
1459
|
+
}
|
1460
|
+
}
|
1461
|
+
}
|
1462
|
+
|
1463
|
+
/*********************** Adjust Times
|
1464
|
+
|
1465
|
+
For an explanation of this function,see the Adjust Times files in the project folder.
|
1466
|
+
|
1467
|
+
RETURN VALUE: adjusted time structure
|
1468
|
+
|
1469
|
+
PARAMETERS: time sStructure for the previous day
|
1470
|
+
time structure for the Current Day
|
1471
|
+
time structure for the Following Day
|
1472
|
+
offset from GMT (hours west)
|
1473
|
+
*/
|
1474
|
+
time_type AdjustTimes( time_type previous_day, time_type current_day,
|
1475
|
+
time_type following_day, int gmt_offset)
|
1476
|
+
{
|
1477
|
+
#define TIME_BEFORE_MIDNIGHT(x) (MINUTES_PER_DAY - x)
|
1478
|
+
#define TIME_AFTER_MIDNIGHT(x) x
|
1479
|
+
time_type result;
|
1480
|
+
int special;
|
1481
|
+
int temp_1;
|
1482
|
+
int temp_2;
|
1483
|
+
|
1484
|
+
// if in the western hemisphere or Britan Summer Time
|
1485
|
+
if (gmt_offset > 0)
|
1486
|
+
{
|
1487
|
+
special = abs(current_day.minute - following_day.minute) > (MINUTES_PER_DAY / 2) ? YES : NO;
|
1488
|
+
if ((current_day.exception > ROUTINE) || (following_day.exception > ROUTINE))
|
1489
|
+
{
|
1490
|
+
if (current_day.exception > ERROR) result = following_day;
|
1491
|
+
else result = current_day;
|
1492
|
+
result.minute += MINUTES_PER_DAY;
|
1493
|
+
result.minute -= gmt_offset;
|
1494
|
+
result.minute %= MINUTES_PER_DAY;
|
1495
|
+
}
|
1496
|
+
else if (TIME_AFTER_MIDNIGHT(current_day.minute) >= gmt_offset)
|
1497
|
+
{
|
1498
|
+
result = current_day;
|
1499
|
+
result.minute -= gmt_offset;
|
1500
|
+
}
|
1501
|
+
else if (TIME_AFTER_MIDNIGHT(following_day.minute) < gmt_offset)
|
1502
|
+
{
|
1503
|
+
result = following_day;
|
1504
|
+
result.minute += MINUTES_PER_DAY;
|
1505
|
+
result.minute -= gmt_offset;
|
1506
|
+
}
|
1507
|
+
else if (special == YES)
|
1508
|
+
{
|
1509
|
+
result = current_day;
|
1510
|
+
temp_1 = (current_day.minute + MINUTES_PER_DAY - gmt_offset) % MINUTES_PER_DAY;
|
1511
|
+
temp_2 = (following_day.minute + MINUTES_PER_DAY - gmt_offset) % MINUTES_PER_DAY;
|
1512
|
+
result.minute = (temp_1 + temp_2) / 2;
|
1513
|
+
}
|
1514
|
+
else
|
1515
|
+
{
|
1516
|
+
result.exception = NONE_TODAY;
|
1517
|
+
}
|
1518
|
+
}
|
1519
|
+
//if in eastern hemisphere
|
1520
|
+
else if (gmt_offset < 0)
|
1521
|
+
{
|
1522
|
+
gmt_offset = abs(gmt_offset);
|
1523
|
+
special = abs(previous_day.minute - current_day.minute) > (MINUTES_PER_DAY / 2)? YES: NO;
|
1524
|
+
if ((current_day.exception > ROUTINE) || (previous_day.exception > ROUTINE))
|
1525
|
+
{
|
1526
|
+
if (previous_day.exception > ERROR) result = current_day;
|
1527
|
+
else result = previous_day;
|
1528
|
+
result.minute += gmt_offset;
|
1529
|
+
result.minute %= MINUTES_PER_DAY;
|
1530
|
+
}
|
1531
|
+
else if (TIME_BEFORE_MIDNIGHT(previous_day.minute) <= gmt_offset)
|
1532
|
+
{
|
1533
|
+
result = previous_day;
|
1534
|
+
result.minute += gmt_offset;
|
1535
|
+
result.minute %= MINUTES_PER_DAY;
|
1536
|
+
}
|
1537
|
+
else if ( (TIME_BEFORE_MIDNIGHT(previous_day.minute) > gmt_offset)
|
1538
|
+
&& (TIME_BEFORE_MIDNIGHT(current_day.minute) > gmt_offset) )
|
1539
|
+
{
|
1540
|
+
result = current_day;
|
1541
|
+
result.minute += gmt_offset;
|
1542
|
+
}
|
1543
|
+
else if (special == YES)
|
1544
|
+
{
|
1545
|
+
result = current_day;
|
1546
|
+
temp_1 = (previous_day.minute + gmt_offset) % MINUTES_PER_DAY;
|
1547
|
+
temp_2 = (current_day.minute + gmt_offset) % MINUTES_PER_DAY;
|
1548
|
+
result.minute = (temp_1 + temp_2) / 2;
|
1549
|
+
}
|
1550
|
+
else
|
1551
|
+
{
|
1552
|
+
result.exception = NONE_TODAY;
|
1553
|
+
}
|
1554
|
+
}
|
1555
|
+
else
|
1556
|
+
{
|
1557
|
+
result = current_day;
|
1558
|
+
}
|
1559
|
+
return result;
|
1560
|
+
}
|
1561
|
+
|
1562
|
+
/*********************** Rise Set Transit Transit Underfoot
|
1563
|
+
|
1564
|
+
This function is the heart of the original Heafner code. It has been substantially changed as
|
1565
|
+
follows:
|
1566
|
+
|
1567
|
+
1) The original function got latitude and longitude data from file scope variables obser_lat and
|
1568
|
+
obser_lon. Those have been replaced by parameters lat and lon.
|
1569
|
+
|
1570
|
+
2) The original function returned results as text strings. These have been replaced by a singgle
|
1571
|
+
rst_type structure which is comprised of time type structures. Each time type strucuture
|
1572
|
+
includes exception codes.
|
1573
|
+
|
1574
|
+
3) The original function reported exceptions (object never rises or sets, event occurs previous
|
1575
|
+
or following day) as text strings. These have been replaced by the exceptions member of the
|
1576
|
+
structure.
|
1577
|
+
|
1578
|
+
4) The rsflag has been repurposed to show the exception.
|
1579
|
+
|
1580
|
+
5) The original function got the ra[] and dec[] arrays as parameters. These are now determined
|
1581
|
+
from the JPL file.
|
1582
|
+
|
1583
|
+
6) The original function had delta t as a parameter. This is now a fixed value of 69 which is
|
1584
|
+
average between the 2016 value of 68.5 and the 2020 value of 69.5.
|
1585
|
+
|
1586
|
+
7) Added a fudge factor to z0 to make moon rise and set times agree with published data.
|
1587
|
+
|
1588
|
+
RETURN VALUE: RST structure
|
1589
|
+
|
1590
|
+
PARAMETERS: handle to the cata file - already opened.
|
1591
|
+
object - SUN or MOON
|
1592
|
+
julian date
|
1593
|
+
latitude
|
1594
|
+
longitude
|
1595
|
+
*/
|
1596
|
+
rst_type RST(FILE *file, int object, double jed, double lat, double lon)
|
1597
|
+
{
|
1598
|
+
int rsflag, c;
|
1599
|
+
double h0, cosh0, newm, oldm, m, m0, m1, m2;
|
1600
|
+
double ristime, settime, trntime, gast0;
|
1601
|
+
double d1, d2, d3, r1, r2, r3;
|
1602
|
+
double deltat;
|
1603
|
+
double ra[3];
|
1604
|
+
double dec[3];
|
1605
|
+
double z0;
|
1606
|
+
double hp;
|
1607
|
+
double sd;
|
1608
|
+
int index;
|
1609
|
+
int rst_tries;
|
1610
|
+
rst_type result;
|
1611
|
+
jpl_type jpl[3];
|
1612
|
+
|
1613
|
+
deltat = 69;
|
1614
|
+
index = (int)(floor(jed) - floor(JDATE_BASE));
|
1615
|
+
fseek(file, ((index - 1) * sizeof(jpl_type)), SEEK_SET);
|
1616
|
+
fread(&jpl[0], sizeof(jpl_type), 3, file);
|
1617
|
+
if (object == SUN)
|
1618
|
+
{
|
1619
|
+
ra[0] = D2R * jpl[0].sun.ra;
|
1620
|
+
dec[0] = D2R * jpl[0].sun.dec;
|
1621
|
+
ra[1] = D2R * jpl[1].sun.ra;
|
1622
|
+
dec[1] = D2R * jpl[1].sun.dec;
|
1623
|
+
ra[2] = D2R * jpl[2].sun.ra;
|
1624
|
+
dec[2] = D2R * jpl[2].sun.dec;
|
1625
|
+
z0 = D2R * deg(90.34 + 0.16);
|
1626
|
+
}
|
1627
|
+
else
|
1628
|
+
{
|
1629
|
+
ra[0] = D2R * jpl[0].moon.ra;
|
1630
|
+
dec[0] = D2R * jpl[0].moon.dec;
|
1631
|
+
ra[1] = D2R * jpl[1].moon.ra;
|
1632
|
+
dec[1] = D2R * jpl[1].moon.dec;
|
1633
|
+
ra[2] = D2R * jpl[2].moon.ra;
|
1634
|
+
dec[2] = D2R * jpl[2].moon.dec;
|
1635
|
+
hp = D2R * deg(0.444156);
|
1636
|
+
sd = asin(0.272493 * sin(hp));
|
1637
|
+
z0 = D2R * deg(90.34) + sd - hp;
|
1638
|
+
z0 -= 0.00275; // fudge factor
|
1639
|
+
}
|
1640
|
+
/* Make sure the ra[]'s are in continuous order */
|
1641
|
+
|
1642
|
+
if ((ra[1] < ra[0]) && (ra[2] > ra[1])) {
|
1643
|
+
ra[1] = ra[1] + TWOPI;
|
1644
|
+
ra[2] = ra[2] + TWOPI;
|
1645
|
+
}
|
1646
|
+
else if ((ra[1] > ra[0]) && (ra[2] < ra[1])) {
|
1647
|
+
ra[2] = ra[2] + TWOPI;
|
1648
|
+
}
|
1649
|
+
|
1650
|
+
r1 = ra[1] - ra[0];
|
1651
|
+
r2 = ra[2] - ra[1];
|
1652
|
+
r3 = r2 - r1;
|
1653
|
+
d1 = dec[1] - dec[0];
|
1654
|
+
d2 = dec[2] - dec[1];
|
1655
|
+
d3 = d2 - d1;
|
1656
|
+
|
1657
|
+
rsflag = 0;
|
1658
|
+
cosh0 = (cos(z0) - sin(lat) * sin(dec[1])) / (cos(lat) * cos(dec[1]));
|
1659
|
+
if (cosh0 < -1.0)
|
1660
|
+
{
|
1661
|
+
// Object - never sets
|
1662
|
+
rsflag = NEVER_SET;
|
1663
|
+
}
|
1664
|
+
else if (cosh0 > 1.0)
|
1665
|
+
{
|
1666
|
+
// Object never rises
|
1667
|
+
rsflag = NEVER_RISE;
|
1668
|
+
}
|
1669
|
+
|
1670
|
+
GetGST(jed, 1, &gast0);
|
1671
|
+
|
1672
|
+
m0 = (ra[1] - lon - gast0) / TWOPI;
|
1673
|
+
m0 = amodulo(m0, 1.0);
|
1674
|
+
|
1675
|
+
if (rsflag == 0)
|
1676
|
+
{
|
1677
|
+
h0 = acos(cosh0);
|
1678
|
+
h0 = amodulo(h0, PI);
|
1679
|
+
m1 = m0 - h0 / TWOPI;
|
1680
|
+
m1 = amodulo(m1, 1.0);
|
1681
|
+
m2 = m0 + h0 / TWOPI;
|
1682
|
+
m2 = amodulo(m2, 1.0);
|
1683
|
+
|
1684
|
+
// Rising
|
1685
|
+
oldm = m1;
|
1686
|
+
c = 1;
|
1687
|
+
rst_tries = RST_Interpolate(c, z0, oldm, gast0, deltat, ra, dec,
|
1688
|
+
r1, r2, r3, d1, d2, d3, lat, lon, &newm);
|
1689
|
+
if (rst_tries == RST_MAX_TRIES)
|
1690
|
+
{
|
1691
|
+
result.ris.exception = RST_ERROR;
|
1692
|
+
}
|
1693
|
+
else if (rst_tries > RST_MAX_TRIES)
|
1694
|
+
{
|
1695
|
+
result.ris.exception = RST_FAIL;
|
1696
|
+
}
|
1697
|
+
else
|
1698
|
+
{
|
1699
|
+
m = newm;
|
1700
|
+
ristime = 24.0 * m;
|
1701
|
+
|
1702
|
+
if (ristime > 24.0) {
|
1703
|
+
ristime = ristime - 24.0;
|
1704
|
+
// Event occurs the following day
|
1705
|
+
result.ris = FmtTime(ristime);
|
1706
|
+
result.ris.exception = NEXT_DAY;
|
1707
|
+
}
|
1708
|
+
else if (ristime < 0.0) {
|
1709
|
+
ristime = ristime + 24.0;
|
1710
|
+
// Event occurs the previous day
|
1711
|
+
result.ris = FmtTime(ristime);
|
1712
|
+
result.ris.exception = PREV_DAY;
|
1713
|
+
}
|
1714
|
+
else {
|
1715
|
+
result.ris = FmtTime(ristime);
|
1716
|
+
}
|
1717
|
+
}
|
1718
|
+
// Setting
|
1719
|
+
oldm = m2;
|
1720
|
+
c = 1;
|
1721
|
+
rst_tries = RST_Interpolate(c, z0, oldm, gast0, deltat, ra, dec,
|
1722
|
+
r1, r2, r3, d1, d2, d3, lat, lon, &newm);
|
1723
|
+
if (rst_tries == RST_MAX_TRIES)
|
1724
|
+
{
|
1725
|
+
result.set.exception = RST_ERROR;
|
1726
|
+
}
|
1727
|
+
else if (rst_tries > RST_MAX_TRIES)
|
1728
|
+
{
|
1729
|
+
result.set.exception = RST_FAIL;
|
1730
|
+
}
|
1731
|
+
else
|
1732
|
+
{
|
1733
|
+
m = newm;
|
1734
|
+
settime = 24.0 * m;
|
1735
|
+
if (settime > 24.0)
|
1736
|
+
{
|
1737
|
+
settime = settime - 24.0;
|
1738
|
+
result.set = FmtTime(settime);
|
1739
|
+
result.set.exception = NEXT_DAY;
|
1740
|
+
}
|
1741
|
+
else if (settime < 0.0) {
|
1742
|
+
settime = settime + 24.0;
|
1743
|
+
result.set = FmtTime(settime);
|
1744
|
+
result.set.exception = PREV_DAY;
|
1745
|
+
}
|
1746
|
+
else {
|
1747
|
+
result.set = FmtTime(settime);
|
1748
|
+
}
|
1749
|
+
}
|
1750
|
+
}
|
1751
|
+
|
1752
|
+
else
|
1753
|
+
{
|
1754
|
+
result.set = FmtTime(0);
|
1755
|
+
result.ris = FmtTime(0);
|
1756
|
+
result.set.exception = rsflag;
|
1757
|
+
result.ris.exception = rsflag;
|
1758
|
+
}
|
1759
|
+
// Transiting
|
1760
|
+
oldm = m0;
|
1761
|
+
c = 0;
|
1762
|
+
rst_tries = RST_Interpolate(c, z0, oldm, gast0, deltat, ra, dec,
|
1763
|
+
r1, r2, r3, d1, d2, d3, lat, lon, &newm);
|
1764
|
+
if (rst_tries == RST_MAX_TRIES)
|
1765
|
+
{
|
1766
|
+
result.trn.exception = RST_ERROR;
|
1767
|
+
}
|
1768
|
+
if (rst_tries > RST_MAX_TRIES)
|
1769
|
+
{
|
1770
|
+
result.trn.exception = RST_FAIL;
|
1771
|
+
}
|
1772
|
+
else
|
1773
|
+
{
|
1774
|
+
m = newm;
|
1775
|
+
trntime = 24.0 * m;
|
1776
|
+
if (trntime > 24.0) {
|
1777
|
+
trntime = trntime - 24.0;
|
1778
|
+
result.trn = FmtTime(trntime);
|
1779
|
+
result.trn.exception = NEXT_DAY;
|
1780
|
+
}
|
1781
|
+
else if (trntime < 0.0) {
|
1782
|
+
trntime = trntime + 24.0;
|
1783
|
+
result.trn = FmtTime(trntime);
|
1784
|
+
result.trn.exception = PREV_DAY;
|
1785
|
+
}
|
1786
|
+
else {
|
1787
|
+
result.trn = FmtTime(trntime);
|
1788
|
+
}
|
1789
|
+
}
|
1790
|
+
return result;
|
1791
|
+
}
|
1792
|
+
|
1793
|
+
/*********************** Interpolation required by RST()
|
1794
|
+
|
1795
|
+
This is original Heafner code. For explanation, see the originalfunction in astrolib.c.
|
1796
|
+
The only modification is that the original function got latitude and longitude data from
|
1797
|
+
file scope variables obser_lat and obser_lon. Those have been replaced by parameters lat
|
1798
|
+
and lon.
|
1799
|
+
|
1800
|
+
RETURN VALUE: count of inerations in do loop
|
1801
|
+
|
1802
|
+
PARAMETERS: lat latitude
|
1803
|
+
lon longitude
|
1804
|
+
(see original function in astrolib to describe others)
|
1805
|
+
*/
|
1806
|
+
static int RST_Interpolate(int c, double z0, double oldm, double gast0,
|
1807
|
+
double deltat, double *ra, double *dec, double r1, double r2, double r3,
|
1808
|
+
double d1, double d2, double d3, double lat, double lon, double *newm) {
|
1809
|
+
|
1810
|
+
double alpha, dm, h, gast, delta, alt, n;
|
1811
|
+
int count;
|
1812
|
+
|
1813
|
+
count = 0;
|
1814
|
+
*newm = oldm;
|
1815
|
+
do {
|
1816
|
+
count ++;
|
1817
|
+
if (count > RST_MAX_TRIES)
|
1818
|
+
{
|
1819
|
+
break;
|
1820
|
+
}
|
1821
|
+
gast = gast0 + 6.300388093 * (*newm);
|
1822
|
+
gast = amodulo(gast, TWOPI);
|
1823
|
+
n = *newm + deltat / 86400.0;
|
1824
|
+
alpha = ra[1] + 0.5 * n * (r1 + r2 + n * r3);
|
1825
|
+
alpha = amodulo(alpha, TWOPI);
|
1826
|
+
delta = dec[1] + 0.5 * n * (d1 + d2 + n * d3);
|
1827
|
+
h = gast + lon - alpha;
|
1828
|
+
alt = asin(sin(delta) * sin(lat) + cos(delta) * cos(lat) * cos(h));
|
1829
|
+
if (c == 0) {
|
1830
|
+
/* h must satisfy -PI <= h <= PI */
|
1831
|
+
h = amodulo(h, TWOPI);
|
1832
|
+
if (h > PI) {
|
1833
|
+
h = h - TWOPI;
|
1834
|
+
}
|
1835
|
+
dm = -h / TWOPI;
|
1836
|
+
}
|
1837
|
+
else {
|
1838
|
+
dm = (alt - PIDIV2 + z0) / (TWOPI * cos(delta) * cos(lat) * sin(h));
|
1839
|
+
}
|
1840
|
+
*newm = (*newm) + dm;
|
1841
|
+
|
1842
|
+
|
1843
|
+
} while (fabs(dm) >= 1e-15);
|
1844
|
+
if ((*newm >= 2.0) || (*newm <= -1.0))
|
1845
|
+
{
|
1846
|
+
count = RST_MAX_TRIES;
|
1847
|
+
}
|
1848
|
+
return count;
|
1849
|
+
}
|
1850
|
+
|
1851
|
+
/*********************** Convert Degrees
|
1852
|
+
|
1853
|
+
This function cnverts degrees in the format dd.mmss to decimal degrees.
|
1854
|
+
It is original Heafner code with no changes
|
1855
|
+
|
1856
|
+
RETURN VALUE: decimal degrees
|
1857
|
+
|
1858
|
+
PARAMETERS: degrees in format dD.MMSS
|
1859
|
+
*/
|
1860
|
+
double deg(double x) {
|
1861
|
+
|
1862
|
+
double dd, d, fixdd, ddfixdd;
|
1863
|
+
|
1864
|
+
if (x == 0.0) return (0.0);
|
1865
|
+
|
1866
|
+
dd = fabs(x);
|
1867
|
+
fixdd = floor(dd);
|
1868
|
+
ddfixdd = dd - fixdd + 5.0e-10; /* fudge factor */
|
1869
|
+
d = fixdd + floor(100.0 * ddfixdd) / 60.0;
|
1870
|
+
d = d + (10000.0 * ddfixdd - 100.0 * floor(100.0 * ddfixdd)) / 3600.0;
|
1871
|
+
|
1872
|
+
return ((x / dd) * d);
|
1873
|
+
}
|
1874
|
+
|
1875
|
+
/*********************** Get Grenwich Sidereal Time
|
1876
|
+
|
1877
|
+
This function computes Sidereal time (in radians) from the Julian date.It is original Heafner
|
1878
|
+
code excdpt:
|
1879
|
+
|
1880
|
+
1) The original was siginicantly more complicated in that it computed apparent sidereal time.
|
1881
|
+
We don't require that kind of (sub-minute) accuracy, so we will use mean sidereal time. All
|
1882
|
+
code required to calculate apparent sidereal time has been removed.
|
1883
|
+
|
1884
|
+
2) The parameter that specified mean or apparent sideereal time has been removed.
|
1885
|
+
|
1886
|
+
3) The original had logic such that saved the time and apparent flag. If the call was the
|
1887
|
+
same as the previous call, the function would simply return with no changes. That would force
|
1888
|
+
the calling function to save the result for use if it happened to call this function twice in
|
1889
|
+
a row with the same date. That may have been useful when being called by some functions not
|
1890
|
+
used in our application, but where it is called in RST, the result (gast0) is not saved. The
|
1891
|
+
result was that an unitialized value was sent to RST_Interpolate() which caused it to fail.
|
1892
|
+
That logic has been removed.
|
1893
|
+
|
1894
|
+
RETURN VALUE: none
|
1895
|
+
|
1896
|
+
PARAMETERS: Juilian date
|
1897
|
+
address of result
|
1898
|
+
*/
|
1899
|
+
void GetGST(double jed, int s, double *gst) {
|
1900
|
+
|
1901
|
+
double T;
|
1902
|
+
|
1903
|
+
T = (jed - J2000) / JulCty;
|
1904
|
+
|
1905
|
+
/* compute GMST in seconds */
|
1906
|
+
*gst = 67310.54841 + T * ((876600.0 * 3600.0 + 8640184.812866)
|
1907
|
+
+ T * (0.093104 + T * (-0.0000062)));
|
1908
|
+
|
1909
|
+
/* convert to radians */
|
1910
|
+
*gst = amodulo(*gst / 3600.0, 24.0) * H2R;
|
1911
|
+
*gst = amodulo(*gst, TWOPI);
|
1912
|
+
}
|
1913
|
+
|
1914
|
+
/*********************** Calculate the modulo of an angle
|
1915
|
+
|
1916
|
+
This function calculates the module of an angle to the specified base. It us used with values in
|
1917
|
+
radians with either PI or TWOPI
|
1918
|
+
|
1919
|
+
RETURN VALUE: modulo of the angle
|
1920
|
+
|
1921
|
+
PARAMETERS: the angle
|
1922
|
+
the base
|
1923
|
+
*/
|
1924
|
+
double amodulo(double a, double b) {
|
1925
|
+
|
1926
|
+
double x;
|
1927
|
+
|
1928
|
+
x = a - b * floor(a / b);
|
1929
|
+
return (x);
|
1930
|
+
}
|
1931
|
+
|
1932
|
+
/*************************** Ruby interface code *******************************************************/
|
1933
|
+
|
1934
|
+
static VALUE
|
1935
|
+
test_function(VALUE self, VALUE number) {
|
1936
|
+
VALUE v;
|
1937
|
+
long i;
|
1938
|
+
i = FIX2LONG(number);
|
1939
|
+
i = i*2;
|
1940
|
+
v = LONG2FIX(i);
|
1941
|
+
return v;
|
1942
|
+
}
|
1943
|
+
|
1944
|
+
/* This function initializes the new Solunar object - the names should match, and capitalization seems to come from Ruby magic.
|
1945
|
+
* A "Value" is C/Ruby.h/C++ speak for a Ruby object. In this case, with the rb_intern stuff, that object is of the class "Solunar" and is registered as such.
|
1946
|
+
* Registration is pure ruby magic. rb_define_method uses this, of the format (root_object - always the thing declared before, name to be registered as, function name, number of arguements to pass)
|
1947
|
+
* Caveat to the above: Functions that will return to Ruby always are of type "Value", and always have a first object, of type value, that does something likely important - but exactly what, I couldn't tell you...
|
1948
|
+
*/
|
1949
|
+
|
1950
|
+
void
|
1951
|
+
Init_solunar(void) {
|
1952
|
+
VALUE cSolunar;
|
1953
|
+
|
1954
|
+
cSolunar = rb_const_get(rb_cObject, rb_intern("Solunar"));
|
1955
|
+
|
1956
|
+
rb_define_method(cSolunar, "multi", test_function, 1);
|
1957
|
+
rb_define_method(cSolunar, "generate", generate, 7);
|
1958
|
+
}
|
1959
|
+
|