1 /*
2  *  This library is free software; you can redistribute it and/or
3  *  modify it under the terms of the GNU Lesser General Public
4  *  License as published by the Free Software Foundation; either
5  *  version 2 of the License, or (at your option) any later version.
6  *
7  *  This library is distributed in the hope that it will be useful,
8  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
10  *  Lesser General Public License for more details.
11  *
12  *  You should have received a copy of the GNU General Public License
13  *  along with this program; if not, write to the Free Software
14  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
15  *
16  *  Copyright (C) 2000 - 2005 Liam Girdwood <lgirdwood@gmail.com>
17  */
18 
19 module nova.solar;
20 
21 import std.math;
22 import std.stdio;
23 
24 import nova.earth;
25 import nova.nutation;
26 import nova.transform;
27 import nova.rise_set;
28 import nova.utility;
29 import nova.ln_types;
30 
31 enum LN_SOLAR_STANDART_HORIZON =            -0.8333;
32 
33 extern (C) {
34 
35 /*! \fn void ln_get_solar_geom_coords(double JD, struct ln_helio_posn *position)
36 * \param JD Julian day
37 * \param position Pointer to store calculated solar position.
38 *
39 * Calculate geometric coordinates and radius vector
40 * accuracy 0.01 arc second error - uses VSOP87 solution.
41 *
42 * Latitude and Longitude returned are in degrees, whilst radius
43 * vector returned is in AU.
44 */
45 
46 @nogc void ln_get_solar_geom_coords(double JD, ref ln_helio_posn position) nothrow
47 {
48 	/* get earths heliocentric position */
49 	ln_get_earth_helio_coords(JD, position);
50 
51 	position.L += 180.0;
52 	position.L = ln_range_degrees(position.L);
53 	position.B *= -1.0;
54 }
55 
56 /*! \fn void ln_get_solar_equ_coords(double JD, struct ln_equ_posn *position)
57 * \param JD Julian day
58 * \param position Pointer to store calculated solar position.
59 *
60 * Calculate apparent equatorial solar coordinates for given julian day.
61 * This function includes the effects of aberration and nutation.
62 */
63 @nogc void ln_get_solar_equ_coords(double JD, ref ln_equ_posn position) nothrow
64 {
65 	ln_helio_posn sol;
66 	ln_lnlat_posn LB;
67 	ln_nutation nutation;
68 	double aberration;
69 
70 	/* get geometric coords */
71 	ln_get_solar_geom_coords(JD, sol);
72 
73 	/* add nutation */
74 	ln_get_nutation(JD, nutation);
75 	sol.L += nutation.longitude;
76 
77 	/* aberration */
78 	aberration = (20.4898 / (360.0 * 60.0 * 60.0)) / sol.R;
79 	sol.L -= aberration;
80 
81 	/* transform to equatorial */
82 	LB.lat = sol.B;
83 	LB.lng = sol.L;
84 	ln_get_equ_from_ecl(LB, JD, position);
85 }
86 
87 /*! \fn void ln_get_solar_ecl_coords(double JD, struct ln_lnlat_posn *position)
88 * \param JD Julian day
89 * \param position Pointer to store calculated solar position.
90 *
91 * Calculate apparent ecliptical solar coordinates for given julian day.
92 * This function includes the effects of aberration and nutation.
93 */
94 @nogc void ln_get_solar_ecl_coords(double JD, ref ln_lnlat_posn position) nothrow
95 {
96 	ln_helio_posn sol;
97 	ln_nutation nutation;
98 	double aberration;
99 
100 	/* get geometric coords */
101 	ln_get_solar_geom_coords(JD, sol);
102 
103 	/* add nutation */
104 	ln_get_nutation(JD, nutation);
105 	sol.L += nutation.longitude;
106 
107 	/* aberration */
108 	aberration = (20.4898 / (360.0 * 60.0 * 60.0)) / sol.R;
109 	sol.L -= aberration;
110 
111 	position.lng = sol.L;
112 	position.lat = sol.B;
113 }
114 
115 /*! \fn void ln_get_solar_geo_coords(double JD, struct ln_rect_posn *position)
116 * \param JD Julian day
117 * \param position Pointer to store calculated solar position.
118 *
119 * Calculate geocentric coordinates (rectangular) for given julian day.
120 * Accuracy 0.01 arc second error - uses VSOP87 solution.
121 * Position returned is in units of AU.
122 */
123 @nogc void ln_get_solar_geo_coords(double JD, ref ln_rect_posn position) nothrow
124 {
125 	/* get earths's heliocentric position */
126 	ln_helio_posn sol;
127 	ln_get_earth_helio_coords(JD, sol);
128 
129 	/* now get rectangular coords */
130 	ln_get_rect_from_helio(sol, position);
131 	position.X *=-1.0;
132 	position.Y *=-1.0;
133 	position.Z *=-1.0;
134 }
135 
136 @nogc int ln_get_solar_rst_horizon(double JD, const ref ln_lnlat_posn observer,
137 	double horizon, ref ln_rst_time rst) nothrow
138 {
139 	return ln_get_body_rst_horizon(JD, observer, &ln_get_solar_equ_coords, horizon, rst);
140 }
141 
142 
143 /*! \fn double ln_get_solar_rst(double JD, struct ln_lnlat_posn *observer, struct ln_rst_time *rst);
144  * Calls get_solar_rst_horizon with horizon set to LN_SOLAR_STANDART_HORIZON.
145  */
146 
147 @nogc int ln_get_solar_rst(double JD, const ref ln_lnlat_posn observer,
148 	ref ln_rst_time rst) nothrow
149 {
150 	return ln_get_solar_rst_horizon(JD, observer,
151 		LN_SOLAR_STANDART_HORIZON, rst);
152 }
153 
154 /*! \fn double ln_get_solar_sdiam(double JD)
155 * \param JD Julian day
156 * \return Semidiameter in arc seconds
157 *
158 * Calculate the semidiameter of the Sun in arc seconds for the
159 * given julian day.
160 */
161 @nogc double ln_get_solar_sdiam(double JD) nothrow
162 {
163 	double So = 959.63; /* at 1 AU */
164 	double dist;
165 
166 	dist = ln_get_earth_solar_dist(JD);
167 	return So / dist;
168 }
169 
170 /*! \example sun.c
171  *
172  * Examples of how to use solar functions.
173  */
174 
175 }