1 /*
2  * Stellarium
3  * Copyright (C) 2002 Fabien Chereau
4  * Copyright (C) 2021 Georg Zotti
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA  02110-1335, USA.
19  */
20 
21 #include "StelCore.hpp"
22 #include "Planet.hpp"
23 #include "StelUtils.hpp"
24 
25 #include <limits>
26 #include <QString>
27 #include <QDebug>
28 
29 // Also include the GRS corrections here
30 bool RotationElements::flagCustomGrsSettings = false;
31 double RotationElements::customGrsJD = 2456901.5;
32 double RotationElements::customGrsLongitude = 216.;
33 double RotationElements::customGrsDrift = 15.;
34 
35 RotationElements::PlanetCorrections RotationElements::planetCorrections;
36 
37 
updatePlanetCorrections(const double JDE,const PlanetCorrection planet)38 void RotationElements::updatePlanetCorrections(const double JDE, const PlanetCorrection planet)
39 {
40 	// The angles are always given in degrees. We let the compiler do the conversion. Leave it for readability!
41 	const double d=(JDE-J2000);
42 	const double T=d/36525.0;
43 
44 	switch (planet){
45 		case EarthMoon:
46 			if (fabs(JDE-planetCorrections.JDE_E)>StelCore::JD_MINUTE)
47 			{ // Moon/Earth correction terms. This is from WGCCRE2009. We must fmod them, else we have sin(LARGE)>>1
48 				planetCorrections.JDE_E=JDE; // keep record of when these values are valid.
49 				planetCorrections.E1= M_PI_180* (125.045 - remainder( 0.0529921*d, 360.0));
50 				planetCorrections.E2= M_PI_180* (250.089 - remainder( 0.1059842*d, 360.0));
51 				planetCorrections.E3= M_PI_180* (260.008 + remainder(13.0120009*d, 360.0));
52 				planetCorrections.E4= M_PI_180* (176.625 + remainder(13.3407154*d, 360.0));
53 				planetCorrections.E5= M_PI_180* (357.529 + remainder( 0.9856003*d, 360.0));
54 				planetCorrections.E6= M_PI_180* (311.589 + remainder(26.4057084*d, 360.0));
55 				planetCorrections.E7= M_PI_180* (134.963 + remainder(13.0649930*d, 360.0));
56 				planetCorrections.E8= M_PI_180* (276.617 + remainder( 0.3287146*d, 360.0));
57 				planetCorrections.E9= M_PI_180* ( 34.226 + remainder( 1.7484877*d, 360.0));
58 				planetCorrections.E10=M_PI_180* ( 15.134 - remainder( 0.1589763*d, 360.0));
59 				planetCorrections.E11=M_PI_180* (119.743 + remainder( 0.0036096*d, 360.0));
60 				planetCorrections.E12=M_PI_180* (239.961 + remainder( 0.1643573*d, 360.0));
61 				planetCorrections.E13=M_PI_180* ( 25.053 + remainder(12.9590088*d, 360.0));
62 			}
63 			break;
64 		case Mars:
65 			if (fabs(JDE-planetCorrections.JDE_E)>5*StelCore::JD_MINUTE)
66 			{ // Mars correction terms. This is from WGCCRE2015. We must fmod them, else we have sin(LARGE)>>1
67 				planetCorrections.JDE_M=JDE; // keep record of when these values are valid.
68 				planetCorrections.M1= M_PI_180* (190.72646643 + remainder(   15917.10818695*T, 360.0));
69 				planetCorrections.M2= M_PI_180* ( 21.46892470 + remainder(   31834.27934054*T, 360.0));
70 				planetCorrections.M3= M_PI_180* (332.86082793 + remainder(   19139.89694742*T, 360.0));
71 				planetCorrections.M4= M_PI_180* (394.93256437 + remainder(   38280.79631835*T, 360.0));
72 				planetCorrections.M5= M_PI_180* (189.63271560 + remainder(41215158.18420050*T, 360.0) + remainder(12.71192322*T*T, 360.0));
73 				planetCorrections.M6= M_PI_180* (121.46893664 + remainder(     660.22803474*T, 360.0));
74 				planetCorrections.M7= M_PI_180* (231.05028581 + remainder(     660.99123540*T, 360.0));
75 				planetCorrections.M8= M_PI_180* (251.37314025 + remainder(    1320.50145245*T, 360.0));
76 				planetCorrections.M9= M_PI_180* (217.98635955 + remainder(   38279.96125550*T, 360.0));
77 				planetCorrections.M10=M_PI_180* (196.19729402 + remainder(   19139.83628608*T, 360.0));
78 			}
79 			break;
80 		case Jupiter:
81 			if (fabs(JDE-planetCorrections.JDE_J)>0.025) // large changes in the values below :-(
82 			{
83 				planetCorrections.JDE_J=JDE; // keep record of when these values are valid.
84 				planetCorrections.Ja =M_PI_180* ( 99.360714+remainder( 4850.4046*T, 360.0)); // Jupiter axis terms, Table 10.1
85 				planetCorrections.Jb =M_PI_180* (175.895369+remainder( 1191.9605*T, 360.0));
86 				planetCorrections.Jc =M_PI_180* (300.323162+remainder(  262.5475*T, 360.0));
87 				planetCorrections.Jd =M_PI_180* (114.012305+remainder( 6070.2476*T, 360.0));
88 				planetCorrections.Je =M_PI_180* ( 49.511251+remainder(   64.3000*T, 360.0));
89 				planetCorrections.J1 =M_PI_180* ( 73.32    +remainder(91472.9   *T, 360.0)); // corrective terms for Jupiter' moons, Table 10.10
90 				planetCorrections.J2 =M_PI_180* ( 24.62    +remainder(45137.2   *T, 360.0));
91 				planetCorrections.J3 =M_PI_180* (283.90    +remainder( 4850.7   *T, 360.0));
92 				planetCorrections.J4 =M_PI_180* (355.80    +remainder( 1191.3   *T, 360.0));
93 				planetCorrections.J5 =M_PI_180* (119.90    +remainder(  262.1   *T, 360.0));
94 				planetCorrections.J6 =M_PI_180* (229.80    +remainder(   64.3   *T, 360.0));
95 				planetCorrections.J7 =M_PI_180* (352.25    +remainder( 2382.6   *T, 360.0));
96 				planetCorrections.J8 =M_PI_180* (113.35    +remainder( 6070.0   *T, 360.0));
97 			}
98 			break;
99 		case Saturn:
100 			if (fabs(JDE-planetCorrections.JDE_S)>0.025) // large changes in the values below :-(
101 			{
102 				planetCorrections.JDE_S=JDE; // keep record of when these values are valid.
103 				planetCorrections.S1=M_PI_180* (353.32+remainder( 75706.7*T, 360.0)); // corrective terms for Saturn's moons, Table 10.12
104 				planetCorrections.S2=M_PI_180* ( 28.72+remainder( 75706.7*T, 360.0));
105 				planetCorrections.S3=M_PI_180* (177.40+remainder(-36505.5*T, 360.0));
106 				planetCorrections.S4=M_PI_180* (300.00+remainder( -7225.9*T, 360.0));
107 				planetCorrections.S5=M_PI_180* (316.45+remainder(   506.2*T, 360.0));
108 				planetCorrections.S6=M_PI_180* (345.20+remainder( -1016.3*T, 360.0));
109 			}
110 			break;
111 		case Uranus:
112 			if (fabs(JDE-planetCorrections.JDE_U)>0.025) // large changes in the values below :-(
113 			{
114 				planetCorrections.JDE_U=JDE; // keep record of when these values are valid.
115 				planetCorrections.U1 =M_PI_180* (115.75+remainder(54991.87*T, 360.0)); // corrective terms for Uranus's moons, Table 10.14.
116 				planetCorrections.U2 =M_PI_180* (141.69+remainder(41887.66*T, 360.0));
117 				//planetCorrections.U3 =M_PI_180* (135.03+remainder(29927.35*T, 360.0)); // not in 0.20
118 				planetCorrections.U4 =M_PI_180* ( 61.77+remainder(25733.59*T, 360.0));
119 				planetCorrections.U5 =M_PI_180* (249.32+remainder(24471.46*T, 360.0));
120 				planetCorrections.U6 =M_PI_180* ( 43.86+remainder(22278.41*T, 360.0));
121 				//planetCorrections.U7 =M_PI_180* ( 77.66+remainder(20289.42*T, 360.0)); // not in 0.20
122 				//planetCorrections.U8 =M_PI_180* (157.36+remainder(16652.76*T, 360.0)); // not in 0.20
123 				//planetCorrections.U9 =M_PI_180* (101.81+remainder(12872.63*T, 360.0)); // not in 0.20
124 				planetCorrections.U10=M_PI_180* (138.64+remainder( 8061.81*T, 360.0));
125 				planetCorrections.U11=M_PI_180* (102.23+remainder(-2024.22*T, 360.0));
126 				planetCorrections.U12=M_PI_180* (316.41+remainder( 2863.96*T, 360.0));
127 				planetCorrections.U13=M_PI_180* (304.01+remainder(  -51.94*T, 360.0));
128 				planetCorrections.U14=M_PI_180* (308.71+remainder(  -93.17*T, 360.0));
129 				planetCorrections.U15=M_PI_180* (340.82+remainder(  -75.32*T, 360.0));
130 				planetCorrections.U16=M_PI_180* (259.14+remainder( -504.81*T, 360.0));
131 			}
132 			break;
133 		case Neptune:
134 			if (fabs(JDE-planetCorrections.JDE_N)>0.025) // large changes in the values below :-(
135 			{
136 				planetCorrections.JDE_N=JDE; // keep record of when these values are valid.
137 				planetCorrections.Na=M_PI_180* (357.85+remainder(   52.316*T, 360.0)); // Neptune axis term
138 				planetCorrections.N1=M_PI_180* (323.92+remainder(62606.6*T, 360.0)); // corrective terms for Neptune's moons, Table 10.15 (N=Na!)
139 				planetCorrections.N2=M_PI_180* (220.51+remainder(55064.2*T, 360.0));
140 				planetCorrections.N3=M_PI_180* (354.27+remainder(46564.5*T, 360.0));
141 				planetCorrections.N4=M_PI_180* ( 75.31+remainder(26109.4*T, 360.0));
142 				planetCorrections.N5=M_PI_180* ( 35.36+remainder(14325.4*T, 360.0));
143 				planetCorrections.N6=M_PI_180* (142.61+remainder( 2824.6*T, 360.0));
144 				planetCorrections.N7=M_PI_180* (177.85+remainder(   52.316*T, 360.0));
145 			}
146 			break;
147 	}
148 }
149 
150 const QMap<QString, RotationElements::axisRotFuncType>RotationElements::axisRotCorrFuncMap={
151 	{"Moon",       &RotationElements::corrWMoon},
152 	{"Mercury",    &RotationElements::corrWMercury},
153 	{"Mars",       &RotationElements::corrWMars},
154 	{"Jupiter",    &RotationElements::corrWJupiter},
155 	{"Neptune",    &RotationElements::corrWNeptune},
156 	{"Phobos",     &RotationElements::corrWPhobos},
157 	{"Deimos",     &RotationElements::corrWDeimos},
158 	{"Io",         &RotationElements::corrWIo},
159 	{"Europa",     &RotationElements::corrWEuropa},
160 	{"Ganymede",   &RotationElements::corrWGanymede},
161 	{"Callisto",   &RotationElements::corrWCallisto},
162 	{"Amalthea",   &RotationElements::corrWAmalthea},
163 	{"Thebe",      &RotationElements::corrWThebe},
164 	{"Mimas",      &RotationElements::corrWMimas},
165 	{"Tethys",     &RotationElements::corrWTethys},
166 	{"Rhea",       &RotationElements::corrWRhea},
167 	{"Janus",      &RotationElements::corrWJanus},
168 	{"Epimetheus", &RotationElements::corrWEpimetheus},
169 	{"Cordelia",   &RotationElements::corrWCordelia},
170 	{"Ophelia",    &RotationElements::corrWOphelia},
171 	{"Bianca",     &RotationElements::corrWBianca},
172 	{"Cressida",   &RotationElements::corrWCressida},
173 	{"Desdemona",  &RotationElements::corrWDesdemona},
174 	{"Juliet",     &RotationElements::corrWJuliet},
175 	{"Portia",     &RotationElements::corrWPortia},
176 	{"Rosalind",   &RotationElements::corrWRosalind},
177 	{"Belinda",    &RotationElements::corrWBelinda},
178 	{"Puck",       &RotationElements::corrWPuck},
179 	{"Ariel",      &RotationElements::corrWAriel},
180 	{"Umbriel",    &RotationElements::corrWUmbriel},
181 	{"Titania",    &RotationElements::corrWTitania},
182 	{"Oberon",     &RotationElements::corrWOberon},
183 	{"Miranda",    &RotationElements::corrWMiranda},
184 	{"Triton",     &RotationElements::corrWTriton},
185 	{"Naiad",      &RotationElements::corrWNaiad},
186 	{"Thalassa",   &RotationElements::corrWThalassa},
187 	{"Despina",    &RotationElements::corrWDespina},
188 	{"Galatea",    &RotationElements::corrWGalatea},
189 	{"Larissa",    &RotationElements::corrWLarissa},
190 	{"Proteus",    &RotationElements::corrWProteus}
191 };
192 
193 const QMap<QString, RotationElements::axisOriFuncType>RotationElements::axisOriCorrFuncMap={
194 	{"Moon",       &RotationElements::corrOriMoon},
195 	{"Mars",       &RotationElements::corrOriMars},
196 	{"Jupiter",    &RotationElements::corrOriJupiter},
197 	{"Neptune",    &RotationElements::corrOriNeptune},
198 	{"Phobos",     &RotationElements::corrOriPhobos},
199 	{"Deimos",     &RotationElements::corrOriDeimos},
200 	{"Io",         &RotationElements::corrOriIo},
201 	{"Europa",     &RotationElements::corrOriEuropa},
202 	{"Ganymede",   &RotationElements::corrOriGanymede},
203 	{"Callisto",   &RotationElements::corrOriCallisto},
204 	{"Amalthea",   &RotationElements::corrOriAmalthea},
205 	{"Thebe",      &RotationElements::corrOriThebe},
206 	{"Mimas",      &RotationElements::corrOriMimas},
207 	{"Tethys",     &RotationElements::corrOriTethys},
208 	{"Rhea",       &RotationElements::corrOriRhea},
209 	{"Janus",      &RotationElements::corrOriJanus},
210 	{"Epimetheus", &RotationElements::corrOriEpimetheus},
211 	{"Ariel",      &RotationElements::corrOriAriel},
212 	{"Umbriel",    &RotationElements::corrOriUmbriel},
213 	{"Titania",    &RotationElements::corrOriTitania},
214 	{"Oberon",     &RotationElements::corrOriOberon},
215 	{"Miranda",    &RotationElements::corrOriMiranda},
216 	{"Cordelia",   &RotationElements::corrOriCordelia},
217 	{"Ophelia",    &RotationElements::corrOriOphelia},
218 	{"Bianca",     &RotationElements::corrOriBianca},
219 	{"Cressida",   &RotationElements::corrOriCressida},
220 	{"Desdemona",  &RotationElements::corrOriDesdemona},
221 	{"Juliet",     &RotationElements::corrOriJuliet},
222 	{"Portia",     &RotationElements::corrOriPortia},
223 	{"Rosalind",   &RotationElements::corrOriRosalind},
224 	{"Belinda",    &RotationElements::corrOriBelinda},
225 	{"Puck",       &RotationElements::corrOriPuck},
226 	{"Triton",     &RotationElements::corrOriTriton},
227 	{"Naiad",      &RotationElements::corrOriNaiad},
228 	{"Thalassa",   &RotationElements::corrOriThalassa},
229 	{"Despina",    &RotationElements::corrOriDespina},
230 	{"Galatea",    &RotationElements::corrOriGalatea},
231 	{"Larissa",    &RotationElements::corrOriLarissa},
232 	{"Proteus",    &RotationElements::corrOriProteus}
233 };
234 
235 
236 
corrWMoon(const double d,const double T)237 double RotationElements::corrWMoon(const double d, const double T)
238 {
239 	Q_UNUSED(T)
240 	return -1.4e-12*d*d                        + 3.5610*sin(planetCorrections.E1)
241 		+0.1208*sin(planetCorrections.E2)  - 0.0642*sin(planetCorrections.E3)  +  0.0158*sin(planetCorrections.E4)
242 		+0.0252*sin(planetCorrections.E5)  - 0.0066*sin(planetCorrections.E6)  -  0.0047*sin(planetCorrections.E7)
243 		-0.0046*sin(planetCorrections.E8)  + 0.0028*sin(planetCorrections.E9)  +  0.0052*sin(planetCorrections.E10)
244 		+0.0040*sin(planetCorrections.E11) + 0.0019*sin(planetCorrections.E12) -  0.0044*sin(planetCorrections.E13);
245 }
246 
corrWMercury(const double d,const double T)247 double RotationElements::corrWMercury(const double d, const double T)
248 {
249 	Q_UNUSED(T)
250 	const double M1=(174.7910857*M_PI_180) + remainder(( 4.092335*M_PI_180)*d, 2.0*M_PI);
251 	const double M2=(349.5821714*M_PI_180) + remainder(( 8.184670*M_PI_180)*d, 2.0*M_PI);
252 	const double M3=(164.3732571*M_PI_180) + remainder((12.277005*M_PI_180)*d, 2.0*M_PI);
253 	const double M4=(339.1643429*M_PI_180) + remainder((16.369340*M_PI_180)*d, 2.0*M_PI);
254 	const double M5=(153.9554286*M_PI_180) + remainder((20.461675*M_PI_180)*d, 2.0*M_PI);
255 
256 	return -0.00000571*sin(M5) - 0.00002539*sin(M4) - 0.00011040*sin(M3) - 0.00112309*sin(M2) + 0.01067257*sin(M1);
257 }
258 
corrWMars(const double d,const double T)259 double RotationElements::corrWMars(const double d, const double T)
260 {
261 	Q_UNUSED(d)
262 	return
263 	+0.000145*sin(M_PI_180*(129.071773 + remainder(19140.0328244*T, 360.)))
264 	+0.000157*sin(M_PI_180*( 36.352167 + remainder(38281.0473591*T, 360.)))
265 	+0.000040*sin(M_PI_180*( 56.668646 + remainder(57420.9295360*T, 360.)))
266 	+0.000001*sin(M_PI_180*( 67.364003 + remainder(76560.2552215*T, 360.)))
267 	+0.000001*sin(M_PI_180*(104.792680 + remainder(95700.4387578*T, 360.)))
268 	+0.584542*sin(M_PI_180*( 95.391654 + remainder(    0.5042615*T, 360.)));
269 }
270 
271 // The default W delivers SystemII longitude.
272 // We have to shift by GRS position and texture position.
273 // The final value will no longer be W but the rotation value required to show the GRS.
corrWJupiter(const double d,const double T)274 double RotationElements::corrWJupiter(const double d, const double T)
275 {
276 	Q_UNUSED(T)
277 	const double JDE=d+J2000;
278 	// Note that earth-bound computations of "Central Meridian, System II" do not apply here.
279 	// For comparison, see http://www.projectpluto.com/grs_form.htm
280 	// Instead we patch W_II.
281 	// https://skyandtelescope.org/observing/interactive-sky-watching-tools/transit-times-of-jupiters-great-red-spot/ writes:
282 	// These predictions assume the Red Spot was at Jovian System II longitude 349° in January 2021 and continues to drift 1.75° per month,
283 	// based on historical trends noted by JUPOS. If the GRS moves elsewhere, it will transit 1 2/3 minutes late for every 1° of longitude greater
284 	// than that used in this tool or 1 2/3 minutes early for every 1° less than the longitude in this tool.
285 	// GRS longitude was at 2014-09-08 216d with a drift of 1.25d every month
286 	// Updated 01/2021 noting LII=349 and drift 1.75 degrees/month.
287 	double longitudeGRS = (flagCustomGrsSettings ?
288 		customGrsLongitude + customGrsDrift*(JDE - customGrsJD)/365.25 :
289 		349+1.75*(JDE - 2459216.)/30.);
290 	return - longitudeGRS  +  ((187./512.)*360.-90.); // Last term is pixel position of GRS in texture, and a spherical coordinate offset for the texture.
291 	// To verify:
292 	// GRS at 2015-02-26 23:07 UT on picture at https://maximusphotography.files.wordpress.com/2015/03/jupiter-febr-26-2015.jpg
293 	//        2014-02-25 19:03 UT    http://www.damianpeach.com/jup1314/2014_02_25rgb0305.jpg
294 	//	  2013-05-01 10:29 UT    http://astro.christone.net/jupiter/jupiter2012/jupiter20130501.jpg
295 	//        2012-10-26 00:12 UT at http://www.lunar-captures.com//jupiter2012_files/121026_JupiterGRS_Tar.jpg
296 	//	  2011-08-28 02:29 UT at http://www.damianpeach.com/jup1112/2011_08_28rgb.jpg
297 }
298 
corrWNeptune(const double d,const double T)299 double RotationElements::corrWNeptune(const double d, const double T)
300 {
301 	Q_UNUSED(d) Q_UNUSED(T)
302 	return  -0.48 * sin(planetCorrections.Na);
303 }
304 
corrWPhobos(const double d,const double T)305 double RotationElements::corrWPhobos(const double d, const double T)
306 {
307 	Q_UNUSED(d) Q_UNUSED(T)
308 	return 12.72192797*T*T
309 	 +1.42421769*sin(planetCorrections.M1)
310 	 -0.02273783*sin(planetCorrections.M2)
311 	 +0.00410711*sin(planetCorrections.M3)
312 	 +0.00631964*sin(planetCorrections.M4)
313 	 -1.143     *sin(planetCorrections.M5);
314 }
315 
corrWDeimos(const double d,const double T)316 double RotationElements::corrWDeimos(const double d, const double T)
317 {
318 	Q_UNUSED(d) Q_UNUSED(T)
319 	return
320 	 -2.73954829*sin(planetCorrections.M6)
321 	 -0.39968606*sin(planetCorrections.M7)
322 	 -0.06563259*sin(planetCorrections.M8)
323 	 -0.02912940*sin(planetCorrections.M9)
324 	 +0.01699160*sin(planetCorrections.M10);
325 }
326 
corrWIo(const double d,const double T)327 double RotationElements::corrWIo(const double d, const double T)
328 {
329 	Q_UNUSED(d) Q_UNUSED(T)
330 	return (-0.085)*sin(planetCorrections.J3) - (0.022)*sin(planetCorrections.J4);
331 }
332 
corrWEuropa(const double d,const double T)333 double RotationElements::corrWEuropa(const double d, const double T)
334 {
335 	Q_UNUSED(d) Q_UNUSED(T)
336 	return (-0.980)*sin(planetCorrections.J4) - (0.054)*sin(planetCorrections.J5) - (0.014)*sin(planetCorrections.J6) - (0.008)*sin(planetCorrections.J7);
337 }
338 
corrWGanymede(const double d,const double T)339 double RotationElements::corrWGanymede(const double d, const double T)
340 {
341 	Q_UNUSED(d) Q_UNUSED(T)
342 	return (0.033)*sin(planetCorrections.J4) - (0.389)*sin(planetCorrections.J5) - (0.082)*sin(planetCorrections.J6);
343 }
344 
corrWCallisto(const double d,const double T)345 double RotationElements::corrWCallisto(const double d, const double T)
346 {
347 	Q_UNUSED(d) Q_UNUSED(T)
348 	return (0.061)*sin(planetCorrections.J5) - (0.533)*sin(planetCorrections.J6) - (0.009)*sin(planetCorrections.J8);
349 }
350 
corrWAmalthea(const double d,const double T)351 double RotationElements::corrWAmalthea(const double d, const double T)
352 {
353 	Q_UNUSED(d) Q_UNUSED(T)
354 	return (0.76)*sin(planetCorrections.J1) - (0.01)*sin(2.*planetCorrections.J1);
355 }
356 
corrWThebe(const double d,const double T)357 double RotationElements::corrWThebe(const double d, const double T)
358 {
359 	Q_UNUSED(d) Q_UNUSED(T)
360 	return (1.91)*sin(planetCorrections.J2) - (0.04)*sin(2.*planetCorrections.J2);
361 }
362 
corrWMimas(const double d,const double T)363 double RotationElements::corrWMimas(const double d, const double T)
364 {
365 	Q_UNUSED(d) Q_UNUSED(T)
366 	return (-13.48)*sin(planetCorrections.S3) - (44.85)*sin(planetCorrections.S5);
367 }
368 
corrWTethys(const double d,const double T)369 double RotationElements::corrWTethys(const double d, const double T){
370 	Q_UNUSED(d) Q_UNUSED(T)
371 	return (-9.60)*sin(planetCorrections.S4) + (2.23)*sin(planetCorrections.S5);
372 }
373 
corrWRhea(const double d,const double T)374 double RotationElements::corrWRhea(const double d, const double T)
375 {
376 	Q_UNUSED(d) Q_UNUSED(T)
377 	return (-3.08)*sin(planetCorrections.S6);
378 }
379 
corrWJanus(const double d,const double T)380 double RotationElements::corrWJanus(const double d, const double T)
381 {
382 	Q_UNUSED(d) Q_UNUSED(T)
383 	return (1.613)*sin(planetCorrections.S2) - (0.023)*sin(2.*planetCorrections.S2);
384 }
385 
corrWEpimetheus(const double d,const double T)386 double RotationElements::corrWEpimetheus(const double d, const double T)
387 {
388 	Q_UNUSED(d) Q_UNUSED(T)
389 	return 3.133 * sin(planetCorrections.S1) - (0.086)*sin(2.*planetCorrections.S1);
390 }
391 
corrWCordelia(const double d,const double T)392 double RotationElements::corrWCordelia(const double d, const double T)
393 {
394 	Q_UNUSED(d) Q_UNUSED(T)
395 	return (-0.04)*sin(planetCorrections.U1);
396 }
397 
corrWOphelia(const double d,const double T)398 double RotationElements::corrWOphelia(const double d, const double T)
399 {
400 	Q_UNUSED(d) Q_UNUSED(T)
401 	return (-0.03)*sin(planetCorrections.U2);
402 }
403 
corrWBianca(const double d,const double T)404 double RotationElements::corrWBianca(const double d, const double T)
405 {
406 	Q_UNUSED(d) Q_UNUSED(T)
407 	return (-0.04)*sin(planetCorrections.U3);
408 }
409 
corrWCressida(const double d,const double T)410 double RotationElements::corrWCressida(const double d, const double T)
411 {
412 	Q_UNUSED(d) Q_UNUSED(T)
413 	return (-0.01)*sin(planetCorrections.U4);
414 }
415 
corrWDesdemona(const double d,const double T)416 double RotationElements::corrWDesdemona(const double d, const double T)
417 {
418 	Q_UNUSED(d) Q_UNUSED(T)
419 	return -0.04 * sin(planetCorrections.U5);
420 }
421 
corrWJuliet(const double d,const double T)422 double RotationElements::corrWJuliet(const double d, const double T)
423 {
424 	Q_UNUSED(d) Q_UNUSED(T)
425 	return -0.02 * sin(planetCorrections.U6);
426 }
427 
corrWPortia(const double d,const double T)428 double RotationElements::corrWPortia(const double d, const double T)
429 {
430 	Q_UNUSED(d) Q_UNUSED(T)
431 	return -0.02 * sin(planetCorrections.U7);
432 }
433 
corrWRosalind(const double d,const double T)434 double RotationElements::corrWRosalind(const double d, const double T)
435 {
436 	Q_UNUSED(d) Q_UNUSED(T)
437 	return -0.08 * sin(planetCorrections.U8);
438 }
439 
corrWBelinda(const double d,const double T)440 double RotationElements::corrWBelinda(const double d, const double T)
441 {
442 	Q_UNUSED(d) Q_UNUSED(T)
443 	return -0.01 * sin(planetCorrections.U9);
444 }
445 
corrWPuck(const double d,const double T)446 double RotationElements::corrWPuck(const double d, const double T)
447 {
448 	Q_UNUSED(d) Q_UNUSED(T)
449 	return -0.09 * sin(planetCorrections.U10);
450 }
451 
corrWAriel(const double d,const double T)452 double RotationElements::corrWAriel(const double d, const double T)
453 {
454 	Q_UNUSED(d) Q_UNUSED(T)
455 	return 0.05 * sin(planetCorrections.U12) + 0.08 * sin(planetCorrections.U13);
456 }
457 
corrWUmbriel(const double d,const double T)458 double RotationElements::corrWUmbriel(const double d, const double T)
459 {
460 	Q_UNUSED(d) Q_UNUSED(T)
461 	return -0.09 * sin(planetCorrections.U12) + 0.06 * sin(planetCorrections.U14);
462 }
463 
corrWTitania(const double d,const double T)464 double RotationElements::corrWTitania(const double d, const double T)
465 {
466 	Q_UNUSED(d) Q_UNUSED(T)
467 	return 0.08 * sin(planetCorrections.U15);
468 }
469 
corrWOberon(const double d,const double T)470 double RotationElements::corrWOberon(const double d, const double T)
471 {
472 	Q_UNUSED(d) Q_UNUSED(T)
473 	return 0.04 * sin(planetCorrections.U16);
474 }
475 
corrWMiranda(const double d,const double T)476 double RotationElements::corrWMiranda(const double d, const double T)
477 {
478 	Q_UNUSED(d) Q_UNUSED(T)
479 	return   -1.27 * sin(planetCorrections.U12) + 0.15 * sin(2.*planetCorrections.U12)
480 		+ 1.15 * sin(planetCorrections.U11) - 0.09 * sin(2.*planetCorrections.U11);
481 }
482 
corrWTriton(const double d,const double T)483 double RotationElements::corrWTriton(const double d, const double T)
484 {
485 	Q_UNUSED(d) Q_UNUSED(T)
486 	return   22.25 * sin(   planetCorrections.N7) + 6.73 * sin(2.*planetCorrections.N7)
487 		+ 2.05 * sin(3.*planetCorrections.N7) + 0.74 * sin(4.*planetCorrections.N7)
488 		+ 0.28 * sin(5.*planetCorrections.N7) + 0.11 * sin(6.*planetCorrections.N7)
489 		+ 0.05 * sin(7.*planetCorrections.N7) + 0.02 * sin(8.*planetCorrections.N7)
490 		+ 0.01 * sin(9.*planetCorrections.N7);
491 }
492 
corrWNaiad(const double d,const double T)493 double RotationElements::corrWNaiad(const double d, const double T)
494 {
495 	Q_UNUSED(d) Q_UNUSED(T)
496 	return (-0.48)*sin(planetCorrections.Na) + (4.40)*sin(planetCorrections.N1) - (0.27)*sin(2.*planetCorrections.N1);
497 }
498 
corrWThalassa(const double d,const double T)499 double RotationElements::corrWThalassa(const double d, const double T)
500 {
501 	Q_UNUSED(d) Q_UNUSED(T)
502 	return (-0.48)*sin(planetCorrections.Na) + (0.19)*sin(planetCorrections.N2);
503 }
504 
corrWDespina(const double d,const double T)505 double RotationElements::corrWDespina(const double d, const double T)
506 {
507 	Q_UNUSED(d) Q_UNUSED(T)
508 	return (-0.49)*sin(planetCorrections.Na) + (0.06)*sin(planetCorrections.N3);
509 }
510 
corrWGalatea(const double d,const double T)511 double RotationElements::corrWGalatea(const double d, const double T)
512 {
513 	Q_UNUSED(d) Q_UNUSED(T)
514 	return (-0.48)*sin(planetCorrections.Na) + (0.05)*sin(planetCorrections.N4);
515 }
516 
corrWLarissa(const double d,const double T)517 double RotationElements::corrWLarissa(const double d, const double T)
518 {
519 	Q_UNUSED(d) Q_UNUSED(T)
520 	return (-0.48)*sin(planetCorrections.Na) + (0.19)*sin(planetCorrections.N5);
521 }
522 
corrWProteus(const double d,const double T)523 double RotationElements::corrWProteus(const double d, const double T)
524 {
525 	Q_UNUSED(d) Q_UNUSED(T)
526 	return (-0.48)*sin(planetCorrections.Na) + (0.04)*sin(planetCorrections.N6);
527 }
528 
corrOriMoon(const double d,const double T,double * J2000NPoleRA,double * J2000NPoleDE)529 void RotationElements::corrOriMoon(const double d, const double T, double* J2000NPoleRA, double* J2000NPoleDE)
530 {
531 	// This is from WGCCRE2009.
532 	Q_UNUSED(d) Q_UNUSED(T)
533 	*J2000NPoleRA += - (3.8787*M_PI_180)*sin(planetCorrections.E1)  - (0.1204*M_PI_180)*sin(planetCorrections.E2) + (0.0700*M_PI_180)*sin(planetCorrections.E3)
534 			- (0.0172*M_PI_180)*sin(planetCorrections.E4)  + (0.0072*M_PI_180)*sin(planetCorrections.E6) - (0.0052*M_PI_180)*sin(planetCorrections.E10)
535 			+ (0.0043*M_PI_180)*sin(planetCorrections.E13);
536 	*J2000NPoleDE += + (1.5419*M_PI_180)*cos(planetCorrections.E1)  + (0.0239*M_PI_180)*cos(planetCorrections.E2) - (0.0278*M_PI_180)*cos(planetCorrections.E3)
537 			+ (0.0068*M_PI_180)*cos(planetCorrections.E4)  - (0.0029*M_PI_180)*cos(planetCorrections.E6) + (0.0009*M_PI_180)*cos(planetCorrections.E7)
538 			+ (0.0008*M_PI_180)*cos(planetCorrections.E10) - (0.0009*M_PI_180)*cos(planetCorrections.E13);
539 }
540 
corrOriMars(const double d,const double T,double * J2000NPoleRA,double * J2000NPoleDE)541 void RotationElements::corrOriMars(const double d, const double T, double* J2000NPoleRA, double* J2000NPoleDE)
542 {
543 	Q_UNUSED(d)
544 	*J2000NPoleRA+=	 (0.000068*M_PI_180)*sin(M_PI_180*(198.991226+remainder(19139.4819985*T, 360.)))
545 			+(0.000238*M_PI_180)*sin(M_PI_180*(226.292679+remainder(38280.8511281*T, 360.)))
546 			+(0.000052*M_PI_180)*sin(M_PI_180*(249.663391+remainder(57420.7251593*T, 360.)))
547 			+(0.000009*M_PI_180)*sin(M_PI_180*(266.183510+remainder(76560.6367950*T, 360.)))
548 			+(0.419057*M_PI_180)*sin(M_PI_180*( 79.398797+remainder(    0.5042615*T, 360.)));
549 	*J2000NPoleDE+=	 (0.000051*M_PI_180)*cos(M_PI_180*(122.433576+remainder(19139.9407476*T, 360.)))
550 			+(0.000141*M_PI_180)*cos(M_PI_180*( 43.058401+remainder(38280.8753272*T, 360.)))
551 			+(0.000031*M_PI_180)*cos(M_PI_180*( 57.663379+remainder(57420.7517205*T, 360.)))
552 			-(0.000005*M_PI_180)*cos(M_PI_180*( 79.476401+remainder(76560.6495004*T, 360.)))
553 			+(1.591274*M_PI_180)*cos(M_PI_180*(166.325722+remainder(    0.5042615*T, 360.)));
554 }
555 
corrOriJupiter(const double d,const double T,double * J2000NPoleRA,double * J2000NPoleDE)556 void RotationElements::corrOriJupiter(const double d, const double T, double* J2000NPoleRA, double* J2000NPoleDE)
557 {
558 	Q_UNUSED(d) Q_UNUSED(T)
559 	*J2000NPoleRA+=	 (0.000117*M_PI_180)*sin(planetCorrections.Ja)
560 			+(0.000938*M_PI_180)*sin(planetCorrections.Jb)
561 			+(0.001432*M_PI_180)*sin(planetCorrections.Jc)
562 			+(0.000030*M_PI_180)*sin(planetCorrections.Jd)
563 			+(0.002150*M_PI_180)*sin(planetCorrections.Je);
564 	*J2000NPoleDE+=	 (0.000050*M_PI_180)*cos(planetCorrections.Ja)
565 			+(0.000404*M_PI_180)*cos(planetCorrections.Jb)
566 			+(0.000617*M_PI_180)*cos(planetCorrections.Jc)
567 			-(0.000013*M_PI_180)*cos(planetCorrections.Jd)
568 			+(0.000926*M_PI_180)*cos(planetCorrections.Je);
569 }
570 
corrOriNeptune(const double d,const double T,double * J2000NPoleRA,double * J2000NPoleDE)571 void RotationElements::corrOriNeptune(const double d, const double T, double* J2000NPoleRA, double* J2000NPoleDE)
572 {
573 	Q_UNUSED(d) Q_UNUSED(T)
574 	*J2000NPoleRA+= (0.7 *M_PI_180)*sin(planetCorrections.Na);
575 	*J2000NPoleDE-= (0.51*M_PI_180)*cos(planetCorrections.Na);
576 }
577 
corrOriPhobos(const double d,const double T,double * J2000NPoleRA,double * J2000NPoleDE)578 void RotationElements::corrOriPhobos(const double d, const double T, double* J2000NPoleRA, double* J2000NPoleDE)
579 {
580 	Q_UNUSED(d) Q_UNUSED(T)
581 	*J2000NPoleRA+=
582 			+(-1.78428399*M_PI_180)*sin(planetCorrections.M1)
583 			+(+0.02212824*M_PI_180)*sin(planetCorrections.M2)
584 			+(-0.01028251*M_PI_180)*sin(planetCorrections.M3)
585 			+(-0.00475595*M_PI_180)*sin(planetCorrections.M4);
586 	*J2000NPoleDE+=
587 			+(-1.07516537*M_PI_180)*cos(planetCorrections.M1)
588 			+(+0.00668626*M_PI_180)*cos(planetCorrections.M2)
589 			+(-0.00648740*M_PI_180)*cos(planetCorrections.M3)
590 			+(+0.00281576*M_PI_180)*cos(planetCorrections.M4);
591 }
592 
corrOriDeimos(const double d,const double T,double * J2000NPoleRA,double * J2000NPoleDE)593 void RotationElements::corrOriDeimos(const double d, const double T, double* J2000NPoleRA, double* J2000NPoleDE)
594 {
595 	Q_UNUSED(d) Q_UNUSED(T)
596 	*J2000NPoleRA+=   (3.09217726*M_PI_180)*sin(planetCorrections.M6)
597 			+(0.22980637*M_PI_180)*sin(planetCorrections.M7)
598 			+(0.06418655*M_PI_180)*sin(planetCorrections.M8)
599 			+(0.02533537*M_PI_180)*sin(planetCorrections.M9)
600 			+(0.00778695*M_PI_180)*sin(planetCorrections.M10);
601 
602 	*J2000NPoleDE-=   (1.83936004*M_PI_180)*cos(planetCorrections.M6)
603 			+(0.14325320*M_PI_180)*cos(planetCorrections.M7)
604 			+(0.01911409*M_PI_180)*cos(planetCorrections.M8)
605 			-(0.01482590*M_PI_180)*cos(planetCorrections.M9)
606 			+(0.00192430*M_PI_180)*cos(planetCorrections.M10);
607 }
608 
corrOriIo(const double d,const double T,double * J2000NPoleRA,double * J2000NPoleDE)609 void RotationElements::corrOriIo(const double d, const double T, double* J2000NPoleRA, double* J2000NPoleDE)
610 {
611 	Q_UNUSED(d) Q_UNUSED(T)
612 	*J2000NPoleRA+=(M_PI_180*0.094)*sin(planetCorrections.J3) + (M_PI_180*0.024)*sin(planetCorrections.J4);
613 	*J2000NPoleDE+=(M_PI_180*0.040)*cos(planetCorrections.J3) + (M_PI_180*0.011)*cos(planetCorrections.J4);
614 }
615 
corrOriEuropa(const double d,const double T,double * J2000NPoleRA,double * J2000NPoleDE)616 void RotationElements::corrOriEuropa(const double d, const double T, double* J2000NPoleRA, double* J2000NPoleDE)
617 {
618 	Q_UNUSED(d) Q_UNUSED(T)
619 	*J2000NPoleRA+=(M_PI_180*1.086)*sin(planetCorrections.J4) + (M_PI_180*0.060)*sin(planetCorrections.J5) + (M_PI_180*0.015)*sin(planetCorrections.J6) + (M_PI_180*0.009)*sin(planetCorrections.J7);
620 	*J2000NPoleDE+=(M_PI_180*0.468)*cos(planetCorrections.J4) + (M_PI_180*0.026)*cos(planetCorrections.J5) + (M_PI_180*0.007)*cos(planetCorrections.J6) + (M_PI_180*0.002)*cos(planetCorrections.J7);
621 }
622 
corrOriGanymede(const double d,const double T,double * J2000NPoleRA,double * J2000NPoleDE)623 void RotationElements::corrOriGanymede(const double d, const double T, double* J2000NPoleRA, double* J2000NPoleDE)
624 {
625 	Q_UNUSED(d) Q_UNUSED(T)
626 	*J2000NPoleRA+=(M_PI_180*-.037)*sin(planetCorrections.J4) + (M_PI_180*0.431)*sin(planetCorrections.J5) + (M_PI_180*0.091)*sin(planetCorrections.J6);
627 	*J2000NPoleDE+=(M_PI_180*-.016)*cos(planetCorrections.J4) + (M_PI_180*0.186)*cos(planetCorrections.J5) + (M_PI_180*0.039)*cos(planetCorrections.J6);
628 }
629 
corrOriCallisto(const double d,const double T,double * J2000NPoleRA,double * J2000NPoleDE)630 void RotationElements::corrOriCallisto(const double d, const double T, double* J2000NPoleRA, double* J2000NPoleDE)
631 {
632 	Q_UNUSED(d) Q_UNUSED(T)
633 	*J2000NPoleRA+=(M_PI_180*-.068)*sin(planetCorrections.J5) + (M_PI_180*0.590)*sin(planetCorrections.J6) + (M_PI_180*0.010)*sin(planetCorrections.J8);
634 	*J2000NPoleDE+=(M_PI_180*-.029)*cos(planetCorrections.J5) + (M_PI_180*0.254)*cos(planetCorrections.J6) - (M_PI_180*0.004)*cos(planetCorrections.J8);
635 }
636 
corrOriAmalthea(const double d,const double T,double * J2000NPoleRA,double * J2000NPoleDE)637 void RotationElements::corrOriAmalthea(const double d, const double T, double* J2000NPoleRA, double* J2000NPoleDE)
638 {
639 	Q_UNUSED(d) Q_UNUSED(T)
640 	*J2000NPoleRA+=(M_PI_180*0.01)*sin(2.*planetCorrections.J1) - (M_PI_180*0.84)*sin(planetCorrections.J1);
641 	*J2000NPoleDE-=(M_PI_180*0.36)*cos(planetCorrections.J1);
642 }
643 
corrOriThebe(const double d,const double T,double * J2000NPoleRA,double * J2000NPoleDE)644 void RotationElements::corrOriThebe(const double d, const double T, double* J2000NPoleRA, double* J2000NPoleDE)
645 {
646 	Q_UNUSED(d) Q_UNUSED(T)
647 	*J2000NPoleRA+=(M_PI_180*-2.11)*sin(planetCorrections.J2) + (M_PI_180*0.04)*sin(2.*planetCorrections.J2);
648 	*J2000NPoleDE+=(M_PI_180*-0.91)*cos(planetCorrections.J2) + (M_PI_180*0.01)*cos(2.*planetCorrections.J2);
649 }
650 
corrOriMimas(const double d,const double T,double * J2000NPoleRA,double * J2000NPoleDE)651 void RotationElements::corrOriMimas(const double d, const double T, double* J2000NPoleRA, double* J2000NPoleDE)
652 {
653 	Q_UNUSED(d) Q_UNUSED(T)
654 	*J2000NPoleRA+=(M_PI_180*13.56)*sin(planetCorrections.S3);
655 	*J2000NPoleDE+=(M_PI_180*-1.53)*cos(planetCorrections.S3);
656 }
657 
corrOriTethys(const double d,const double T,double * J2000NPoleRA,double * J2000NPoleDE)658 void RotationElements::corrOriTethys(const double d, const double T, double* J2000NPoleRA, double* J2000NPoleDE)
659 {
660 	Q_UNUSED(d) Q_UNUSED(T)
661 	*J2000NPoleRA+=(M_PI_180* 9.66)*sin(planetCorrections.S4);
662 	*J2000NPoleDE+=(M_PI_180*-1.09)*cos(planetCorrections.S4);
663 }
664 
corrOriRhea(const double d,const double T,double * J2000NPoleRA,double * J2000NPoleDE)665 void RotationElements::corrOriRhea(const double d, const double T, double* J2000NPoleRA, double* J2000NPoleDE)
666 {
667 	Q_UNUSED(d) Q_UNUSED(T)
668 	*J2000NPoleRA+=(M_PI/180.* 3.10)*sin(planetCorrections.S6);
669 	*J2000NPoleDE+=(M_PI/180.*-0.35)*cos(planetCorrections.S6);
670 }
671 
corrOriJanus(const double d,const double T,double * J2000NPoleRA,double * J2000NPoleDE)672 void RotationElements::corrOriJanus(const double d, const double T, double* J2000NPoleRA, double* J2000NPoleDE)
673 {
674 	Q_UNUSED(d) Q_UNUSED(T)
675 	*J2000NPoleRA+=(M_PI_180*0.023)*sin(2.*planetCorrections.S2)-(M_PI_180*1.623)*sin(planetCorrections.S2);
676 	*J2000NPoleDE+=(M_PI_180*0.001)*cos(2.*planetCorrections.S2)-(M_PI_180*0.183)*cos(planetCorrections.S2);
677 }
678 
corrOriEpimetheus(const double d,const double T,double * J2000NPoleRA,double * J2000NPoleDE)679 void RotationElements::corrOriEpimetheus(const double d, const double T, double* J2000NPoleRA, double* J2000NPoleDE)
680 {
681 	Q_UNUSED(d) Q_UNUSED(T)
682 	*J2000NPoleRA+=(M_PI_180*0.086)*sin(2.*planetCorrections.S1)-(M_PI_180*3.153)*sin(planetCorrections.S1);
683 	*J2000NPoleDE+=(M_PI_180*0.005)*cos(2.*planetCorrections.S1)-(M_PI_180*0.356)*cos(planetCorrections.S1);
684 }
685 
corrOriAriel(const double d,const double T,double * J2000NPoleRA,double * J2000NPoleDE)686 void RotationElements::corrOriAriel(const double d, const double T, double* J2000NPoleRA, double* J2000NPoleDE)
687 {
688 	Q_UNUSED(d) Q_UNUSED(T)
689 	*J2000NPoleRA+=(M_PI_180* 0.29)*sin(planetCorrections.U13);
690 	*J2000NPoleDE+=(M_PI_180* 0.28)*cos(planetCorrections.U13);
691 }
692 
corrOriUmbriel(const double d,const double T,double * J2000NPoleRA,double * J2000NPoleDE)693 void RotationElements::corrOriUmbriel(const double d, const double T, double* J2000NPoleRA, double* J2000NPoleDE)
694 {
695 	Q_UNUSED(d) Q_UNUSED(T)
696 	*J2000NPoleRA+=(M_PI_180* 0.21)*sin(planetCorrections.U14);
697 	*J2000NPoleDE+=(M_PI_180* 0.2 )*cos(planetCorrections.U14);
698 }
699 
corrOriTitania(const double d,const double T,double * J2000NPoleRA,double * J2000NPoleDE)700 void RotationElements::corrOriTitania(const double d, const double T, double* J2000NPoleRA, double* J2000NPoleDE)
701 {
702 	Q_UNUSED(d) Q_UNUSED(T)
703 	*J2000NPoleRA+=(M_PI_180* 0.29)*sin(planetCorrections.U15);
704 	*J2000NPoleDE+=(M_PI_180* 0.28)*cos(planetCorrections.U15);
705 }
706 
corrOriOberon(const double d,const double T,double * J2000NPoleRA,double * J2000NPoleDE)707 void RotationElements::corrOriOberon(const double d, const double T, double* J2000NPoleRA, double* J2000NPoleDE)
708 {
709 	Q_UNUSED(d) Q_UNUSED(T)
710 	*J2000NPoleRA+=(M_PI_180* 0.16)*sin(planetCorrections.U16);
711 	*J2000NPoleDE+=(M_PI_180* 0.16)*cos(planetCorrections.U16);
712 }
713 
corrOriMiranda(const double d,const double T,double * J2000NPoleRA,double * J2000NPoleDE)714 void RotationElements::corrOriMiranda(const double d, const double T, double* J2000NPoleRA, double* J2000NPoleDE)
715 {
716 	Q_UNUSED(d) Q_UNUSED(T)
717 	*J2000NPoleRA+=(M_PI_180* 4.41)*sin(planetCorrections.U11) - (M_PI_180* 0.04)*sin(2.*planetCorrections.U11);
718 	*J2000NPoleDE+=(M_PI_180* 4.25)*cos(planetCorrections.U11) - (M_PI_180* 0.02)*cos(2.*planetCorrections.U11);
719 }
720 
corrOriCordelia(const double d,const double T,double * J2000NPoleRA,double * J2000NPoleDE)721 void RotationElements::corrOriCordelia(const double d, const double T, double* J2000NPoleRA, double* J2000NPoleDE)
722 {
723 	Q_UNUSED(d) Q_UNUSED(T)
724 	*J2000NPoleRA+=(M_PI_180*-0.15)*sin(planetCorrections.U1);
725 	*J2000NPoleDE+=(M_PI_180* 0.14)*cos(planetCorrections.U1);
726 }
727 
corrOriOphelia(const double d,const double T,double * J2000NPoleRA,double * J2000NPoleDE)728 void RotationElements::corrOriOphelia(const double d, const double T, double* J2000NPoleRA, double* J2000NPoleDE)
729 {
730 	Q_UNUSED(d) Q_UNUSED(T)
731 	*J2000NPoleRA+=(M_PI_180*-0.09)*sin(planetCorrections.U2);
732 	*J2000NPoleDE+=(M_PI_180* 0.09)*cos(planetCorrections.U2);
733 }
734 
corrOriBianca(const double d,const double T,double * J2000NPoleRA,double * J2000NPoleDE)735 void RotationElements::corrOriBianca(const double d, const double T, double* J2000NPoleRA, double* J2000NPoleDE)
736 {
737 	Q_UNUSED(d) Q_UNUSED(T)
738 	*J2000NPoleRA+=(M_PI_180*-0.16)*sin(planetCorrections.U3);
739 	*J2000NPoleDE+=(M_PI_180* 0.16)*cos(planetCorrections.U3);
740 }
741 
corrOriCressida(const double d,const double T,double * J2000NPoleRA,double * J2000NPoleDE)742 void RotationElements::corrOriCressida(const double d, const double T, double* J2000NPoleRA, double* J2000NPoleDE)
743 {
744 	Q_UNUSED(d) Q_UNUSED(T)
745 	*J2000NPoleRA+=(M_PI_180*-0.04)*sin(planetCorrections.U4);
746 	*J2000NPoleDE+=(M_PI_180* 0.04)*cos(planetCorrections.U4);
747 }
748 
corrOriDesdemona(const double d,const double T,double * J2000NPoleRA,double * J2000NPoleDE)749 void RotationElements::corrOriDesdemona(const double d, const double T, double* J2000NPoleRA, double* J2000NPoleDE)
750 {
751 	Q_UNUSED(d) Q_UNUSED(T)
752 	*J2000NPoleRA+=(M_PI_180*-0.17)*sin(planetCorrections.U5);
753 	*J2000NPoleDE+=(M_PI_180* 0.16)*cos(planetCorrections.U5);
754 }
755 
corrOriJuliet(const double d,const double T,double * J2000NPoleRA,double * J2000NPoleDE)756 void RotationElements::corrOriJuliet(const double d, const double T, double* J2000NPoleRA, double* J2000NPoleDE)
757 {
758 	Q_UNUSED(d) Q_UNUSED(T)
759 	*J2000NPoleRA+=(M_PI_180*-0.06)*sin(planetCorrections.U6);
760 	*J2000NPoleDE+=(M_PI_180* 0.06)*cos(planetCorrections.U6);
761 }
762 
corrOriPortia(const double d,const double T,double * J2000NPoleRA,double * J2000NPoleDE)763 void RotationElements::corrOriPortia(const double d, const double T, double* J2000NPoleRA, double* J2000NPoleDE)
764 {
765 	Q_UNUSED(d) Q_UNUSED(T)
766 	*J2000NPoleRA+=(M_PI_180*-0.09)*sin(planetCorrections.U7);
767 	*J2000NPoleDE+=(M_PI_180* 0.09)*cos(planetCorrections.U7);
768 }
769 
corrOriRosalind(const double d,const double T,double * J2000NPoleRA,double * J2000NPoleDE)770 void RotationElements::corrOriRosalind(const double d, const double T, double* J2000NPoleRA, double* J2000NPoleDE)
771 {
772 	Q_UNUSED(d) Q_UNUSED(T)
773 	*J2000NPoleRA+=(M_PI_180*-0.29)*sin(planetCorrections.U8);
774 	*J2000NPoleDE+=(M_PI_180* 0.28)*cos(planetCorrections.U8);
775 }
776 
corrOriBelinda(const double d,const double T,double * J2000NPoleRA,double * J2000NPoleDE)777 void RotationElements::corrOriBelinda(const double d, const double T, double* J2000NPoleRA, double* J2000NPoleDE)
778 {
779 	Q_UNUSED(d) Q_UNUSED(T)
780 	*J2000NPoleRA+=(M_PI_180*-0.03)*sin(planetCorrections.U9);
781 	*J2000NPoleDE+=(M_PI_180* 0.03)*cos(planetCorrections.U9);
782 }
783 
corrOriPuck(const double d,const double T,double * J2000NPoleRA,double * J2000NPoleDE)784 void RotationElements::corrOriPuck(const double d, const double T, double* J2000NPoleRA, double* J2000NPoleDE)
785 {
786 	Q_UNUSED(d) Q_UNUSED(T)
787 	*J2000NPoleRA+=(M_PI_180*-0.33)*sin(planetCorrections.U10);
788 	*J2000NPoleDE+=(M_PI_180* 0.31)*cos(planetCorrections.U10);
789 }
790 
corrOriTriton(const double d,const double T,double * J2000NPoleRA,double * J2000NPoleDE)791 void RotationElements::corrOriTriton(const double d, const double T, double* J2000NPoleRA, double* J2000NPoleDE)
792 {
793 	Q_UNUSED(d) Q_UNUSED(T)
794 	*J2000NPoleRA+=    (M_PI_180*-32.35)*sin(planetCorrections.N7)  - (M_PI_180*6.28)*sin(2.*planetCorrections.N7)
795 			- (M_PI_180*2.08)*sin(3.*planetCorrections.N7) - (M_PI_180*0.74)*sin(4.*planetCorrections.N7)
796 			- (M_PI_180*0.28)*sin(5.*planetCorrections.N7) - (M_PI_180*0.11)*sin(6.*planetCorrections.N7)
797 			- (M_PI_180*0.07)*sin(7.*planetCorrections.N7) - (M_PI_180*0.02)*sin(8.*planetCorrections.N7)
798 			- (M_PI_180*0.01)*sin(9.*planetCorrections.N7);
799 	*J2000NPoleDE+=    (M_PI_180* 22.55)*cos(planetCorrections.N7)  + (M_PI_180*2.10)*cos(2.*planetCorrections.N7)
800 			+ (M_PI_180*0.55)*cos(3.*planetCorrections.N7) + (M_PI_180*0.16)*cos(4.*planetCorrections.N7)
801 			+ (M_PI_180*0.05)*cos(5.*planetCorrections.N7) + (M_PI_180*0.02)*cos(6.*planetCorrections.N7)
802 			+ (M_PI_180*0.01)*cos(7.*planetCorrections.N7);
803 }
804 
corrOriNaiad(const double d,const double T,double * J2000NPoleRA,double * J2000NPoleDE)805 void RotationElements::corrOriNaiad(const double d, const double T, double* J2000NPoleRA, double* J2000NPoleDE)
806 {
807 	Q_UNUSED(d) Q_UNUSED(T)
808 	*J2000NPoleRA+=(M_PI_180* 0.70)*sin(planetCorrections.Na) - (M_PI_180* 6.49)*sin(planetCorrections.N1) + (M_PI_180* 0.25)*sin(2.*planetCorrections.N1);
809 	*J2000NPoleDE+=(M_PI_180*-0.51)*cos(planetCorrections.Na) - (M_PI_180* 4.75)*cos(planetCorrections.N1) + (M_PI_180* 0.09)*cos(2.*planetCorrections.N1);
810 }
811 
corrOriThalassa(const double d,const double T,double * J2000NPoleRA,double * J2000NPoleDE)812 void RotationElements::corrOriThalassa(const double d, const double T, double* J2000NPoleRA, double* J2000NPoleDE)
813 {
814 	Q_UNUSED(d) Q_UNUSED(T)
815 	*J2000NPoleRA+=(M_PI_180* 0.70)*sin(planetCorrections.Na) - (M_PI_180* 0.28)*sin(planetCorrections.N2);
816 	*J2000NPoleDE+=(M_PI_180*-0.51)*cos(planetCorrections.Na) - (M_PI_180* 0.21)*cos(planetCorrections.N2);
817 }
818 
corrOriDespina(const double d,const double T,double * J2000NPoleRA,double * J2000NPoleDE)819 void RotationElements::corrOriDespina(const double d, const double T, double* J2000NPoleRA, double* J2000NPoleDE)
820 {
821 	Q_UNUSED(d) Q_UNUSED(T)
822 	*J2000NPoleRA+=(M_PI_180* 0.70)*sin(planetCorrections.Na) - (M_PI_180* 0.09)*sin(planetCorrections.N3);
823 	*J2000NPoleDE+=(M_PI_180*-0.51)*cos(planetCorrections.Na) - (M_PI_180* 0.07)*cos(planetCorrections.N3);
824 }
825 
corrOriGalatea(const double d,const double T,double * J2000NPoleRA,double * J2000NPoleDE)826 void RotationElements::corrOriGalatea(const double d, const double T, double* J2000NPoleRA, double* J2000NPoleDE)
827 {
828 	Q_UNUSED(d) Q_UNUSED(T)
829 	*J2000NPoleRA+=(M_PI_180* 0.70)*sin(planetCorrections.Na) - (M_PI_180* 0.07)*sin(planetCorrections.N4);
830 	*J2000NPoleDE+=(M_PI_180*-0.51)*cos(planetCorrections.Na) - (M_PI_180* 0.05)*cos(planetCorrections.N4);
831 }
832 
corrOriLarissa(const double d,const double T,double * J2000NPoleRA,double * J2000NPoleDE)833 void RotationElements::corrOriLarissa(const double d, const double T, double* J2000NPoleRA, double* J2000NPoleDE)
834 {
835 	Q_UNUSED(d) Q_UNUSED(T)
836 	*J2000NPoleRA+=(M_PI_180* 0.70)*sin(planetCorrections.Na) - (M_PI_180* 0.27)*sin(planetCorrections.N5);
837 	*J2000NPoleDE+=(M_PI_180*-0.51)*cos(planetCorrections.Na) - (M_PI_180* 0.20)*cos(planetCorrections.N5);
838 }
839 
corrOriProteus(const double d,const double T,double * J2000NPoleRA,double * J2000NPoleDE)840 void RotationElements::corrOriProteus(const double d, const double T, double* J2000NPoleRA, double* J2000NPoleDE)
841 {
842 	Q_UNUSED(d) Q_UNUSED(T)
843 	*J2000NPoleRA+=(M_PI_180* 0.70)*sin(planetCorrections.Na) - (M_PI_180* 0.05)*sin(planetCorrections.N6);
844 	*J2000NPoleDE+=(M_PI_180*-0.51)*cos(planetCorrections.Na) - (M_PI_180* 0.04)*cos(planetCorrections.N6);
845 }
846 
847 const QList<Vec3d> RotationElements::marsMagLs =
848 {
849 	{ -20.0,  0.024, -0.030},
850 	{ -10.0,  0.034, -0.017},
851 	{   0.0,  0.036, -0.029},
852 	{  10.0,  0.045, -0.017},
853 	{  20.0,  0.038, -0.014},
854 	{  30.0,  0.023, -0.006},
855 	{  40.0,  0.015, -0.018},
856 	{  50.0,  0.011, -0.020},
857 	{  60.0,  0.000, -0.014},
858 	{  70.0, -0.012, -0.030},
859 	{  80.0, -0.018, -0.008},
860 	{  90.0, -0.036, -0.040},
861 	{ 100.0, -0.044, -0.024},
862 	{ 110.0, -0.059, -0.037},
863 	{ 120.0, -0.060, -0.036},
864 	{ 130.0, -0.055, -0.032},
865 	{ 140.0, -0.043,  0.010},
866 	{ 150.0, -0.041,  0.010},
867 	{ 160.0, -0.041, -0.001},
868 	{ 170.0, -0.036,  0.044},
869 	{ 180.0, -0.036,  0.025},
870 	{ 190.0, -0.018, -0.004},
871 	{ 200.0, -0.038, -0.016},
872 	{ 210.0, -0.011, -0.008},
873 	{ 220.0,  0.002,  0.029},
874 	{ 230.0,  0.004, -0.054},
875 	{ 240.0,  0.018,  0.0  },
876 	{ 250.0,  0.019,  0.055},
877 	{ 260.0,  0.035,  0.017},
878 	{ 270.0,  0.050,  0.052},
879 	{ 280.0,  0.035,  0.006},
880 	{ 290.0,  0.027,  0.087},
881 	{ 300.0,  0.037,  0.006},
882 	{ 310.0,  0.048,  0.064},
883 	{ 320.0,  0.025,  0.030},
884 	{ 330.0,  0.022,  0.019},
885 	{ 340.0,  0.024, -0.030},
886 	{ 350.0,  0.034, -0.017},
887 	{ 360.0,  0.036, -0.029},
888 	{ 370.0,  0.045, -0.017},
889 	{ 380.0,  0.038, -0.014}};
890 
891 // Retrieve magnitude variation depending on angle Ls [radians].
892 // Source: A. Mallama: The magnitude and albedo of Mars. Icarus 192(2007) 404-416.
893 // @arg albedo true  to return longitudinal albedo correction, the average of sub-earth and sub-solar planetographic longitudes
894 //             false for the Orbital Longitude correction
895 
896 // Orbital Longitude: In the context given by Mallama 2007, this defines the position of the Sun along the planet's "ecliptic", counted from the vernal equinox of Mars.
897 // Stellarium does not provide this number directly, however we have in the old rotation elements ascending node and obliquity.
898 // The ascending node is that of the Mars equator over the ecliptic of J2000.0 given as node=82.91 degrees. When the sun is there, it moves from the northern to the southern hemisphere of Mars.
899 // That means, if Mars is at heliocentric l=82.91°, the sun is crossing northwards, i.e. this is where Ls=0. Therefore Ls= (l-node) mod 2pi.
getMarsMagLs(const double Ls,const bool albedo)900 double RotationElements::getMarsMagLs(const double Ls, const bool albedo)
901 {
902 	const double l=StelUtils::fmodpos(Ls, 2.0*M_PI) * M_180_PI; // longitude in degrees [0...360]
903 	int pos=std::lround(std::floor(l/10.))+2; // index of central value for 5-point Spline interpolation
904 	Q_ASSERT(pos>=2);
905 	Q_ASSERT(pos<38);
906 	double n=(l-marsMagLs.at(pos)[0]) / 10.0;
907 	Q_ASSERT(abs(n)<1.);
908 	if (albedo)
909 		return StelUtils::interpolate5(n, marsMagLs.at(pos-2)[1], marsMagLs.at(pos-1)[1], marsMagLs.at(pos)[1], marsMagLs.at(pos+1)[1], marsMagLs.at(pos+2)[1]);
910 	else
911 		return StelUtils::interpolate5(n, marsMagLs.at(pos-2)[2], marsMagLs.at(pos-1)[2], marsMagLs.at(pos)[2], marsMagLs.at(pos+1)[2], marsMagLs.at(pos+2)[2]);
912 }
913