1 /*
2  * Stellarium
3  * Copyright (C) 2007 Fabien Chereau
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA  02110-1335, USA.
18  */
19 
20 #include "GridLinesMgr.hpp"
21 #include "StelApp.hpp"
22 #include "StelUtils.hpp"
23 #include "StelTranslator.hpp"
24 #include "StelProjector.hpp"
25 #include "StelFader.hpp"
26 #include "Planet.hpp"
27 #include "SolarSystem.hpp"
28 #include "StelLocaleMgr.hpp"
29 #include "StelModuleMgr.hpp"
30 #include "StelCore.hpp"
31 #include "StelObserver.hpp"
32 #include "StelPainter.hpp"
33 #include "StelSkyDrawer.hpp"
34 #include "StelTextureMgr.hpp"
35 #include "StelFileMgr.hpp"
36 #include "StelMovementMgr.hpp"
37 #include "precession.h"
38 
39 #include <set>
40 #include <QSettings>
41 #include <QDebug>
42 #include <QFontMetrics>
43 
44 //! @class SkyGrid
45 //! Class which manages a grid to display in the sky.
46 class SkyGrid
47 {
48 public:
49 	// Create and precompute positions of a SkyGrid
50 	SkyGrid(StelCore::FrameType frame);
51 	virtual ~SkyGrid();
52 	void draw(const StelCore* prj) const;
53 	void setFontSize(int newFontSize);
setColor(const Vec3f & c)54 	void setColor(const Vec3f& c) {color = c;}
getColor() const55 	const Vec3f& getColor() const {return color;}
update(double deltaTime)56 	void update(double deltaTime) {fader.update(static_cast<int>(deltaTime*1000));}
setFadeDuration(float duration)57 	void setFadeDuration(float duration) {fader.setDuration(static_cast<int>(duration*1000.f));}
setDisplayed(const bool displayed)58 	void setDisplayed(const bool displayed){fader = displayed;}
isDisplayed() const59 	bool isDisplayed() const {return fader;}
setLineThickness(const int thickness)60 	void setLineThickness(const int thickness) {lineThickness = thickness;}
getLineThickness() const61 	int getLineThickness() const {return lineThickness;}
62 private:
63 	Vec3f color;
64 	StelCore::FrameType frameType;
65 	QFont font;
66 	LinearFader fader;
67 	int lineThickness;
68 };
69 
70 //! @class SkyPoint
71 //! Class which manages a point to display around the sky like the North Celestial Pole.
72 class SkyPoint
73 {
74 public:
75 	enum SKY_POINT_TYPE
76 	{
77 		CELESTIALPOLES_J2000,
78 		CELESTIALPOLES_OF_DATE,
79 		ZENITH_NADIR,
80 		ECLIPTICPOLES_J2000,
81 		ECLIPTICPOLES_OF_DATE,
82 		GALACTICPOLES,
83 		GALACTICCENTER,
84 		SUPERGALACTICPOLES,
85 		EQUINOXES_J2000,
86 		EQUINOXES_OF_DATE,
87 		SOLSTICES_J2000,
88 		SOLSTICES_OF_DATE,
89 		ANTISOLAR,
90 		EARTH_UMBRA_CENTER,
91 		APEX
92 	};
93 	// Create and precompute positions of a SkyGrid
94 	SkyPoint(SKY_POINT_TYPE _point_type = CELESTIALPOLES_J2000);
95 	virtual ~SkyPoint();
96 	void draw(StelCore* core) const;
setColor(const Vec3f & c)97 	void setColor(const Vec3f& c) {color = c;}
getColor() const98 	const Vec3f& getColor() const {return color;}
update(double deltaTime)99 	void update(double deltaTime) {fader.update(static_cast<int>(deltaTime*1000));}
setFadeDuration(float duration)100 	void setFadeDuration(float duration) {fader.setDuration(static_cast<int>(duration*1000.f));}
setDisplayed(const bool displayed)101 	void setDisplayed(const bool displayed){fader = displayed;}
isDisplayed() const102 	bool isDisplayed() const {return fader;}
103 	void setFontSize(int newSize);
104 	//! Re-translates the label.
105 	void updateLabel();
106 private:
107 	QSharedPointer<Planet> earth, sun;
108 	SKY_POINT_TYPE point_type;
109 	Vec3f color;
110 	StelCore::FrameType frameType;
111 	LinearFader fader;
112 	QFont font;
113 	QString northernLabel, southernLabel;
114 	StelTextureSP texCross;
115 };
116 
117 
118 //! @class SkyLine
119 //! Class which manages a line to display around the sky like the ecliptic line.
120 class SkyLine
121 {
122 public:
123 	enum SKY_LINE_TYPE
124 	{
125 		EQUATOR_J2000,
126 		EQUATOR_OF_DATE,
127 		ECLIPTIC_J2000,
128 		ECLIPTIC_OF_DATE,
129 		PRECESSIONCIRCLE_N,
130 		PRECESSIONCIRCLE_S,
131 		MERIDIAN,
132 		HORIZON,
133 		GALACTICEQUATOR,
134 		SUPERGALACTICEQUATOR,
135 		LONGITUDE,
136 		PRIME_VERTICAL,
137 		CURRENT_VERTICAL,
138 		COLURE_1,
139 		COLURE_2,
140 		CIRCUMPOLARCIRCLE_N,
141 		CIRCUMPOLARCIRCLE_S,
142 		INVARIABLEPLANE,
143 		SOLAR_EQUATOR,
144 		EARTH_UMBRA,
145 		EARTH_PENUMBRA
146 	};
147 	// Create and precompute positions of a SkyGrid
148 	SkyLine(SKY_LINE_TYPE _line_type = EQUATOR_J2000);
149 	virtual ~SkyLine();
150 	static void init(); //! call once before creating the first line.
151 	static void deinit(); //! call once after deleting all lines.
152 	void draw(StelCore* core) const;
setColor(const Vec3f & c)153 	void setColor(const Vec3f& c) {color = c;}
setPartitions(bool visible)154 	void setPartitions(bool visible) {showPartitions = visible;}
showsPartitions() const155 	bool showsPartitions() const {return showPartitions;}
getColor() const156 	const Vec3f& getColor() const {return color;}
update(double deltaTime)157 	void update(double deltaTime) {fader.update(static_cast<int>(deltaTime*1000));}
setFadeDuration(float duration)158 	void setFadeDuration(float duration) {fader.setDuration(static_cast<int>(duration*1000.f));}
setDisplayed(const bool displayed)159 	void setDisplayed(const bool displayed){fader = displayed;}
isDisplayed() const160 	bool isDisplayed() const {return fader;}
setLabeled(const bool displayed)161 	void setLabeled(const bool displayed){showLabel = displayed;}
isLabeled() const162 	bool isLabeled() const {return showLabel;}
163 	void setFontSize(int newSize);
setLineThickness(const int thickness)164 	void setLineThickness(const int thickness) {lineThickness = thickness;}
getLineThickness() const165 	int getLineThickness() const {return lineThickness;}
setPartThickness(const int thickness)166 	void setPartThickness(const int thickness) {partThickness = thickness;}
getPartThickness() const167 	int getPartThickness() const {return partThickness;}
168 	//! Re-translates the label and sets the frameType. Must be called in the constructor!
169 	void updateLabel();
170 	static void setSolarSystem(SolarSystem* ss);
171 private:
172 	static QSharedPointer<Planet> earth, sun, moon;
173 	SKY_LINE_TYPE line_type;
174 	Vec3f color;
175 	StelCore::FrameType frameType;
176 	LinearFader fader;
177 	QFont font;
178 	QString label;
179 	int lineThickness;
180 	int partThickness;
181 	bool showPartitions;
182 	bool showLabel;
183 	static QMap<int, double> precessionPartitions;
184 };
185 
186 // rms added color as parameter
SkyGrid(StelCore::FrameType frame)187 SkyGrid::SkyGrid(StelCore::FrameType frame) : color(0.2f,0.2f,0.2f), frameType(frame), lineThickness(1)
188 {
189 	// Font size is 12
190 	font.setPixelSize(StelApp::getInstance().getScreenFontSize()-1);
191 }
192 
~SkyGrid()193 SkyGrid::~SkyGrid()
194 {
195 }
196 
setFontSize(int newFontSize)197 void SkyGrid::setFontSize(int newFontSize)
198 {
199 	font.setPixelSize(newFontSize);
200 }
201 
202 // Step sizes in arcsec
203 static const double STEP_SIZES_DMS[] = {0.05, 0.2, 1., 5., 10., 60., 300., 600., 1200., 3600., 3600.*5., 3600.*10.};
204 static const double STEP_SIZES_HMS[] = {0.05, 0.2, 1.5, 7.5, 15., 15.*5., 15.*10., 15.*60., 15.*60.*5., 15.*60*10., 15.*60*60};
205 
206 //! Return the angular grid step in degree which best fits the given scale
getClosestResolutionDMS(double pixelPerRad)207 static double getClosestResolutionDMS(double pixelPerRad)
208 {
209 	double minResolution = 80.;
210 	double minSizeArcsec = minResolution/pixelPerRad*M_180_PI*3600;
211 	for (unsigned int i=0;i<12;++i)
212 	{
213 		if (STEP_SIZES_DMS[i]>minSizeArcsec)
214 			return STEP_SIZES_DMS[i]/3600.;
215 	}
216 	return 10.;
217 }
218 
219 //! Return the angular grid step in degree which best fits the given scale
getClosestResolutionHMS(double pixelPerRad)220 static double getClosestResolutionHMS(double pixelPerRad)
221 {
222 	double minResolution = 80.;
223 	double minSizeArcsec = minResolution/pixelPerRad*M_180_PI*3600;
224 	for (unsigned int i=0;i<11;++i)
225 	{
226 		if (STEP_SIZES_HMS[i]>minSizeArcsec)
227 			return STEP_SIZES_HMS[i]/3600.;
228 	}
229 	return 15.;
230 }
231 
232 struct ViewportEdgeIntersectCallbackData
233 {
ViewportEdgeIntersectCallbackDataViewportEdgeIntersectCallbackData234 	ViewportEdgeIntersectCallbackData(StelPainter* p)
235 		: sPainter(p)
236 		, raAngle(0.0)
237 		, frameType(StelCore::FrameUninitialized) {}
238 	StelPainter* sPainter;
239 	Vec4f textColor;
240 	QString text;		// Label to display at the intersection of the lines and screen side
241 	double raAngle;		// Used for meridians
242 	StelCore::FrameType frameType;
243 };
244 
245 // Callback which draws the label of the grid
viewportEdgeIntersectCallback(const Vec3d & screenPos,const Vec3d & direction,void * userData)246 void viewportEdgeIntersectCallback(const Vec3d& screenPos, const Vec3d& direction, void* userData)
247 {
248 	ViewportEdgeIntersectCallbackData* d = static_cast<ViewportEdgeIntersectCallbackData*>(userData);
249 	const Vec4f tmpColor = d->sPainter->getColor();
250 	d->sPainter->setColor(d->textColor);
251 	const bool withDecimalDegree = StelApp::getInstance().getFlagShowDecimalDegrees();
252 	const bool useOldAzimuth = StelApp::getInstance().getFlagSouthAzimuthUsage();
253 	const float ppx = static_cast<float>(d->sPainter->getProjector()->getDevicePixelsPerPixel());
254 
255 	QString text;
256 	if (d->text.isEmpty())
257 	{
258 		// We are in the case of meridians, we need to determine which of the 2 labels (3h or 15h) to use
259 		Vec3d tmpV;
260 		d->sPainter->getProjector()->unProject(screenPos, tmpV);
261 		double lon, lat, textAngle, raAngle;
262 		StelUtils::rectToSphe(&lon, &lat, tmpV);
263 		switch (d->frameType)
264 		{
265 			case StelCore::FrameAltAz:
266 			{
267 				raAngle = ::fmod(M_PI-d->raAngle,2.*M_PI);
268 				lon = ::fmod(M_PI-lon,2.*M_PI);
269 
270 				if (std::fabs(2.*M_PI-lon)<0.001) // We are at meridian 0
271 					lon = 0.;
272 
273 				const double delta = raAngle<M_PI ? M_PI : -M_PI;
274 				if (std::fabs(lon-raAngle) < 0.01 || (lon==0. && raAngle!=M_PI))
275 					textAngle = raAngle;
276 				else
277 					textAngle = raAngle+delta;
278 
279 				if (raAngle==2*M_PI && delta==-M_PI)
280 					textAngle = 0;
281 
282 				if (useOldAzimuth)
283 					textAngle += M_PI;
284 
285 				if (withDecimalDegree)
286 					text = StelUtils::radToDecDegStr(textAngle, 4, false, true);
287 				else
288 					text = StelUtils::radToDmsStrAdapt(textAngle);
289 
290 				break;
291 			}
292 			case StelCore::FrameObservercentricEclipticJ2000:
293 			case StelCore::FrameObservercentricEclipticOfDate:
294 			{
295 				raAngle = d->raAngle;
296 				if (raAngle<0.)
297 					raAngle += 2.*M_PI;
298 
299 				if (lon<0.)
300 					lon += 2*M_PI;
301 
302 				if (std::fabs(2.*M_PI-lon)<0.001) // We are at meridian 0
303 					lon = 0.;
304 
305 				const double delta = raAngle<M_PI ? M_PI : -M_PI;
306 				if (std::fabs(lon-raAngle) < 1. || lon==0.)
307 					textAngle = raAngle;
308 				else
309 					textAngle = raAngle+delta;
310 
311 				if (raAngle==2*M_PI && delta==-M_PI)
312 					textAngle = 0;
313 
314 				if (withDecimalDegree)
315 					text = StelUtils::radToDecDegStr(textAngle, 4, false, true);
316 				else
317 					text = StelUtils::radToDmsStrAdapt(textAngle);
318 
319 				break;
320 			}
321 			default:
322 			{
323 				raAngle = M_PI-d->raAngle;
324 				lon = M_PI-lon;
325 
326 				if (raAngle<0)
327 					raAngle+=2.*M_PI;
328 
329 				if (lon<0)
330 					lon+=2.*M_PI;
331 
332 				if (std::fabs(2.*M_PI-lon)<0.01) // We are at meridian 0
333 					lon = 0.;
334 
335 				if (std::fabs(lon-raAngle) < 0.01)
336 					textAngle = -raAngle+M_PI;
337 				else
338 				{
339 					const double delta = raAngle<M_PI ? M_PI : -M_PI;
340 					textAngle = -raAngle-delta+M_PI;
341 				}
342 
343 
344 				if (withDecimalDegree)
345 					text = StelUtils::radToDecDegStr(textAngle, 4, false, true);
346 				else
347 				{
348 					if (d->frameType == StelCore::FrameGalactic || d->frameType == StelCore::FrameSupergalactic)
349 						text = StelUtils::radToDmsStrAdapt(textAngle);
350 					else
351 						text = StelUtils::radToHmsStrAdapt(textAngle);
352 				}
353 			}
354 		}
355 	}
356 	else
357 		text = d->text;
358 
359 	Vec3f direc=direction.toVec3f();
360 	direc.normalize();
361 	float angleDeg = std::atan2(-direc[1], -direc[0])*M_180_PIf;
362 	float xshift=6.f;
363 	float yshift=6.f;
364 	if (angleDeg>90.f || angleDeg<-90.f)
365 	{
366 		angleDeg+=180.f;
367 		xshift=-(d->sPainter->getFontMetrics().boundingRect(text).width() + xshift*ppx);
368 	}
369 
370 	d->sPainter->drawText(static_cast<float>(screenPos[0]), static_cast<float>(screenPos[1]), text, angleDeg, xshift*ppx, yshift*ppx);
371 	d->sPainter->setColor(tmpColor);
372 	d->sPainter->setBlending(true);
373 }
374 
375 //! Draw the sky grid in the current frame
draw(const StelCore * core) const376 void SkyGrid::draw(const StelCore* core) const
377 {
378 	const StelProjectorP prj = core->getProjection(frameType, frameType!=StelCore::FrameAltAz ? StelCore::RefractionAuto : StelCore::RefractionOff);
379 	if (fader.getInterstate() <= 0.f)
380 		return;
381 
382 	const bool withDecimalDegree = StelApp::getInstance().getFlagShowDecimalDegrees();
383 
384 	// Look for all meridians and parallels intersecting with the disk bounding the viewport
385 	// Check whether the pole are in the viewport
386 	bool northPoleInViewport = false;
387 	bool southPoleInViewport = false;
388 	Vec3f win;
389 	if (prj->project(Vec3f(0,0,1), win) && prj->checkInViewport(win))
390 		northPoleInViewport = true;
391 	if (prj->project(Vec3f(0,0,-1), win) && prj->checkInViewport(win))
392 		southPoleInViewport = true;
393 	// Get the longitude and latitude resolution at the center of the viewport
394 	Vec3d centerV;
395 	prj->unProject(prj->getViewportPosX()+prj->getViewportWidth()/2., prj->getViewportPosY()+prj->getViewportHeight()/2.+1., centerV);
396 	double lon2, lat2;
397 	StelUtils::rectToSphe(&lon2, &lat2, centerV);
398 
399 	const double gridStepParallelRad = M_PI_180*getClosestResolutionDMS(static_cast<double>(prj->getPixelPerRadAtCenter()));
400 	double gridStepMeridianRad;
401 	if (northPoleInViewport || southPoleInViewport)
402 		gridStepMeridianRad = (frameType==StelCore::FrameAltAz || frameType==StelCore::FrameGalactic || frameType==StelCore::FrameSupergalactic) ? M_PI/180.* 10. : M_PI/180.* 15.;
403 	else
404 	{
405 		const double closestResLon = (frameType==StelCore::FrameAltAz || frameType==StelCore::FrameGalactic || frameType==StelCore::FrameSupergalactic) ?
406 					getClosestResolutionDMS(static_cast<double>(prj->getPixelPerRadAtCenter())*std::cos(lat2)) :
407 					getClosestResolutionHMS(static_cast<double>(prj->getPixelPerRadAtCenter())*std::cos(lat2));
408 		gridStepMeridianRad = M_PI/180.* closestResLon;
409 	}
410 
411 	// Get the bounding halfspace
412 	const SphericalCap& viewPortSphericalCap = prj->getBoundingCap();
413 
414 	// Compute the first grid starting point. This point is close to the center of the screen
415 	// and lies at the intersection of a meridian and a parallel
416 	lon2 = gridStepMeridianRad*(static_cast<int>(lon2/gridStepMeridianRad+0.5));
417 	lat2 = gridStepParallelRad*(static_cast<int>(lat2/gridStepParallelRad+0.5));
418 	Vec3d firstPoint;
419 	StelUtils::spheToRect(lon2, lat2, firstPoint);
420 	firstPoint.normalize();
421 
422 	// Q_ASSERT(viewPortSphericalCap.contains(firstPoint));
423 
424 	// Initialize a painter and set OpenGL state
425 	StelPainter sPainter(prj);
426 	sPainter.setBlending(true);
427 	if (lineThickness>1)
428 		sPainter.setLineWidth(lineThickness); // set line thickness
429 	sPainter.setLineSmooth(true);
430 
431 	// make text colors just a bit brighter. (But if >1, QColor::setRgb fails and makes text invisible.)
432 	Vec4f textColor(qMin(1.0f, 1.25f*color[0]), qMin(1.0f, 1.25f*color[1]), qMin(1.0f, 1.25f*color[2]), fader.getInterstate());
433 	sPainter.setColor(color, fader.getInterstate());
434 
435 	sPainter.setFont(font);
436 	ViewportEdgeIntersectCallbackData userData(&sPainter);
437 	userData.textColor = textColor;
438 	userData.frameType = frameType;
439 
440 	/////////////////////////////////////////////////
441 	// Draw all the meridians (great circles)
442 	SphericalCap meridianSphericalCap(Vec3d(1,0,0), 0);
443 	Mat4d rotLon = Mat4d::zrotation(gridStepMeridianRad);
444 	Vec3d fpt = firstPoint;
445 	Vec3d p1, p2;
446 	int maxNbIter = static_cast<int>(M_PI/gridStepMeridianRad);
447 	int i;
448 	for (i=0; i<maxNbIter; ++i)
449 	{
450 		StelUtils::rectToSphe(&lon2, &lat2, fpt);
451 		userData.raAngle = lon2;
452 
453 		meridianSphericalCap.n = fpt^Vec3d(0,0,1);
454 		meridianSphericalCap.n.normalize();
455 		if (!SphericalCap::intersectionPoints(viewPortSphericalCap, meridianSphericalCap, p1, p2))
456 		{
457 			if (viewPortSphericalCap.d<meridianSphericalCap.d && viewPortSphericalCap.contains(meridianSphericalCap.n))
458 			{
459 				// The meridian is fully included in the viewport, draw it in 3 sub-arcs to avoid length > 180.
460 				const Mat4d& rotLon120 = Mat4d::rotation(meridianSphericalCap.n, 120.*M_PI/180.);
461 				Vec3d rotFpt=fpt;
462 				rotFpt.transfo4d(rotLon120);
463 				Vec3d rotFpt2=rotFpt;
464 				rotFpt2.transfo4d(rotLon120);
465 				sPainter.drawGreatCircleArc(fpt, rotFpt, Q_NULLPTR, viewportEdgeIntersectCallback, &userData);
466 				sPainter.drawGreatCircleArc(rotFpt, rotFpt2, Q_NULLPTR, viewportEdgeIntersectCallback, &userData);
467 				sPainter.drawGreatCircleArc(rotFpt2, fpt, Q_NULLPTR, viewportEdgeIntersectCallback, &userData);
468 				fpt.transfo4d(rotLon);
469 				continue;
470 			}
471 			else
472 				break;
473 		}
474 
475 		Vec3d middlePoint = p1+p2;
476 		middlePoint.normalize();
477 		if (!viewPortSphericalCap.contains(middlePoint))
478 			middlePoint*=-1.;
479 
480 		// Draw the arc in 2 sub-arcs to avoid lengths > 180 deg
481 		sPainter.drawGreatCircleArc(p1, middlePoint, Q_NULLPTR, viewportEdgeIntersectCallback, &userData);
482 		sPainter.drawGreatCircleArc(p2, middlePoint, Q_NULLPTR, viewportEdgeIntersectCallback, &userData);
483 
484 		fpt.transfo4d(rotLon);
485 	}
486 
487 	if (i!=maxNbIter)
488 	{
489 		rotLon = Mat4d::zrotation(-gridStepMeridianRad);
490 		fpt = firstPoint;
491 		fpt.transfo4d(rotLon);
492 		for (int j=0; j<maxNbIter-i; ++j)
493 		{
494 			StelUtils::rectToSphe(&lon2, &lat2, fpt);
495 			userData.raAngle = lon2;
496 
497 			meridianSphericalCap.n = fpt^Vec3d(0,0,1);
498 			meridianSphericalCap.n.normalize();
499 			if (!SphericalCap::intersectionPoints(viewPortSphericalCap, meridianSphericalCap, p1, p2))
500 				break;
501 
502 			Vec3d middlePoint = p1+p2;
503 			middlePoint.normalize();
504 			if (!viewPortSphericalCap.contains(middlePoint))
505 				middlePoint*=-1;
506 
507 			sPainter.drawGreatCircleArc(p1, middlePoint, Q_NULLPTR, viewportEdgeIntersectCallback, &userData);
508 			sPainter.drawGreatCircleArc(p2, middlePoint, Q_NULLPTR, viewportEdgeIntersectCallback, &userData);
509 
510 			fpt.transfo4d(rotLon);
511 		}
512 	}
513 
514 	/////////////////////////////////////////////////
515 	// Draw all the parallels (small circles)
516 	SphericalCap parallelSphericalCap(Vec3d(0,0,1), 0);
517 	rotLon = Mat4d::rotation(firstPoint^Vec3d(0,0,1), gridStepParallelRad);
518 	fpt = firstPoint;
519 	maxNbIter = static_cast<int>(M_PI/gridStepParallelRad)-1;
520 	for (i=0; i<maxNbIter; ++i)
521 	{
522 		StelUtils::rectToSphe(&lon2, &lat2, fpt);
523 		if (withDecimalDegree)
524 			userData.text = StelUtils::radToDecDegStr(lat2);
525 		else
526 			userData.text = StelUtils::radToDmsStrAdapt(lat2);
527 
528 		parallelSphericalCap.d = fpt[2];
529 		if (parallelSphericalCap.d>0.9999999)
530 			break;
531 
532 		const Vec3d rotCenter(0,0,parallelSphericalCap.d);
533 		if (!SphericalCap::intersectionPoints(viewPortSphericalCap, parallelSphericalCap, p1, p2))
534 		{
535 			if ((viewPortSphericalCap.d<parallelSphericalCap.d && viewPortSphericalCap.contains(parallelSphericalCap.n))
536 				|| (viewPortSphericalCap.d<-parallelSphericalCap.d && viewPortSphericalCap.contains(-parallelSphericalCap.n)))
537 			{
538 				// The parallel is fully included in the viewport, draw it in 3 sub-arcs to avoid lengths >= 180 deg
539 				static const Mat4d rotLon120 = Mat4d::zrotation(120.*M_PI/180.);
540 				Vec3d rotFpt=fpt;
541 				rotFpt.transfo4d(rotLon120);
542 				Vec3d rotFpt2=rotFpt;
543 				rotFpt2.transfo4d(rotLon120);
544 				sPainter.drawSmallCircleArc(fpt, rotFpt, rotCenter, viewportEdgeIntersectCallback, &userData);
545 				sPainter.drawSmallCircleArc(rotFpt, rotFpt2, rotCenter, viewportEdgeIntersectCallback, &userData);
546 				sPainter.drawSmallCircleArc(rotFpt2, fpt, rotCenter, viewportEdgeIntersectCallback, &userData);
547 				fpt.transfo4d(rotLon);
548 				continue;
549 			}
550 			else
551 				break;
552 		}
553 
554 		// Draw the arc in 2 sub-arcs to avoid lengths > 180 deg
555 		Vec3d middlePoint = p1-rotCenter+p2-rotCenter;
556 		middlePoint.normalize();
557 		middlePoint*=(p1-rotCenter).length();
558 		middlePoint+=rotCenter;
559 		if (!viewPortSphericalCap.contains(middlePoint))
560 		{
561 			middlePoint-=rotCenter;
562 			middlePoint*=-1.;
563 			middlePoint+=rotCenter;
564 		}
565 
566 		sPainter.drawSmallCircleArc(p1, middlePoint, rotCenter, viewportEdgeIntersectCallback, &userData);
567 		sPainter.drawSmallCircleArc(p2, middlePoint, rotCenter, viewportEdgeIntersectCallback, &userData);
568 
569 		fpt.transfo4d(rotLon);
570 	}
571 
572 	if (i!=maxNbIter)
573 	{
574 		rotLon = Mat4d::rotation(firstPoint^Vec3d(0,0,1), -gridStepParallelRad);
575 		fpt = firstPoint;
576 		fpt.transfo4d(rotLon);
577 		for (int j=0; j<maxNbIter-i; ++j)
578 		{
579 			StelUtils::rectToSphe(&lon2, &lat2, fpt);
580 			if (withDecimalDegree)
581 				userData.text = StelUtils::radToDecDegStr(lat2);
582 			else
583 				userData.text = StelUtils::radToDmsStrAdapt(lat2);
584 
585 			parallelSphericalCap.d = fpt[2];
586 			const Vec3d rotCenter(0,0,parallelSphericalCap.d);
587 			if (!SphericalCap::intersectionPoints(viewPortSphericalCap, parallelSphericalCap, p1, p2))
588 			{
589 				if ((viewPortSphericalCap.d<parallelSphericalCap.d && viewPortSphericalCap.contains(parallelSphericalCap.n))
590 					 || (viewPortSphericalCap.d<-parallelSphericalCap.d && viewPortSphericalCap.contains(-parallelSphericalCap.n)))
591 				{
592 					// The parallel is fully included in the viewport, draw it in 3 sub-arcs to avoid lengths >= 180 deg
593 					static const Mat4d rotLon120 = Mat4d::zrotation(120.*M_PI/180.);
594 					Vec3d rotFpt=fpt;
595 					rotFpt.transfo4d(rotLon120);
596 					Vec3d rotFpt2=rotFpt;
597 					rotFpt2.transfo4d(rotLon120);
598 					sPainter.drawSmallCircleArc(fpt, rotFpt, rotCenter, viewportEdgeIntersectCallback, &userData);
599 					sPainter.drawSmallCircleArc(rotFpt, rotFpt2, rotCenter, viewportEdgeIntersectCallback, &userData);
600 					sPainter.drawSmallCircleArc(rotFpt2, fpt, rotCenter, viewportEdgeIntersectCallback, &userData);
601 					fpt.transfo4d(rotLon);
602 					continue;
603 				}
604 				else
605 					break;
606 			}
607 
608 			// Draw the arc in 2 sub-arcs to avoid lengths > 180 deg
609 			Vec3d middlePoint = p1-rotCenter+p2-rotCenter;
610 			middlePoint.normalize();
611 			middlePoint*=(p1-rotCenter).length();
612 			middlePoint+=rotCenter;
613 			if (!viewPortSphericalCap.contains(middlePoint))
614 			{
615 				middlePoint-=rotCenter;
616 				middlePoint*=-1.;
617 				middlePoint+=rotCenter;
618 			}
619 
620 			sPainter.drawSmallCircleArc(p1, middlePoint, rotCenter, viewportEdgeIntersectCallback, &userData);
621 			sPainter.drawSmallCircleArc(p2, middlePoint, rotCenter, viewportEdgeIntersectCallback, &userData);
622 
623 			fpt.transfo4d(rotLon);
624 		}
625 	}
626 
627 	if (lineThickness>1)
628 		sPainter.setLineWidth(1); // reset tickness of line
629 	sPainter.setLineSmooth(false);
630 }
631 
SkyLine(SKY_LINE_TYPE _line_type)632 SkyLine::SkyLine(SKY_LINE_TYPE _line_type) : line_type(_line_type), color(0.f, 0.f, 1.f), lineThickness(1), partThickness(1), showPartitions(true), showLabel(true)
633 {
634 	// Font size is 14
635 	font.setPixelSize(StelApp::getInstance().getScreenFontSize()+1);
636 	updateLabel();
637 }
638 
639 // Contains ecliptic rotations from -13000, -12900, ... , +13000
640 QMap<int, double> SkyLine::precessionPartitions;
641 QSharedPointer<Planet> SkyLine::earth, SkyLine::sun, SkyLine::moon;
642 
643 //! call once before creating the first line.
init()644 void SkyLine::init()
645 {
646 	setSolarSystem(GETSTELMODULE(SolarSystem));
647 	// The years for the precession circles start in -13000, this is 15000 before J2000.
648 	for (int y=-13000; y<=17000; y+=100) // Range of DE431. Maybe extend to -50000..+50000?
649 	{
650 		double jdY0, epsilonA, chiA, omegaA, psiA;
651 		StelUtils::getJDFromDate(&jdY0, y, 1, 0, 0, 0, 0); // JD of Jan.0.
652 		getPrecessionAnglesVondrak(jdY0, &epsilonA, &chiA, &omegaA, &psiA);
653 		precessionPartitions.insert(y, psiA); // Store only the value of shift along the ecliptic.
654 	}
655 }
656 
setSolarSystem(SolarSystem * ss)657 void SkyLine::setSolarSystem(SolarSystem* ss)
658 {
659 	earth = ss->getEarth();
660 	sun   = ss->getSun();
661 	moon  = ss->getMoon();
662 }
663 
deinit()664 void SkyLine::deinit()
665 {
666 	earth = Q_NULLPTR;
667 	sun   = Q_NULLPTR;
668 	moon  = Q_NULLPTR;
669 }
670 
~SkyLine()671 SkyLine::~SkyLine()
672 {
673 }
674 
setFontSize(int newFontSize)675 void SkyLine::setFontSize(int newFontSize)
676 {
677 	font.setPixelSize(newFontSize);
678 }
679 
updateLabel()680 void SkyLine::updateLabel()
681 {
682 	switch (line_type)
683 	{
684 		case MERIDIAN:
685 			frameType = StelCore::FrameAltAz;
686 			label = q_("Meridian");
687 			break;
688 		case ECLIPTIC_J2000:
689 			frameType = StelCore::FrameObservercentricEclipticJ2000;
690 			label = q_("Ecliptic of J2000.0");
691 			break;
692 		case ECLIPTIC_OF_DATE:
693 			frameType = StelCore::FrameObservercentricEclipticOfDate;
694 			label = q_("Ecliptic of Date");
695 			break;
696 		case EQUATOR_J2000:
697 			frameType = StelCore::FrameJ2000;
698 			label = q_("Equator of J2000.0");
699 			break;
700 		case EQUATOR_OF_DATE:
701 			frameType = StelCore::FrameEquinoxEqu;
702 			label = q_("Equator");
703 			break;
704 		case PRECESSIONCIRCLE_N:
705 		case PRECESSIONCIRCLE_S:
706 			frameType = StelCore::FrameObservercentricEclipticOfDate;
707 			label = q_("Precession Circle");
708 			break;
709 		case HORIZON:
710 			frameType = StelCore::FrameAltAz;
711 			label = q_("Horizon");
712 			break;
713 		case GALACTICEQUATOR:
714 			frameType = StelCore::FrameGalactic;
715 			label = q_("Galactic Equator");
716 			break;
717 		case SUPERGALACTICEQUATOR:
718 			frameType = StelCore::FrameSupergalactic;
719 			label = q_("Supergalactic Equator");
720 			break;
721 		case LONGITUDE:
722 			frameType = StelCore::FrameObservercentricEclipticOfDate;
723 			// TRANSLATORS: Full term is "opposition/conjunction longitude"
724 			label = q_("O./C. longitude");
725 			break;
726 		case PRIME_VERTICAL:
727 			frameType=StelCore::FrameAltAz;
728 			label = q_("Prime Vertical");
729 			break;
730 		case CURRENT_VERTICAL:
731 			frameType=StelCore::FrameAltAz;
732 			label = q_("Altitude");
733 			break;
734 		case COLURE_1:
735 			frameType=StelCore::FrameEquinoxEqu;
736 			label = q_("Equinoctial Colure");
737 			break;
738 		case COLURE_2:
739 			frameType=StelCore::FrameEquinoxEqu;
740 			label = q_("Solstitial Colure");
741 			break;
742 		case CIRCUMPOLARCIRCLE_N:
743 		case CIRCUMPOLARCIRCLE_S:
744 			frameType = StelCore::FrameEquinoxEqu;
745 			label = q_("Circumpolar Circle");
746 			break;
747 		case EARTH_UMBRA:
748 			frameType = StelCore::FrameHeliocentricEclipticJ2000;
749 			label = q_("Umbra");
750 			break;
751 		case EARTH_PENUMBRA:
752 			frameType = StelCore::FrameHeliocentricEclipticJ2000;
753 			label = q_("Penumbra");
754 			break;
755 		case INVARIABLEPLANE:
756 			frameType = StelCore::FrameJ2000;
757 			label = q_("Invariable Plane");
758 			break;
759 		case SOLAR_EQUATOR:
760 			frameType = StelCore::FrameJ2000;
761 			label = q_("Projected Solar Equator");
762 			break;
763 	}
764 }
765 
draw(StelCore * core) const766 void SkyLine::draw(StelCore *core) const
767 {
768 	if (fader.getInterstate() <= 0.f)
769 		return;
770 
771 	StelProjectorP prj = core->getProjection(frameType, frameType!=StelCore::FrameAltAz ? StelCore::RefractionAuto : StelCore::RefractionOff);
772 
773 	// Get the bounding halfspace
774 	const SphericalCap& viewPortSphericalCap = prj->getBoundingCap();
775 
776 	// Initialize a painter and set openGL state
777 	StelPainter sPainter(prj);
778 	sPainter.setColor(color, fader.getInterstate());
779 	sPainter.setBlending(true);
780 	const float oldLineWidth=sPainter.getLineWidth();
781 	sPainter.setLineWidth(lineThickness); // set line thickness
782 	sPainter.setLineSmooth(true);
783 
784 	ViewportEdgeIntersectCallbackData userData(&sPainter);
785 	sPainter.setFont(font);
786 	userData.textColor = Vec4f(color, fader.getInterstate());
787 	userData.text = label;
788 	double alt=0, az=0; // Required only for CURRENT_VERTICAL line. Will contain alt/az of view.
789 	/////////////////////////////////////////////////
790 	// Draw the line
791 
792 	// Precession and Circumpolar circles are Small Circles, all others are Great Circles.
793 	if (QList<SKY_LINE_TYPE>({PRECESSIONCIRCLE_N, PRECESSIONCIRCLE_S, CIRCUMPOLARCIRCLE_N, CIRCUMPOLARCIRCLE_S, EARTH_UMBRA, EARTH_PENUMBRA}).contains(line_type))
794 	{
795 		// partitions for precession. (mark millennia!)
796 		double lat=0.;
797 		if (line_type==PRECESSIONCIRCLE_N || line_type==PRECESSIONCIRCLE_S)
798 		{
799 			lat=(line_type==PRECESSIONCIRCLE_S ? -1.0 : 1.0) * (M_PI_2-getPrecessionAngleVondrakCurrentEpsilonA());
800 		}
801 		else if (line_type==CIRCUMPOLARCIRCLE_N || line_type==CIRCUMPOLARCIRCLE_S)
802 		{
803 			const double obsLatRad=core->getCurrentLocation().latitude * (M_PI_180);
804 			if (obsLatRad == 0.)
805 			{
806 				sPainter.setLineWidth(oldLineWidth); // restore painter state
807 				sPainter.setLineSmooth(false);
808 				sPainter.setBlending(false);
809 				return;
810 			}
811 			if (line_type==CIRCUMPOLARCIRCLE_N)
812 				lat=(obsLatRad>0 ? -1.0 : +1.0) * obsLatRad + (M_PI_2);
813 			else // southern circle
814 				lat=(obsLatRad>0 ? +1.0 : -1.0) * obsLatRad - (M_PI_2);
815 		}
816 
817 		if ((line_type==EARTH_UMBRA) || (line_type==EARTH_PENUMBRA))
818 		{
819 			// resizing the shadow together with the Moon would require considerable trickery.
820 			// It seems better to just switch it off.
821 			if (GETSTELMODULE(SolarSystem)->getFlagMoonScale()) return;
822 
823 			// We compute the shadow circle attached to the geocenter, but must point it in the opposite direction of the sun's aberrated position.
824 			const Vec3d pos=earth->getEclipticPos();
825 			const Vec3d dir= - sun->getAberrationPush() + pos;
826 			double lambda, beta;
827 			StelUtils::rectToSphe(&lambda, &beta, dir);
828 			const QPair<Vec3d, Vec3d> radii=GETSTELMODULE(SolarSystem)->getEarthShadowRadiiAtLunarDistance();
829 			const double radius=(line_type==EARTH_UMBRA ? radii.first[1] : radii.second[1]);
830 			const double dist=moon->getEclipticPos().length();  // geocentric Lunar distance [AU]
831 			const Mat4d rot=Mat4d::zrotation(lambda)*Mat4d::yrotation(-beta);
832 
833 			StelVertexArray circle(StelVertexArray::LineLoop);
834 			for (int i=0; i<360; ++i)
835 			{
836 				Vec3d point(dist, cos(i*M_PI_180)*radius, sin(i*M_PI_180)*radius); // disk towards First Point of Aries
837 				rot.transfo(point);                                                // rotate towards earth position
838 				circle.vertex.append(pos+point);                                   // attach to earth centre
839 			}
840 			sPainter.drawStelVertexArray(circle, false); // setting true does not paint for cylindrical&friends :-(
841 
842 			// Special case for Umbra and Penumbra labels
843 			Vec3d point(dist, 0.0, 0.0);
844 			rot.transfo(point);
845 			const float shift=sPainter.getProjector()->getPixelPerRadAtCenter()*(line_type==EARTH_UMBRA ? radii.first[0] : radii.second[0])*0.0000112f/M_PIf;
846 			sPainter.drawText(pos+point, (line_type==EARTH_UMBRA ? q_("Umbra") : q_("Penumbra")), 0.f, shift, shift, false);
847 			return;
848 		}
849 		else
850 		{
851 			SphericalCap declinationCap(Vec3d(0,0,1), std::sin(lat));
852 			const Vec3d rotCenter(0,0,declinationCap.d);
853 
854 			Vec3d p1, p2;
855 			if (!SphericalCap::intersectionPoints(viewPortSphericalCap, declinationCap, p1, p2))
856 			{
857 				if ((viewPortSphericalCap.d<declinationCap.d && viewPortSphericalCap.contains(declinationCap.n))
858 						|| (viewPortSphericalCap.d<-declinationCap.d && viewPortSphericalCap.contains(-declinationCap.n)))
859 				{
860 					// The line is fully included in the viewport, draw it in 3 sub-arcs to avoid length > 180.
861 					Vec3d pt1;
862 					Vec3d pt2;
863 					Vec3d pt3;
864 					const double lon1=0.0;
865 					const double lon2=120.0*M_PI_180;
866 					const double lon3=240.0*M_PI_180;
867 					StelUtils::spheToRect(lon1, lat, pt1); pt1.normalize();
868 					StelUtils::spheToRect(lon2, lat, pt2); pt2.normalize();
869 					StelUtils::spheToRect(lon3, lat, pt3); pt3.normalize();
870 
871 					sPainter.drawSmallCircleArc(pt1, pt2, rotCenter, viewportEdgeIntersectCallback, &userData);
872 					sPainter.drawSmallCircleArc(pt2, pt3, rotCenter, viewportEdgeIntersectCallback, &userData);
873 					sPainter.drawSmallCircleArc(pt3, pt1, rotCenter, viewportEdgeIntersectCallback, &userData);
874 				}
875 			}
876 			else
877 			{
878 				// Draw the arc in 2 sub-arcs to avoid lengths > 180 deg
879 				Vec3d middlePoint = p1-rotCenter+p2-rotCenter;
880 				middlePoint.normalize();
881 				middlePoint*=(p1-rotCenter).length();
882 				middlePoint+=rotCenter;
883 				if (!viewPortSphericalCap.contains(middlePoint))
884 				{
885 					middlePoint-=rotCenter;
886 					middlePoint*=-1.;
887 					middlePoint+=rotCenter;
888 				}
889 
890 				sPainter.drawSmallCircleArc(p1, middlePoint, rotCenter,viewportEdgeIntersectCallback, &userData);
891 				sPainter.drawSmallCircleArc(p2, middlePoint, rotCenter, viewportEdgeIntersectCallback, &userData);
892 			}
893 
894 			if (showPartitions && (line_type==PRECESSIONCIRCLE_N))
895 			{
896 				const float lineThickness=sPainter.getLineWidth();
897 				sPainter.setLineWidth(partThickness);
898 
899 				// Find current value of node rotation.
900 				double epsilonA, chiA, omegaA, psiA;
901 				getPrecessionAnglesVondrak(core->getJDE(), &epsilonA, &chiA, &omegaA, &psiA);
902 				// psiA is the current angle, counted from J2000. Other century years have been precomputed in precessionPartitions.
903 				// We cannot simply sum up the rotations, but must find the century locations one-by-one.
904 
905 				Vec3d part0; // current pole point on the northern precession circle.
906 				StelUtils::spheToRect(0., M_PI/2.-core->getCurrentPlanet().data()->getRotObliquity(core->getJDE()), part0);
907 				Vec3d partAxis(0,1,0);
908 				Vec3d partZAxis = Vec3d(0,0,1); // rotation axis for the year partitions
909 				Vec3d part100=part0;  part100.transfo4d(Mat4d::rotation(partAxis, 0.10*M_PI/180)); // part1 should point to 0.05deg south of "equator"
910 				Vec3d part500=part0;  part500.transfo4d(Mat4d::rotation(partAxis, 0.25*M_PI/180));
911 				Vec3d part1000=part0; part1000.transfo4d(Mat4d::rotation(partAxis, 0.45*M_PI/180));
912 				Vec3d part1000l=part0; part1000l.transfo4d(Mat4d::rotation(partAxis, 0.475*M_PI/180)); // label
913 
914 				Vec3d pt0, ptTgt;
915 				for (int y=-13000; y<13000; y+=100)
916 				{
917 					const double tickAngle=M_PI_2+psiA-precessionPartitions.value(y, 0.);
918 					pt0=part0; pt0.transfo4d(Mat4d::rotation(partZAxis, tickAngle));
919 					if (y%1000 == 0)
920 					{
921 						ptTgt=part1000; ptTgt.transfo4d(Mat4d::rotation(partZAxis, tickAngle));
922 						if (viewPortSphericalCap.contains(pt0) || viewPortSphericalCap.contains(ptTgt))
923 							sPainter.drawGreatCircleArc(pt0, ptTgt, Q_NULLPTR, Q_NULLPTR, Q_NULLPTR);
924 						if (showLabel)
925 						{
926 							Vec3d ptTgtL=part1000l; ptTgtL.transfo4d(Mat4d::rotation(partZAxis, tickAngle));
927 							QString label(QString::number(y));
928 							Vec3d screenPosTgt, screenPosTgtL;
929 							prj->project(ptTgt, screenPosTgt);
930 							prj->project(ptTgtL, screenPosTgtL);
931 							double dx=screenPosTgtL[0]-screenPosTgt[0];
932 							double dy=screenPosTgtL[1]-screenPosTgt[1];
933 							float textAngle=static_cast<float>(atan2(dy,dx));
934 
935 							const float shiftx = 2.f;
936 							const float shifty = - static_cast<float>(sPainter.getFontMetrics().height()) / 4.f;
937 							sPainter.drawText(ptTgt, label, textAngle*M_180_PIf, shiftx, shifty, true);
938 						}
939 					}
940 					else
941 					{
942 						ptTgt=(y%500 == 0 ? part500 : part100);
943 						ptTgt.transfo4d(Mat4d::rotation(partZAxis, tickAngle));
944 						if (viewPortSphericalCap.contains(pt0) || viewPortSphericalCap.contains(ptTgt))
945 							sPainter.drawGreatCircleArc(pt0, ptTgt, Q_NULLPTR, Q_NULLPTR, Q_NULLPTR);
946 					}
947 				}
948 
949 				sPainter.setLineWidth(lineThickness);
950 			}
951 			if (showPartitions && (line_type==PRECESSIONCIRCLE_S))
952 			{
953 				const float lineThickness=sPainter.getLineWidth();
954 				sPainter.setLineWidth(partThickness);
955 
956 				// Find current value of node rotation.
957 				double epsilonA, chiA, omegaA, psiA;
958 				getPrecessionAnglesVondrak(core->getJDE(), &epsilonA, &chiA, &omegaA, &psiA);
959 				// psiA is the current angle, counted from J2000. Other century years have been precomputed in precessionPartitions.
960 				// We cannot simply sum up the rotations, but must find the century locations one-by-one.
961 
962 				Vec3d part0; // current pole point on the northern precession circle.
963 				StelUtils::spheToRect(0., -M_PI/2.+core->getCurrentPlanet().data()->getRotObliquity(core->getJDE()), part0);
964 				Vec3d partAxis(0,1,0);
965 				Vec3d partZAxis = Vec3d(0,0,1); // rotation axis for the year partitions
966 				Vec3d part100=part0;  part100.transfo4d(Mat4d::rotation(partAxis, -0.10*M_PI/180)); // part1 should point to 0.05deg south of "equator"
967 				Vec3d part500=part0;  part500.transfo4d(Mat4d::rotation(partAxis, -0.25*M_PI/180));
968 				Vec3d part1000=part0; part1000.transfo4d(Mat4d::rotation(partAxis, -0.45*M_PI/180));
969 				Vec3d part1000l=part0; part1000.transfo4d(Mat4d::rotation(partAxis, -0.475*M_PI/180)); // label
970 
971 				Vec3d pt0, ptTgt;
972 				for (int y=-13000; y<13000; y+=100)
973 				{
974 					const double tickAngle=-M_PI_2+psiA-precessionPartitions.value(y, 0.);
975 					pt0=part0; pt0.transfo4d(Mat4d::rotation(partZAxis, tickAngle));
976 					if (y%1000 == 0)
977 					{
978 						ptTgt=part1000; ptTgt.transfo4d(Mat4d::rotation(partZAxis, tickAngle));
979 						if (viewPortSphericalCap.contains(pt0) || viewPortSphericalCap.contains(ptTgt))
980 							sPainter.drawGreatCircleArc(pt0, ptTgt, Q_NULLPTR, Q_NULLPTR, Q_NULLPTR);
981 						if (showLabel)
982 						{
983 							Vec3d ptTgtL=part1000l; ptTgtL.transfo4d(Mat4d::rotation(partZAxis, tickAngle));
984 							QString label(QString::number(y));
985 							Vec3d screenPosTgt, screenPosTgtL;
986 							prj->project(ptTgt, screenPosTgt);
987 							prj->project(ptTgtL, screenPosTgtL);
988 							double dx=screenPosTgtL[0]-screenPosTgt[0];
989 							double dy=screenPosTgtL[1]-screenPosTgt[1];
990 							float textAngle=static_cast<float>(atan2(dy,dx));
991 
992 							const float shiftx = -5.f - static_cast<float>(sPainter.getFontMetrics().boundingRect(label).width());
993 							const float shifty = - static_cast<float>(sPainter.getFontMetrics().height()) / 4.f;
994 							sPainter.drawText(ptTgt, label, textAngle*M_180_PIf, shiftx, shifty, true);
995 						}
996 					}
997 					else
998 					{
999 						ptTgt=(y%500 == 0 ? part500 : part100);
1000 						ptTgt.transfo4d(Mat4d::rotation(partZAxis, tickAngle));
1001 						if (viewPortSphericalCap.contains(pt0) || viewPortSphericalCap.contains(ptTgt))
1002 							sPainter.drawGreatCircleArc(pt0, ptTgt, Q_NULLPTR, Q_NULLPTR, Q_NULLPTR);
1003 					}
1004 				}
1005 
1006 				sPainter.setLineWidth(lineThickness);
1007 			}
1008 		}
1009 		sPainter.setLineWidth(oldLineWidth); // restore line thickness
1010 		sPainter.setLineSmooth(false);
1011 		sPainter.setBlending(false);
1012 
1013 		return;
1014 	}
1015 
1016 	// All the other "lines" are Great Circles
1017 	SphericalCap sphericalCap(Vec3d(0,0,1), 0);
1018 	Vec3d fpt(1,0,0); // First Point
1019 
1020 	if ((line_type==MERIDIAN) || (line_type==COLURE_1))
1021 	{
1022 		sphericalCap.n.set(0,1,0);
1023 	}
1024 	else if ((line_type==PRIME_VERTICAL) || (line_type==COLURE_2))
1025 	{
1026 		sphericalCap.n.set(1,0,0);
1027 		fpt.set(0,0,1);
1028 	}
1029 	else if (line_type==CURRENT_VERTICAL)
1030 	{
1031 		Vec3d coordJ2000=GETSTELMODULE(StelMovementMgr)->getViewDirectionJ2000();
1032 		Vec3d coordAltAz=core->j2000ToAltAz(coordJ2000, StelCore::RefractionAuto);
1033 		StelUtils::rectToSphe(&az, &alt, coordAltAz);
1034 		sphericalCap.n.set(sin(-az), cos(-az), 0.);
1035 		fpt.set(0,0,1);
1036 	}
1037 	else if (line_type==LONGITUDE)
1038 	{
1039 		Vec3d coord;
1040 		const double eclJDE = earth->getRotObliquity(core->getJDE());
1041 		double ra_equ, dec_equ, lambdaJDE, betaJDE;
1042 
1043 		StelUtils::rectToSphe(&ra_equ,&dec_equ, sun->getEquinoxEquatorialPos(core));
1044 		StelUtils::equToEcl(ra_equ, dec_equ, eclJDE, &lambdaJDE, &betaJDE);
1045 		if (lambdaJDE<0) lambdaJDE+=2.0*M_PI;
1046 
1047 		StelUtils::spheToRect(lambdaJDE + M_PI_2, 0., coord);
1048 		sphericalCap.n=coord;
1049 		fpt.set(0,0,1);
1050 	}
1051 	else if (line_type==INVARIABLEPLANE)
1052 	{
1053 		// RA, DEC of the Invariable Plane given in WGCCRE2015 report
1054 		static const Mat4d mat=Mat4d::zrotation(M_PI_180*(273.85+90.))*Mat4d::xrotation(M_PI_180*(90.-66.99));
1055 		static const Vec3d axis=mat*Vec3d(0, 0, 1);
1056 		static const Vec3d ivFpt=mat*Vec3d(1, 0, 0);
1057 		sphericalCap.n=axis;
1058 		fpt=ivFpt;
1059 	}
1060 	else if (line_type==SOLAR_EQUATOR)
1061 	{
1062 		// Split out the const part of rotation: rotate along ICRS equator to ascending node
1063 		static const Mat4d solarFrame = Mat4d::zrotation((286.13+90)*M_PI_180) * Mat4d::xrotation((90-63.87)*M_PI_180);
1064 		// Axis rotation. N.B. By this formulation, we ignore any light time correction.
1065 		Mat4d solarRot=solarFrame * Mat4d::zrotation((sun->getSiderealTime(core->getJD(), core->getJDE())*M_PI_180));
1066 
1067 		sphericalCap.n=solarRot*sphericalCap.n;
1068 		fpt=solarRot*fpt;
1069 	}
1070 
1071 	if (showPartitions && !(QList<SKY_LINE_TYPE>({INVARIABLEPLANE, EARTH_UMBRA, EARTH_PENUMBRA}).contains(line_type)))
1072 	{
1073 		const float lineThickness=sPainter.getLineWidth();
1074 		sPainter.setLineWidth(partThickness);
1075 
1076 		// TODO: Before drawing the lines themselves (and returning), draw the short partition lines
1077 		// Define short lines from "equator" a bit "southwards"
1078 		Vec3d part0 = fpt;
1079 		Vec3d partAxis(0,1,0);
1080 		Vec3d partZAxis = sphericalCap.n; // rotation axis for the 360 partitions
1081 		if ((line_type==MERIDIAN) || (line_type==COLURE_1))
1082 		{
1083 			partAxis.set(0,0,1);
1084 		}
1085 		else if ((line_type==PRIME_VERTICAL) || (line_type==COLURE_2))
1086 		{
1087 			part0.set(0,1,0);
1088 			partAxis.set(0,0,1);
1089 		}
1090 		else if ((line_type==LONGITUDE) || (line_type==CURRENT_VERTICAL) || (line_type==SOLAR_EQUATOR))
1091 		{
1092 			partAxis=sphericalCap.n ^ part0;
1093 		}
1094 
1095 		Vec3d part1=part0;  part1.transfo4d(Mat4d::rotation(partAxis, 0.10*M_PI/180)); // part1 should point to 0.05deg south of "equator"
1096 		Vec3d part5=part0;  part5.transfo4d(Mat4d::rotation(partAxis, 0.25*M_PI/180));
1097 		Vec3d part10=part0; part10.transfo4d(Mat4d::rotation(partAxis, 0.45*M_PI/180));
1098 		Vec3d part30=part0; part30.transfo4d(Mat4d::rotation(partAxis, 0.75*M_PI/180));
1099 		Vec3d part30l=part0; part30l.transfo4d(Mat4d::rotation(partAxis, 0.775*M_PI/180));
1100 		const Mat4d& rotZ1 = Mat4d::rotation(partZAxis, 1.0*M_PI/180.);
1101 		// Limit altitude marks to the displayed range
1102 		int i_min= 0;
1103 		int i_max=(line_type==CURRENT_VERTICAL ? 181 : 360);
1104 		if ((line_type==CURRENT_VERTICAL) && (GETSTELMODULE(StelMovementMgr)->getMountMode()==StelMovementMgr::MountAltAzimuthal) &&
1105 		    (core->getCurrentProjectionType()!=StelCore::ProjectionEqualArea) && (core->getCurrentProjectionType()!=StelCore::ProjectionStereographic) && (core->getCurrentProjectionType()!=StelCore::ProjectionFisheye))
1106 		{
1107 			// Avoid marks creeping sideways
1108 			if (alt<= 2*M_PI_180) i_min =static_cast<int>(-alt*M_180_PI)+2;
1109 			if (alt>=-2*M_PI_180) i_max-=static_cast<int>( alt*M_180_PI)+2;
1110 		}
1111 
1112 		for (int i=0; i<i_max; ++i)
1113 		{
1114 			if ((line_type==CURRENT_VERTICAL && i>=i_min) || (line_type!=CURRENT_VERTICAL)){
1115 
1116 				if (i%30 == 0 && (viewPortSphericalCap.contains(part0) || viewPortSphericalCap.contains(part30)))
1117 				{
1118 					sPainter.drawGreatCircleArc(part0, part30, Q_NULLPTR, Q_NULLPTR, Q_NULLPTR);
1119 
1120 					if (showLabel)
1121 					{
1122 						// we must adapt (rotate) some labels to observers on the southern hemisphere.
1123 						const bool southernHemi = core->getCurrentLocation().latitude < 0.f;
1124 						int value=i;
1125 						float extraTextAngle=0.f;
1126 						// shiftx/y is OK for equator, horizon, ecliptic.
1127 						float shiftx = - static_cast<float>(sPainter.getFontMetrics().boundingRect(QString("%1°").arg(value)).width()) * 0.5f;
1128 						float shifty = - static_cast<float>(sPainter.getFontMetrics().height());
1129 						QString unit("°");
1130 						QString label;
1131 						switch (line_type) {
1132 							case EQUATOR_J2000:
1133 							case EQUATOR_OF_DATE:
1134 								if (!StelApp::getInstance().getFlagShowDecimalDegrees())
1135 								{
1136 									value /= 15;
1137 									unit="h";
1138 								}
1139 								extraTextAngle = southernHemi ? -90.f : 90.f;
1140 								if (southernHemi) shifty*=-0.25f;
1141 								break;
1142 							case HORIZON:
1143 								value=(360-i+(StelApp::getInstance().getFlagSouthAzimuthUsage() ? 0 : 180)) % 360;
1144 								extraTextAngle=90.f;
1145 								break;
1146 							case MERIDIAN:
1147 							case COLURE_1: // Equinoctial Colure
1148 								shifty = - static_cast<float>(sPainter.getFontMetrics().height()) * 0.25f;
1149 								if (i<90) // South..Nadir | ARI0..CSP
1150 								{
1151 									value=-i;
1152 									extraTextAngle = (line_type==COLURE_1 && southernHemi) ? 0.f : 180.f;
1153 									shiftx = (line_type==COLURE_1 && southernHemi) ? 3.f : - static_cast<float>(sPainter.getFontMetrics().boundingRect(QString("%1°").arg(value)).width()) - 3.f;
1154 								}
1155 								else if (i>270) // Zenith..South | CNP..ARI0
1156 								{
1157 									value=360-i;
1158 									extraTextAngle = (line_type==COLURE_1 && southernHemi) ? 0.f : 180.f;
1159 									shiftx = (line_type==COLURE_1 && southernHemi) ? 3.f : - static_cast<float>(sPainter.getFontMetrics().boundingRect(QString("%1°").arg(value)).width()) - 3.f;
1160 								}
1161 								else // Nadir..North..Zenith | CSP..Equator:12h..CNP
1162 								{
1163 									value=i-180;
1164 									extraTextAngle = (line_type==COLURE_1 && southernHemi) ? 180.f : 0.f;
1165 									shiftx = (line_type==COLURE_1 && southernHemi) ? - static_cast<float>(sPainter.getFontMetrics().boundingRect(QString("%1°").arg(value)).width()) - 3.f : 3.f;
1166 								}
1167 								break;
1168 							case PRIME_VERTICAL:
1169 							case COLURE_2: // Solstitial Colure
1170 								shifty = - static_cast<float>(sPainter.getFontMetrics().height()) * 0.25f;
1171 								if (i<90) // East..Zenith | Equator:6h..SummerSolstice..CNP
1172 								{
1173 									value=i;
1174 									extraTextAngle = (line_type==COLURE_2 && southernHemi) ? 0.f : 180.f;
1175 									shiftx = (line_type==COLURE_2 && southernHemi) ? 3.f : - static_cast<float>(sPainter.getFontMetrics().boundingRect(QString("%1°").arg(value)).width()) - 3.f;
1176 								}
1177 								else if (i<270) // Zenith..West..Nadir | CNP..WinterSolstice..CSP
1178 								{
1179 									value=180-i;
1180 									extraTextAngle = (line_type==COLURE_2 && southernHemi) ? 180.f : 0.f;
1181 									shiftx = (line_type==COLURE_2 && southernHemi) ? - static_cast<float>(sPainter.getFontMetrics().boundingRect(QString("%1°").arg(value)).width()) - 3.f : 3.f;
1182 								}
1183 								else // Nadir..East | CSP..Equator:6h
1184 								{
1185 									value=i-360;
1186 									extraTextAngle = (line_type==COLURE_2 && southernHemi) ? 0.f : 180.f;
1187 									shiftx = (line_type==COLURE_2 && southernHemi) ? 3.f : - static_cast<float>(sPainter.getFontMetrics().boundingRect(QString("%1°").arg(value)).width()) - 3.f;
1188 								}
1189 								break;
1190 							case CURRENT_VERTICAL:
1191 								shifty = - static_cast<float>(sPainter.getFontMetrics().height()) * 0.25f;
1192 								value=90-i;
1193 								shiftx = 3.0f;
1194 								break;
1195 							case LONGITUDE:
1196 								value=( i<180 ? 90-i : i-270 );
1197 								shifty = - static_cast<float>(sPainter.getFontMetrics().height()) * 0.25f;
1198 								shiftx = (i<180) ^ southernHemi ? 3.f : -static_cast<float>(sPainter.getFontMetrics().boundingRect(QString("%1°").arg(value)).width()) - 3.f;
1199 								extraTextAngle = (i<180) ^ southernHemi ? 0.f : 180.f;
1200 								break;
1201 							case GALACTICEQUATOR:
1202 							case SUPERGALACTICEQUATOR:
1203 								extraTextAngle = 90.f;
1204 								break;
1205 							default:
1206 								extraTextAngle = southernHemi ? -90.f : 90.f;
1207 								if (southernHemi) shifty*=-0.25f;
1208 								break;
1209 						}
1210 						label = QString("%1%2").arg(value).arg(unit);
1211 						Vec3d screenPosTgt, screenPosTgtL;
1212 						prj->project(part30, screenPosTgt);
1213 						prj->project(part30l, screenPosTgtL);
1214 						double dx=screenPosTgtL[0]-screenPosTgt[0];
1215 						double dy=screenPosTgtL[1]-screenPosTgt[1];
1216 						float textAngle=static_cast<float>(atan2(dy,dx));
1217 						sPainter.drawText(part30l, label, textAngle*M_180_PIf + extraTextAngle, shiftx, shifty, false);
1218 					}
1219 				}
1220 
1221 				else if (i%10 == 0 && (viewPortSphericalCap.contains(part0) || viewPortSphericalCap.contains(part10)))
1222 					sPainter.drawGreatCircleArc(part0, part10, Q_NULLPTR, Q_NULLPTR, Q_NULLPTR);
1223 				else if (i%5 == 0 && (viewPortSphericalCap.contains(part0) || viewPortSphericalCap.contains(part5)))
1224 					sPainter.drawGreatCircleArc(part0, part5, Q_NULLPTR, Q_NULLPTR, Q_NULLPTR);
1225 				else if( viewPortSphericalCap.contains(part0) || viewPortSphericalCap.contains(part1))
1226 					sPainter.drawGreatCircleArc(part0, part1, Q_NULLPTR, Q_NULLPTR, Q_NULLPTR);
1227 			}
1228 			part0.transfo4d(rotZ1);
1229 			part1.transfo4d(rotZ1);
1230 			part5.transfo4d(rotZ1);
1231 			part10.transfo4d(rotZ1);
1232 			part30.transfo4d(rotZ1);
1233 			part30l.transfo4d(rotZ1);
1234 		}
1235 		sPainter.setLineWidth(lineThickness);
1236 	}
1237 
1238 	Vec3d p1, p2;
1239 	if (line_type==CURRENT_VERTICAL)
1240 	{
1241 		// The usual handling should always projects this circle into a straight line. However, with some projections we see ugly artifacts. Better handle this line specially.
1242 		p1.set(0.,0.,1.);
1243 		p2.set(0.,0.,-1.);
1244 		Vec3d pHori;
1245 		StelUtils::spheToRect(az, 0., pHori);
1246 		if (GETSTELMODULE(StelMovementMgr)->getMountMode()==StelMovementMgr::MountAltAzimuthal)
1247 		{
1248 			switch (core->getCurrentProjectionType())
1249 			{
1250 				case StelCore::ProjectionOrthographic:
1251 					StelUtils::spheToRect(az, qMin(M_PI_2, alt+M_PI_2), p1);
1252 					StelUtils::spheToRect(az, qMax(-M_PI_2, alt-M_PI_2), p2);
1253 					break;
1254 				case StelCore::ProjectionEqualArea:
1255 					if (alt*M_180_PI<-89.0) StelUtils::spheToRect(az,  89.5*M_PI_180, p1);
1256 					if (alt*M_180_PI> 89.0) StelUtils::spheToRect(az, -89.5*M_PI_180, p2);
1257 					break;
1258 				case StelCore::ProjectionHammer:
1259 				case StelCore::ProjectionSinusoidal:
1260 				case StelCore::ProjectionMercator:
1261 				case StelCore::ProjectionMiller:
1262 				case StelCore::ProjectionCylinder:
1263 					StelUtils::spheToRect(az, qMin(M_PI_2, alt+M_PI_2)-0.05*M_PI_180, p1);
1264 					StelUtils::spheToRect(az, qMax(-M_PI_2, alt-M_PI_2)+0.05*M_PI_180, p2);
1265 					break;
1266 				default:
1267 					break;
1268 			}
1269 		}
1270 		// Now draw through a middle point.
1271 		sPainter.drawGreatCircleArc(p1, pHori, Q_NULLPTR, viewportEdgeIntersectCallback, &userData);
1272 		sPainter.drawGreatCircleArc(p2, pHori, Q_NULLPTR, viewportEdgeIntersectCallback, &userData);
1273 	}
1274 	else
1275 	{
1276 		if (!SphericalCap::intersectionPoints(viewPortSphericalCap, sphericalCap, p1, p2))
1277 		{
1278 			if ((viewPortSphericalCap.d< sphericalCap.d && viewPortSphericalCap.contains( sphericalCap.n))
1279 			 || (viewPortSphericalCap.d<-sphericalCap.d && viewPortSphericalCap.contains(-sphericalCap.n)))
1280 			{
1281 				// The meridian is fully included in the viewport, draw it in 3 sub-arcs to avoid length > 180.
1282 				const Mat4d& rotLon120 = Mat4d::rotation(sphericalCap.n, 120.*M_PI_180);
1283 				Vec3d rotFpt=fpt;
1284 				rotFpt.transfo4d(rotLon120);
1285 				Vec3d rotFpt2=rotFpt;
1286 				rotFpt2.transfo4d(rotLon120);
1287 				sPainter.drawGreatCircleArc(fpt, rotFpt, Q_NULLPTR, viewportEdgeIntersectCallback, &userData);
1288 				sPainter.drawGreatCircleArc(rotFpt, rotFpt2, Q_NULLPTR, viewportEdgeIntersectCallback, &userData);
1289 				sPainter.drawGreatCircleArc(rotFpt2, fpt, Q_NULLPTR, viewportEdgeIntersectCallback, &userData);
1290 			}
1291 		}
1292 		else
1293 		{
1294 			Vec3d middlePoint = p1+p2;
1295 			middlePoint.normalize();
1296 			if (!viewPortSphericalCap.contains(middlePoint))
1297 				middlePoint*=-1.;
1298 
1299 			// Draw the arc in 2 sub-arcs to avoid lengths > 180 deg
1300 			sPainter.drawGreatCircleArc(p1, middlePoint, Q_NULLPTR, viewportEdgeIntersectCallback, &userData);
1301 			sPainter.drawGreatCircleArc(p2, middlePoint, Q_NULLPTR, viewportEdgeIntersectCallback, &userData);
1302 		}
1303 	}
1304 
1305 	sPainter.setLineWidth(oldLineWidth); // restore line thickness
1306 	sPainter.setLineSmooth(false);
1307 	sPainter.setBlending(false);
1308 }
1309 
SkyPoint(SKY_POINT_TYPE _point_type)1310 SkyPoint::SkyPoint(SKY_POINT_TYPE _point_type) : point_type(_point_type), color(0.f, 0.f, 1.f)
1311 {
1312 	// Font size is 14
1313 	font.setPixelSize(StelApp::getInstance().getScreenFontSize()+1);
1314 	texCross = StelApp::getInstance().getTextureManager().createTexture(StelFileMgr::getInstallationDir()+"/textures/cross.png");
1315 
1316 	earth = GETSTELMODULE(SolarSystem)->getEarth();
1317 	sun = GETSTELMODULE(SolarSystem)->getSun();
1318 
1319 	updateLabel();
1320 }
1321 
~SkyPoint()1322 SkyPoint::~SkyPoint()
1323 {
1324 	texCross.clear();
1325 }
1326 
setFontSize(int newFontSize)1327 void SkyPoint::setFontSize(int newFontSize)
1328 {
1329 	font.setPixelSize(newFontSize);
1330 }
1331 
updateLabel()1332 void SkyPoint::updateLabel()
1333 {
1334 	switch (point_type)
1335 	{
1336 		case CELESTIALPOLES_J2000:
1337 		{
1338 			frameType = StelCore::FrameJ2000;
1339 			// TRANSLATORS: North Celestial Pole
1340 			northernLabel = q_("NCP");
1341 			// TRANSLATORS: South Celestial Pole
1342 			southernLabel = q_("SCP");
1343 			break;
1344 		}
1345 		case CELESTIALPOLES_OF_DATE:
1346 		{
1347 			frameType = StelCore::FrameEquinoxEqu;
1348 			// TRANSLATORS: North Celestial Pole
1349 			northernLabel = q_("NCP");
1350 			// TRANSLATORS: South Celestial Pole
1351 			southernLabel = q_("SCP");
1352 			break;
1353 		}
1354 		case ZENITH_NADIR:
1355 		{
1356 			frameType = StelCore::FrameAltAz;
1357 			// TRANSLATORS: Zenith
1358 			northernLabel = qc_("Z", "zenith");
1359 			// TRANSLATORS: Nadir
1360 			southernLabel = qc_("Z'", "nadir");
1361 			break;
1362 		}
1363 		case ECLIPTICPOLES_J2000:
1364 		{
1365 			frameType = StelCore::FrameObservercentricEclipticJ2000;
1366 			// TRANSLATORS: North Ecliptic Pole
1367 			northernLabel = q_("NEP");
1368 			// TRANSLATORS: South Ecliptic Pole
1369 			southernLabel = q_("SEP");
1370 			break;
1371 		}
1372 		case ECLIPTICPOLES_OF_DATE:
1373 		{
1374 			frameType = StelCore::FrameObservercentricEclipticOfDate;
1375 			// TRANSLATORS: North Ecliptic Pole
1376 			northernLabel = q_("NEP");
1377 			// TRANSLATORS: South Ecliptic Pole
1378 			southernLabel = q_("SEP");
1379 			break;
1380 		}
1381 		case GALACTICPOLES:
1382 		{
1383 			frameType = StelCore::FrameGalactic;
1384 			// TRANSLATORS: North Galactic Pole
1385 			northernLabel = q_("NGP");
1386 			// TRANSLATORS: South Galactic Pole
1387 			southernLabel = q_("SGP");
1388 			break;
1389 		}
1390 		case GALACTICCENTER:
1391 		{
1392 			frameType = StelCore::FrameGalactic;
1393 			// TRANSLATORS: Galactic Center point
1394 			northernLabel = q_("GC");
1395 			// TRANSLATORS: Galactic Anticenter point
1396 			southernLabel = q_("GA");
1397 			break;
1398 		}
1399 		case SUPERGALACTICPOLES:
1400 		{
1401 			frameType = StelCore::FrameSupergalactic;
1402 			// TRANSLATORS: North Supergalactic Pole
1403 			northernLabel = q_("NSGP");
1404 			// TRANSLATORS: South Supergalactic Pole
1405 			southernLabel = q_("SSGP");
1406 			break;
1407 		}
1408 		case EQUINOXES_J2000:
1409 		{
1410 			frameType = StelCore::FrameJ2000;
1411 			northernLabel = QChar(0x2648); // Vernal equinox
1412 			southernLabel = QChar(0x264E); // Autumnal equinox
1413 			break;
1414 		}
1415 		case EQUINOXES_OF_DATE:
1416 		{
1417 			frameType = StelCore::FrameEquinoxEqu;
1418 			northernLabel = QChar(0x2648); // Vernal equinox
1419 			southernLabel = QChar(0x264E); // Autumnal equinox
1420 			break;
1421 		}
1422 		case SOLSTICES_J2000:
1423 		{
1424 			frameType = StelCore::FrameObservercentricEclipticJ2000;
1425 			northernLabel = QChar(0x264B); // Summer solstice
1426 			southernLabel = QChar(0x2651); // Winter solstice
1427 			break;
1428 		}
1429 		case SOLSTICES_OF_DATE:
1430 		{
1431 			frameType = StelCore::FrameObservercentricEclipticOfDate;
1432 			northernLabel = QChar(0x264B); // Summer solstice
1433 			southernLabel = QChar(0x2651); // Winter solstice
1434 			break;
1435 		}
1436 		case ANTISOLAR:
1437 		{
1438 			frameType = StelCore::FrameObservercentricEclipticJ2000;
1439 			// TRANSLATORS: Antisolar Point
1440 			northernLabel = q_("ASP");
1441 			break;
1442 		}
1443 		case EARTH_UMBRA_CENTER:
1444 		{
1445 			frameType = StelCore::FrameHeliocentricEclipticJ2000;
1446 			// TRANSLATORS: Center of the umbra
1447 			northernLabel = q_("C.U.");
1448 			break;
1449 		}
1450 		case APEX:
1451 		{
1452 			frameType = StelCore::FrameObservercentricEclipticJ2000;
1453 			// TRANSLATORS: Apex Point, where the observer planet is heading to
1454 			northernLabel = q_("Apex");
1455 			// TRANSLATORS: Antapex Point, where the observer planet is receding from
1456 			southernLabel = q_("Antapex");
1457 			// add heliocentric speed
1458 			StelCore *core=StelApp::getInstance().getCore();
1459 			QSharedPointer<Planet> planet=core->getCurrentObserver()->getHomePlanet();
1460 			Q_ASSERT(planet);
1461 			const Vec3d dir=planet->getHeliocentricEclipticVelocity();
1462 			const double speed=dir.length()*(AU/86400.0);
1463 			// In some cases we don't have a valid speed vector
1464 			if (speed>0.)
1465 			{
1466 				const QString kms = qc_("km/s", "speed");
1467 				QString speedStr = QString(" (%1 %2)").arg(QString::number(speed, 'f', 2)).arg(kms);
1468 				northernLabel += speedStr;
1469 				speedStr = QString(" (-%1 %2)").arg(QString::number(speed, 'f', 2)).arg(kms);
1470 				southernLabel += speedStr;
1471 			}
1472 			break;
1473 		}
1474 		default:
1475 			Q_ASSERT(0);
1476 	}
1477 }
1478 
draw(StelCore * core) const1479 void SkyPoint::draw(StelCore *core) const
1480 {
1481 	if (!fader.getInterstate())
1482 		return;
1483 
1484 	StelProjectorP prj = core->getProjection(frameType, frameType!=StelCore::FrameAltAz ? StelCore::RefractionAuto : StelCore::RefractionOff);
1485 
1486 	// Initialize a painter and set openGL state
1487 	StelPainter sPainter(prj);
1488 	sPainter.setColor(color, fader.getInterstate());
1489 	Vec4f textColor(color, fader.getInterstate());
1490 
1491 	sPainter.setFont(font);
1492 	/////////////////////////////////////////////////
1493 	// Draw the point
1494 
1495 	texCross->bind();
1496 	const float size = 0.00001f*M_PI_180f*sPainter.getProjector()->getPixelPerRadAtCenter();
1497 	const float shift = 4.f + size/1.8f;
1498 
1499 	sPainter.setBlending(true, GL_ONE, GL_ONE);
1500 
1501 	switch (point_type)
1502 	{
1503 		case CELESTIALPOLES_J2000:
1504 		case CELESTIALPOLES_OF_DATE:
1505 		case ZENITH_NADIR:
1506 		case ECLIPTICPOLES_J2000:
1507 		case ECLIPTICPOLES_OF_DATE:
1508 		case GALACTICPOLES:
1509 		case SUPERGALACTICPOLES:
1510 		{
1511 			// North Pole
1512 			sPainter.drawSprite2dMode(Vec3d(0,0,1), 5.f);
1513 			sPainter.drawText(Vec3d(0,0,1), northernLabel, 0, shift, shift, false);
1514 
1515 			// South Pole
1516 			sPainter.drawSprite2dMode(Vec3d(0,0,-1), 5.f);
1517 			sPainter.drawText(Vec3d(0,0,-1), southernLabel, 0, shift, shift, false);
1518 			break;
1519 		}
1520 		case EQUINOXES_J2000:
1521 		case EQUINOXES_OF_DATE:
1522 		{
1523 			// Vernal equinox
1524 			sPainter.drawSprite2dMode(Vec3d(1,0,0), 5.f);
1525 			sPainter.drawText(Vec3d(1,0,0), northernLabel, 0, shift, shift, false);
1526 
1527 			// Autumnal equinox
1528 			sPainter.drawSprite2dMode(Vec3d(-1,0,0), 5.f);
1529 			sPainter.drawText(Vec3d(-1,0,0), southernLabel, 0, shift, shift, false);
1530 			break;
1531 		}
1532 		case SOLSTICES_J2000:
1533 		case SOLSTICES_OF_DATE:
1534 		{
1535 			// Summer solstice
1536 			sPainter.drawSprite2dMode(Vec3d(0,1,0), 5.f);
1537 			sPainter.drawText(Vec3d(0,1,0), northernLabel, 0, shift, shift, false);
1538 
1539 			// Winter solstice
1540 			sPainter.drawSprite2dMode(Vec3d(0,-1,0), 5.f);
1541 			sPainter.drawText(Vec3d(0,-1,0), southernLabel, 0, shift, shift, false);
1542 			break;
1543 		}
1544 		case GALACTICCENTER:
1545 		{
1546 			// Galactic Center point
1547 			sPainter.drawSprite2dMode(Vec3d(1,0,0), 5.f);
1548 			sPainter.drawText(Vec3d(1,0,0), northernLabel, 0, shift, shift, false);
1549 
1550 			// Galactic Anticenter point
1551 			sPainter.drawSprite2dMode(Vec3d(-1,0,0), 5.f);
1552 			sPainter.drawText(Vec3d(-1,0,0), southernLabel, 0, shift, shift, false);
1553 			break;
1554 		}
1555 		case ANTISOLAR:
1556 		{
1557 			// Antisolar Point
1558 			Vec3d coord=core->getCurrentObserver()->getHomePlanet()->getHeliocentricEclipticPos();
1559 			sPainter.drawSprite2dMode(coord, 5.f);
1560 			sPainter.drawText(coord, northernLabel, 0, shift, shift, false);
1561 			break;
1562 		}
1563 		case EARTH_UMBRA_CENTER:
1564 		{
1565 			// We compute the shadow center attached to the geocenter, but must point it in the opposite direction of the sun's aberrated position.
1566 			const Vec3d pos=earth->getEclipticPos();
1567 			const Vec3d dir= - sun->getAberrationPush() + pos;
1568 			double lambda, beta;
1569 			StelUtils::rectToSphe(&lambda, &beta, dir);
1570 			const double dist=GETSTELMODULE(SolarSystem)->getMoon()->getEclipticPos().length();
1571 			const Mat4d rot=Mat4d::zrotation(lambda)*Mat4d::yrotation(-beta);
1572 
1573 			Vec3d point(dist, 0.0, 0.0);
1574 			rot.transfo(point);
1575 			Vec3d coord = pos+point;
1576 			sPainter.drawSprite2dMode(coord, 5.f);
1577 			sPainter.drawText(coord, northernLabel, 0, shift, shift, false);
1578 			break;
1579 		}
1580 		case APEX:
1581 		{
1582 			// Observer planet apex (heading point)
1583 			QSharedPointer<Planet> planet=core->getCurrentObserver()->getHomePlanet();
1584 			Q_ASSERT(planet);
1585 			const Vec3d dir=planet->getHeliocentricEclipticVelocity();
1586 			// In some cases we don't have a valid speed vector
1587 			if (dir.lengthSquared()>0.)
1588 			{
1589 				sPainter.drawSprite2dMode(dir, 5.f);
1590 				sPainter.drawText(dir, northernLabel, 0, shift, shift, false);
1591 				sPainter.drawSprite2dMode(-dir, 5.f);
1592 				sPainter.drawText(-dir, southernLabel, 0, shift, shift, false);
1593 			}
1594 			break;
1595 		}
1596 		default:
1597 			Q_ASSERT(0);
1598 	}
1599 }
1600 
1601 
GridLinesMgr()1602 GridLinesMgr::GridLinesMgr()
1603 	: gridlinesDisplayed(true)
1604 {
1605 	setObjectName("GridLinesMgr");
1606 	SkyLine::init();
1607 
1608 	equGrid = new SkyGrid(StelCore::FrameEquinoxEqu);
1609 	equJ2000Grid = new SkyGrid(StelCore::FrameJ2000);
1610 	eclJ2000Grid = new SkyGrid(StelCore::FrameObservercentricEclipticJ2000);
1611 	eclGrid = new SkyGrid(StelCore::FrameObservercentricEclipticOfDate);
1612 	galacticGrid = new SkyGrid(StelCore::FrameGalactic);
1613 	supergalacticGrid = new SkyGrid(StelCore::FrameSupergalactic);
1614 	aziGrid = new SkyGrid(StelCore::FrameAltAz);
1615 	equatorLine = new SkyLine(SkyLine::EQUATOR_OF_DATE);
1616 	equatorJ2000Line = new SkyLine(SkyLine::EQUATOR_J2000);
1617 	eclipticJ2000Line = new SkyLine(SkyLine::ECLIPTIC_J2000);
1618 	eclipticLine = new SkyLine(SkyLine::ECLIPTIC_OF_DATE);
1619 	invariablePlaneLine = new SkyLine(SkyLine::INVARIABLEPLANE);
1620 	solarEquatorLine = new SkyLine(SkyLine::SOLAR_EQUATOR);
1621 	precessionCircleN = new SkyLine(SkyLine::PRECESSIONCIRCLE_N);
1622 	precessionCircleS = new SkyLine(SkyLine::PRECESSIONCIRCLE_S);
1623 	meridianLine = new SkyLine(SkyLine::MERIDIAN);
1624 	horizonLine = new SkyLine(SkyLine::HORIZON);
1625 	galacticEquatorLine = new SkyLine(SkyLine::GALACTICEQUATOR);
1626 	supergalacticEquatorLine = new SkyLine(SkyLine::SUPERGALACTICEQUATOR);
1627 	longitudeLine = new SkyLine(SkyLine::LONGITUDE);
1628 	primeVerticalLine = new SkyLine(SkyLine::PRIME_VERTICAL);
1629 	currentVerticalLine = new SkyLine(SkyLine::CURRENT_VERTICAL);
1630 	colureLine_1 = new SkyLine(SkyLine::COLURE_1);
1631 	colureLine_2 = new SkyLine(SkyLine::COLURE_2);
1632 	circumpolarCircleN = new SkyLine(SkyLine::CIRCUMPOLARCIRCLE_N);
1633 	circumpolarCircleS = new SkyLine(SkyLine::CIRCUMPOLARCIRCLE_S);
1634 	umbraCircle = new SkyLine(SkyLine::EARTH_UMBRA);
1635 	penumbraCircle = new SkyLine(SkyLine::EARTH_PENUMBRA);
1636 	celestialJ2000Poles = new SkyPoint(SkyPoint::CELESTIALPOLES_J2000);
1637 	celestialPoles = new SkyPoint(SkyPoint::CELESTIALPOLES_OF_DATE);
1638 	zenithNadir = new SkyPoint(SkyPoint::ZENITH_NADIR);
1639 	eclipticJ2000Poles = new SkyPoint(SkyPoint::ECLIPTICPOLES_J2000);
1640 	eclipticPoles = new SkyPoint(SkyPoint::ECLIPTICPOLES_OF_DATE);
1641 	galacticPoles = new SkyPoint(SkyPoint::GALACTICPOLES);
1642 	galacticCenter = new SkyPoint(SkyPoint::GALACTICCENTER);
1643 	supergalacticPoles = new SkyPoint(SkyPoint::SUPERGALACTICPOLES);
1644 	equinoxJ2000Points = new SkyPoint(SkyPoint::EQUINOXES_J2000);
1645 	equinoxPoints = new SkyPoint(SkyPoint::EQUINOXES_OF_DATE);
1646 	solsticeJ2000Points = new SkyPoint(SkyPoint::SOLSTICES_J2000);
1647 	solsticePoints = new SkyPoint(SkyPoint::SOLSTICES_OF_DATE);
1648 	antisolarPoint = new SkyPoint(SkyPoint::ANTISOLAR);
1649 	umbraCenterPoint = new SkyPoint(SkyPoint::EARTH_UMBRA_CENTER);
1650 	apexPoints = new SkyPoint(SkyPoint::APEX);
1651 
1652 	earth = GETSTELMODULE(SolarSystem)->getEarth();
1653 	connect(GETSTELMODULE(SolarSystem), SIGNAL(solarSystemDataReloaded()), this, SLOT(connectSolarSystem()));
1654 }
1655 
~GridLinesMgr()1656 GridLinesMgr::~GridLinesMgr()
1657 {
1658 	delete equGrid;
1659 	delete equJ2000Grid;
1660 	delete eclJ2000Grid;
1661 	delete eclGrid;
1662 	delete galacticGrid;
1663 	delete supergalacticGrid;
1664 	delete aziGrid;
1665 	delete equatorLine;
1666 	delete equatorJ2000Line;
1667 	delete eclipticLine;
1668 	delete eclipticJ2000Line;
1669 	delete invariablePlaneLine;
1670 	delete solarEquatorLine;
1671 	delete precessionCircleN;
1672 	delete precessionCircleS;
1673 	delete meridianLine;
1674 	delete horizonLine;
1675 	delete galacticEquatorLine;
1676 	delete supergalacticEquatorLine;
1677 	delete longitudeLine;
1678 	delete primeVerticalLine;
1679 	delete currentVerticalLine;
1680 	delete colureLine_1;
1681 	delete colureLine_2;
1682 	delete circumpolarCircleN;
1683 	delete circumpolarCircleS;
1684 	delete umbraCircle;
1685 	delete penumbraCircle;
1686 	delete celestialJ2000Poles;
1687 	delete celestialPoles;
1688 	delete zenithNadir;
1689 	delete eclipticJ2000Poles;
1690 	delete eclipticPoles;
1691 	delete galacticPoles;
1692 	delete galacticCenter;
1693 	delete supergalacticPoles;
1694 	delete equinoxJ2000Points;
1695 	delete equinoxPoints;
1696 	delete solsticeJ2000Points;
1697 	delete solsticePoints;
1698 	delete antisolarPoint;
1699 	delete umbraCenterPoint;
1700 	delete apexPoints;
1701 	SkyLine::deinit();
1702 }
1703 
1704 /*************************************************************************
1705  Reimplementation of the getCallOrder method
1706 *************************************************************************/
getCallOrder(StelModuleActionName actionName) const1707 double GridLinesMgr::getCallOrder(StelModuleActionName actionName) const
1708 {
1709 	if (actionName==StelModule::ActionDraw)
1710 		return StelApp::getInstance().getModuleMgr().getModule("NebulaMgr")->getCallOrder(actionName)+10.;
1711 	return 0.;
1712 }
1713 
init()1714 void GridLinesMgr::init()
1715 {
1716 	QSettings* conf = StelApp::getInstance().getSettings();
1717 	Q_ASSERT(conf);
1718 
1719 	// Upgrade config keys
1720 	if (conf->contains("color/longitude_color"))
1721 	{
1722 		conf->setValue("color/oc_longitude_color", conf->value("color/longitude_color", "0.2,0.4,0.4").toString());
1723 		conf->remove("color/longitude_color");
1724 	}
1725 
1726 	setFlagGridlines(conf->value("viewing/flag_gridlines", true).toBool());
1727 	setFlagAzimuthalGrid(conf->value("viewing/flag_azimuthal_grid").toBool());
1728 	setFlagEquatorGrid(conf->value("viewing/flag_equatorial_grid").toBool());
1729 	setFlagEquatorJ2000Grid(conf->value("viewing/flag_equatorial_J2000_grid").toBool());
1730 	setFlagEclipticJ2000Grid(conf->value("viewing/flag_ecliptic_J2000_grid").toBool());
1731 	setFlagEclipticGrid(conf->value("viewing/flag_ecliptic_grid").toBool());
1732 	setFlagGalacticGrid(conf->value("viewing/flag_galactic_grid").toBool());
1733 	setFlagSupergalacticGrid(conf->value("viewing/flag_supergalactic_grid").toBool());
1734 	setFlagEquatorLine(conf->value("viewing/flag_equator_line").toBool());
1735 	setFlagEquatorParts(conf->value("viewing/flag_equator_parts").toBool());
1736 	setFlagEquatorLabeled(conf->value("viewing/flag_equator_labels").toBool());
1737 	setFlagEquatorJ2000Line(conf->value("viewing/flag_equator_J2000_line").toBool());
1738 	setFlagEquatorJ2000Parts(conf->value("viewing/flag_equator_J2000_parts").toBool());
1739 	setFlagEquatorJ2000Labeled(conf->value("viewing/flag_equator_J2000_labels").toBool());
1740 	setFlagEclipticLine(conf->value("viewing/flag_ecliptic_line").toBool());
1741 	setFlagEclipticParts(conf->value("viewing/flag_ecliptic_parts").toBool());
1742 	setFlagEclipticLabeled(conf->value("viewing/flag_ecliptic_labels").toBool());
1743 	setFlagEclipticJ2000Line(conf->value("viewing/flag_ecliptic_J2000_line").toBool());
1744 	setFlagEclipticJ2000Parts(conf->value("viewing/flag_ecliptic_J2000_parts").toBool());
1745 	setFlagEclipticJ2000Labeled(conf->value("viewing/flag_ecliptic_J2000_labels").toBool());
1746 	setFlagInvariablePlaneLine(conf->value("viewing/flag_invariable_plane_line").toBool());
1747 	setFlagSolarEquatorLine(conf->value("viewing/flag_solar_equator_line").toBool());
1748 	setFlagSolarEquatorParts(conf->value("viewing/flag_solar_equator_parts").toBool());
1749 	setFlagSolarEquatorLabeled(conf->value("viewing/flag_solar_equator_labels").toBool());
1750 	setFlagPrecessionCircles(conf->value("viewing/flag_precession_circles").toBool());
1751 	setFlagPrecessionParts(conf->value("viewing/flag_precession_parts").toBool());
1752 	setFlagPrecessionLabeled(conf->value("viewing/flag_precession_labels").toBool());
1753 	setFlagMeridianLine(conf->value("viewing/flag_meridian_line").toBool());
1754 	setFlagMeridianParts(conf->value("viewing/flag_meridian_parts").toBool());
1755 	setFlagMeridianLabeled(conf->value("viewing/flag_meridian_labels").toBool());
1756 	setFlagHorizonLine(conf->value("viewing/flag_horizon_line").toBool());
1757 	setFlagHorizonParts(conf->value("viewing/flag_horizon_parts").toBool());
1758 	setFlagHorizonLabeled(conf->value("viewing/flag_horizon_labels").toBool());
1759 	setFlagGalacticEquatorLine(conf->value("viewing/flag_galactic_equator_line").toBool());
1760 	setFlagGalacticEquatorParts(conf->value("viewing/flag_galactic_equator_parts").toBool());
1761 	setFlagGalacticEquatorLabeled(conf->value("viewing/flag_galactic_equator_labels").toBool());
1762 	setFlagSupergalacticEquatorLine(conf->value("viewing/flag_supergalactic_equator_line").toBool());
1763 	setFlagSupergalacticEquatorParts(conf->value("viewing/flag_supergalactic_equator_parts").toBool());
1764 	setFlagSupergalacticEquatorLabeled(conf->value("viewing/flag_supergalactic_equator_labels").toBool());
1765 	setFlagLongitudeLine(conf->value("viewing/flag_longitude_line").toBool());
1766 	setFlagLongitudeParts(conf->value("viewing/flag_longitude_parts").toBool());
1767 	setFlagLongitudeLabeled(conf->value("viewing/flag_longitude_labels").toBool());
1768 	setFlagPrimeVerticalLine(conf->value("viewing/flag_prime_vertical_line").toBool());
1769 	setFlagPrimeVerticalParts(conf->value("viewing/flag_prime_vertical_parts").toBool());
1770 	setFlagPrimeVerticalLabeled(conf->value("viewing/flag_prime_vertical_labels").toBool());
1771 	setFlagCurrentVerticalLine(conf->value("viewing/flag_current_vertical_line").toBool());
1772 	setFlagCurrentVerticalParts(conf->value("viewing/flag_current_vertical_parts").toBool());
1773 	setFlagCurrentVerticalLabeled(conf->value("viewing/flag_current_vertical_labels").toBool());
1774 	setFlagColureLines(conf->value("viewing/flag_colure_lines").toBool());
1775 	setFlagColureParts(conf->value("viewing/flag_colure_parts").toBool());
1776 	setFlagColureLabeled(conf->value("viewing/flag_colure_labels").toBool());
1777 	setFlagCircumpolarCircles(conf->value("viewing/flag_circumpolar_circles").toBool());
1778 	setFlagUmbraCircle(conf->value("viewing/flag_umbra_circle").toBool());
1779 	setFlagPenumbraCircle(conf->value("viewing/flag_penumbra_circle").toBool());
1780 	setFlagCelestialJ2000Poles(conf->value("viewing/flag_celestial_J2000_poles").toBool());
1781 	setFlagCelestialPoles(conf->value("viewing/flag_celestial_poles").toBool());
1782 	setFlagZenithNadir(conf->value("viewing/flag_zenith_nadir").toBool());
1783 	setFlagEclipticJ2000Poles(conf->value("viewing/flag_ecliptic_J2000_poles").toBool());
1784 	setFlagEclipticPoles(conf->value("viewing/flag_ecliptic_poles").toBool());
1785 	setFlagGalacticPoles(conf->value("viewing/flag_galactic_poles").toBool());
1786 	setFlagGalacticCenter(conf->value("viewing/flag_galactic_center").toBool());
1787 	setFlagSupergalacticPoles(conf->value("viewing/flag_supergalactic_poles").toBool());
1788 	setFlagEquinoxJ2000Points(conf->value("viewing/flag_equinox_J2000_points").toBool());
1789 	setFlagEquinoxPoints(conf->value("viewing/flag_equinox_points").toBool());
1790 	setFlagSolsticeJ2000Points(conf->value("viewing/flag_solstice_J2000_points").toBool());
1791 	setFlagSolsticePoints(conf->value("viewing/flag_solstice_points").toBool());
1792 	setFlagAntisolarPoint(conf->value("viewing/flag_antisolar_point").toBool());
1793 	setFlagUmbraCenterPoint(conf->value("viewing/flag_umbra_center_point").toBool());
1794 	setFlagApexPoints(conf->value("viewing/flag_apex_points").toBool());
1795 
1796 	// Set the line thickness for grids and lines
1797 	setLineThickness(conf->value("viewing/line_thickness", 1).toInt());
1798 	setPartThickness(conf->value("viewing/part_thickness", 1).toInt());
1799 
1800 	// Load colors from config file
1801 	QString defaultColor = conf->value("color/default_color", "0.5,0.5,0.7").toString();
1802 	setColorEquatorGrid(			Vec3f(conf->value("color/equatorial_color", defaultColor).toString()));
1803 	setColorEquatorJ2000Grid(		Vec3f(conf->value("color/equatorial_J2000_color", defaultColor).toString()));
1804 	setColorEclipticJ2000Grid(		Vec3f(conf->value("color/ecliptical_J2000_color", defaultColor).toString()));
1805 	setColorEclipticGrid(			Vec3f(conf->value("color/ecliptical_color", defaultColor).toString()));
1806 	setColorGalacticGrid(			Vec3f(conf->value("color/galactic_color", defaultColor).toString()));
1807 	setColorSupergalacticGrid(		Vec3f(conf->value("color/supergalactic_color", defaultColor).toString()));
1808 	setColorAzimuthalGrid(			Vec3f(conf->value("color/azimuthal_color", defaultColor).toString()));
1809 	setColorEquatorLine(			Vec3f(conf->value("color/equator_color", defaultColor).toString()));
1810 	setColorEquatorJ2000Line(		Vec3f(conf->value("color/equator_J2000_color", defaultColor).toString()));
1811 	setColorEclipticLine(			Vec3f(conf->value("color/ecliptic_color", defaultColor).toString()));
1812 	setColorEclipticJ2000Line(		Vec3f(conf->value("color/ecliptic_J2000_color", defaultColor).toString()));
1813 	setColorInvariablePlaneLine(		Vec3f(conf->value("color/invariable_plane_color", defaultColor).toString()));
1814 	setColorSolarEquatorLine(		Vec3f(conf->value("color/solar_equator_color", defaultColor).toString()));
1815 	setColorPrecessionCircles(		Vec3f(conf->value("color/precession_circles_color", defaultColor).toString()));
1816 	setColorMeridianLine(			Vec3f(conf->value("color/meridian_color", defaultColor).toString()));
1817 	setColorHorizonLine(			Vec3f(conf->value("color/horizon_color", defaultColor).toString()));
1818 	setColorGalacticEquatorLine(		Vec3f(conf->value("color/galactic_equator_color", defaultColor).toString()));
1819 	setColorSupergalacticEquatorLine(Vec3f(conf->value("color/supergalactic_equator_color", defaultColor).toString()));
1820 	setColorLongitudeLine(			Vec3f(conf->value("color/oc_longitude_color", defaultColor).toString()));
1821 	setColorPrimeVerticalLine(		Vec3f(conf->value("color/prime_vertical_color", defaultColor).toString()));
1822 	setColorCurrentVerticalLine(		Vec3f(conf->value("color/current_vertical_color", defaultColor).toString()));
1823 	setColorColureLines(			Vec3f(conf->value("color/colures_color", defaultColor).toString()));
1824 	setColorCircumpolarCircles(		Vec3f(conf->value("color/circumpolar_circles_color", defaultColor).toString()));
1825 	setColorUmbraCircle(			Vec3f(conf->value("color/umbra_circle_color", defaultColor).toString()));
1826 	setColorPenumbraCircle(		Vec3f(conf->value("color/penumbra_circle_color", defaultColor).toString()));
1827 	setColorCelestialJ2000Poles(		Vec3f(conf->value("color/celestial_J2000_poles_color", defaultColor).toString()));
1828 	setColorCelestialPoles(			Vec3f(conf->value("color/celestial_poles_color", defaultColor).toString()));
1829 	setColorZenithNadir(			Vec3f(conf->value("color/zenith_nadir_color", defaultColor).toString()));
1830 	setColorEclipticJ2000Poles(		Vec3f(conf->value("color/ecliptic_J2000_poles_color", defaultColor).toString()));
1831 	setColorEclipticPoles(			Vec3f(conf->value("color/ecliptic_poles_color", defaultColor).toString()));
1832 	setColorGalacticPoles(			Vec3f(conf->value("color/galactic_poles_color", defaultColor).toString()));
1833 	setColorGalacticCenter(			Vec3f(conf->value("color/galactic_center_color", defaultColor).toString()));
1834 	setColorSupergalacticPoles(		Vec3f(conf->value("color/supergalactic_poles_color", defaultColor).toString()));
1835 	setColorEquinoxJ2000Points(		Vec3f(conf->value("color/equinox_J2000_points_color", defaultColor).toString()));
1836 	setColorEquinoxPoints(			Vec3f(conf->value("color/equinox_points_color", defaultColor).toString()));
1837 	setColorSolsticeJ2000Points(		Vec3f(conf->value("color/solstice_J2000_points_color", defaultColor).toString()));
1838 	setColorSolsticePoints(			Vec3f(conf->value("color/solstice_points_color", defaultColor).toString()));
1839 	setColorAntisolarPoint(			Vec3f(conf->value("color/antisolar_point_color", defaultColor).toString()));
1840 	setColorApexPoints(			Vec3f(conf->value("color/apex_points_color", defaultColor).toString()));
1841 
1842 	StelApp& app = StelApp::getInstance();
1843 	connect(&app, SIGNAL(languageChanged()), this, SLOT(updateLabels()));
1844 	connect(&app, SIGNAL(screenFontSizeChanged(int)), this, SLOT(setFontSizeFromApp(int)));
1845 
1846 	QString displayGroup = N_("Display Options");
1847 	addAction("actionShow_Gridlines",			displayGroup, N_("Grids and lines"), "gridlinesDisplayed");
1848 	addAction("actionShow_Equatorial_Grid",		displayGroup, N_("Equatorial grid"), "equatorGridDisplayed", "E");
1849 	addAction("actionShow_Azimuthal_Grid",		displayGroup, N_("Azimuthal grid"), "azimuthalGridDisplayed", "Z");
1850 	addAction("actionShow_Ecliptic_Line",			displayGroup, N_("Ecliptic line"), "eclipticLineDisplayed", ",");
1851 	addAction("actionShow_Ecliptic_J2000_Line",	displayGroup, N_("Ecliptic J2000 line"), "eclipticJ2000LineDisplayed");
1852 	addAction("actionShow_Invariable_Plane_Line",	displayGroup, N_("Invariable Plane line"), "invariablePlaneLineDisplayed");
1853 	addAction("actionShow_Solar_Equator_Line",	displayGroup, N_("Solar Equator Plane line"), "solarEquatorLineDisplayed");
1854 	addAction("actionShow_Equator_Line",			displayGroup, N_("Equator line"), "equatorLineDisplayed", ".");
1855 	addAction("actionShow_Equator_J2000_Line",	displayGroup, N_("Equator J2000 line"), "equatorJ2000LineDisplayed"); // or with Hotkey??
1856 	addAction("actionShow_Meridian_Line",			displayGroup, N_("Meridian line"), "meridianLineDisplayed", ";");
1857 	addAction("actionShow_Horizon_Line",			displayGroup, N_("Horizon line"), "horizonLineDisplayed", "H");
1858 	addAction("actionShow_Equatorial_J2000_Grid",	displayGroup, N_("Equatorial J2000 grid"), "equatorJ2000GridDisplayed");
1859 	addAction("actionShow_Ecliptic_J2000_Grid",	displayGroup, N_("Ecliptic J2000 grid"), "eclipticJ2000GridDisplayed");
1860 	addAction("actionShow_Ecliptic_Grid",			displayGroup, N_("Ecliptic grid"), "eclipticGridDisplayed");
1861 	addAction("actionShow_Galactic_Grid",			displayGroup, N_("Galactic grid"), "galacticGridDisplayed");
1862 	addAction("actionShow_Galactic_Equator_Line",	displayGroup, N_("Galactic equator"), "galacticEquatorLineDisplayed");
1863 	addAction("actionShow_Supergalactic_Grid",		displayGroup, N_("Supergalactic grid"), "supergalacticGridDisplayed");
1864 	addAction("actionShow_Supergalactic_Equator_Line", displayGroup, N_("Supergalactic equator"), "supergalacticEquatorLineDisplayed");
1865 	addAction("actionShow_Longitude_Line",		displayGroup, N_("Opposition/conjunction longitude line"), "longitudeLineDisplayed");
1866 	addAction("actionShow_Precession_Circles",		displayGroup, N_("Precession Circles"), "precessionCirclesDisplayed");
1867 	addAction("actionShow_Prime_Vertical_Line",	displayGroup, N_("Prime Vertical"), "primeVerticalLineDisplayed");
1868 	addAction("actionShow_Current_Vertical_Line",	displayGroup, N_("Current Vertical"), "currentVerticalLineDisplayed");
1869 	addAction("actionShow_Colure_Lines",			displayGroup, N_("Colure Lines"), "colureLinesDisplayed");
1870 	addAction("actionShow_Circumpolar_Circles",	displayGroup, N_("Circumpolar Circles"), "circumpolarCirclesDisplayed");
1871 	addAction("actionShow_Umbra_Circle",			displayGroup, N_("Umbra Circle"), "umbraCircleDisplayed");
1872 	addAction("actionShow_Penumbra_Circle",		displayGroup, N_("Penumbra Circle"), "penumbraCircleDisplayed");
1873 	addAction("actionShow_Celestial_J2000_Poles",	displayGroup, N_("Celestial J2000 poles"), "celestialJ2000PolesDisplayed");
1874 	addAction("actionShow_Celestial_Poles",		displayGroup, N_("Celestial poles"), "celestialPolesDisplayed");
1875 	addAction("actionShow_Zenith_Nadir",			displayGroup, N_("Zenith and nadir"), "zenithNadirDisplayed");
1876 	addAction("actionShow_Ecliptic_J2000_Poles",	displayGroup, N_("Ecliptic J2000 poles"), "eclipticJ2000PolesDisplayed");
1877 	addAction("actionShow_Ecliptic_Poles",			displayGroup, N_("Ecliptic poles"), "eclipticPolesDisplayed");
1878 	addAction("actionShow_Galactic_Poles",		displayGroup, N_("Galactic poles"), "galacticPolesDisplayed");
1879 	addAction("actionShow_Galactic_Center",		displayGroup, N_("Galactic center and anticenter"), "galacticCenterDisplayed");
1880 	addAction("actionShow_Supergalactic_Poles",	displayGroup, N_("Supergalactic poles"), "supergalacticPolesDisplayed");
1881 	addAction("actionShow_Equinox_J2000_Points",	displayGroup, N_("Equinox J2000 points"), "equinoxJ2000PointsDisplayed");
1882 	addAction("actionShow_Equinox_Points",		displayGroup, N_("Equinox points"), "equinoxPointsDisplayed");
1883 	addAction("actionShow_Solstice_J2000_Points",	displayGroup, N_("Solstice J2000 points"), "solsticeJ2000PointsDisplayed");
1884 	addAction("actionShow_Solstice_Points",		displayGroup, N_("Solstice points"), "solsticePointsDisplayed");
1885 	addAction("actionShow_Antisolar_Point",		displayGroup, N_("Antisolar point"), "antisolarPointDisplayed");
1886 	addAction("actionShow_Umbra_Center_Point",	displayGroup, N_("The center of the Earth's umbra"), "umbraCenterPointDisplayed");
1887 	addAction("actionShow_Apex_Points",			displayGroup, N_("Apex points"), "apexPointsDisplayed");
1888 }
1889 
connectSolarSystem()1890 void GridLinesMgr::connectSolarSystem()
1891 {
1892 	SolarSystem *ss=GETSTELMODULE(SolarSystem);
1893 	earth = ss->getEarth();
1894 	SkyLine::setSolarSystem(ss);
1895 }
1896 
update(double deltaTime)1897 void GridLinesMgr::update(double deltaTime)
1898 {
1899 	// Update faders
1900 	equGrid->update(deltaTime);
1901 	equJ2000Grid->update(deltaTime);
1902 	eclJ2000Grid->update(deltaTime);
1903 	eclGrid->update(deltaTime);
1904 	galacticGrid->update(deltaTime);
1905 	supergalacticGrid->update(deltaTime);
1906 	aziGrid->update(deltaTime);
1907 	equatorLine->update(deltaTime);
1908 	equatorJ2000Line->update(deltaTime);
1909 	eclipticLine->update(deltaTime);
1910 	eclipticJ2000Line->update(deltaTime);
1911 	invariablePlaneLine->update(deltaTime);
1912 	solarEquatorLine->update(deltaTime);
1913 	precessionCircleN->update(deltaTime);
1914 	precessionCircleS->update(deltaTime);
1915 	meridianLine->update(deltaTime);
1916 	horizonLine->update(deltaTime);
1917 	galacticEquatorLine->update(deltaTime);
1918 	supergalacticEquatorLine->update(deltaTime);
1919 	longitudeLine->update(deltaTime);
1920 	primeVerticalLine->update(deltaTime);
1921 	currentVerticalLine->update(deltaTime);
1922 	colureLine_1->update(deltaTime);
1923 	colureLine_2->update(deltaTime);
1924 	circumpolarCircleN->update(deltaTime);
1925 	circumpolarCircleS->update(deltaTime);
1926 	umbraCircle->update(deltaTime);
1927 	penumbraCircle->update(deltaTime);
1928 	celestialJ2000Poles->update(deltaTime);
1929 	celestialPoles->update(deltaTime);
1930 	zenithNadir->update(deltaTime);
1931 	eclipticJ2000Poles->update(deltaTime);
1932 	eclipticPoles->update(deltaTime);
1933 	galacticPoles->update(deltaTime);
1934 	galacticCenter->update(deltaTime);
1935 	supergalacticPoles->update(deltaTime);
1936 	equinoxJ2000Points->update(deltaTime);
1937 	equinoxPoints->update(deltaTime);
1938 	solsticeJ2000Points->update(deltaTime);
1939 	solsticePoints->update(deltaTime);
1940 	antisolarPoint->update(deltaTime);
1941 	umbraCenterPoint->update(deltaTime);
1942 	apexPoints->update(deltaTime);
1943 	apexPoints->updateLabel();
1944 }
1945 
draw(StelCore * core)1946 void GridLinesMgr::draw(StelCore* core)
1947 {
1948 	if (!gridlinesDisplayed)
1949 		return;
1950 
1951 	galacticGrid->draw(core);
1952 	supergalacticGrid->draw(core);
1953 	equJ2000Grid->draw(core);
1954 	equGrid->draw(core);
1955 	aziGrid->draw(core);
1956 	eclJ2000Grid->draw(core);
1957 	// While ecliptic of J2000 may be helpful to get a feeling of the Z=0 plane of VSOP87,
1958 	// ecliptic of date is related to Earth and does not make much sense for the other planets.
1959 	// Of course, orbital plane of respective planet would be better, but is not implemented.
1960 	if (core->getCurrentPlanet()==earth)
1961 	{
1962 		penumbraCircle->draw(core);
1963 		umbraCircle->draw(core);
1964 		eclGrid->draw(core);
1965 		eclipticLine->draw(core);
1966 		precessionCircleN->draw(core);
1967 		precessionCircleS->draw(core);
1968 		colureLine_1->draw(core);
1969 		colureLine_2->draw(core);
1970 		eclipticPoles->draw(core);
1971 		equinoxPoints->draw(core);
1972 		solsticePoints->draw(core);
1973 		longitudeLine->draw(core);
1974 		umbraCenterPoint->draw(core);
1975 	}
1976 
1977 	// Lines after grids, to be able to e.g. draw equators in different color!
1978 	galacticEquatorLine->draw(core);
1979 	supergalacticEquatorLine->draw(core);
1980 	eclipticJ2000Line->draw(core);
1981 	equatorJ2000Line->draw(core);
1982 	equatorLine->draw(core);
1983 	invariablePlaneLine->draw(core);
1984 	solarEquatorLine->draw(core);
1985 	meridianLine->draw(core);
1986 	horizonLine->draw(core);
1987 	primeVerticalLine->draw(core);
1988 	currentVerticalLine->draw(core);
1989 	circumpolarCircleN->draw(core);
1990 	circumpolarCircleS->draw(core);
1991 	celestialJ2000Poles->draw(core);
1992 	celestialPoles->draw(core);
1993 	zenithNadir->draw(core);
1994 	eclipticJ2000Poles->draw(core);
1995 	galacticPoles->draw(core);
1996 	galacticCenter->draw(core);
1997 	supergalacticPoles->draw(core);
1998 	equinoxJ2000Points->draw(core);
1999 	solsticeJ2000Points->draw(core);
2000 	apexPoints->draw(core);
2001 	antisolarPoint->draw(core);
2002 }
2003 
updateLabels()2004 void GridLinesMgr::updateLabels()
2005 {
2006 	equatorJ2000Line->updateLabel();
2007 	equatorLine->updateLabel();
2008 	eclipticLine->updateLabel();
2009 	eclipticJ2000Line->updateLabel();
2010 	invariablePlaneLine->updateLabel();
2011 	solarEquatorLine->updateLabel();
2012 	precessionCircleN->updateLabel();
2013 	precessionCircleS->updateLabel();
2014 	meridianLine->updateLabel();
2015 	horizonLine->updateLabel();
2016 	galacticEquatorLine->updateLabel();
2017 	supergalacticEquatorLine->updateLabel();
2018 	longitudeLine->updateLabel();
2019 	primeVerticalLine->updateLabel();
2020 	currentVerticalLine->updateLabel();
2021 	colureLine_1->updateLabel();
2022 	colureLine_2->updateLabel();
2023 	circumpolarCircleN->updateLabel();
2024 	circumpolarCircleS->updateLabel();
2025 	umbraCircle->updateLabel();
2026 	penumbraCircle->updateLabel();
2027 	celestialJ2000Poles->updateLabel();
2028 	celestialPoles->updateLabel();
2029 	zenithNadir->updateLabel();
2030 	eclipticJ2000Poles->updateLabel();
2031 	eclipticPoles->updateLabel();
2032 	galacticPoles->updateLabel();
2033 	galacticCenter->updateLabel();
2034 	supergalacticPoles->updateLabel();
2035 	equinoxJ2000Points->updateLabel();
2036 	equinoxPoints->updateLabel();
2037 	solsticeJ2000Points->updateLabel();
2038 	solsticePoints->updateLabel();
2039 	antisolarPoint->updateLabel();
2040 	umbraCenterPoint->updateLabel();
2041 	apexPoints->updateLabel();
2042 }
2043 
2044 //! Setter ("master switch") for displaying any grid/line.
setFlagGridlines(const bool displayed)2045 void GridLinesMgr::setFlagGridlines(const bool displayed)
2046 {
2047 	if(displayed != gridlinesDisplayed)
2048 	{
2049 		gridlinesDisplayed=displayed;
2050 		emit gridlinesDisplayedChanged(displayed);
2051 	}
2052 }
2053 //! Accessor ("master switch") for displaying any grid/line.
getFlagGridlines() const2054 bool GridLinesMgr::getFlagGridlines() const
2055 {
2056 	return gridlinesDisplayed;
2057 }
2058 
2059 //! Setter ("master switch by type") for displaying all grids esp. for scripting
setFlagAllGrids(const bool displayed)2060 void GridLinesMgr::setFlagAllGrids(const bool displayed)
2061 {
2062 	setFlagEquatorGrid(displayed);
2063 	setFlagEclipticGrid(displayed);
2064 	setFlagGalacticGrid(displayed);
2065 	setFlagAzimuthalGrid(displayed);
2066 	setFlagEquatorJ2000Grid(displayed);
2067 	setFlagEclipticJ2000Grid(displayed);
2068 	setFlagSupergalacticGrid(displayed);
2069 }
2070 
2071 //! Setter ("master switch by type") for displaying all lines esp. for scripting
setFlagAllLines(const bool displayed)2072 void GridLinesMgr::setFlagAllLines(const bool displayed)
2073 {
2074 	setFlagColureLines(displayed);
2075 	setFlagEquatorLine(displayed);
2076 	setFlagHorizonLine(displayed);
2077 	setFlagEclipticLine(displayed);
2078 	setFlagMeridianLine(displayed);
2079 	setFlagLongitudeLine(displayed);
2080 	setFlagEquatorJ2000Line(displayed);
2081 	setFlagEclipticJ2000Line(displayed);
2082 	setFlagInvariablePlaneLine(displayed);
2083 	setFlagSolarEquatorLine(displayed);
2084 	setFlagPrecessionCircles(displayed);
2085 	setFlagPrimeVerticalLine(displayed);
2086 	setFlagCurrentVerticalLine(displayed);
2087 	setFlagCircumpolarCircles(displayed);
2088 	setFlagUmbraCircle(displayed);
2089 	setFlagPenumbraCircle(displayed);
2090 	setFlagGalacticEquatorLine(displayed);
2091 	setFlagSupergalacticEquatorLine(displayed);
2092 }
2093 
2094 //! Setter ("master switch by type") for displaying all points esp. for scripting
setFlagAllPoints(const bool displayed)2095 void GridLinesMgr::setFlagAllPoints(const bool displayed)
2096 {
2097 	setFlagZenithNadir(displayed);
2098 	setFlagEclipticPoles(displayed);
2099 	setFlagEquinoxPoints(displayed);
2100 	setFlagGalacticPoles(displayed);
2101 	setFlagGalacticCenter(displayed);
2102 	setFlagAntisolarPoint(displayed);
2103 	setFlagCelestialPoles(displayed);
2104 	setFlagSolsticePoints(displayed);
2105 	setFlagEclipticJ2000Poles(displayed);
2106 	setFlagEquinoxJ2000Points(displayed);
2107 	setFlagSupergalacticPoles(displayed);
2108 	setFlagCelestialJ2000Poles(displayed);
2109 	setFlagSolsticeJ2000Points(displayed);
2110 	setFlagApexPoints(displayed);
2111 	setFlagUmbraCenterPoint(displayed);
2112 }
2113 
2114 //! Set flag for displaying Azimuthal Grid
setFlagAzimuthalGrid(const bool displayed)2115 void GridLinesMgr::setFlagAzimuthalGrid(const bool displayed)
2116 {
2117 	if(displayed != aziGrid->isDisplayed())
2118 	{
2119 		aziGrid->setDisplayed(displayed);
2120 		emit azimuthalGridDisplayedChanged(displayed);
2121 	}
2122 }
2123 //! Get flag for displaying Azimuthal Grid
getFlagAzimuthalGrid() const2124 bool GridLinesMgr::getFlagAzimuthalGrid() const
2125 {
2126 	return aziGrid->isDisplayed();
2127 }
getColorAzimuthalGrid() const2128 Vec3f GridLinesMgr::getColorAzimuthalGrid() const
2129 {
2130 	return aziGrid->getColor();
2131 }
setColorAzimuthalGrid(const Vec3f & newColor)2132 void GridLinesMgr::setColorAzimuthalGrid(const Vec3f& newColor)
2133 {
2134 	if(newColor != aziGrid->getColor())
2135 	{
2136 		aziGrid->setColor(newColor);
2137 		emit azimuthalGridColorChanged(newColor);
2138 	}
2139 }
2140 
2141 //! Set flag for displaying Equatorial Grid
setFlagEquatorGrid(const bool displayed)2142 void GridLinesMgr::setFlagEquatorGrid(const bool displayed)
2143 {
2144 	if(displayed != equGrid->isDisplayed())
2145 	{
2146 		equGrid->setDisplayed(displayed);
2147 		emit equatorGridDisplayedChanged(displayed);
2148 	}
2149 }
2150 //! Get flag for displaying Equatorial Grid
getFlagEquatorGrid() const2151 bool GridLinesMgr::getFlagEquatorGrid() const
2152 {
2153 	return equGrid->isDisplayed();
2154 }
getColorEquatorGrid() const2155 Vec3f GridLinesMgr::getColorEquatorGrid() const
2156 {
2157 	return equGrid->getColor();
2158 }
setColorEquatorGrid(const Vec3f & newColor)2159 void GridLinesMgr::setColorEquatorGrid(const Vec3f& newColor)
2160 {
2161 	if(newColor != equGrid->getColor())
2162 	{
2163 		equGrid->setColor(newColor);
2164 		emit equatorGridColorChanged(newColor);
2165 	}
2166 }
2167 
2168 //! Set flag for displaying Equatorial J2000 Grid
setFlagEquatorJ2000Grid(const bool displayed)2169 void GridLinesMgr::setFlagEquatorJ2000Grid(const bool displayed)
2170 {
2171 	if(displayed != equJ2000Grid->isDisplayed())
2172 	{
2173 		equJ2000Grid->setDisplayed(displayed);
2174 		emit equatorJ2000GridDisplayedChanged(displayed);
2175 	}
2176 }
2177 //! Get flag for displaying Equatorial J2000 Grid
getFlagEquatorJ2000Grid() const2178 bool GridLinesMgr::getFlagEquatorJ2000Grid() const
2179 {
2180 	return equJ2000Grid->isDisplayed();
2181 }
getColorEquatorJ2000Grid() const2182 Vec3f GridLinesMgr::getColorEquatorJ2000Grid() const
2183 {
2184 	return equJ2000Grid->getColor();
2185 }
setColorEquatorJ2000Grid(const Vec3f & newColor)2186 void GridLinesMgr::setColorEquatorJ2000Grid(const Vec3f& newColor)
2187 {
2188 	if(newColor != equJ2000Grid->getColor())
2189 	{
2190 		equJ2000Grid->setColor(newColor);
2191 		emit equatorJ2000GridColorChanged(newColor);
2192 	}
2193 }
2194 
2195 //! Set flag for displaying Ecliptic J2000 Grid
setFlagEclipticJ2000Grid(const bool displayed)2196 void GridLinesMgr::setFlagEclipticJ2000Grid(const bool displayed)
2197 {
2198 	if(displayed != eclJ2000Grid->isDisplayed())
2199 	{
2200 		eclJ2000Grid->setDisplayed(displayed);
2201 		emit eclipticJ2000GridDisplayedChanged(displayed);
2202 	}
2203 }
2204 //! Get flag for displaying Ecliptic J2000 Grid
getFlagEclipticJ2000Grid() const2205 bool GridLinesMgr::getFlagEclipticJ2000Grid() const
2206 {
2207 	return eclJ2000Grid->isDisplayed();
2208 }
getColorEclipticJ2000Grid() const2209 Vec3f GridLinesMgr::getColorEclipticJ2000Grid() const
2210 {
2211 	return eclJ2000Grid->getColor();
2212 }
setColorEclipticJ2000Grid(const Vec3f & newColor)2213 void GridLinesMgr::setColorEclipticJ2000Grid(const Vec3f& newColor)
2214 {
2215 	if(newColor != eclJ2000Grid->getColor())
2216 	{
2217 		eclJ2000Grid->setColor(newColor);
2218 		emit eclipticJ2000GridColorChanged(newColor);
2219 	}
2220 }
2221 
2222 //! Set flag for displaying Ecliptic of Date Grid
setFlagEclipticGrid(const bool displayed)2223 void GridLinesMgr::setFlagEclipticGrid(const bool displayed)
2224 {
2225 	if(displayed != eclGrid->isDisplayed())
2226 	{
2227 		eclGrid->setDisplayed(displayed);
2228 		emit eclipticGridDisplayedChanged(displayed);
2229 	}
2230 }
2231 //! Get flag for displaying Ecliptic of Date Grid
getFlagEclipticGrid() const2232 bool GridLinesMgr::getFlagEclipticGrid() const
2233 {
2234 	return eclGrid->isDisplayed();
2235 }
getColorEclipticGrid() const2236 Vec3f GridLinesMgr::getColorEclipticGrid() const
2237 {
2238 	return eclGrid->getColor();
2239 }
setColorEclipticGrid(const Vec3f & newColor)2240 void GridLinesMgr::setColorEclipticGrid(const Vec3f& newColor)
2241 {
2242 	if(newColor != eclGrid->getColor())
2243 	{
2244 		eclGrid->setColor(newColor);
2245 		emit eclipticGridColorChanged(newColor);
2246 	}
2247 }
2248 
2249 //! Set flag for displaying Galactic Grid
setFlagGalacticGrid(const bool displayed)2250 void GridLinesMgr::setFlagGalacticGrid(const bool displayed)
2251 {
2252 	if(displayed != galacticGrid->isDisplayed())
2253 	{
2254 		galacticGrid->setDisplayed(displayed);
2255 		emit galacticGridDisplayedChanged(displayed);
2256 	}
2257 }
2258 //! Get flag for displaying Galactic Grid
getFlagGalacticGrid() const2259 bool GridLinesMgr::getFlagGalacticGrid() const
2260 {
2261 	return galacticGrid->isDisplayed();
2262 }
getColorGalacticGrid() const2263 Vec3f GridLinesMgr::getColorGalacticGrid() const
2264 {
2265 	return galacticGrid->getColor();
2266 }
setColorGalacticGrid(const Vec3f & newColor)2267 void GridLinesMgr::setColorGalacticGrid(const Vec3f& newColor)
2268 {
2269 	if(newColor != galacticGrid->getColor())
2270 	{
2271 		galacticGrid->setColor(newColor);
2272 		emit galacticGridColorChanged(newColor);
2273 	}
2274 }
2275 
2276 //! Set flag for displaying Supergalactic Grid
setFlagSupergalacticGrid(const bool displayed)2277 void GridLinesMgr::setFlagSupergalacticGrid(const bool displayed)
2278 {
2279 	if(displayed != supergalacticGrid->isDisplayed())
2280 	{
2281 		supergalacticGrid->setDisplayed(displayed);
2282 		emit supergalacticGridDisplayedChanged(displayed);
2283 	}
2284 }
2285 //! Get flag for displaying Supergalactic Grid
getFlagSupergalacticGrid() const2286 bool GridLinesMgr::getFlagSupergalacticGrid() const
2287 {
2288 	return supergalacticGrid->isDisplayed();
2289 }
getColorSupergalacticGrid() const2290 Vec3f GridLinesMgr::getColorSupergalacticGrid() const
2291 {
2292 	return supergalacticGrid->getColor();
2293 }
setColorSupergalacticGrid(const Vec3f & newColor)2294 void GridLinesMgr::setColorSupergalacticGrid(const Vec3f& newColor)
2295 {
2296 	if(newColor != supergalacticGrid->getColor())
2297 	{
2298 		supergalacticGrid->setColor(newColor);
2299 		emit supergalacticGridColorChanged(newColor);
2300 	}
2301 }
2302 
2303 //! Set flag for displaying Equatorial Line
setFlagEquatorLine(const bool displayed)2304 void GridLinesMgr::setFlagEquatorLine(const bool displayed)
2305 {
2306 	if(displayed != equatorLine->isDisplayed())
2307 	{
2308 		equatorLine->setDisplayed(displayed);
2309 		emit equatorLineDisplayedChanged(displayed);
2310 	}
2311 }
2312 //! Get flag for displaying Equatorial Line
getFlagEquatorLine() const2313 bool GridLinesMgr::getFlagEquatorLine() const
2314 {
2315 	return equatorLine->isDisplayed();
2316 }
2317 //! Set flag for displaying Equatorial Line partitions
setFlagEquatorParts(const bool displayed)2318 void GridLinesMgr::setFlagEquatorParts(const bool displayed)
2319 {
2320 	if(displayed != equatorLine->showsPartitions())
2321 	{
2322 		equatorLine->setPartitions(displayed);
2323 		emit equatorPartsDisplayedChanged(displayed);
2324 	}
2325 }
2326 //! Get flag for displaying Equatorial Line partitions
getFlagEquatorParts() const2327 bool GridLinesMgr::getFlagEquatorParts() const
2328 {
2329 	return equatorLine->showsPartitions();
2330 }
setFlagEquatorLabeled(const bool displayed)2331 void GridLinesMgr::setFlagEquatorLabeled(const bool displayed)
2332 {
2333 	if(displayed != equatorLine->isLabeled())
2334 	{
2335 		equatorLine->setLabeled(displayed);
2336 		emit equatorPartsLabeledChanged(displayed);
2337 	}
2338 }
getFlagEquatorLabeled() const2339 bool GridLinesMgr::getFlagEquatorLabeled() const
2340 {
2341 	return equatorLine->isLabeled();
2342 }
getColorEquatorLine() const2343 Vec3f GridLinesMgr::getColorEquatorLine() const
2344 {
2345 	return equatorLine->getColor();
2346 }
setColorEquatorLine(const Vec3f & newColor)2347 void GridLinesMgr::setColorEquatorLine(const Vec3f& newColor)
2348 {
2349 	if(newColor != equatorLine->getColor())
2350 	{
2351 		equatorLine->setColor(newColor);
2352 		emit equatorLineColorChanged(newColor);
2353 	}
2354 }
2355 
2356 //! Set flag for displaying J2000 Equatorial Line
setFlagEquatorJ2000Line(const bool displayed)2357 void GridLinesMgr::setFlagEquatorJ2000Line(const bool displayed)
2358 {
2359 	if(displayed != equatorJ2000Line->isDisplayed())
2360 	{
2361 		equatorJ2000Line->setDisplayed(displayed);
2362 		emit equatorJ2000LineDisplayedChanged(displayed);
2363 	}
2364 }
2365 //! Get flag for displaying J2000 Equatorial Line
getFlagEquatorJ2000Line() const2366 bool GridLinesMgr::getFlagEquatorJ2000Line() const
2367 {
2368 	return equatorJ2000Line->isDisplayed();
2369 }
2370 //! Set flag for displaying J2000 Equatorial Line partitions
setFlagEquatorJ2000Parts(const bool displayed)2371 void GridLinesMgr::setFlagEquatorJ2000Parts(const bool displayed)
2372 {
2373 	if(displayed != equatorJ2000Line->showsPartitions())
2374 	{
2375 		equatorJ2000Line->setPartitions(displayed);
2376 		emit equatorJ2000PartsDisplayedChanged(displayed);
2377 	}
2378 }
2379 //! Get flag for displaying J2000 Equatorial Line partitions
getFlagEquatorJ2000Parts() const2380 bool GridLinesMgr::getFlagEquatorJ2000Parts() const
2381 {
2382 	return equatorJ2000Line->showsPartitions();
2383 }
setFlagEquatorJ2000Labeled(const bool displayed)2384 void GridLinesMgr::setFlagEquatorJ2000Labeled(const bool displayed)
2385 {
2386 	if(displayed != equatorJ2000Line->isLabeled())
2387 	{
2388 		equatorJ2000Line->setLabeled(displayed);
2389 		emit equatorJ2000PartsLabeledChanged(displayed);
2390 	}
2391 }
getFlagEquatorJ2000Labeled() const2392 bool GridLinesMgr::getFlagEquatorJ2000Labeled() const
2393 {
2394 	return equatorJ2000Line->isLabeled();
2395 }
getColorEquatorJ2000Line() const2396 Vec3f GridLinesMgr::getColorEquatorJ2000Line() const
2397 {
2398 	return equatorJ2000Line->getColor();
2399 }
setColorEquatorJ2000Line(const Vec3f & newColor)2400 void GridLinesMgr::setColorEquatorJ2000Line(const Vec3f& newColor)
2401 {
2402 	if(newColor != equatorJ2000Line->getColor())
2403 	{
2404 		equatorJ2000Line->setColor(newColor);
2405 		emit equatorJ2000LineColorChanged(newColor);
2406 	}
2407 }
2408 
2409 //! Set flag for displaying Ecliptic Line
setFlagEclipticLine(const bool displayed)2410 void GridLinesMgr::setFlagEclipticLine(const bool displayed)
2411 {
2412 	if(displayed != eclipticLine->isDisplayed())
2413 	{
2414 		eclipticLine->setDisplayed(displayed);
2415 		emit eclipticLineDisplayedChanged(displayed);
2416 	}
2417 }
2418 //! Get flag for displaying Ecliptic Line
getFlagEclipticLine() const2419 bool GridLinesMgr::getFlagEclipticLine() const
2420 {
2421 	return eclipticLine->isDisplayed();
2422 }
2423 //! Set flag for displaying Ecliptic Line partitions
setFlagEclipticParts(const bool displayed)2424 void GridLinesMgr::setFlagEclipticParts(const bool displayed)
2425 {
2426 	if(displayed != eclipticLine->showsPartitions())
2427 	{
2428 		eclipticLine->setPartitions(displayed);
2429 		emit eclipticPartsDisplayedChanged(displayed);
2430 	}
2431 }
2432 //! Get flag for displaying Ecliptic Line partitions
getFlagEclipticParts() const2433 bool GridLinesMgr::getFlagEclipticParts() const
2434 {
2435 	return eclipticLine->showsPartitions();
2436 }
2437 //! Set flag for displaying Ecliptic Line partitions
setFlagEclipticLabeled(const bool displayed)2438 void GridLinesMgr::setFlagEclipticLabeled(const bool displayed)
2439 {
2440 	if(displayed != eclipticLine->isLabeled())
2441 	{
2442 		eclipticLine->setLabeled(displayed);
2443 		emit eclipticPartsLabeledChanged(displayed);
2444 	}
2445 }
2446 //! Get flag for displaying Ecliptic Line partitions
getFlagEclipticLabeled() const2447 bool GridLinesMgr::getFlagEclipticLabeled() const
2448 {
2449 	return eclipticLine->isLabeled();
2450 }
getColorEclipticLine() const2451 Vec3f GridLinesMgr::getColorEclipticLine() const
2452 {
2453 	return eclipticLine->getColor();
2454 }
setColorEclipticLine(const Vec3f & newColor)2455 void GridLinesMgr::setColorEclipticLine(const Vec3f& newColor)
2456 {
2457 	if(newColor != eclipticLine->getColor())
2458 	{
2459 		eclipticLine->setColor(newColor);
2460 		emit eclipticLineColorChanged(newColor);
2461 	}
2462 }
2463 
2464 //! Set flag for displaying Ecliptic J2000 Line
setFlagEclipticJ2000Line(const bool displayed)2465 void GridLinesMgr::setFlagEclipticJ2000Line(const bool displayed)
2466 {
2467 	if(displayed != eclipticJ2000Line->isDisplayed())
2468 	{
2469 		eclipticJ2000Line->setDisplayed(displayed);
2470 		emit eclipticJ2000LineDisplayedChanged(displayed);
2471 	}
2472 }
2473 //! Get flag for displaying Ecliptic J2000 Line
getFlagEclipticJ2000Line() const2474 bool GridLinesMgr::getFlagEclipticJ2000Line() const
2475 {
2476 	return eclipticJ2000Line->isDisplayed();
2477 }
2478 //! Set flag for displaying Ecliptic J2000 Line partitions
setFlagEclipticJ2000Parts(const bool displayed)2479 void GridLinesMgr::setFlagEclipticJ2000Parts(const bool displayed)
2480 {
2481 	if(displayed != eclipticJ2000Line->showsPartitions())
2482 	{
2483 		eclipticJ2000Line->setPartitions(displayed);
2484 		emit eclipticJ2000PartsDisplayedChanged(displayed);
2485 	}
2486 }
2487 //! Get flag for displaying Ecliptic J2000 Line partitions
getFlagEclipticJ2000Parts() const2488 bool GridLinesMgr::getFlagEclipticJ2000Parts() const
2489 {
2490 	return eclipticJ2000Line->showsPartitions();
2491 }
2492 //! Set flag for displaying Ecliptic J2000 Line partitions
setFlagEclipticJ2000Labeled(const bool displayed)2493 void GridLinesMgr::setFlagEclipticJ2000Labeled(const bool displayed)
2494 {
2495 	if(displayed != eclipticJ2000Line->isLabeled())
2496 	{
2497 		eclipticJ2000Line->setLabeled(displayed);
2498 		emit eclipticJ2000PartsLabeledChanged(displayed);
2499 	}
2500 }
2501 //! Get flag for displaying Ecliptic J2000 Line partitions
getFlagEclipticJ2000Labeled() const2502 bool GridLinesMgr::getFlagEclipticJ2000Labeled() const
2503 {
2504 	return eclipticJ2000Line->isLabeled();
2505 }
getColorEclipticJ2000Line() const2506 Vec3f GridLinesMgr::getColorEclipticJ2000Line() const
2507 {
2508 	return eclipticJ2000Line->getColor();
2509 }
setColorEclipticJ2000Line(const Vec3f & newColor)2510 void GridLinesMgr::setColorEclipticJ2000Line(const Vec3f& newColor)
2511 {
2512 	if(newColor != eclipticJ2000Line->getColor())
2513 	{
2514 		eclipticJ2000Line->setColor(newColor);
2515 		emit eclipticJ2000LineColorChanged(newColor);
2516 	}
2517 }
2518 
2519 //! Set flag for displaying Invariable Plane Line
setFlagInvariablePlaneLine(const bool displayed)2520 void GridLinesMgr::setFlagInvariablePlaneLine(const bool displayed)
2521 {
2522 	if(displayed != invariablePlaneLine->isDisplayed())
2523 	{
2524 		invariablePlaneLine->setDisplayed(displayed);
2525 		emit invariablePlaneLineDisplayedChanged(displayed);
2526 	}
2527 }
2528 //! Get flag for displaying Invariable Plane Line
getFlagInvariablePlaneLine() const2529 bool GridLinesMgr::getFlagInvariablePlaneLine() const
2530 {
2531 	return invariablePlaneLine->isDisplayed();
2532 }
getColorInvariablePlaneLine() const2533 Vec3f GridLinesMgr::getColorInvariablePlaneLine() const
2534 {
2535 	return invariablePlaneLine->getColor();
2536 }
setColorInvariablePlaneLine(const Vec3f & newColor)2537 void GridLinesMgr::setColorInvariablePlaneLine(const Vec3f& newColor)
2538 {
2539 	if(newColor != invariablePlaneLine->getColor())
2540 	{
2541 		invariablePlaneLine->setColor(newColor);
2542 		emit invariablePlaneLineColorChanged(newColor);
2543 	}
2544 }
2545 
2546 //! Set flag for displaying Solar Equator Line
setFlagSolarEquatorLine(const bool displayed)2547 void GridLinesMgr::setFlagSolarEquatorLine(const bool displayed)
2548 {
2549 	if(displayed != solarEquatorLine->isDisplayed())
2550 	{
2551 		solarEquatorLine->setDisplayed(displayed);
2552 		emit solarEquatorLineDisplayedChanged(displayed);
2553 	}
2554 }
2555 //! Get flag for displaying Solar Equator Line
getFlagSolarEquatorLine() const2556 bool GridLinesMgr::getFlagSolarEquatorLine() const
2557 {
2558 	return solarEquatorLine->isDisplayed();
2559 }
2560 //! Set flag for displaying Solar Equator Line partitions
setFlagSolarEquatorParts(const bool displayed)2561 void GridLinesMgr::setFlagSolarEquatorParts(const bool displayed)
2562 {
2563 	if(displayed != solarEquatorLine->showsPartitions())
2564 	{
2565 		solarEquatorLine->setPartitions(displayed);
2566 		emit solarEquatorPartsDisplayedChanged(displayed);
2567 	}
2568 }
2569 //! Get flag for displaying Solar Equator Line partitions
getFlagSolarEquatorParts() const2570 bool GridLinesMgr::getFlagSolarEquatorParts() const
2571 {
2572 	return solarEquatorLine->showsPartitions();
2573 }
2574 //! Set flag for displaying Solar Equator Line partitions
setFlagSolarEquatorLabeled(const bool displayed)2575 void GridLinesMgr::setFlagSolarEquatorLabeled(const bool displayed)
2576 {
2577 	if(displayed != solarEquatorLine->isLabeled())
2578 	{
2579 		solarEquatorLine->setLabeled(displayed);
2580 		emit solarEquatorPartsLabeledChanged(displayed);
2581 	}
2582 }
2583 //! Get flag for displaying Solar Equator Line partitions
getFlagSolarEquatorLabeled() const2584 bool GridLinesMgr::getFlagSolarEquatorLabeled() const
2585 {
2586 	return solarEquatorLine->isLabeled();
2587 }
getColorSolarEquatorLine() const2588 Vec3f GridLinesMgr::getColorSolarEquatorLine() const
2589 {
2590 	return solarEquatorLine->getColor();
2591 }
setColorSolarEquatorLine(const Vec3f & newColor)2592 void GridLinesMgr::setColorSolarEquatorLine(const Vec3f& newColor)
2593 {
2594 	if(newColor != solarEquatorLine->getColor())
2595 	{
2596 		solarEquatorLine->setColor(newColor);
2597 		emit solarEquatorLineColorChanged(newColor);
2598 	}
2599 }
2600 
2601 //! Set flag for displaying Precession Circles
setFlagPrecessionCircles(const bool displayed)2602 void GridLinesMgr::setFlagPrecessionCircles(const bool displayed)
2603 {
2604 	if(displayed != precessionCircleN->isDisplayed())
2605 	{
2606 		precessionCircleN->setDisplayed(displayed);
2607 		precessionCircleS->setDisplayed(displayed);
2608 		emit precessionCirclesDisplayedChanged(displayed);
2609 	}
2610 }
2611 //! Get flag for displaying Precession Circles
getFlagPrecessionCircles() const2612 bool GridLinesMgr::getFlagPrecessionCircles() const
2613 {
2614 	// precessionCircleS is always synchronous, no separate queries.
2615 	return precessionCircleN->isDisplayed();
2616 }
2617 //! Set flag for displaying Precession Circle partitions
setFlagPrecessionParts(const bool displayed)2618 void GridLinesMgr::setFlagPrecessionParts(const bool displayed)
2619 {
2620 	if(displayed != precessionCircleN->showsPartitions())
2621 	{
2622 		precessionCircleN->setPartitions(displayed);
2623 		precessionCircleS->setPartitions(displayed);
2624 		emit precessionPartsDisplayedChanged(displayed);
2625 	}
2626 }
2627 //! Get flag for displaying Precession Circle partitions
getFlagPrecessionParts() const2628 bool GridLinesMgr::getFlagPrecessionParts() const
2629 {
2630 	// precessionCircleS is always synchronous, no separate queries.
2631 	return precessionCircleN->showsPartitions();
2632 }
2633 //! Set flag for displaying Precession Circle partitions
setFlagPrecessionLabeled(const bool displayed)2634 void GridLinesMgr::setFlagPrecessionLabeled(const bool displayed)
2635 {
2636 	if(displayed != precessionCircleN->isLabeled())
2637 	{
2638 		precessionCircleN->setLabeled(displayed);
2639 		precessionCircleS->setLabeled(displayed);
2640 		emit precessionPartsLabeledChanged(displayed);
2641 	}
2642 }
2643 //! Get flag for displaying Precession Circle partitions
getFlagPrecessionLabeled() const2644 bool GridLinesMgr::getFlagPrecessionLabeled() const
2645 {
2646 	// precessionCircleS is always synchronous, no separate queries.
2647 	return precessionCircleN->isLabeled();
2648 }
getColorPrecessionCircles() const2649 Vec3f GridLinesMgr::getColorPrecessionCircles() const
2650 {
2651 	return precessionCircleN->getColor();
2652 }
setColorPrecessionCircles(const Vec3f & newColor)2653 void GridLinesMgr::setColorPrecessionCircles(const Vec3f& newColor)
2654 {
2655 	if(newColor != precessionCircleN->getColor())
2656 	{
2657 		precessionCircleN->setColor(newColor);
2658 		precessionCircleS->setColor(newColor);
2659 		emit precessionCirclesColorChanged(newColor);
2660 	}
2661 }
2662 
2663 //! Set flag for displaying Meridian Line
setFlagMeridianLine(const bool displayed)2664 void GridLinesMgr::setFlagMeridianLine(const bool displayed)
2665 {
2666 	if(displayed != meridianLine->isDisplayed())
2667 	{
2668 		meridianLine->setDisplayed(displayed);
2669 		emit meridianLineDisplayedChanged(displayed);
2670 	}
2671 }
2672 //! Get flag for displaying Meridian Line
getFlagMeridianLine() const2673 bool GridLinesMgr::getFlagMeridianLine() const
2674 {
2675 	return meridianLine->isDisplayed();
2676 }
2677 //! Set flag for displaying Meridian Line partitions
setFlagMeridianParts(const bool displayed)2678 void GridLinesMgr::setFlagMeridianParts(const bool displayed)
2679 {
2680 	if(displayed != meridianLine->showsPartitions())
2681 	{
2682 		meridianLine->setPartitions(displayed);
2683 		emit meridianPartsDisplayedChanged(displayed);
2684 	}
2685 }
2686 //! Get flag for displaying Meridian Line partitions
getFlagMeridianParts() const2687 bool GridLinesMgr::getFlagMeridianParts() const
2688 {
2689 	return meridianLine->showsPartitions();
2690 }
2691 //! Set flag for displaying Meridian Line partitions
setFlagMeridianLabeled(const bool displayed)2692 void GridLinesMgr::setFlagMeridianLabeled(const bool displayed)
2693 {
2694 	if(displayed != meridianLine->isLabeled())
2695 	{
2696 		meridianLine->setLabeled(displayed);
2697 		emit meridianPartsLabeledChanged(displayed);
2698 	}
2699 }
2700 //! Get flag for displaying Meridian Line partitions
getFlagMeridianLabeled() const2701 bool GridLinesMgr::getFlagMeridianLabeled() const
2702 {
2703 	return meridianLine->isLabeled();
2704 }
getColorMeridianLine() const2705 Vec3f GridLinesMgr::getColorMeridianLine() const
2706 {
2707 	return meridianLine->getColor();
2708 }
setColorMeridianLine(const Vec3f & newColor)2709 void GridLinesMgr::setColorMeridianLine(const Vec3f& newColor)
2710 {
2711 	if(newColor != meridianLine->getColor())
2712 	{
2713 		meridianLine->setColor(newColor);
2714 		emit meridianLineColorChanged(newColor);
2715 	}
2716 }
2717 
2718 //! Set flag for displaying opposition/conjunction longitude line
setFlagLongitudeLine(const bool displayed)2719 void GridLinesMgr::setFlagLongitudeLine(const bool displayed)
2720 {
2721 	if(displayed != longitudeLine->isDisplayed())
2722 	{
2723 		longitudeLine->setDisplayed(displayed);
2724 		emit longitudeLineDisplayedChanged(displayed);
2725 	}
2726 }
2727 //! Get flag for displaying opposition/conjunction longitude line
getFlagLongitudeLine() const2728 bool GridLinesMgr::getFlagLongitudeLine() const
2729 {
2730 	return longitudeLine->isDisplayed();
2731 }
2732 //! Set flag for displaying opposition/conjunction longitude line partitions
setFlagLongitudeParts(const bool displayed)2733 void GridLinesMgr::setFlagLongitudeParts(const bool displayed)
2734 {
2735 	if(displayed != longitudeLine->showsPartitions())
2736 	{
2737 		longitudeLine->setPartitions(displayed);
2738 		emit longitudePartsDisplayedChanged(displayed);
2739 	}
2740 }
2741 //! Get flag for displaying opposition/conjunction longitude line partitions
getFlagLongitudeParts() const2742 bool GridLinesMgr::getFlagLongitudeParts() const
2743 {
2744 	return longitudeLine->showsPartitions();
2745 }
2746 //! Set flag for displaying opposition/conjunction longitude line partitions
setFlagLongitudeLabeled(const bool displayed)2747 void GridLinesMgr::setFlagLongitudeLabeled(const bool displayed)
2748 {
2749 	if(displayed != longitudeLine->isLabeled())
2750 	{
2751 		longitudeLine->setLabeled(displayed);
2752 		emit longitudePartsLabeledChanged(displayed);
2753 	}
2754 }
getFlagLongitudeLabeled() const2755 bool GridLinesMgr::getFlagLongitudeLabeled() const
2756 {
2757 	return longitudeLine->isLabeled();
2758 }
getColorLongitudeLine() const2759 Vec3f GridLinesMgr::getColorLongitudeLine() const
2760 {
2761 	return longitudeLine->getColor();
2762 }
setColorLongitudeLine(const Vec3f & newColor)2763 void GridLinesMgr::setColorLongitudeLine(const Vec3f& newColor)
2764 {
2765 	if(newColor != longitudeLine->getColor())
2766 	{
2767 		longitudeLine->setColor(newColor);
2768 		emit longitudeLineColorChanged(newColor);
2769 	}
2770 }
2771 
2772 //! Set flag for displaying Horizon Line
setFlagHorizonLine(const bool displayed)2773 void GridLinesMgr::setFlagHorizonLine(const bool displayed)
2774 {
2775 	if(displayed != horizonLine->isDisplayed())
2776 	{
2777 		horizonLine->setDisplayed(displayed);
2778 		emit horizonLineDisplayedChanged(displayed);
2779 	}
2780 }
2781 //! Get flag for displaying Horizon Line
getFlagHorizonLine() const2782 bool GridLinesMgr::getFlagHorizonLine() const
2783 {
2784 	return horizonLine->isDisplayed();
2785 }
2786 //! Set flag for displaying Horizon Line partitions
setFlagHorizonParts(const bool displayed)2787 void GridLinesMgr::setFlagHorizonParts(const bool displayed)
2788 {
2789 	if(displayed != horizonLine->showsPartitions())
2790 	{
2791 		horizonLine->setPartitions(displayed);
2792 		emit horizonPartsDisplayedChanged(displayed);
2793 	}
2794 }
2795 //! Get flag for displaying Horizon Line partitions
getFlagHorizonParts() const2796 bool GridLinesMgr::getFlagHorizonParts() const
2797 {
2798 	return horizonLine->showsPartitions();
2799 }
2800 //! Set flag for displaying Horizon Line partitions
setFlagHorizonLabeled(const bool displayed)2801 void GridLinesMgr::setFlagHorizonLabeled(const bool displayed)
2802 {
2803 	if(displayed != horizonLine->isLabeled())
2804 	{
2805 		horizonLine->setLabeled(displayed);
2806 		emit horizonPartsLabeledChanged(displayed);
2807 	}
2808 }
2809 //! Get flag for displaying Horizon Line partitions
getFlagHorizonLabeled() const2810 bool GridLinesMgr::getFlagHorizonLabeled() const
2811 {
2812 	return horizonLine->isLabeled();
2813 }
getColorHorizonLine() const2814 Vec3f GridLinesMgr::getColorHorizonLine() const
2815 {
2816 	return horizonLine->getColor();
2817 }
setColorHorizonLine(const Vec3f & newColor)2818 void GridLinesMgr::setColorHorizonLine(const Vec3f& newColor)
2819 {
2820 	if(newColor != horizonLine->getColor())
2821 	{
2822 		horizonLine->setColor(newColor);
2823 		emit horizonLineColorChanged(newColor);
2824 	}
2825 }
2826 
2827 //! Set flag for displaying Galactic Equator Line
setFlagGalacticEquatorLine(const bool displayed)2828 void GridLinesMgr::setFlagGalacticEquatorLine(const bool displayed)
2829 {
2830 	if(displayed != galacticEquatorLine->isDisplayed())
2831 	{
2832 		galacticEquatorLine->setDisplayed(displayed);
2833 		emit galacticEquatorLineDisplayedChanged(displayed);
2834 	}
2835 }
2836 //! Get flag for displaying Galactic Equator Line
getFlagGalacticEquatorLine() const2837 bool GridLinesMgr::getFlagGalacticEquatorLine() const
2838 {
2839 	return galacticEquatorLine->isDisplayed();
2840 }
2841 //! Set flag for displaying Galactic Equator Line partitions
setFlagGalacticEquatorParts(const bool displayed)2842 void GridLinesMgr::setFlagGalacticEquatorParts(const bool displayed)
2843 {
2844 	if(displayed != galacticEquatorLine->showsPartitions())
2845 	{
2846 		galacticEquatorLine->setPartitions(displayed);
2847 		emit galacticEquatorPartsDisplayedChanged(displayed);
2848 	}
2849 }
2850 //! Get flag for displaying Galactic Equator Line partitions
getFlagGalacticEquatorParts() const2851 bool GridLinesMgr::getFlagGalacticEquatorParts() const
2852 {
2853 	return galacticEquatorLine->showsPartitions();
2854 }
2855 //! Set flag for displaying Galactic Equator Line partitions
setFlagGalacticEquatorLabeled(const bool displayed)2856 void GridLinesMgr::setFlagGalacticEquatorLabeled(const bool displayed)
2857 {
2858 	if(displayed != galacticEquatorLine->isLabeled())
2859 	{
2860 		galacticEquatorLine->setLabeled(displayed);
2861 		emit galacticEquatorPartsLabeledChanged(displayed);
2862 	}
2863 }
2864 //! Get flag for displaying Galactic Equator Line partitions
getFlagGalacticEquatorLabeled() const2865 bool GridLinesMgr::getFlagGalacticEquatorLabeled() const
2866 {
2867 	return galacticEquatorLine->isLabeled();
2868 }
getColorGalacticEquatorLine() const2869 Vec3f GridLinesMgr::getColorGalacticEquatorLine() const
2870 {
2871 	return galacticEquatorLine->getColor();
2872 }
setColorGalacticEquatorLine(const Vec3f & newColor)2873 void GridLinesMgr::setColorGalacticEquatorLine(const Vec3f& newColor)
2874 {
2875 	if(newColor != galacticEquatorLine->getColor())
2876 	{
2877 		galacticEquatorLine->setColor(newColor);
2878 		emit galacticEquatorLineColorChanged(newColor);
2879 	}
2880 }
2881 
2882 //! Set flag for displaying Supergalactic Equator Line
setFlagSupergalacticEquatorLine(const bool displayed)2883 void GridLinesMgr::setFlagSupergalacticEquatorLine(const bool displayed)
2884 {
2885 	if(displayed != supergalacticEquatorLine->isDisplayed())
2886 	{
2887 		supergalacticEquatorLine->setDisplayed(displayed);
2888 		emit supergalacticEquatorLineDisplayedChanged(displayed);
2889 	}
2890 }
2891 //! Get flag for displaying Supergalactic Equator Line
getFlagSupergalacticEquatorLine() const2892 bool GridLinesMgr::getFlagSupergalacticEquatorLine() const
2893 {
2894 	return supergalacticEquatorLine->isDisplayed();
2895 }
2896 //! Set flag for displaying Supergalactic Equator Line partitions
setFlagSupergalacticEquatorParts(const bool displayed)2897 void GridLinesMgr::setFlagSupergalacticEquatorParts(const bool displayed)
2898 {
2899 	if(displayed != supergalacticEquatorLine->showsPartitions())
2900 	{
2901 		supergalacticEquatorLine->setPartitions(displayed);
2902 		emit supergalacticEquatorPartsDisplayedChanged(displayed);
2903 	}
2904 }
2905 //! Get flag for displaying Supergalactic Equator Line partitions
getFlagSupergalacticEquatorParts() const2906 bool GridLinesMgr::getFlagSupergalacticEquatorParts() const
2907 {
2908 	return supergalacticEquatorLine->showsPartitions();
2909 }
2910 //! Set flag for displaying Supergalactic Equator Line partitions
setFlagSupergalacticEquatorLabeled(const bool displayed)2911 void GridLinesMgr::setFlagSupergalacticEquatorLabeled(const bool displayed)
2912 {
2913 	if(displayed != supergalacticEquatorLine->isLabeled())
2914 	{
2915 		supergalacticEquatorLine->setLabeled(displayed);
2916 		emit supergalacticEquatorPartsLabeledChanged(displayed);
2917 	}
2918 }
2919 //! Get flag for displaying Supergalactic Equator Line partitions
getFlagSupergalacticEquatorLabeled() const2920 bool GridLinesMgr::getFlagSupergalacticEquatorLabeled() const
2921 {
2922 	return supergalacticEquatorLine->isLabeled();
2923 }
getColorSupergalacticEquatorLine() const2924 Vec3f GridLinesMgr::getColorSupergalacticEquatorLine() const
2925 {
2926 	return supergalacticEquatorLine->getColor();
2927 }
setColorSupergalacticEquatorLine(const Vec3f & newColor)2928 void GridLinesMgr::setColorSupergalacticEquatorLine(const Vec3f& newColor)
2929 {
2930 	if(newColor != supergalacticEquatorLine->getColor())
2931 	{
2932 		supergalacticEquatorLine->setColor(newColor);
2933 		emit supergalacticEquatorLineColorChanged(newColor);
2934 	}
2935 }
2936 
2937 //! Set flag for displaying Prime Vertical Line
setFlagPrimeVerticalLine(const bool displayed)2938 void GridLinesMgr::setFlagPrimeVerticalLine(const bool displayed)
2939 {
2940 	if(displayed != primeVerticalLine->isDisplayed())
2941 	{
2942 		primeVerticalLine->setDisplayed(displayed);
2943 		emit  primeVerticalLineDisplayedChanged(displayed);
2944 	}
2945 }
2946 //! Get flag for displaying Prime Vertical Line
getFlagPrimeVerticalLine() const2947 bool GridLinesMgr::getFlagPrimeVerticalLine() const
2948 {
2949 	return primeVerticalLine->isDisplayed();
2950 }
2951 //! Set flag for displaying Prime Vertical Line partitions
setFlagPrimeVerticalParts(const bool displayed)2952 void GridLinesMgr::setFlagPrimeVerticalParts(const bool displayed)
2953 {
2954 	if(displayed != primeVerticalLine->showsPartitions())
2955 	{
2956 		primeVerticalLine->setPartitions(displayed);
2957 		emit  primeVerticalPartsDisplayedChanged(displayed);
2958 	}
2959 }
2960 //! Get flag for displaying Prime Vertical Line partitions
getFlagPrimeVerticalParts() const2961 bool GridLinesMgr::getFlagPrimeVerticalParts() const
2962 {
2963 	return primeVerticalLine->showsPartitions();
2964 }
2965 //! Set flag for displaying Prime Vertical Line partitions
setFlagPrimeVerticalLabeled(const bool displayed)2966 void GridLinesMgr::setFlagPrimeVerticalLabeled(const bool displayed)
2967 {
2968 	if(displayed != primeVerticalLine->isLabeled())
2969 	{
2970 		primeVerticalLine->setLabeled(displayed);
2971 		emit  primeVerticalPartsLabeledChanged(displayed);
2972 	}
2973 }
2974 //! Get flag for displaying Prime Vertical Line partitions
getFlagPrimeVerticalLabeled() const2975 bool GridLinesMgr::getFlagPrimeVerticalLabeled() const
2976 {
2977 	return primeVerticalLine->isLabeled();
2978 }
getColorPrimeVerticalLine() const2979 Vec3f GridLinesMgr::getColorPrimeVerticalLine() const
2980 {
2981 	return primeVerticalLine->getColor();
2982 }
setColorPrimeVerticalLine(const Vec3f & newColor)2983 void GridLinesMgr::setColorPrimeVerticalLine(const Vec3f& newColor)
2984 {
2985 	if(newColor != primeVerticalLine->getColor())
2986 	{
2987 		primeVerticalLine->setColor(newColor);
2988 		emit primeVerticalLineColorChanged(newColor);
2989 	}
2990 }
2991 
2992 //! Set flag for displaying Current Vertical Line
setFlagCurrentVerticalLine(const bool displayed)2993 void GridLinesMgr::setFlagCurrentVerticalLine(const bool displayed)
2994 {
2995 	if(displayed != currentVerticalLine->isDisplayed())
2996 	{
2997 		currentVerticalLine->setDisplayed(displayed);
2998 		emit  currentVerticalLineDisplayedChanged(displayed);
2999 	}
3000 }
3001 //! Get flag for displaying Current Vertical Line
getFlagCurrentVerticalLine() const3002 bool GridLinesMgr::getFlagCurrentVerticalLine() const
3003 {
3004 	return currentVerticalLine->isDisplayed();
3005 }
3006 //! Set flag for displaying Current Vertical Line partitions
setFlagCurrentVerticalParts(const bool displayed)3007 void GridLinesMgr::setFlagCurrentVerticalParts(const bool displayed)
3008 {
3009 	if(displayed != currentVerticalLine->showsPartitions())
3010 	{
3011 		currentVerticalLine->setPartitions(displayed);
3012 		emit  currentVerticalPartsDisplayedChanged(displayed);
3013 	}
3014 }
3015 //! Get flag for displaying Current Vertical Line partitions
getFlagCurrentVerticalParts() const3016 bool GridLinesMgr::getFlagCurrentVerticalParts() const
3017 {
3018 	return currentVerticalLine->showsPartitions();
3019 }
3020 //! Set flag for displaying Current Vertical Line partitions
setFlagCurrentVerticalLabeled(const bool displayed)3021 void GridLinesMgr::setFlagCurrentVerticalLabeled(const bool displayed)
3022 {
3023 	if(displayed != currentVerticalLine->isLabeled())
3024 	{
3025 		currentVerticalLine->setLabeled(displayed);
3026 		emit  currentVerticalPartsLabeledChanged(displayed);
3027 	}
3028 }
3029 //! Get flag for displaying Current Vertical Line partitions
getFlagCurrentVerticalLabeled() const3030 bool GridLinesMgr::getFlagCurrentVerticalLabeled() const
3031 {
3032 	return currentVerticalLine->isLabeled();
3033 }
getColorCurrentVerticalLine() const3034 Vec3f GridLinesMgr::getColorCurrentVerticalLine() const
3035 {
3036 	return currentVerticalLine->getColor();
3037 }
setColorCurrentVerticalLine(const Vec3f & newColor)3038 void GridLinesMgr::setColorCurrentVerticalLine(const Vec3f& newColor)
3039 {
3040 	if(newColor != currentVerticalLine->getColor())
3041 	{
3042 		currentVerticalLine->setColor(newColor);
3043 		emit currentVerticalLineColorChanged(newColor);
3044 	}
3045 }
3046 
3047 //! Set flag for displaying Colure Lines
setFlagColureLines(const bool displayed)3048 void GridLinesMgr::setFlagColureLines(const bool displayed)
3049 {
3050 	if(displayed != colureLine_1->isDisplayed())
3051 	{
3052 		colureLine_1->setDisplayed(displayed);
3053 		colureLine_2->setDisplayed(displayed);
3054 		emit  colureLinesDisplayedChanged(displayed);
3055 	}
3056 }
3057 //! Get flag for displaying Colure Lines
getFlagColureLines() const3058 bool GridLinesMgr::getFlagColureLines() const
3059 {
3060 	return colureLine_1->isDisplayed();
3061 }
3062 //! Set flag for displaying Colure Line partitions
setFlagColureParts(const bool displayed)3063 void GridLinesMgr::setFlagColureParts(const bool displayed)
3064 {
3065 	if(displayed != colureLine_1->showsPartitions())
3066 	{
3067 		colureLine_1->setPartitions(displayed);
3068 		colureLine_2->setPartitions(displayed);
3069 		emit  colurePartsDisplayedChanged(displayed);
3070 	}
3071 }
3072 //! Get flag for displaying Colure Line partitions
getFlagColureParts() const3073 bool GridLinesMgr::getFlagColureParts() const
3074 {
3075 	return colureLine_1->showsPartitions();
3076 }
setFlagColureLabeled(const bool displayed)3077 void GridLinesMgr::setFlagColureLabeled(const bool displayed)
3078 {
3079 	if(displayed != colureLine_1->isLabeled())
3080 	{
3081 		colureLine_1->setLabeled(displayed);
3082 		colureLine_2->setLabeled(displayed);
3083 		emit  colurePartsLabeledChanged(displayed);
3084 	}
3085 }
3086 //! Get flag for displaying Colure Line partitions
getFlagColureLabeled() const3087 bool GridLinesMgr::getFlagColureLabeled() const
3088 {
3089 	return colureLine_1->isLabeled();
3090 }
getColorColureLines() const3091 Vec3f GridLinesMgr::getColorColureLines() const
3092 {
3093 	return colureLine_1->getColor();
3094 }
setColorColureLines(const Vec3f & newColor)3095 void GridLinesMgr::setColorColureLines(const Vec3f& newColor)
3096 {
3097 	if(newColor != colureLine_1->getColor())
3098 	{
3099 		colureLine_1->setColor(newColor);
3100 		colureLine_2->setColor(newColor);
3101 		emit colureLinesColorChanged(newColor);
3102 	}
3103 }
3104 
3105 //! Set flag for displaying Circumpolar Circles
setFlagCircumpolarCircles(const bool displayed)3106 void GridLinesMgr::setFlagCircumpolarCircles(const bool displayed)
3107 {
3108 	if(displayed != circumpolarCircleN->isDisplayed())
3109 	{
3110 		circumpolarCircleN->setDisplayed(displayed);
3111 		circumpolarCircleS->setDisplayed(displayed);
3112 		emit circumpolarCirclesDisplayedChanged(displayed);
3113 	}
3114 }
3115 //! Get flag for displaying Circumpolar Circles
getFlagCircumpolarCircles() const3116 bool GridLinesMgr::getFlagCircumpolarCircles() const
3117 {
3118 	// circumpolarCircleS is always synchronous, no separate queries.
3119 	return circumpolarCircleN->isDisplayed();
3120 }
getColorCircumpolarCircles() const3121 Vec3f GridLinesMgr::getColorCircumpolarCircles() const
3122 {
3123 	return circumpolarCircleN->getColor();
3124 }
setColorCircumpolarCircles(const Vec3f & newColor)3125 void GridLinesMgr::setColorCircumpolarCircles(const Vec3f& newColor)
3126 {
3127 	if(newColor != circumpolarCircleN->getColor())
3128 	{
3129 		circumpolarCircleN->setColor(newColor);
3130 		circumpolarCircleS->setColor(newColor);
3131 		emit circumpolarCirclesColorChanged(newColor);
3132 	}
3133 }
3134 
3135 //! Set flag for displaying Umbra Circle
setFlagUmbraCircle(const bool displayed)3136 void GridLinesMgr::setFlagUmbraCircle(const bool displayed)
3137 {
3138 	if(displayed != umbraCircle->isDisplayed())
3139 	{
3140 		umbraCircle->setDisplayed(displayed);
3141 		emit umbraCircleDisplayedChanged(displayed);
3142 	}
3143 }
3144 //! Get flag for displaying Umbra Circle
getFlagUmbraCircle() const3145 bool GridLinesMgr::getFlagUmbraCircle() const
3146 {
3147 	return umbraCircle->isDisplayed();
3148 }
getColorUmbraCircle() const3149 Vec3f GridLinesMgr::getColorUmbraCircle() const
3150 {
3151 	return umbraCircle->getColor();
3152 }
setColorUmbraCircle(const Vec3f & newColor)3153 void GridLinesMgr::setColorUmbraCircle(const Vec3f& newColor)
3154 {
3155 	if(newColor != umbraCircle->getColor())
3156 	{
3157 		umbraCircle->setColor(newColor);
3158 		umbraCenterPoint->setColor(newColor);
3159 		emit umbraCircleColorChanged(newColor);
3160 	}
3161 }
3162 
3163 //! Set flag for displaying Penumbra Circle
setFlagPenumbraCircle(const bool displayed)3164 void GridLinesMgr::setFlagPenumbraCircle(const bool displayed)
3165 {
3166 	if(displayed != penumbraCircle->isDisplayed())
3167 	{
3168 		penumbraCircle->setDisplayed(displayed);
3169 		emit penumbraCircleDisplayedChanged(displayed);
3170 	}
3171 }
3172 //! Get flag for displaying Penumbra Circle
getFlagPenumbraCircle() const3173 bool GridLinesMgr::getFlagPenumbraCircle() const
3174 {
3175 	return penumbraCircle->isDisplayed();
3176 }
getColorPenumbraCircle() const3177 Vec3f GridLinesMgr::getColorPenumbraCircle() const
3178 {
3179 	return penumbraCircle->getColor();
3180 }
setColorPenumbraCircle(const Vec3f & newColor)3181 void GridLinesMgr::setColorPenumbraCircle(const Vec3f& newColor)
3182 {
3183 	if(newColor != penumbraCircle->getColor())
3184 	{
3185 		penumbraCircle->setColor(newColor);
3186 		emit penumbraCircleColorChanged(newColor);
3187 	}
3188 }
3189 
3190 //! Set flag for displaying celestial poles of J2000
setFlagCelestialJ2000Poles(const bool displayed)3191 void GridLinesMgr::setFlagCelestialJ2000Poles(const bool displayed)
3192 {
3193 	if(displayed != celestialJ2000Poles->isDisplayed())
3194 	{
3195 		celestialJ2000Poles->setDisplayed(displayed);
3196 		emit celestialJ2000PolesDisplayedChanged(displayed);
3197 	}
3198 }
3199 //! Get flag for displaying celestial poles of J2000
getFlagCelestialJ2000Poles() const3200 bool GridLinesMgr::getFlagCelestialJ2000Poles() const
3201 {
3202 	return celestialJ2000Poles->isDisplayed();
3203 }
getColorCelestialJ2000Poles() const3204 Vec3f GridLinesMgr::getColorCelestialJ2000Poles() const
3205 {
3206 	return celestialJ2000Poles->getColor();
3207 }
setColorCelestialJ2000Poles(const Vec3f & newColor)3208 void GridLinesMgr::setColorCelestialJ2000Poles(const Vec3f& newColor)
3209 {
3210 	if(newColor != celestialJ2000Poles->getColor())
3211 	{
3212 		celestialJ2000Poles->setColor(newColor);
3213 		emit celestialJ2000PolesColorChanged(newColor);
3214 	}
3215 }
3216 
3217 //! Set flag for displaying celestial poles
setFlagCelestialPoles(const bool displayed)3218 void GridLinesMgr::setFlagCelestialPoles(const bool displayed)
3219 {
3220 	if(displayed != celestialPoles->isDisplayed())
3221 	{
3222 		celestialPoles->setDisplayed(displayed);
3223 		emit celestialPolesDisplayedChanged(displayed);
3224 	}
3225 }
3226 //! Get flag for displaying celestial poles
getFlagCelestialPoles() const3227 bool GridLinesMgr::getFlagCelestialPoles() const
3228 {
3229 	return celestialPoles->isDisplayed();
3230 }
getColorCelestialPoles() const3231 Vec3f GridLinesMgr::getColorCelestialPoles() const
3232 {
3233 	return celestialPoles->getColor();
3234 }
setColorCelestialPoles(const Vec3f & newColor)3235 void GridLinesMgr::setColorCelestialPoles(const Vec3f& newColor)
3236 {
3237 	if(newColor != celestialPoles->getColor())
3238 	{
3239 		celestialPoles->setColor(newColor);
3240 		emit celestialPolesColorChanged(newColor);
3241 	}
3242 }
3243 
3244 //! Set flag for displaying zenith and nadir
setFlagZenithNadir(const bool displayed)3245 void GridLinesMgr::setFlagZenithNadir(const bool displayed)
3246 {
3247 	if(displayed != zenithNadir->isDisplayed())
3248 	{
3249 		zenithNadir->setDisplayed(displayed);
3250 		emit zenithNadirDisplayedChanged(displayed);
3251 	}
3252 }
3253 //! Get flag for displaying zenith and nadir
getFlagZenithNadir() const3254 bool GridLinesMgr::getFlagZenithNadir() const
3255 {
3256 	return zenithNadir->isDisplayed();
3257 }
getColorZenithNadir() const3258 Vec3f GridLinesMgr::getColorZenithNadir() const
3259 {
3260 	return zenithNadir->getColor();
3261 }
setColorZenithNadir(const Vec3f & newColor)3262 void GridLinesMgr::setColorZenithNadir(const Vec3f& newColor)
3263 {
3264 	if(newColor != zenithNadir->getColor())
3265 	{
3266 		zenithNadir->setColor(newColor);
3267 		emit zenithNadirColorChanged(newColor);
3268 	}
3269 }
3270 
3271 //! Set flag for displaying ecliptic poles of J2000
setFlagEclipticJ2000Poles(const bool displayed)3272 void GridLinesMgr::setFlagEclipticJ2000Poles(const bool displayed)
3273 {
3274 	if(displayed != eclipticJ2000Poles->isDisplayed())
3275 	{
3276 		eclipticJ2000Poles->setDisplayed(displayed);
3277 		emit eclipticJ2000PolesDisplayedChanged(displayed);
3278 	}
3279 }
3280 //! Get flag for displaying ecliptic poles of J2000
getFlagEclipticJ2000Poles() const3281 bool GridLinesMgr::getFlagEclipticJ2000Poles() const
3282 {
3283 	return eclipticJ2000Poles->isDisplayed();
3284 }
getColorEclipticJ2000Poles() const3285 Vec3f GridLinesMgr::getColorEclipticJ2000Poles() const
3286 {
3287 	return eclipticJ2000Poles->getColor();
3288 }
setColorEclipticJ2000Poles(const Vec3f & newColor)3289 void GridLinesMgr::setColorEclipticJ2000Poles(const Vec3f& newColor)
3290 {
3291 	if(newColor != eclipticJ2000Poles->getColor())
3292 	{
3293 		eclipticJ2000Poles->setColor(newColor);
3294 		emit eclipticJ2000PolesColorChanged(newColor);
3295 	}
3296 }
3297 
3298 //! Set flag for displaying ecliptic poles
setFlagEclipticPoles(const bool displayed)3299 void GridLinesMgr::setFlagEclipticPoles(const bool displayed)
3300 {
3301 	if(displayed != eclipticPoles->isDisplayed())
3302 	{
3303 		eclipticPoles->setDisplayed(displayed);
3304 		emit eclipticPolesDisplayedChanged(displayed);
3305 	}
3306 }
3307 //! Get flag for displaying ecliptic poles
getFlagEclipticPoles() const3308 bool GridLinesMgr::getFlagEclipticPoles() const
3309 {
3310 	return eclipticPoles->isDisplayed();
3311 }
getColorEclipticPoles() const3312 Vec3f GridLinesMgr::getColorEclipticPoles() const
3313 {
3314 	return eclipticPoles->getColor();
3315 }
setColorEclipticPoles(const Vec3f & newColor)3316 void GridLinesMgr::setColorEclipticPoles(const Vec3f& newColor)
3317 {
3318 	if(newColor != eclipticPoles->getColor())
3319 	{
3320 		eclipticPoles->setColor(newColor);
3321 		emit eclipticPolesColorChanged(newColor);
3322 	}
3323 }
3324 
3325 //! Set flag for displaying galactic poles
setFlagGalacticPoles(const bool displayed)3326 void GridLinesMgr::setFlagGalacticPoles(const bool displayed)
3327 {
3328 	if(displayed != galacticPoles->isDisplayed())
3329 	{
3330 		galacticPoles->setDisplayed(displayed);
3331 		emit galacticPolesDisplayedChanged(displayed);
3332 	}
3333 }
3334 //! Get flag for displaying galactic poles
getFlagGalacticPoles() const3335 bool GridLinesMgr::getFlagGalacticPoles() const
3336 {
3337 	return galacticPoles->isDisplayed();
3338 }
getColorGalacticPoles() const3339 Vec3f GridLinesMgr::getColorGalacticPoles() const
3340 {
3341 	return galacticPoles->getColor();
3342 }
setColorGalacticPoles(const Vec3f & newColor)3343 void GridLinesMgr::setColorGalacticPoles(const Vec3f& newColor)
3344 {
3345 	if(newColor != galacticPoles->getColor())
3346 	{
3347 		galacticPoles->setColor(newColor);
3348 		emit galacticPolesColorChanged(newColor);
3349 	}
3350 }
3351 
3352 //! Set flag for displaying galactic center and anticenter markers
setFlagGalacticCenter(const bool displayed)3353 void GridLinesMgr::setFlagGalacticCenter(const bool displayed)
3354 {
3355 	if(displayed != galacticCenter->isDisplayed())
3356 	{
3357 		galacticCenter->setDisplayed(displayed);
3358 		emit galacticCenterDisplayedChanged(displayed);
3359 	}
3360 }
3361 //! Get flag for displaying galactic center and anticenter markers
getFlagGalacticCenter() const3362 bool GridLinesMgr::getFlagGalacticCenter() const
3363 {
3364 	return galacticCenter->isDisplayed();
3365 }
getColorGalacticCenter() const3366 Vec3f GridLinesMgr::getColorGalacticCenter() const
3367 {
3368 	return galacticCenter->getColor();
3369 }
setColorGalacticCenter(const Vec3f & newColor)3370 void GridLinesMgr::setColorGalacticCenter(const Vec3f& newColor)
3371 {
3372 	if(newColor != galacticCenter->getColor())
3373 	{
3374 		galacticCenter->setColor(newColor);
3375 		emit galacticCenterColorChanged(newColor);
3376 	}
3377 }
3378 
3379 //! Set flag for displaying supergalactic poles
setFlagSupergalacticPoles(const bool displayed)3380 void GridLinesMgr::setFlagSupergalacticPoles(const bool displayed)
3381 {
3382 	if(displayed != supergalacticPoles->isDisplayed())
3383 	{
3384 		supergalacticPoles->setDisplayed(displayed);
3385 		emit supergalacticPolesDisplayedChanged(displayed);
3386 	}
3387 }
3388 //! Get flag for displaying supergalactic poles
getFlagSupergalacticPoles() const3389 bool GridLinesMgr::getFlagSupergalacticPoles() const
3390 {
3391 	return supergalacticPoles->isDisplayed();
3392 }
getColorSupergalacticPoles() const3393 Vec3f GridLinesMgr::getColorSupergalacticPoles() const
3394 {
3395 	return supergalacticPoles->getColor();
3396 }
setColorSupergalacticPoles(const Vec3f & newColor)3397 void GridLinesMgr::setColorSupergalacticPoles(const Vec3f& newColor)
3398 {
3399 	if(newColor != supergalacticPoles->getColor())
3400 	{
3401 		supergalacticPoles->setColor(newColor);
3402 		emit supergalacticPolesColorChanged(newColor);
3403 	}
3404 }
3405 
3406 //! Set flag for displaying equinox points of J2000
setFlagEquinoxJ2000Points(const bool displayed)3407 void GridLinesMgr::setFlagEquinoxJ2000Points(const bool displayed)
3408 {
3409 	if(displayed != equinoxJ2000Points->isDisplayed())
3410 	{
3411 		equinoxJ2000Points->setDisplayed(displayed);
3412 		emit equinoxJ2000PointsDisplayedChanged(displayed);
3413 	}
3414 }
3415 //! Get flag for displaying equinox points of J2000
getFlagEquinoxJ2000Points() const3416 bool GridLinesMgr::getFlagEquinoxJ2000Points() const
3417 {
3418 	return equinoxJ2000Points->isDisplayed();
3419 }
getColorEquinoxJ2000Points() const3420 Vec3f GridLinesMgr::getColorEquinoxJ2000Points() const
3421 {
3422 	return equinoxJ2000Points->getColor();
3423 }
setColorEquinoxJ2000Points(const Vec3f & newColor)3424 void GridLinesMgr::setColorEquinoxJ2000Points(const Vec3f& newColor)
3425 {
3426 	if(newColor != equinoxJ2000Points->getColor())
3427 	{
3428 		equinoxJ2000Points->setColor(newColor);
3429 		emit equinoxJ2000PointsColorChanged(newColor);
3430 	}
3431 }
3432 
3433 //! Set flag for displaying equinox points
setFlagEquinoxPoints(const bool displayed)3434 void GridLinesMgr::setFlagEquinoxPoints(const bool displayed)
3435 {
3436 	if(displayed != equinoxPoints->isDisplayed())
3437 	{
3438 		equinoxPoints->setDisplayed(displayed);
3439 		emit equinoxPointsDisplayedChanged(displayed);
3440 	}
3441 }
3442 //! Get flag for displaying equinox points
getFlagEquinoxPoints() const3443 bool GridLinesMgr::getFlagEquinoxPoints() const
3444 {
3445 	return equinoxPoints->isDisplayed();
3446 }
getColorEquinoxPoints() const3447 Vec3f GridLinesMgr::getColorEquinoxPoints() const
3448 {
3449 	return equinoxPoints->getColor();
3450 }
setColorEquinoxPoints(const Vec3f & newColor)3451 void GridLinesMgr::setColorEquinoxPoints(const Vec3f& newColor)
3452 {
3453 	if(newColor != equinoxPoints->getColor())
3454 	{
3455 		equinoxPoints->setColor(newColor);
3456 		emit equinoxPointsColorChanged(newColor);
3457 	}
3458 }
3459 
3460 //! Set flag for displaying solstice points of J2000
setFlagSolsticeJ2000Points(const bool displayed)3461 void GridLinesMgr::setFlagSolsticeJ2000Points(const bool displayed)
3462 {
3463 	if(displayed != solsticeJ2000Points->isDisplayed())
3464 	{
3465 		solsticeJ2000Points->setDisplayed(displayed);
3466 		emit solsticeJ2000PointsDisplayedChanged(displayed);
3467 	}
3468 }
3469 //! Get flag for displaying solstice points of J2000
getFlagSolsticeJ2000Points() const3470 bool GridLinesMgr::getFlagSolsticeJ2000Points() const
3471 {
3472 	return solsticeJ2000Points->isDisplayed();
3473 }
getColorSolsticeJ2000Points() const3474 Vec3f GridLinesMgr::getColorSolsticeJ2000Points() const
3475 {
3476 	return solsticeJ2000Points->getColor();
3477 }
setColorSolsticeJ2000Points(const Vec3f & newColor)3478 void GridLinesMgr::setColorSolsticeJ2000Points(const Vec3f& newColor)
3479 {
3480 	if(newColor != solsticeJ2000Points->getColor())
3481 	{
3482 		solsticeJ2000Points->setColor(newColor);
3483 		emit solsticeJ2000PointsColorChanged(newColor);
3484 	}
3485 }
3486 
3487 //! Set flag for displaying solstice points
setFlagSolsticePoints(const bool displayed)3488 void GridLinesMgr::setFlagSolsticePoints(const bool displayed)
3489 {
3490 	if(displayed != solsticePoints->isDisplayed())
3491 	{
3492 		solsticePoints->setDisplayed(displayed);
3493 		emit solsticePointsDisplayedChanged(displayed);
3494 	}
3495 }
3496 //! Get flag for displaying solstice points
getFlagSolsticePoints() const3497 bool GridLinesMgr::getFlagSolsticePoints() const
3498 {
3499 	return solsticePoints->isDisplayed();
3500 }
getColorSolsticePoints() const3501 Vec3f GridLinesMgr::getColorSolsticePoints() const
3502 {
3503 	return solsticePoints->getColor();
3504 }
setColorSolsticePoints(const Vec3f & newColor)3505 void GridLinesMgr::setColorSolsticePoints(const Vec3f& newColor)
3506 {
3507 	if(newColor != solsticePoints->getColor())
3508 	{
3509 		solsticePoints->setColor(newColor);
3510 		emit solsticePointsColorChanged(newColor);
3511 	}
3512 }
3513 
3514 //! Set flag for displaying antisolar point
setFlagAntisolarPoint(const bool displayed)3515 void GridLinesMgr::setFlagAntisolarPoint(const bool displayed)
3516 {
3517 	if(displayed != antisolarPoint->isDisplayed())
3518 	{
3519 		antisolarPoint->setDisplayed(displayed);
3520 		emit antisolarPointDisplayedChanged(displayed);
3521 	}
3522 }
3523 //! Get flag for displaying antisolar point
getFlagAntisolarPoint() const3524 bool GridLinesMgr::getFlagAntisolarPoint() const
3525 {
3526 	return antisolarPoint->isDisplayed();
3527 }
getColorAntisolarPoint() const3528 Vec3f GridLinesMgr::getColorAntisolarPoint() const
3529 {
3530 	return antisolarPoint->getColor();
3531 }
setColorAntisolarPoint(const Vec3f & newColor)3532 void GridLinesMgr::setColorAntisolarPoint(const Vec3f& newColor)
3533 {
3534 	if(newColor != antisolarPoint->getColor())
3535 	{
3536 		antisolarPoint->setColor(newColor);
3537 		emit antisolarPointColorChanged(newColor);
3538 	}
3539 }
3540 
setFlagUmbraCenterPoint(const bool displayed)3541 void GridLinesMgr::setFlagUmbraCenterPoint(const bool displayed)
3542 {
3543 	if(displayed != umbraCenterPoint->isDisplayed())
3544 	{
3545 		umbraCenterPoint->setDisplayed(displayed);
3546 		emit umbraCenterPointDisplayedChanged(displayed);
3547 	}
3548 }
getFlagUmbraCenterPoint() const3549 bool GridLinesMgr::getFlagUmbraCenterPoint() const
3550 {
3551 	return umbraCenterPoint->isDisplayed();
3552 }
3553 
3554 //! Set flag for displaying vector point
setFlagApexPoints(const bool displayed)3555 void GridLinesMgr::setFlagApexPoints(const bool displayed)
3556 {
3557 	if(displayed != apexPoints->isDisplayed())
3558 	{
3559 		apexPoints->setDisplayed(displayed);
3560 		emit apexPointsDisplayedChanged(displayed);
3561 	}
3562 }
3563 //! Get flag for displaying vector point
getFlagApexPoints() const3564 bool GridLinesMgr::getFlagApexPoints() const
3565 {
3566 	return apexPoints->isDisplayed();
3567 }
getColorApexPoints() const3568 Vec3f GridLinesMgr::getColorApexPoints() const
3569 {
3570 	return apexPoints->getColor();
3571 }
setColorApexPoints(const Vec3f & newColor)3572 void GridLinesMgr::setColorApexPoints(const Vec3f& newColor)
3573 {
3574 	if(newColor != apexPoints->getColor())
3575 	{
3576 		apexPoints->setColor(newColor);
3577 		emit apexPointsColorChanged(newColor);
3578 	}
3579 }
3580 
setLineThickness(const int thickness)3581 void GridLinesMgr::setLineThickness(const int thickness)
3582 {
3583 	int lineThickness = equGrid->getLineThickness();
3584 	if (lineThickness!=thickness)
3585 	{
3586 		lineThickness=qBound(1, thickness, 5);
3587 		// Grids
3588 		equGrid->setLineThickness(lineThickness);
3589 		equJ2000Grid->setLineThickness(lineThickness);
3590 		galacticGrid->setLineThickness(lineThickness);
3591 		supergalacticGrid->setLineThickness(lineThickness);
3592 		eclGrid->setLineThickness(lineThickness);
3593 		eclJ2000Grid->setLineThickness(lineThickness);
3594 		aziGrid->setLineThickness(lineThickness);
3595 		// Lines
3596 		equatorLine->setLineThickness(lineThickness);
3597 		equatorJ2000Line->setLineThickness(lineThickness);
3598 		eclipticLine->setLineThickness(lineThickness);
3599 		eclipticJ2000Line->setLineThickness(lineThickness);
3600 		invariablePlaneLine->setLineThickness(lineThickness);
3601 		solarEquatorLine->setLineThickness(lineThickness);
3602 		precessionCircleN->setLineThickness(lineThickness);
3603 		precessionCircleS->setLineThickness(lineThickness);
3604 		meridianLine->setLineThickness(lineThickness);
3605 		longitudeLine->setLineThickness(lineThickness);
3606 		horizonLine->setLineThickness(lineThickness);
3607 		galacticEquatorLine->setLineThickness(lineThickness);
3608 		supergalacticEquatorLine->setLineThickness(lineThickness);
3609 		primeVerticalLine->setLineThickness(lineThickness);
3610 		currentVerticalLine->setLineThickness(lineThickness);
3611 		colureLine_1->setLineThickness(lineThickness);
3612 		colureLine_2->setLineThickness(lineThickness);
3613 		circumpolarCircleN->setLineThickness(lineThickness);
3614 		circumpolarCircleS->setLineThickness(lineThickness);
3615 		umbraCircle->setLineThickness(lineThickness);
3616 		penumbraCircle->setLineThickness(lineThickness);
3617 
3618 		emit lineThicknessChanged(lineThickness);
3619 	}
3620 }
3621 
getLineThickness() const3622  int GridLinesMgr::getLineThickness() const
3623 {
3624 	return equGrid->getLineThickness();
3625 }
3626 
setPartThickness(const int thickness)3627  void GridLinesMgr::setPartThickness(const int thickness)
3628  {
3629 	 int partThickness = equatorLine->getPartThickness();
3630 	 if (partThickness!=thickness)
3631 	 {
3632 		 partThickness=qBound(1, thickness, 5);
3633 		 // Lines
3634 		 equatorLine->setPartThickness(partThickness);
3635 		 equatorJ2000Line->setPartThickness(partThickness);
3636 		 eclipticLine->setPartThickness(partThickness);
3637 		 eclipticJ2000Line->setPartThickness(partThickness);
3638 		 //invariablePlaneLine->setPartThickness(partThickness);
3639 		 solarEquatorLine->setPartThickness(partThickness);
3640 		 precessionCircleN->setPartThickness(partThickness);
3641 		 precessionCircleS->setPartThickness(partThickness);
3642 		 meridianLine->setPartThickness(partThickness);
3643 		 longitudeLine->setPartThickness(partThickness);
3644 		 horizonLine->setPartThickness(partThickness);
3645 		 galacticEquatorLine->setPartThickness(partThickness);
3646 		 supergalacticEquatorLine->setPartThickness(partThickness);
3647 		 primeVerticalLine->setPartThickness(partThickness);
3648 		 currentVerticalLine->setPartThickness(partThickness);
3649 		 colureLine_1->setPartThickness(partThickness);
3650 		 colureLine_2->setPartThickness(partThickness);
3651 		 //circumpolarCircleN->setPartThickness(partThickness);
3652 		 //circumpolarCircleS->setPartThickness(partThickness);
3653 
3654 		 emit partThicknessChanged(partThickness);
3655 	 }
3656  }
3657 
getPartThickness() const3658   int GridLinesMgr::getPartThickness() const
3659  {
3660 	 return equatorLine->getPartThickness();
3661  }
3662 
setFontSizeFromApp(int size)3663 void GridLinesMgr::setFontSizeFromApp(int size)
3664 {
3665 	const int gridFontSize=size-1;
3666 	const int lineFontSize=size+1;
3667 	const int pointFontSize=size+1;
3668 
3669 	equGrid->setFontSize(gridFontSize);
3670 	equJ2000Grid->setFontSize(gridFontSize);
3671 	galacticGrid->setFontSize(gridFontSize);
3672 	supergalacticGrid->setFontSize(gridFontSize);
3673 	eclGrid->setFontSize(gridFontSize);
3674 	eclJ2000Grid->setFontSize(gridFontSize);
3675 	aziGrid->setFontSize(gridFontSize);
3676 	equatorLine->setFontSize(lineFontSize);
3677 	equatorJ2000Line->setFontSize(lineFontSize);
3678 	eclipticLine->setFontSize(lineFontSize);
3679 	eclipticJ2000Line->setFontSize(lineFontSize);
3680 	invariablePlaneLine->setFontSize(lineFontSize);
3681 	solarEquatorLine->setFontSize(lineFontSize);
3682 	precessionCircleN->setFontSize(lineFontSize);
3683 	precessionCircleS->setFontSize(lineFontSize);
3684 	meridianLine->setFontSize(lineFontSize);
3685 	longitudeLine->setFontSize(lineFontSize);
3686 	horizonLine->setFontSize(lineFontSize);
3687 	galacticEquatorLine->setFontSize(lineFontSize);
3688 	supergalacticEquatorLine->setFontSize(lineFontSize);
3689 	primeVerticalLine->setFontSize(lineFontSize);
3690 	currentVerticalLine->setFontSize(lineFontSize);
3691 	colureLine_1->setFontSize(lineFontSize);
3692 	colureLine_2->setFontSize(lineFontSize);
3693 	circumpolarCircleN->setFontSize(lineFontSize);
3694 	circumpolarCircleS->setFontSize(lineFontSize);
3695 	umbraCircle->setFontSize(lineFontSize);
3696 	penumbraCircle->setFontSize(lineFontSize);
3697 	celestialJ2000Poles->setFontSize(pointFontSize);
3698 	celestialPoles->setFontSize(pointFontSize);
3699 	zenithNadir->setFontSize(pointFontSize);
3700 	eclipticJ2000Poles->setFontSize(pointFontSize);
3701 	eclipticPoles->setFontSize(pointFontSize);
3702 	galacticPoles->setFontSize(pointFontSize);
3703 	galacticCenter->setFontSize(pointFontSize);
3704 	supergalacticPoles->setFontSize(pointFontSize);
3705 	equinoxJ2000Points->setFontSize(pointFontSize);
3706 	equinoxPoints->setFontSize(pointFontSize);
3707 	solsticeJ2000Points->setFontSize(pointFontSize);
3708 	solsticePoints->setFontSize(pointFontSize);
3709 	apexPoints->setFontSize(pointFontSize);
3710 	umbraCenterPoint->setFontSize(pointFontSize);
3711 }
3712