solunar 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
|