Merge lp:~i-martividal/stellarium/Observability-1.0.2 into lp:stellarium
- Observability-1.0.2
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Alexander Wolf |
Approved revision: | no longer in the source branch. |
Merged at revision: | 5535 |
Proposed branch: | lp:~i-martividal/stellarium/Observability-1.0.2 |
Merge into: | lp:stellarium |
Diff against target: |
1079 lines (+445/-249) 4 files modified
plugins/Observability/src/Observability.cpp (+420/-238) plugins/Observability/src/Observability.hpp (+21/-7) plugins/Observability/src/gui/ObservabilityDialog.cpp (+3/-3) plugins/Observability/src/gui/ObservabilityDialog.ui (+1/-1) |
To merge this branch: | bzr merge lp:~i-martividal/stellarium/Observability-1.0.2 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Alexander Wolf | Approve | ||
gzotti | Approve | ||
Review via email: mp+119999@code.launchpad.net |
Commit message
Description of the change
Dear all,
Here you have a new revision of the Observability plugin. The FIXME issues found by Alexander are solved, and the rise/set/transit times for the planets are now more accurate. I've also solved a few bugs (one more important regarding the dates of Full Moon, since the Secant method could jump to other months, even centuries before the present dates).
The names of the months are again in their compact form, although you can of course change it to your taste (this compact nomenclature is indeed also recognized by the IAU).
I'll answer and comment on the good suggestions made in the pubdevel list in a forthcoming e-mail (as soon as the kid is finally asleep in the bed :S).
Best Wishes,
Ivan
gzotti (georg-zotti) wrote : | # |
Oops, sorry: I updated&rebuilt your first Observability branch! Too many branches out there...
Must check new download.
G.
gzotti (georg-zotti) wrote : | # |
OK, the two latter points are still here. But maybe only for the next version.
G.
Alexander Wolf (alexwolf) : | # |
Alexander Wolf (alexwolf) wrote : | # |
I'm merge this branch before publish RC2.
- 5535. By Alexander Wolf
-
update Observability plugin
Preview Diff
1 | === modified file 'plugins/Observability/src/Observability.cpp' |
2 | --- plugins/Observability/src/Observability.cpp 2012-08-12 15:50:48 +0000 |
3 | +++ plugins/Observability/src/Observability.cpp 2012-08-16 18:31:20 +0000 |
4 | @@ -90,6 +90,7 @@ |
5 | halfpi = 1.57079632675; // pi/2 |
6 | MoonT = 29.530588; // Moon synodic period (used as first estimate of Full Moon). |
7 | RefFullMoon = 2451564.696; // Reference Julian date of a Full Moon. |
8 | + MoonPerilune = 0.0024236308; // Smallest Earth-Moon distance (in AU). |
9 | nextFullMoon = 0.0; |
10 | prevFullMoon = 0.0; |
11 | selName = ""; |
12 | @@ -183,7 +184,9 @@ |
13 | |
14 | |
15 | // Set names of the months: |
16 | - QString mons[12]={q_("January"), q_("February"), q_("March"), q_("April"), q_("May"), q_("June"), q_("July"), q_("August"), q_("September"), q_("October"), q_("November"), q_("December")}; |
17 | +// QString mons[12]={q_("January"), q_("February"), q_("March"), q_("April"), q_("May"), q_("June"), q_("July"), q_("August"), q_("September"), q_("October"), q_("November"), q_("December")}; |
18 | + QString mons[12]={q_("Jan"), q_("Feb"), q_("Mar"), q_("Apr"), q_("May"), q_("Jun"), q_("Jul"), q_("Aug"), q_("Sep"), q_("Oct"), q_("Nov"), q_("Dec")}; |
19 | + |
20 | for (int i=0;i<12;i++) { |
21 | months[i]=mons[i]; |
22 | }; |
23 | @@ -244,10 +247,10 @@ |
24 | |
25 | ///////////////////////////////////////////////////////////////// |
26 | // PRELIMINARS: |
27 | - bool souChanged, locChanged, yearChanged; |
28 | + bool locChanged, yearChanged; |
29 | StelObjectP selectedObject; |
30 | Planet* currPlanet; |
31 | - |
32 | + PlanetP Object, parent; |
33 | |
34 | // Only execute plugin if we are on Earth. |
35 | if (core->getCurrentLocation().planetName != "Earth") {return;}; |
36 | @@ -265,12 +268,13 @@ |
37 | double currheight = (6371.+(core->getCurrentLocation().altitude)/1000.)/UA; |
38 | double currJD = core->getJDay(); |
39 | double currJDint; |
40 | - double currLocalT = 24.*modf(currJD + StelApp::getInstance().getLocaleMgr().getGMTShift(currJD)/24.0,&currJDint); |
41 | + GMTShift = StelApp::getInstance().getLocaleMgr().getGMTShift(currJD)/24.0; |
42 | + double currLocalT = 24.*modf(currJD + GMTShift,&currJDint); |
43 | |
44 | int auxm, auxd, auxy; |
45 | StelUtils::getDateFromJulianDay(currJD,&auxy,&auxm,&auxd); |
46 | bool isSource = StelApp::getInstance().getStelObjectMgr().getWasSelected(); |
47 | - bool show_Year = show_Best_Night || show_Good_Nights || show_AcroCos; // || show_FullMoon; |
48 | + bool show_Year = show_Best_Night || show_Good_Nights || show_AcroCos; |
49 | |
50 | ////////////////////////////////////////////////////////////////// |
51 | |
52 | @@ -332,19 +336,51 @@ |
53 | isMoon = ("Moon" == tempName)?true:false; |
54 | isSun = ("Sun" == tempName)?true:false; |
55 | |
56 | +// If Moon is not selected (or was unselected), force re-compute of Full Moon next time it is selected: |
57 | + if (!isMoon) {prevFullMoon=0.0; nextFullMoon=0.0;}; |
58 | + |
59 | //Update position: |
60 | EquPos = selectedObject->getEquinoxEquatorialPos(core); |
61 | EquPos.normalize(); |
62 | LocPos = core->equinoxEquToAltAz(EquPos); |
63 | |
64 | // Check if the user has changed the source (or if the source is Sun/Moon). |
65 | - if (tempName == selName && isMoon==false && isSun == false) { |
66 | - souChanged = false;} // Don't retouch anything regarding RA/Dec (to save a bit of resources). |
67 | - else { // Check also if the (new) source belongs to the Solar System: |
68 | + if (tempName == selName) |
69 | + { |
70 | + souChanged = false;} |
71 | + else |
72 | + { // Check also if the (new) source belongs to the Solar System: |
73 | + |
74 | + souChanged = true; |
75 | + selName = tempName; |
76 | + |
77 | currPlanet = dynamic_cast<Planet*>(selectedObject.data()); |
78 | isStar = (currPlanet)?false:true; |
79 | - souChanged = true; |
80 | - selName = tempName; |
81 | + |
82 | + if (!isStar && !isMoon && !isSun) // Object in the Solar System, but is not Sun nor Moon. |
83 | + { |
84 | + |
85 | + int gene = -1; |
86 | + |
87 | + // If object is a planet's moon, we get its parent planet: |
88 | + Object = GETSTELMODULE(SolarSystem)->searchByEnglishName(selName); |
89 | + |
90 | + parent = Object->getParent(); |
91 | + |
92 | + if (parent) |
93 | + { |
94 | + while (parent) { |
95 | + gene += 1; |
96 | + parent = parent->getParent();} |
97 | + }; |
98 | + for (int g=0; g<gene;g++) { |
99 | + Object = Object->getParent(); |
100 | + }; |
101 | + |
102 | + // Now get a pointer to the planet's instance: |
103 | + myPlanet = Object.data(); |
104 | + }; |
105 | + |
106 | }; |
107 | } |
108 | else { // There is no source selected! |
109 | @@ -381,23 +417,27 @@ |
110 | QString RS1, RS2, Cul; // strings with Rise/Set/Culmination times |
111 | double Rise, Set; // Actual Rise/Set times (in GMT). |
112 | int d1,m1,s1,d2,m2,s2,dc,mc,sc; // Integers for the time spans in hh:mm:ss. |
113 | - bool solvedMoon = false; |
114 | - bool transit; // Is the source above the horizon? Did it culminate? |
115 | + bool solvedMoon = false; // Check if solutions were found for Sun, Moon, or planet. |
116 | + bool transit = false; // Is the source above the horizon? Did it culminate? |
117 | |
118 | int ephHour, ephMinute, ephSecond; // Local time for selected ephemeris |
119 | |
120 | if (show_Today) { // We show ephemeris for today (i.e., rise, set, and transit times). |
121 | |
122 | - if (isMoon || isSun) { |
123 | - solvedMoon = MoonSunSolve(core); // False if fails; True otherwise. |
124 | + |
125 | + if (!isStar) |
126 | + { |
127 | + int Kind = (isSun)?1:0; // Set "Kind" according to the selected object. |
128 | + Kind += (isMoon)?2:0; Kind += (!isSun && !isMoon)?3:0; |
129 | + |
130 | + solvedMoon = SolarSystemSolve(core, Kind); // False if fails; True otherwise. |
131 | currH = std::abs(24.*(MoonCulm-myJD)/TFrac); |
132 | transit = MoonCulm-myJD<0.0; |
133 | if (solvedMoon) { // If failed, Set and Rise will be dummy. |
134 | Set = std::abs(24.*(MoonSet-myJD)/TFrac); |
135 | Rise = std::abs(24.*(MoonRise-myJD)/TFrac); |
136 | }; |
137 | - } |
138 | - else if (horizH>0.0) { // The source is not circumpolar and can be seen from this latitude. |
139 | + } else if (horizH>0.0) { // The source is not circumpolar and can be seen from this latitude. |
140 | |
141 | if ( LocPos[1]>0.0 ) { // The source is at the eastern side... |
142 | if ( currH>horizH ) { // ... and below the horizon. |
143 | @@ -422,7 +462,7 @@ |
144 | |
145 | }; |
146 | |
147 | - if ((solvedMoon && MoonRise>0.0) || (isMoon==false && isSun==false && horizH>0.0)) |
148 | + if ((solvedMoon && MoonRise>0.0) || (!isSun && !isMoon && horizH>0.0)) |
149 | { |
150 | double2hms(TFrac*Set,d1,m1,s1); |
151 | double2hms(TFrac*Rise,d2,m2,s2); |
152 | @@ -439,7 +479,7 @@ |
153 | RiseTime = QString("%1:%2").arg(ephHour).arg(ephMinute,2,10,QLatin1Char('0')); |
154 | |
155 | RS1 = q_("Sets at %1 (in %2)").arg(SetTime).arg(RS1); |
156 | - RS2 = q_("Raised at %1 (%2 ago)").arg(RiseTime).arg(RS2); |
157 | + RS2 = q_("Rose at %1 (%2 ago)").arg(RiseTime).arg(RS2); |
158 | } |
159 | else |
160 | { |
161 | @@ -449,8 +489,8 @@ |
162 | double2hms(toUnsignedRA(currLocalT+TFrac*Rise+12.),ephHour,ephMinute,ephSecond); |
163 | RiseTime = QString("%1:%2").arg(ephHour).arg(ephMinute,2,10,QLatin1Char('0')); |
164 | |
165 | - RS1 = q_("Has set at %1 (%2 ago)").arg(SetTime).arg(RS1); |
166 | - RS2 = q_("Raises at %1 (in %2)").arg(RiseTime).arg(RS2); |
167 | + RS1 = q_("Set at %1 (%2 ago)").arg(SetTime).arg(RS1); |
168 | + RS2 = q_("Rises at %1 (in %2)").arg(RiseTime).arg(RS2); |
169 | }; |
170 | } |
171 | else { // The source is either circumpolar or never rises: |
172 | @@ -460,8 +500,7 @@ |
173 | |
174 | // Culmination: |
175 | |
176 | - transit = false; |
177 | - if (isSun==false && isMoon == false) |
178 | + if (isStar) |
179 | { |
180 | culmAlt = std::abs(mylat-selDec); // 90.-altitude at transit. |
181 | transit = LocPos[1]<0.0; |
182 | @@ -494,10 +533,6 @@ |
183 | |
184 | // Compute yearly ephemeris (only if necessary, and not for Sun nor Moon): |
185 | |
186 | -// if (isMoon && (show_FullMoon || show_Crescent || show_SuperMoon)) |
187 | -// { |
188 | -// computeMoonEphemeris(); |
189 | -// }; |
190 | |
191 | if (isSun) |
192 | { |
193 | @@ -506,7 +541,7 @@ |
194 | else if (!isMoon && show_Year) { |
195 | |
196 | if (isStar==false && (souChanged || yearChanged)) { // Object moves. |
197 | - PlanetRADec(core,selName);} // Re-compute ephemeris. |
198 | + PlanetRADec(core);} // Re-compute ephemeris. |
199 | |
200 | else { // Object is fixed on the sky. |
201 | double auxH = HourAngle(mylat,0.0,selDec); |
202 | @@ -536,13 +571,20 @@ |
203 | if (show_Best_Night) { |
204 | int selday = 0; |
205 | double deltaPhs = -1.0; // Initial dummy value |
206 | - double tempPhs; //, tempSep; |
207 | - |
208 | + double tempPhs; |
209 | for (int i=0;i<nDays;i++) { // Maximize the Sun-object separation. |
210 | tempPhs = Lambda(ObjectRA[i],ObjectDec[i],SunRA[i],SunDec[i]); |
211 | if (tempPhs>deltaPhs) {selday=i;deltaPhs=tempPhs;}; |
212 | }; |
213 | - bestNight = q_("Largest Sun separation: "); |
214 | + |
215 | + if (selName=="Mercury" || selName=="Venus") |
216 | + { |
217 | + bestNight = q_("Greatest elongation: "); |
218 | + } else |
219 | + { |
220 | + bestNight = q_("Largest Sun separation: "); |
221 | + }; |
222 | + |
223 | bestNight = bestNight + CalenDate(selday) + q_(" (at %1 deg.)").arg(deltaPhs*Rad2Deg,0,'f',1); |
224 | }; |
225 | |
226 | @@ -617,11 +659,9 @@ |
227 | } |
228 | else |
229 | { |
230 | - ObsRange = QString("%1 %2").arg(q_("Best observed")).arg(dateRange); |
231 | + ObsRange = QString("%1 %2").arg(q_("Nights above horizon: ")).arg(dateRange); |
232 | }; |
233 | |
234 | -// if (selName == "Mercury") {ObsRange = "Observable in many dates of the year";}; // Special case of Mercury. |
235 | - |
236 | }; // Comes from show_Good_Nights==True" |
237 | }; // Comes from the "else" of "culmAlt>=..." |
238 | };// Comes from "souChanged || ..." |
239 | @@ -629,34 +669,37 @@ |
240 | |
241 | // Print all results: |
242 | |
243 | - int yLine = 7*fontSize+80; |
244 | + |
245 | + int spacing = (int) (1.3* ( (double) fontSize)); // between lines |
246 | + int spacing2 = 6*fontSize; // between daily and yearly results |
247 | + int yLine = 8*fontSize+80; |
248 | int xLine = 50; |
249 | |
250 | if (show_Today) |
251 | { |
252 | paintresult.drawText(xLine, yLine,q_(" TODAY:")); |
253 | - paintresult.drawText(xLine+fontSize, yLine-fontSize, RS2); |
254 | - paintresult.drawText(xLine+fontSize, yLine-fontSize*2, RS1); |
255 | - paintresult.drawText(xLine+fontSize, yLine-fontSize*3, Cul); |
256 | - yLine -= fontSize*5; |
257 | + paintresult.drawText(xLine+fontSize, yLine-spacing, RS2); |
258 | + paintresult.drawText(xLine+fontSize, yLine-spacing*2, RS1); |
259 | + paintresult.drawText(xLine+fontSize, yLine-spacing*3, Cul); |
260 | + yLine -= spacing2; |
261 | }; |
262 | - |
263 | - if ((isMoon && show_FullMoon) || (isSun == false && isMoon == false && show_Year)) |
264 | + |
265 | + if ((isMoon && show_FullMoon) || (!isSun && !isMoon && show_Year)) |
266 | { |
267 | paintresult.drawText(xLine,yLine," THIS YEAR:"); |
268 | if (show_Best_Night || show_FullMoon) |
269 | { |
270 | - yLine -= fontSize; |
271 | + yLine -= spacing; |
272 | paintresult.drawText(xLine+fontSize, yLine, bestNight); |
273 | }; |
274 | if (show_Good_Nights) |
275 | { |
276 | - yLine -= fontSize; |
277 | + yLine -= spacing; |
278 | paintresult.drawText(xLine+fontSize, yLine, ObsRange); |
279 | }; |
280 | if (show_AcroCos) |
281 | { |
282 | - yLine -= fontSize; |
283 | + yLine -= spacing; |
284 | paintresult.drawText(xLine+fontSize, yLine, AcroCos); |
285 | }; |
286 | |
287 | @@ -719,7 +762,7 @@ |
288 | double ffrac2 = std::modf(60.*ffrac,&f2); |
289 | //FIXME: ffrac2 is unused variable; need fix |
290 | ffrac2 = std::modf(3600.*(ffrac-f2/60.),&f3); |
291 | - h1 = (int)f1 ; h2 = (int)std::abs(f2) ; h3 = (int)std::abs(f3); |
292 | + h1 = (int)f1 ; h2 = (int)std::abs(f2+0.0*ffrac2) ; h3 = (int)std::abs(f3); |
293 | } |
294 | //////////////////////////////////// |
295 | |
296 | @@ -730,7 +773,7 @@ |
297 | { |
298 | double tempRA,tempmod; |
299 | //FIXME: tempmod is unused variable; need fix |
300 | - if (RA<0.0) {tempmod = std::modf(-RA/24.,&tempRA); RA += 24.*(tempRA+1.0);}; |
301 | + if (RA<0.0) {tempmod = std::modf(-RA/24.,&tempRA); RA += 24.*(tempRA+1.0)+0.0*tempmod;}; |
302 | double auxRA = 24.*std::modf(RA/24.,&tempRA); |
303 | auxRA += (auxRA<0.0)?24.0:((auxRA>24.0)?-24.0:0.0); |
304 | return auxRA; |
305 | @@ -752,38 +795,14 @@ |
306 | ////////////////////////////////////////////////// |
307 | // Returns the RA and Dec of the selected planet |
308 | //for each day of the current year: |
309 | -void Observability::PlanetRADec(StelCore *core, QString Name) |
310 | +void Observability::PlanetRADec(StelCore *core) |
311 | { |
312 | - int gene = -1; |
313 | double TempH; |
314 | - Vec3d TP, TP2; |
315 | - Mat4d LocTrans; |
316 | - |
317 | -// If object is a Moon, we select its parent planet: |
318 | - PlanetP Object = GETSTELMODULE(SolarSystem)->searchByEnglishName(Name); |
319 | - PlanetP parent = Object->getParent(); |
320 | - |
321 | - if (parent) { |
322 | - while (parent) { |
323 | - gene += 1; |
324 | - parent = parent->getParent();} |
325 | - }; |
326 | - for (int g=0; g<gene;g++) { |
327 | - Object = Object->getParent(); |
328 | - }; |
329 | - |
330 | -// Get a pointer to the planet's instance: |
331 | - Planet* myPlanet = Object.data(); |
332 | |
333 | // Compute planet's position for each day of the current year: |
334 | |
335 | for (int i=0;i<nDays;i++) { |
336 | - myPlanet->computePosition(yearJD[i]); |
337 | - myPlanet->computeTransMatrix(yearJD[i]); |
338 | - TP = myPlanet->getHeliocentricEclipticPos(); |
339 | - LocTrans = (core->matVsop87ToJ2000)*(Mat4d::translation(EarthPos[i])); |
340 | - TP2 = core->j2000ToEquinoxEqu(LocTrans*TP); |
341 | - toRADec(TP2,ObjectRA[i],ObjectDec[i]); |
342 | + getPlanetCoords(core,yearJD[i],ObjectRA[i],ObjectDec[i],false); |
343 | TempH = HourAngle(mylat,0.0,ObjectDec[i]); |
344 | ObjectH0[i] = TempH; |
345 | ObjectSidT[0][i] = toUnsignedRA(ObjectRA[i]-TempH); |
346 | @@ -791,8 +810,7 @@ |
347 | } |
348 | |
349 | // Return the planet to its current time: |
350 | - myPlanet->computePosition(myJD); |
351 | - myPlanet->computeTransMatrix(myJD); |
352 | + getPlanetCoords(core,myJD,ObjectRA[0],ObjectDec[0],true); |
353 | |
354 | |
355 | } |
356 | @@ -803,7 +821,6 @@ |
357 | void Observability::SunRADec(StelCore* core) |
358 | { |
359 | int day,month,year,year2; |
360 | - Vec3d TP, TP2; |
361 | |
362 | // Get current date: |
363 | StelUtils::getDateFromJulianDay(myJD,&year,&month,&day); |
364 | @@ -820,11 +837,10 @@ |
365 | yearJD[i] = Jan1stJD+(double)i; |
366 | myEarth->computePosition(yearJD[i]); |
367 | myEarth->computeTransMatrix(yearJD[i]); |
368 | - TP = myEarth->getHeliocentricEclipticPos(); |
369 | - TP[0] = -TP[0]; TP[1] = -TP[1]; TP[2] = -TP[2]; |
370 | - TP2 = core->j2000ToEquinoxEqu((core->matVsop87ToJ2000)*TP); |
371 | - EarthPos[i] = TP; |
372 | - toRADec(TP2,SunRA[i],SunDec[i]); |
373 | + Pos1 = myEarth->getHeliocentricEclipticPos(); |
374 | + Pos2 = core->j2000ToEquinoxEqu((core->matVsop87ToJ2000)*(-Pos1)); |
375 | + EarthPos[i] = -Pos1; |
376 | + toRADec(Pos2,SunRA[i],SunDec[i]); |
377 | }; |
378 | |
379 | //Return the Earth to its current time: |
380 | @@ -952,7 +968,6 @@ |
381 | Set *= (BestDiffSet > 0.083)?-1:1; // Check that difference is lower than 5 minutes. |
382 | Rise2 *= (BestDiffRise2 > 0.083)?-1:1; // Check that difference is lower than 5 minutes. |
383 | Set2 *= (BestDiffSet2 > 0.083)?-1:1; // Check that difference is lower than 5 minutes. |
384 | -// qDebug() << q_("%1 %2").arg(Rise).arg(Rise2); |
385 | int Result = (Rise>0 || Set>0)?1:0; |
386 | Result += (Rise2>0 || Set2>0)?2:0; |
387 | return (success)?Result:0; |
388 | @@ -990,10 +1005,10 @@ |
389 | |
390 | if (getBack) // Return the Moon and Earth to their current position: |
391 | { |
392 | - myEarth->computePosition(myJD); |
393 | - myEarth->computeTransMatrix(myJD); |
394 | - myMoon->computePosition(myJD); |
395 | - myMoon->computeTransMatrix(myJD); |
396 | + myEarth->computePosition(JD); |
397 | + myEarth->computeTransMatrix(JD); |
398 | + myMoon->computePosition(JD); |
399 | + myMoon->computeTransMatrix(JD); |
400 | } |
401 | else |
402 | { // Compute coordinates: |
403 | @@ -1022,9 +1037,83 @@ |
404 | |
405 | |
406 | |
407 | -////////////////////////////////////////////// |
408 | -// Solves Moon's or Sun's ephemeris by bissection. Returns JD: |
409 | -bool Observability::MoonSunSolve(StelCore* core) |
410 | +////////////////////////// |
411 | +// Get the Observer-to-Moon distance JD: |
412 | +// getBack controls whether Earth and Moon must be returned to their original positions after computation. |
413 | +void Observability::getMoonDistance(StelCore *core, double JD, double &Distance, bool getBack) |
414 | +{ |
415 | + |
416 | + if (getBack) // Return the Moon and Earth to their current position: |
417 | + { |
418 | + myEarth->computePosition(JD); |
419 | + myEarth->computeTransMatrix(JD); |
420 | + myMoon->computePosition(JD); |
421 | + myMoon->computeTransMatrix(JD); |
422 | + } |
423 | + else |
424 | + { // Compute coordinates: |
425 | + myEarth->computePosition(JD); |
426 | + myEarth->computeTransMatrix(JD); |
427 | + Pos0 = myEarth->getHeliocentricEclipticPos(); |
428 | +// double currSidT; |
429 | + |
430 | +// Sun coordinates: |
431 | +// Pos2 = core->j2000ToEquinoxEqu((core->matVsop87ToJ2000)*(-Pos0)); |
432 | +// toRADec(Pos2,RASun,DecSun); |
433 | + |
434 | +// Moon coordinates: |
435 | +// currSidT = myEarth->getSiderealTime(JD)/Rad2Deg; |
436 | +// RotObserver = (Mat4d::zrotation(currSidT))*ObserverLoc; |
437 | + LocTrans = (core->matVsop87ToJ2000)*(Mat4d::translation(-Pos0)); |
438 | + myMoon->computePosition(JD); |
439 | + myMoon->computeTransMatrix(JD); |
440 | + Pos1 = myMoon->getHeliocentricEclipticPos(); |
441 | + Pos2 = (core->j2000ToEquinoxEqu(LocTrans*Pos1)); //-RotObserver; |
442 | + |
443 | + Distance = std::sqrt(Pos2*Pos2); |
444 | + |
445 | +// toRADec(Pos2,RAMoon,DecMoon); |
446 | + }; |
447 | +} |
448 | +////////////////////////////////////////////// |
449 | + |
450 | + |
451 | + |
452 | + |
453 | +////////////////////////////////////////////// |
454 | +// Get the Coords of a planet: |
455 | +void Observability::getPlanetCoords(StelCore *core, double JD, double &RA, double &Dec, bool getBack) |
456 | +{ |
457 | + |
458 | + if (getBack) |
459 | + { |
460 | + // Return the planet to its current time: |
461 | + myPlanet->computePosition(JD); |
462 | + myPlanet->computeTransMatrix(JD); |
463 | + myEarth->computePosition(JD); |
464 | + myEarth->computeTransMatrix(JD); |
465 | + } else |
466 | + { |
467 | + // Compute planet's position: |
468 | + myPlanet->computePosition(JD); |
469 | + myPlanet->computeTransMatrix(JD); |
470 | + Pos1 = myPlanet->getHeliocentricEclipticPos(); |
471 | + myEarth->computePosition(JD); |
472 | + myEarth->computeTransMatrix(JD); |
473 | + Pos2 = myEarth->getHeliocentricEclipticPos(); |
474 | + LocTrans = (core->matVsop87ToJ2000)*(Mat4d::translation(-Pos2)); |
475 | + Pos2 = core->j2000ToEquinoxEqu(LocTrans*Pos1); |
476 | + toRADec(Pos2,RA,Dec); |
477 | + }; |
478 | + |
479 | +} |
480 | +////////////////////////////////////////////// |
481 | + |
482 | + |
483 | + |
484 | +////////////////////////////////////////////// |
485 | +// Solves Moon's, Sun's, or Planet's ephemeris by bissection. Returns JD: |
486 | +bool Observability::SolarSystemSolve(StelCore* core, int Kind) |
487 | { |
488 | |
489 | int Niter = 100; |
490 | @@ -1038,159 +1127,207 @@ |
491 | |
492 | // Only recompute ephemeris from second to second (at least) |
493 | // or if the source has changed (i.e., Sun <-> Moon). This saves resources: |
494 | - if (std::abs(myJD-lastJDMoon)<JDsec && LastSun==isSun) return raises; |
495 | - |
496 | - LastSun = isSun; |
497 | - myEarth->computePosition(myJD); |
498 | - myEarth->computeTransMatrix(myJD); |
499 | - Pos0 = myEarth->getHeliocentricEclipticPos(); |
500 | - |
501 | - if (isSun) |
502 | + if (std::abs(myJD-lastJDMoon)>JDsec || LastObject!=Kind || souChanged) |
503 | { |
504 | - Pos2 = core->j2000ToEquinoxEqu((core->matVsop87ToJ2000)*(-Pos0));} |
505 | - else |
506 | - { |
507 | - currSidT = myEarth->getSiderealTime(myJD)/Rad2Deg; |
508 | - RotObserver = (Mat4d::zrotation(currSidT))*ObserverLoc; |
509 | - LocTrans = (core->matVsop87ToJ2000)*(Mat4d::translation(-Pos0)); |
510 | - myMoon->computePosition(myJD); |
511 | - myMoon->computeTransMatrix(myJD); |
512 | - Pos1 = myMoon->getHeliocentricEclipticPos(); |
513 | - Pos2 = (core->j2000ToEquinoxEqu(LocTrans*Pos1))-RotObserver; |
514 | - }; |
515 | - |
516 | - toRADec(Pos2,RA,Dec); |
517 | - Vec3d MoonAltAz = core->equinoxEquToAltAz(Pos2); |
518 | - raised = MoonAltAz[2] > 0.0; |
519 | + |
520 | +// qDebug() << q_("%1 %2 %3 %4").arg(Kind).arg(LastObject).arg(myJD,0,'f',5).arg(lastJDMoon,0,'f',5); |
521 | + |
522 | + LastObject = Kind; |
523 | + |
524 | + myEarth->computePosition(myJD); |
525 | + myEarth->computeTransMatrix(myJD); |
526 | + Pos0 = myEarth->getHeliocentricEclipticPos(); |
527 | + |
528 | + if (Kind==1) |
529 | + { // Sun position: |
530 | + Pos2 = core->j2000ToEquinoxEqu((core->matVsop87ToJ2000)*(-Pos0)); |
531 | + } else if (Kind==2) |
532 | + { // Moon position: |
533 | + currSidT = myEarth->getSiderealTime(myJD)/Rad2Deg; |
534 | + RotObserver = (Mat4d::zrotation(currSidT))*ObserverLoc; |
535 | + LocTrans = (core->matVsop87ToJ2000)*(Mat4d::translation(-Pos0)); |
536 | + myMoon->computePosition(myJD); |
537 | + myMoon->computeTransMatrix(myJD); |
538 | + Pos1 = myMoon->getHeliocentricEclipticPos(); |
539 | + Pos2 = (core->j2000ToEquinoxEqu(LocTrans*Pos1))-RotObserver; |
540 | + } else |
541 | + { // Planet position: |
542 | + myPlanet->computePosition(myJD); |
543 | + myPlanet->computeTransMatrix(myJD); |
544 | + Pos1 = myPlanet->getHeliocentricEclipticPos(); |
545 | + LocTrans = (core->matVsop87ToJ2000)*(Mat4d::translation(-Pos0)); |
546 | + Pos2 = core->j2000ToEquinoxEqu(LocTrans*Pos1); |
547 | + }; |
548 | + |
549 | + toRADec(Pos2,RA,Dec); |
550 | + Vec3d MoonAltAz = core->equinoxEquToAltAz(Pos2); |
551 | + raised = MoonAltAz[2] > 0.0; |
552 | |
553 | // Initial guesses of rise/set/transit times. |
554 | -// They are called 'Moon', but are also used for the Sun: |
555 | - |
556 | - double Hcurr = -HourAngle(mylat,alti,selDec)*sign(LocPos[1]); |
557 | - double SidT = toUnsignedRA(selRA + Hcurr); |
558 | - |
559 | - MoonCulm = -Hcurr; |
560 | - MoonRise = (-Hhoriz-Hcurr); |
561 | - MoonSet = (Hhoriz-Hcurr); |
562 | - |
563 | - if (raises) { |
564 | - if (raised==false) { |
565 | - MoonRise += (MoonRise<0.0)?24.0:0.0; |
566 | - MoonSet -= (MoonSet>0.0)?24.0:0.0; |
567 | - }; |
568 | +// They are called 'Moon', but are also used for the Sun or planet: |
569 | + |
570 | + double Hcurr = -HourAngle(mylat,alti,selDec)*sign(LocPos[1]); |
571 | + double SidT = toUnsignedRA(selRA + Hcurr); |
572 | + |
573 | + MoonCulm = -Hcurr; |
574 | + MoonRise = (-Hhoriz-Hcurr); |
575 | + MoonSet = (Hhoriz-Hcurr); |
576 | + |
577 | + if (raises) { |
578 | + if (raised==false) { |
579 | + MoonRise += (MoonRise<0.0)?24.0:0.0; |
580 | + MoonSet -= (MoonSet>0.0)?24.0:0.0; |
581 | + }; |
582 | |
583 | // Rise time: |
584 | - tempEphH = MoonRise*TFrac; |
585 | - MoonRise = myJD + (MoonRise/24.); |
586 | - for (i=0; i<Niter; i++) |
587 | - { |
588 | - // Get modified coordinates: |
589 | - jd1 = MoonRise; |
590 | - getSunMoonCoords(core,jd1,RAS,DecS,RA,Dec,false); |
591 | - if (isSun) {RA = RAS; Dec = DecS;}; |
592 | - |
593 | - // Current hour angle at mod. coordinates: |
594 | - Hcurr = toUnsignedRA(SidT-RA); |
595 | - Hcurr -= (raised)?0.0:24.; |
596 | - Hcurr -= (Hcurr>12.)?24.0:0.0; |
597 | - |
598 | - // H at horizon for mod. coordinates: |
599 | - Hhoriz = HourAngle(mylat,0.0,Dec); |
600 | - // Compute eph. times for mod. coordinates: |
601 | - TempH = (-Hhoriz-Hcurr)*TFrac; |
602 | - if (raised==false) TempH += (TempH<0.0)?24.0:0.0; |
603 | + tempEphH = MoonRise*TFrac; |
604 | + MoonRise = myJD + (MoonRise/24.); |
605 | + for (i=0; i<Niter; i++) |
606 | + { |
607 | + // Get modified coordinates: |
608 | + jd1 = MoonRise; |
609 | + |
610 | + if (Kind<3) |
611 | + { |
612 | + getSunMoonCoords(core,jd1,RAS,DecS,RA,Dec,false); |
613 | + } else |
614 | + { |
615 | + getPlanetCoords(core,jd1,RA,Dec,false); |
616 | + }; |
617 | + |
618 | + if (Kind==1) {RA = RAS; Dec = DecS;}; |
619 | + |
620 | + // Current hour angle at mod. coordinates: |
621 | + Hcurr = toUnsignedRA(SidT-RA); |
622 | + Hcurr -= (raised)?0.0:24.; |
623 | + Hcurr -= (Hcurr>12.)?24.0:0.0; |
624 | + |
625 | + // H at horizon for mod. coordinates: |
626 | + Hhoriz = HourAngle(mylat,0.0,Dec); |
627 | + // Compute eph. times for mod. coordinates: |
628 | + TempH = (-Hhoriz-Hcurr)*TFrac; |
629 | + if (raised==false) TempH += (TempH<0.0)?24.0:0.0; |
630 | + // Check convergence: |
631 | + if (std::abs(TempH-tempEphH)<JDsec) break; |
632 | + // Update rise-time estimate: |
633 | + tempEphH = TempH; |
634 | + MoonRise = myJD + (tempEphH/24.); |
635 | + }; |
636 | + |
637 | +// Set time: |
638 | + tempEphH = MoonSet; |
639 | + MoonSet = myJD + (MoonSet/24.); |
640 | + for (i=0; i<Niter; i++) |
641 | + { |
642 | + // Get modified coordinates: |
643 | + jd1 = MoonSet; |
644 | + |
645 | + if (Kind<3) |
646 | + { |
647 | + getSunMoonCoords(core,jd1,RAS,DecS,RA,Dec,false); |
648 | + } else |
649 | + { |
650 | + getPlanetCoords(core,jd1,RA,Dec,false); |
651 | + }; |
652 | + |
653 | + if (Kind==1) {RA = RAS; Dec = DecS;}; |
654 | + |
655 | + // Current hour angle at mod. coordinates: |
656 | + Hcurr = toUnsignedRA(SidT-RA); |
657 | + Hcurr -= (raised)?24.:0.; |
658 | + Hcurr += (Hcurr<-12.)?24.0:0.0; |
659 | + // H at horizon for mod. coordinates: |
660 | + Hhoriz = HourAngle(mylat,0.0,Dec); |
661 | + // Compute eph. times for mod. coordinates: |
662 | + TempH = (Hhoriz-Hcurr)*TFrac; |
663 | + if (raised==false) TempH -= (TempH>0.0)?24.0:0.0; |
664 | // Check convergence: |
665 | - if (std::abs(TempH-tempEphH)<JDsec) break; |
666 | - // Update rise-time estimate: |
667 | - tempEphH = TempH; |
668 | - MoonRise = myJD + (tempEphH/24.); |
669 | - }; |
670 | - |
671 | -// Set time: |
672 | - tempEphH = MoonSet; |
673 | - MoonSet = myJD + (MoonSet/24.); |
674 | - for (i=0; i<Niter; i++) |
675 | + if (std::abs(TempH-tempEphH)<JDsec) break; |
676 | + // Update set-time estimate: |
677 | + tempEphH = TempH; |
678 | + MoonSet = myJD + (tempEphH/24.); |
679 | + }; |
680 | + } |
681 | + else // Comes from if(raises) |
682 | { |
683 | - // Get modified coordinates: |
684 | - jd1 = MoonSet; |
685 | - getSunMoonCoords(core,jd1,RAS,DecS,RA,Dec,false); |
686 | - if (isSun) {RA = RAS; Dec = DecS;}; |
687 | - |
688 | - // Current hour angle at mod. coordinates: |
689 | - Hcurr = toUnsignedRA(SidT-RA); |
690 | - Hcurr -= (raised)?24.:0.; |
691 | - Hcurr += (Hcurr<-12.)?24.0:0.0; |
692 | - // H at horizon for mod. coordinates: |
693 | - Hhoriz = HourAngle(mylat,0.0,Dec); |
694 | - // Compute eph. times for mod. coordinates: |
695 | - TempH = (Hhoriz-Hcurr)*TFrac; |
696 | - if (raised==false) TempH -= (TempH>0.0)?24.0:0.0; |
697 | - // Check convergence: |
698 | - if (std::abs(TempH-tempEphH)<JDsec) break; |
699 | - // Update set-time estimate: |
700 | - tempEphH = TempH; |
701 | - MoonSet = myJD + (tempEphH/24.); |
702 | + MoonSet = -1.0; MoonRise = -1.0; |
703 | }; |
704 | - } |
705 | - else // Comes from if(raises) |
706 | - { |
707 | - MoonSet = -1.0; MoonRise = -1.0; |
708 | - }; |
709 | |
710 | // Culmination time: |
711 | - tempEphH = MoonCulm; |
712 | - MoonCulm = myJD + (MoonCulm/24.); |
713 | + tempEphH = MoonCulm; |
714 | + MoonCulm = myJD + (MoonCulm/24.); |
715 | |
716 | - for (i=0; i<Niter; i++) |
717 | - { |
718 | + for (i=0; i<Niter; i++) |
719 | + { |
720 | // Get modified coordinates: |
721 | - jd1 = MoonCulm; |
722 | - getSunMoonCoords(core,jd1,RAS,DecS,RA,Dec,false); |
723 | - if (isSun) {RA = RAS; Dec = DecS;}; |
724 | + jd1 = MoonCulm; |
725 | + |
726 | + if (Kind<3) |
727 | + { |
728 | + getSunMoonCoords(core,jd1,RAS,DecS,RA,Dec,false); |
729 | + } else |
730 | + { |
731 | + getPlanetCoords(core,jd1,RA,Dec,false); |
732 | + }; |
733 | + |
734 | + |
735 | + if (Kind==1) {RA = RAS; Dec = DecS;}; |
736 | |
737 | |
738 | // Current hour angle at mod. coordinates: |
739 | - Hcurr = toUnsignedRA(SidT-RA); |
740 | - Hcurr += (LocPos[1]<0.0)?24.0:-24.0; |
741 | - Hcurr -= (Hcurr>12.)?24.0:0.0; |
742 | + Hcurr = toUnsignedRA(SidT-RA); |
743 | + Hcurr += (LocPos[1]<0.0)?24.0:-24.0; |
744 | + Hcurr -= (Hcurr>12.)?24.0:0.0; |
745 | |
746 | // Compute eph. times for mod. coordinates: |
747 | - TempH = -Hcurr*TFrac; |
748 | + TempH = -Hcurr*TFrac; |
749 | // Check convergence: |
750 | - if (std::abs(TempH-tempEphH)<JDsec) break; |
751 | - tempEphH = TempH; |
752 | - MoonCulm = myJD + (tempEphH/24.); |
753 | - culmAlt = std::abs(mylat-Dec); // 90 - altitude at transit. |
754 | - }; |
755 | - |
756 | - |
757 | -// Find out the days of Full Moon and Crescent at Sunset: |
758 | - if (isMoon && show_FullMoon) // || show_SuperMoon)) |
759 | + if (std::abs(TempH-tempEphH)<JDsec) break; |
760 | + tempEphH = TempH; |
761 | + MoonCulm = myJD + (tempEphH/24.); |
762 | + culmAlt = std::abs(mylat-Dec); // 90 - altitude at transit. |
763 | + }; |
764 | + |
765 | +// qDebug() << q_("%1").arg(MoonCulm,0,'f',5); |
766 | + |
767 | + }; // Comes from if (std::abs(myJD-lastJDMoon)>JDsec || LastObject!=Kind) |
768 | + |
769 | + |
770 | + |
771 | + |
772 | +// Find out the days of Full Moon: |
773 | + if (Kind==2 && show_FullMoon) // || show_SuperMoon)) |
774 | { |
775 | |
776 | - // Only extimate date of Full Moon if we have changed Lunar month: |
777 | + // Only estimate date of Full Moon if we have changed Lunar month: |
778 | if (myJD > nextFullMoon || myJD < prevFullMoon) |
779 | { |
780 | |
781 | |
782 | - // Estimate the closest Full Moon: |
783 | + // Estimate the nearest (in time) Full Moon: |
784 | double nT; |
785 | double dT = std::modf((myJD-RefFullMoon)/MoonT,&nT); |
786 | if (dT>0.5) {nT += 1.0;}; |
787 | + if (dT<-0.5) {nT -= 1.0;}; |
788 | + |
789 | double TempFullMoon = RefFullMoon + nT*MoonT; |
790 | |
791 | // Improve the estimate iteratively (Secant method over Lunar-phase vs. time): |
792 | |
793 | - dT = 1./1440.; // Our time span for the finite-difference derivative estimate. |
794 | - //double Phase1, Phase2; // Variables for temporal use. |
795 | + dT = 0.1/1440.; // 6 seconds. Our time span for the finite-difference derivative estimate. |
796 | double Deriv1, Deriv2; // Variables for temporal use. |
797 | - double Sec1, Sec2, Temp1, Temp2; // Variables for temporal use. |
798 | + double Sec1, Sec2, SecMed, Temp1, Temp2; // Variables for temporal use. |
799 | + double iniEst1, iniEst2; // JD values that MUST include the solution within them. |
800 | + double Phase1, Phase2, PhaseMed; |
801 | |
802 | for (int j=0; j<2; j++) |
803 | { // Two steps: one for the previos Full Moon and the other for the next one. |
804 | |
805 | - Sec1 = TempFullMoon - 0.01*MoonT; |
806 | - Sec2 = TempFullMoon + 0.01*MoonT; |
807 | + iniEst1 = TempFullMoon - 0.25*MoonT; |
808 | + iniEst2 = TempFullMoon + 0.25*MoonT; |
809 | + |
810 | + Sec1 = iniEst1; // TempFullMoon - 0.05*MoonT; // Initial estimates of Full-Moon dates |
811 | + Sec2 = iniEst2; // TempFullMoon + 0.05*MoonT; |
812 | |
813 | for (int i=0; i<100; i++) // A limit of 100 iterations. |
814 | { |
815 | @@ -1200,7 +1337,7 @@ |
816 | Temp2 = Lambda(RA,Dec,RAS,DecS); |
817 | |
818 | Deriv1 = (Temp1-Temp2)/dT; |
819 | - //Phase1 = (Temp1+Temp2)/2.; |
820 | + Phase1 = (Temp1+Temp2)/2.; |
821 | |
822 | getSunMoonCoords(core,Sec2+dT/2.,RAS,DecS,RA,Dec,false); |
823 | Temp1 = Lambda(RA,Dec,RAS,DecS); |
824 | @@ -1208,12 +1345,36 @@ |
825 | Temp2 = Lambda(RA,Dec,RAS,DecS); |
826 | |
827 | Deriv2 = (Temp1-Temp2)/dT; |
828 | - //Phase2 = (Temp1+Temp2)/2.; |
829 | + Phase2 = (Temp1+Temp2)/2.; |
830 | + |
831 | + SecMed = (Sec2+Sec1)/2.; |
832 | + getSunMoonCoords(core,SecMed+dT/2.,RAS,DecS,RA,Dec,false); |
833 | + Temp1 = Lambda(RA,Dec,RAS,DecS); |
834 | + getSunMoonCoords(core,SecMed-dT/2.,RAS,DecS,RA,Dec,false); |
835 | + Temp2 = Lambda(RA,Dec,RAS,DecS); |
836 | + |
837 | + // DerivMed = (Temp1-Temp2)/dT; |
838 | + PhaseMed = (Temp1+Temp2)/2.; |
839 | |
840 | Temp1 = Sec2 - Deriv2*(Sec2-Sec1)/(Deriv2-Deriv1); |
841 | - Sec1 = Sec2; Sec2 = Temp1; |
842 | - |
843 | - if (std::abs(Sec2-Sec1) < dT) {break;} // Convergence. |
844 | + |
845 | + // Force the solution to fall within the range of good possible solutions: |
846 | + if (Temp1 < iniEst1 || Temp1 > iniEst2) |
847 | + { |
848 | + if (Phase1>Phase2) |
849 | + { |
850 | + Sec2 = (Phase2 > PhaseMed)?Sec2:SecMed; |
851 | + } else |
852 | + { |
853 | + Sec1 = Sec2; |
854 | + Sec2 = (Phase1>PhaseMed)?Sec1:SecMed; |
855 | + }; |
856 | + } else |
857 | + { |
858 | + Sec1 = Sec2; Sec2 = Temp1; |
859 | + }; |
860 | + |
861 | + if (std::abs(Sec2-Sec1) < 10.*dT) {TempFullMoon = Temp1; break;} // 1 minute accuracy. Convergence. |
862 | |
863 | }; |
864 | |
865 | @@ -1229,51 +1390,72 @@ |
866 | |
867 | }; |
868 | |
869 | - }; |
870 | |
871 | // Update the string shown in the screen: |
872 | - int fullDay, fullMonth,fullYear, fullHour, fullMinute, fullSecond; |
873 | - StelUtils::getDateFromJulianDay(prevFullMoon,&fullYear,&fullMonth,&fullDay); |
874 | - double dT; |
875 | - double nT = 24.*(std::modf(prevFullMoon,&dT)); |
876 | - double2hms(nT,fullHour,fullMinute,fullSecond); |
877 | - bestNight = q_("Previous Full Moon: %1 %2 at %3:%4. ").arg(months[fullMonth-1]).arg(fullDay).arg(fullHour).arg(fullMinute,2,10,QLatin1Char('0')); |
878 | - StelUtils::getDateFromJulianDay(nextFullMoon,&fullYear,&fullMonth,&fullDay); |
879 | - nT = 24.*(std::modf(nextFullMoon,&dT)); |
880 | - double2hms(nT,fullHour,fullMinute,fullSecond); |
881 | - bestNight += q_("Next Full Moon: %1 %2 at %3:%4. ").arg(months[fullMonth-1]).arg(fullDay).arg(fullHour).arg(fullMinute,2,10,QLatin1Char('0')); |
882 | + int fullDay, fullMonth,fullYear, fullHour, fullMinute, fullSecond; |
883 | + double LocalPrev = prevFullMoon+GMTShift+0.5; // Shift to the local time. |
884 | + double LocalNext = nextFullMoon+GMTShift+0.5; |
885 | + double intMoon; |
886 | + double LocalTMoon = 24.*modf(LocalPrev,&intMoon); |
887 | + StelUtils::getDateFromJulianDay(intMoon,&fullYear,&fullMonth,&fullDay); |
888 | + double2hms(toUnsignedRA(LocalTMoon),fullHour,fullMinute,fullSecond); |
889 | + bestNight = q_("Previous Full Moon: %1 "+months[fullMonth-1]+" at %2:%3. ").arg(fullDay).arg(fullHour).arg(fullMinute,2,10,QLatin1Char('0')); |
890 | + |
891 | + LocalTMoon = 24.*modf(LocalNext,&intMoon); |
892 | + StelUtils::getDateFromJulianDay(intMoon,&fullYear,&fullMonth,&fullDay); |
893 | + double2hms(toUnsignedRA(LocalTMoon),fullHour,fullMinute,fullSecond); |
894 | + bestNight += q_(" Next Full Moon: %1 "+months[fullMonth-1]+" at %2:%3. ").arg(fullDay).arg(fullHour).arg(fullMinute,2,10,QLatin1Char('0')); |
895 | + |
896 | + ObsRange = ""; |
897 | + AcroCos = ""; |
898 | |
899 | |
900 | // Now, compute the days of all the Full Moons of the current year, and get the Earth/Moon distance: |
901 | -// double monthFrac; |
902 | -// int PrevMonths = (int) std::modf((nextFullMoon-Jan1stJD)/MoonT,&monthFrac); |
903 | -// double BestDistance = 1.0; // initial dummy value for Sun-Moon distance; |
904 | - |
905 | -// for (int i=-PrevMonths; i<13 ; i++) |
906 | -// { |
907 | -// jd1 = nextFullMoon + MoonT*((double) i); |
908 | -// getSunMoonCoords(core,jd1,RAS,DecS,RA,Dec,false); |
909 | -// COMPUTE THE DISTANCE VECTOR! |
910 | -// if (Dist < BestDistance) |
911 | +// double monthFrac, monthTemp, maxMoonDate; |
912 | +// monthFrac = std::modf((nextFullMoon-Jan1stJD)/MoonT,&monthTemp); |
913 | +// int PrevMonths = (int)(monthTemp+0.0*monthFrac); |
914 | +// double BestDistance = 1.0; // initial dummy value for Sun-Moon distance; |
915 | +// double Distance; // temporal variable to save Earth-Moon distance at each month. |
916 | + |
917 | +// qDebug() << q_("%1 ").arg(PrevMonths); |
918 | + |
919 | +// for (int i=-PrevMonths; i<13 ; i++) |
920 | // { |
921 | -// BestDistance = Dist; |
922 | -// nextSuperMoon = jd1; |
923 | +// jd1 = nextFullMoon + MoonT*((double) i); |
924 | +// getMoonDistance(core,jd1,Distance,false); |
925 | +// if (Distance < BestDistance) |
926 | +// { // Month with the largest Full Moon: |
927 | +// BestDistance = Distance; |
928 | +// maxMoonDate = jd1; |
929 | +// }; |
930 | // }; |
931 | -// }; |
932 | +// maxMoonDate += GMTShift+0.5; |
933 | +// StelUtils::getDateFromJulianDay(maxMoonDate,&fullYear,&fullMonth,&fullDay); |
934 | +// double MoonSize = MoonPerilune/BestDistance*100.; |
935 | +// ObsRange = q_("Greatest Full Moon: %1 "+months[fullMonth-1]+" (%2% of Moon at Perilune)").arg(fullDay).arg(MoonSize,0,'f',2); |
936 | + }; |
937 | } |
938 | - else |
939 | + else if (Kind <3) |
940 | { |
941 | bestNight = ""; |
942 | + ObsRange = ""; |
943 | + AcroCos = ""; |
944 | + |
945 | }; |
946 | |
947 | - ObsRange = ""; |
948 | - AcroCos = ""; |
949 | - |
950 | |
951 | // Return the Moon and Earth to its current position: |
952 | - getSunMoonCoords(core,myJD,RAS,DecS,RA,Dec,true); |
953 | + if (Kind<3) |
954 | + { |
955 | + getSunMoonCoords(core,myJD,RAS,DecS,RA,Dec,true); |
956 | + } else |
957 | + { |
958 | + getPlanetCoords(core,myJD,RA,Dec,true); |
959 | + }; |
960 | + |
961 | lastJDMoon = myJD; |
962 | |
963 | + |
964 | return raises; |
965 | } |
966 | |
967 | |
968 | === modified file 'plugins/Observability/src/Observability.hpp' |
969 | --- plugins/Observability/src/Observability.hpp 2012-08-11 18:00:27 +0000 |
970 | +++ plugins/Observability/src/Observability.hpp 2012-08-16 18:31:20 +0000 |
971 | @@ -108,8 +108,9 @@ |
972 | //! @param ST sidereal time (degrees). |
973 | virtual double HourAngle2(double RA, double ST); |
974 | |
975 | -//! Solves Moon/Sun Rise/Set/Transit times for the current Julian day. This function updates the variables MoonRise, MoonSet, MoonCulm. Returns success status. |
976 | - virtual bool MoonSunSolve(StelCore* core); |
977 | +//! Solves Moon/Sun/Planet Rise/Set/Transit times for the current Julian day. This function updates the variables MoonRise, MoonSet, MoonCulm. Returns success status. |
978 | +//! @param Kind is 1 for Sun, 2 for Moon, 3 for Solar-System planet. |
979 | + virtual bool SolarSystemSolve(StelCore* core, int Kind); |
980 | |
981 | //! Finds the heliacal rise/set dates of the year for the currently-selected object. |
982 | //! @param Rise day of year of the Acronycal rise. |
983 | @@ -130,6 +131,17 @@ |
984 | virtual void getSunMoonCoords(StelCore* core, double JD, double &RASun, double &DecSun, double &RAMoon, double &DecMoon, bool getBack); |
985 | |
986 | |
987 | +//! computes the selected-planet coordinates at a given Julian date. |
988 | +//! @param core the stellarium core. |
989 | +//! @param JD double for the Julian date. |
990 | +//! @param RA right ascension of the planet (in hours). |
991 | +//! @param Dec declination of the planet (in radians). |
992 | +//! @param getBack controls whether the planet must be returned to its original positions after computation. |
993 | + virtual void getPlanetCoords(StelCore* core, double JD, double &RA, double &Dec, bool getBack); |
994 | + |
995 | +//! Comptues the Earth-Moon distance (in AU) at a given Julian date. The parameters are similar to those of getSunMoonCoords or getPlanetCoords. |
996 | + virtual void getMoonDistance(StelCore* core, double JD, double &Distance, bool getBack); |
997 | + |
998 | //! Returns the angular separation (in radians) between two points. |
999 | //! @param RA1 right ascension of point 1 (in hours) |
1000 | //! @param Dec1 declination of point 1 (in radians) |
1001 | @@ -157,8 +169,7 @@ |
1002 | |
1003 | //! Computes the RA, Dec and Rise/Set Sid. times of the selected planet for each day of the current year. |
1004 | //! @param core the current Stellarium core. |
1005 | -//! @param Name name of the currently selected planet. |
1006 | - virtual void PlanetRADec(StelCore *core, QString Name); |
1007 | + virtual void PlanetRADec(StelCore *core); |
1008 | |
1009 | //! Computes the Sun's RA and Dec for each day of a given year. |
1010 | //! @param core current Stellarium core. |
1011 | @@ -178,7 +189,7 @@ |
1012 | virtual bool CheckRise(int i); |
1013 | |
1014 | //! Some useful constants and variables(almost self-explanatory). |
1015 | - double Rad2Deg, Rad2Hr, AstroTwiAlti, UA, TFrac, JDsec, Jan1stJD, halfpi, MoonT, nextFullMoon, prevFullMoon, RefFullMoon; |
1016 | + double Rad2Deg, Rad2Hr, AstroTwiAlti, UA, TFrac, JDsec, Jan1stJD, halfpi, MoonT, nextFullMoon, prevFullMoon, RefFullMoon, GMTShift, MoonPerilune; |
1017 | |
1018 | //! RA, Dec, observer latitude, object's elevation, and Hour Angle at horizon. |
1019 | double selRA, selDec, mylat, mylon, alti, horizH, culmAlt, myJD; |
1020 | @@ -201,9 +212,11 @@ |
1021 | //! Matrix to transform coordinates for Sun/Moon ephemeris: |
1022 | Mat4d LocTrans; |
1023 | |
1024 | -//! Pointer to the Earth: |
1025 | +//! Pointer to the Earth, Moon, and planet: |
1026 | Planet* myEarth; |
1027 | Planet* myMoon; |
1028 | + Planet* myPlanet; |
1029 | + |
1030 | |
1031 | //! Current simulation year and number of days in the year.; |
1032 | int currYear, nDays, iAltitude; |
1033 | @@ -221,7 +234,8 @@ |
1034 | Vec3d EquPos, LocPos; |
1035 | |
1036 | //! Some booleans to check the kind of source selected and the kind of output to produce. |
1037 | - bool isStar,isMoon,isSun,isScreen, LastSun, raised, configChanged; |
1038 | + bool isStar,isMoon,isSun,isScreen, raised, configChanged, souChanged; |
1039 | + int LastObject; |
1040 | |
1041 | //! Some booleans to select the kind of output. |
1042 | bool show_AcroCos, show_Good_Nights, show_Best_Night, show_Today, show_FullMoon; //, show_Crescent, show_SuperMoon; |
1043 | |
1044 | === modified file 'plugins/Observability/src/gui/ObservabilityDialog.cpp' |
1045 | --- plugins/Observability/src/gui/ObservabilityDialog.cpp 2012-08-12 16:35:50 +0000 |
1046 | +++ plugins/Observability/src/gui/ObservabilityDialog.cpp 2012-08-16 18:31:20 +0000 |
1047 | @@ -94,7 +94,7 @@ |
1048 | QString html = "<html><head></head><body>"; |
1049 | |
1050 | html += "<h2>" + q_("Observability Plug-in") + "</h2><table width=\"90%\">"; |
1051 | - html += "<tr width=\"30%\"><td><strong>" + q_("Version") + ":</strong></td><td> 1.0.1</td></tr>"; |
1052 | + html += "<tr width=\"30%\"><td><strong>" + q_("Version") + ":</strong></td><td> 1.0.2</td></tr>"; |
1053 | html += "<tr><td><strong>" + q_("Author") + ":</strong></td><td>Ivan Marti-Vidal <i.martividal@gmail.com></td></tr></table>"; |
1054 | |
1055 | html += "<p>" + q_("Plugin that analyzes the observability of the selected source (or the screen center, if no source is selected). The plugin can show rise, transit, and set times, as well as the best epoch of the year (i.e., largest angular separation from the Sun), the date range when the source is above the horizon at dark night, and the dates of Acronychal and Cosmical rise/set.<br>Ephemeris of the Solar-System objects and parallax effects are taken into account.<br><br> The author thanks Alexander Wolf and Georg Zotti for their advice.<br><br>Ivan Marti-Vidal (Onsala Space Observatory)") + "</p>"; |
1056 | @@ -104,8 +104,8 @@ |
1057 | html += QString("<tr><td>%1</td><td>%2</td></tr>").arg(q_("Today ephemeris:")).arg(q_("Self-explanatory. The program will show the rise, set, and culmination (transit) times. The exact times for these ephemeris are given in two ways: as time spans (referred to the current time) and as clock hours (in local time).")); |
1058 | html += QString("<tr><td>%1</td><td>%2</td></tr>").arg(q_("Acronychal/Cosmical rise/set:")).arg(q_("The Acronychal rise (or set) of an object happens when the object rises (or sets) just when the Sun sets (or rises), respectively. The exact dates of these ephemeris depend on the Observer's location. The dates between the Acronychal set and rise are those when the altitude of the celestial object uses to be high when the Sun is well below the horizon (hence the object can be well observed). On the contrary, the Cosmical rise (or set) happens when both, the object and the Sun, rise (or set) simultaneously. It is obvious that the source is hardly observable (or not observable at all) in the dates between Cosmical set and rise.")); |
1059 | html += QString("<tr><td>%1</td><td>%2</td></tr>").arg(q_("Largest Sun separation:")).arg(q_("Happens when the angular separation between the Sun and the celestial object are maximum. In most cases, this is equivalent to say that the Equatorial longitudes of the Sun and the object differ by 180 degrees, so the Sun is in opposition to the object. When an object is at its maximum possible angular separation from the Sun (no matter if it is a planet or a star), it culminates roughly at midnight, and on the darkest possible area of the Sky at that declination. Hence, that is the 'best' night to observe a particular object.")); |
1060 | - html += QString("<tr><td>%1</td><td>%2</td></tr>").arg(q_("Best observed from ... to ...:")).arg(q_("The program computes the range of dates when the celestial object is above the horizon at least during one moment of the night. By 'night', the program consideres the time span when the Sun altitude is below that of the twilight (which can be set by the user; see above). When the objects are fixed on the sky (or are exterior planets), the range of observable epochs for the current year can have two possible forms: either a range from one date to another (e.g., 20 Jan to 15 Sep) or in two steps (from 1 Jan to a given date and from another date to 31 Dec). In the first case, the first date (20 Jan in our example) shall be close to the so-called 'Heliacal rise of a star' and the second date (15 Sep in our example) shall be close to the 'Heliacal set'. In the second case (e.g., a range in the form 1 Jan to 20 May and 21 Sep to 31 Dec), the first date (20 May in our example) would be close to the Heliacal set and the second one (21 Sep in our example) to the Heliacal rise. More exact equations to estimate the Heliacal rise/set of stars and planets (which will not depend on the mere input of a twilight Sun elevation by the user) will be implemented in future versions of this plugin.")); |
1061 | - html += QString("<tr><td>%1</td><td>%2</td></tr>").arg(q_("Full Moon:")).arg(q_("When the Moon is selected, the program can compute the exact closest dates (up to 1 minute accuracy) of the Moon's opposition to the Sun.")); |
1062 | + html += QString("<tr><td>%1</td><td>%2</td></tr>").arg(q_("Nights with source above horizon:")).arg(q_("The program computes the range of dates when the celestial object is above the horizon at least during one moment of the night. By 'night', the program considers the time span when the Sun altitude is below that of the twilight (which can be set by the user; see above). When the objects are fixed on the sky (or are exterior planets), the range of observable epochs for the current year can have two possible forms: either a range from one date to another (e.g., 20 Jan to 15 Sep) or in two steps (from 1 Jan to a given date and from another date to 31 Dec). In the first case, the first date (20 Jan in our example) shall be close to the so-called 'Heliacal rise of a star' and the second date (15 Sep in our example) shall be close to the 'Heliacal set'. In the second case (e.g., a range in the form 1 Jan to 20 May and 21 Sep to 31 Dec), the first date (20 May in our example) would be close to the Heliacal set and the second one (21 Sep in our example) to the Heliacal rise. More exact equations to estimate the Heliacal rise/set of stars and planets (which will not depend on the mere input of a twilight Sun elevation by the user) will be implemented in future versions of this plugin.")); |
1063 | + html += QString("<tr><td>%1</td><td>%2</td></tr>").arg(q_("Full Moon:")).arg(q_("When the Moon is selected, the program can compute the exact closest dates of the Moon's opposition to the Sun.")); |
1064 | html += "</table>"; |
1065 | html += "</body></html>"; |
1066 | |
1067 | |
1068 | === modified file 'plugins/Observability/src/gui/ObservabilityDialog.ui' |
1069 | --- plugins/Observability/src/gui/ObservabilityDialog.ui 2012-08-12 12:12:04 +0000 |
1070 | +++ plugins/Observability/src/gui/ObservabilityDialog.ui 2012-08-16 18:31:20 +0000 |
1071 | @@ -177,7 +177,7 @@ |
1072 | <item> |
1073 | <widget class="QCheckBox" name="Goods"> |
1074 | <property name="text"> |
1075 | - <string>Range of observable epochs</string> |
1076 | + <string>Nights with the source above horizon</string> |
1077 | </property> |
1078 | </widget> |
1079 | </item> |
The rise/rose/risen issue (indeed wrong!) is still to be corrected. (allow some days for translators!)
I just tested cosmical set for Mercury, 2012-09-05. For me Sep 4 is closer to a simultaneous set (?)
The rise/transit/set for Mercury (and I guess for the other planets as well) change during the day caused by the planet's speed. For a better estimate, you might want to precompute positions for previous day, day of observation, following day, and do a spline interpolation. (maybe only for 0.12?)
HTH, G.