7#include "skyqpainter.h"
11#include "kstarsdata.h"
15#include "projections/projector.h"
16#include "skycomponents/flagcomponent.h"
17#include "skycomponents/linelist.h"
18#include "skycomponents/linelistlabel.h"
19#include "skycomponents/satellitescomponent.h"
20#include "skycomponents/skiphashlist.h"
21#include "skycomponents/skymapcomposite.h"
22#include "skycomponents/solarsystemcomposite.h"
23#include "skycomponents/earthshadowcomponent.h"
24#include "skycomponents/imageoverlaycomponent.h"
25#include "skyobjects/skyobject.h"
26#include "skyobjects/constellationsart.h"
27#include "skyobjects/catalogobject.h"
28#include "skyobjects/ksasteroid.h"
29#include "skyobjects/kscomet.h"
30#include "skyobjects/kssun.h"
31#include "skyobjects/satellite.h"
32#include "skyobjects/supernova.h"
33#include "skyobjects/ksearthshadow.h"
35#include "skyobjects/mosaictiles.h"
37#include "hips/hipsrenderer.h"
38#include "terrain/terrainrenderer.h"
39#include <QElapsedTimer>
40#include "auxiliary/rectangleoverlap.h"
46int harvardToIndex(
char c)
78const int nStarSizes = 15;
81const int nSPclasses = 7;
86QPixmap *imageCache[nSPclasses][nStarSizes] = { {
nullptr } };
91int SkyQPainter::starColorMode = 0;
97 for (
char &color : ColorMap.keys())
101 for (
int size = 1; size < nStarSizes; size++)
106 pmap[size] =
nullptr;
115 m_size =
QSize(
pd->width(),
pd->height());
116 m_hipsRender =
new HIPSRenderer();
124 m_hipsRender =
new HIPSRenderer();
131 m_pd = (
pd ?
pd : widget);
132 m_size = widget->
size();
133 m_hipsRender =
new HIPSRenderer();
136SkyQPainter::~SkyQPainter()
138 delete (m_hipsRender);
144 bool aa = !SkyMap::Instance()->isSlewing() && Options::useAntialias();
147 m_proj = SkyMap::Instance()->projector();
159 KStarsData::Instance()->colorScheme()->colorNamed(
"SkyColor"));
174 const int starColorIntensity = Options::starColorIntensity();
177 switch (Options::starColorMode())
200 if (ColorMap.isEmpty())
202 ColorMap.insert(
'O', m_starColor);
203 ColorMap.insert(
'B', m_starColor);
204 ColorMap.insert(
'A', m_starColor);
205 ColorMap.insert(
'F', m_starColor);
206 ColorMap.insert(
'G', m_starColor);
207 ColorMap.insert(
'K', m_starColor);
208 ColorMap.insert(
'M', m_starColor);
211 for (
char &color : ColorMap.keys())
219 if (Options::starColorMode() == 0)
225 for (
int i = 0; i < 8; i++)
227 for (
int j = 0;
j < 8;
j++)
231 qreal
dist =
sqrt(x * x + y * y) / 7.0;
235 dist < (10 - starColorIntensity) / 10.0 ? 0 :
dist),
238 dist < (10 - starColorIntensity) / 20.0 ? 1 : 1 -
dist));
257 QPixmap **
pmap = imageCache[harvardToIndex(color)];
259 for (
int size = 1; size < nStarSizes; size++)
267 starColorMode = Options::starColorMode();
302 LineListLabel *label)
304 SkyList *points = list->points();
307 if (points->size() == 0)
311 isVisibleLast &= m_proj->checkVisibility(points->first().get());
314 for (
int j = 1;
j < points->size();
j++)
320 isVisible &= m_proj->checkVisibility(
pThis);
329 if (SkyMap::Instance()->projector()->type() == Projector::Gnomonic)
346 label->updateLabelCandidates(
oThis.x(),
oThis.y(), list,
j);
358 SkyList *points = list->points();
363 for (
const auto &point : *points)
365 polygon << m_proj->toScreen(point.get(),
false, &
isVisibleLast);
370 if (polygon.
size() && isVisible)
381 for (
const auto &point : *points)
386 isVisible &= m_proj->checkVisibility(
pThis);
415 if (!m_proj->checkVisibility(planet))
418 bool visible =
false;
419 QPointF pos = m_proj->toScreen(planet,
true, &visible);
420 if (!visible || !m_proj->onScreen(pos))
424 (10 - planet->
mag()) / 10;
428 double size = planet->
angSize() *
dms::PI * Options::zoomFactor() / 10800.0;
439 else if (planet->
name() ==
i18n(
"Jupiter") || planet->
name() ==
i18n(
"Mercury") ||
455 if (planet->
name() ==
i18n(
"Sun")) size = size * Options::sunScale();
456 if (planet->
name() ==
i18n(
"Moon")) size = size * Options::moonScale();
461 if (Options::showPlanetImages() && !planet->
image().isNull())
464 if (planet->
name() ==
"Saturn")
465 size = int(2.5 * size);
467 else if (planet->
name() ==
"Pluto")
468 size = int(size *
exp(1.5 * size));
472 rotate(m_proj->findPA(planet, pos.
x(), pos.
y()));
486 if (!m_proj->checkVisibility(shadow))
489 bool visible =
false;
490 QPointF pos = m_proj->toScreen(shadow,
true, &visible);
512 if (!m_proj->checkVisibility(
com))
516 com->angSize() *
dms::PI * Options::zoomFactor() / 10800.0 / 2;
520 bool visible =
false;
521 QPointF pos = m_proj->toScreen(
com,
true, &visible);
524 if (visible && m_proj->onScreen(pos))
530 (
com->getComaAngSize().arcmin() *
dms::PI * Options::zoomFactor() / 10800.0);
533 if (Options::showCometComas() &&
comaLength > size)
536 KStarsData::Instance()->skyComposite()->solarSystemComposite()->sun();
539 double comaAngle = m_proj->findPA(sun, pos.
x(), pos.
y());
580 if (!m_proj->checkVisibility(
ast))
585 bool visible =
false;
586 QPointF pos = m_proj->toScreen(
ast,
true, &visible);
588 if (visible && m_proj->onScreen(pos))
605 if (!m_proj->checkVisibility(
loc))
608 bool visible =
false;
609 QPointF pos = m_proj->toScreen(
loc,
true, &visible);
611 if (visible && m_proj->onScreen(pos))
624 int isize =
qMin(
static_cast<int>(size), 14);
625 if (!m_vectorStars || starColorMode == 0)
628 QPixmap *
im = imageCache[harvardToIndex(sp)][isize];
629 float offset = 0.5 *
im->width();
635 if (starColorMode != 4)
652 drawEllipse(pos.
x() - 0.5 * size, pos.
y() - 0.5 * size,
int(size),
int(size));
660 double zoom = Options::zoomFactor();
662 bool visible =
false;
664 KStarsData::Instance()->geo()->lat());
684 if (m_proj->viewParams().mirror)
698bool SkyQPainter::drawMosaicPanel(MosaicTiles *obj)
700 bool visible =
false;
702 KStarsData::Instance()->geo()->lat());
705 if (!visible || !m_proj->onScreen(
tileMid) || !obj->isValid())
711 const auto mirror = m_proj->viewParams().mirror;
712 auto PA = (obj->positionAngle() < 0) ? obj->positionAngle() + 360 : obj->positionAngle();
738 bool rendered = m_hipsRender->render(w, h, m_HiPSImage.
data(), m_proj);
752 TerrainRenderer *renderer = TerrainRenderer::Instance();
764 if (!Options::showImageOverlays())
770 auto localTime = KStarsData::Instance()->geo()->UTtoLT(KStarsData::Instance()->clock()->utc());
773 const double vw = view.width,
vh = view.height;
779 for (
const ImageOverlay &o : *imageOverlays)
781 if (o.m_Status != ImageOverlay::AVAILABLE || o.m_Img.get() ==
nullptr)
784 double orientation = o.m_Orientation, ra = o.m_RA, dec = o.m_DEC,
scale = o.m_ArcsecPerPixel;
795 coord.EquatorialToHorizontal(KStarsData::Instance()->lst(), KStarsData::Instance()->geo()->lat());
799 const double zoom = Options::zoomFactor();
802 const double w = a *
dms::PI * zoom / 10800.0;
813 const auto PA = (orientation < 0) ? orientation + 360 : orientation;
814 const auto mirror = m_proj->viewParams().mirror;
815 const auto finalPA = m_proj->findNorthPA(&
coord, pos.
x(), pos.
y()) - (mirror ? -PA : PA);
824 this->
scale(-1., 1.);
837 const auto &image = obj.
image();
842 double zoom = Options::zoomFactor();
843 double w = obj.
a() *
dms::PI * zoom / 10800.0;
844 double h = obj.
e() * w;
855 if (!m_proj->checkVisibility(&obj))
858 bool visible =
false;
859 QPointF pos = m_proj->toScreen(&obj,
true, &visible);
860 if (!visible || !m_proj->onScreen(pos))
873 const auto mirror = m_proj->viewParams().mirror;
874 const auto positionAngle = m_proj->findNorthPA(&obj, pos.
x(), pos.
y())
875 - (mirror ? -obj.
pa() : obj.
pa())
879 if (Options::showInlineImages() && Options::zoomFactor() > 5. * MINZOOM &&
880 !Options::showHIPS())
881 drawCatalogObjectImage(pos, obj, positionAngle);
884 drawDeepSkySymbol(pos, obj.
type(), size, obj.
e(), positionAngle);
889void SkyQPainter::drawDeepSkySymbol(
const QPointF &pos,
int type,
float size,
float e,
894 float zoom = Options::zoomFactor();
896 int isize = int(size);
898 float dx1 = -0.5 * size;
899 float dx2 = 0.5 * size;
900 float dy1 = -1.0 * e * size / 2.;
901 float dy2 = e * size / 2.;
907 float dxa = -size / 4.;
908 float dxb = size / 4.;
909 float dya = -1.0 * e * size / 4.;
910 float dyb = e * size / 4.;
926 if (Options::useAntialias())
963 case SkyObject::STAR:
964 case SkyObject::CATALOG_STAR:
970 case SkyObject::PLANET:
972 case SkyObject::OPEN_CLUSTER:
973 case SkyObject::ASTERISM:
976 color =
pen().color().name();
998 case SkyObject::GLOBULAR_CLUSTER:
1003 color =
pen().color().name();
1010 case SkyObject::GASEOUS_NEBULA:
1011 case SkyObject::DARK_NEBULA:
1015 color =
pen().color().name();
1022 case SkyObject::PLANETARY_NEBULA:
1028 color =
pen().color().name();
1036 case SkyObject::SUPERNOVA_REMNANT:
1040 color =
pen().color().name();
1047 case SkyObject::GALAXY:
1048 case SkyObject::QUASAR:
1049 color =
pen().color().name();
1067 case SkyObject::GALAXY_CLUSTER:
1071 color =
pen().color().name();
1085 color =
pen().color().name();
1096#if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)
1102 f.setPointSizeF(f.pointSizeF() * scaleFactor);
1107 if (Options::useAntialias())
1111 int idx1 = int(dx1);
1112 int idy1 = int(dy1);
1120 if (Options::useAntialias())
1132 bool visible =
false;
1133 QPointF o = m_proj->toScreen(obj,
true, &visible);
1134 if (!visible || !m_proj->onScreen(o))
1138 float x1 = o.
x() - 0.5 * size;
1139 float y1 = o.
y() - 0.5 * size;
1148 std::shared_ptr<SkyPoint> point;
1150 bool visible =
false;
1153 for (
int i = 0; i < data->
skyComposite()->flags()->size(); i++)
1159 point->EquatorialToHorizontal(data->
lst(), data->
geo()->
lat());
1162 pos = m_proj->toScreen(point.get(),
true, &visible);
1165 if (!visible || !m_proj->onScreen(pos))
1184 for (
int i = 0; i <
ground.size(); ++i)
1185 groundPoly[i] = KSUtils::vecToPoint(
ground[i]);
1190 groundPoly.append(groundPoly.first());
1198 if (!m_proj->checkVisibility(sat))
1202 bool visible =
false;
1206 pos = m_proj->toScreen(sat,
true, &visible);
1208 if (!visible || !m_proj->onScreen(pos))
1211 if (Options::drawSatellitesLikeStars())
1238 if (!m_proj->checkVisibility(
sup))
1243 bool visible =
false;
1244 QPointF pos = m_proj->toScreen(
sup,
true, &visible);
1247 if (!visible || !m_proj->onScreen(pos))
A simple container object to hold the minimum information for a Deep Sky Object to be drawn on the sk...
std::pair< bool, const QImage & > image() const
Get the image for this object.
double pa() const override
QColor colorNamed(const QString &name) const
Retrieve a color by name.
Information about a ConstellationsArt object.
QColor labelColor(int index)
Get label color.
QString label(int index)
Get label.
QImage image(int index)
Get image.
const CachingDms * lat() const
A subclass of KSPlanetBase that implements asteroids.
A subclass of KSPlanetBase that implements comets.
A class that manages the calculation of the earths shadow (in moon distance) as a 'virtual' skyobject...
double getPenumbraAngSize() const
double getUmbraAngSize() const
A subclass of TrailObject that provides additional information needed for most solar system objects.
const QImage & image() const
Child class of KSPlanetBase; encapsulates information about the Sun.
KStarsData is the backbone of KStars.
ColorScheme * colorScheme()
SkyMapComposite * skyComposite()
static KStars * Instance()
A simple data container used by LineListIndex.
This class checks if two rectangles overlap.
bool intersects(const QPointF ¢er, int width, int height, double rotationDegrees=0.0) const
Check if the input rectangle overlaps the reference rectangle.
Represents an artificial satellites.
Provides all necessary information about an object in the sky: its coordinates, name(s),...
virtual QString name(void) const
TYPE
The type classification of the SkyObject.
Draws things on the sky, without regard to backend.
float starWidth(float mag) const
Get the width of a star of magnitude mag.
The sky coordinates of a point in the sky.
void EquatorialToHorizontal(const CachingDms *LST, const CachingDms *lat)
Determine the (Altitude, Azimuth) coordinates of the SkyPoint from its (RA, Dec) coordinates,...
bool drawAsteroid(KSAsteroid *ast) override
Draw an asteroid in the sky.
bool drawComet(KSComet *com) override
Draw a comet in the sky.
void end() override
End and finalize painting.
SkyQPainter(QPaintDevice *pd, const QSize &canvasSize)
Creates a SkyQPainter with the given QPaintDevice and uses the dimensions of the paint device as canv...
bool drawPlanet(KSPlanetBase *planet) override
Draw a planet.
bool drawPointSource(const SkyPoint *loc, float mag, char sp='A') override
Draw a point source (e.g., a star).
void drawSkyLine(SkyPoint *a, SkyPoint *b) override
Draw a line between points in the sky.
bool drawImageOverlay(const QList< ImageOverlay > *imageOverlays, bool useCache=false) override
drawImageOverlay Draws a user-supplied image onto the skymap
void setBrush(const QBrush &brush) override
Set the brush of the painter.
void drawSkyPolyline(LineList *list, SkipHashList *skipList=nullptr, LineListLabel *label=nullptr) override
Draw a polyline in the sky.
bool drawTerrain(bool useCache=false) override
drawTerrain Draw the Terrain
void drawSkyPolygon(LineList *list, bool forceClip=true) override
Draw a polygon in the sky.
void drawSkyBackground() override
Draw the sky background.
bool drawCatalogObject(const CatalogObject &obj) override
Draw a deep sky object (loaded from the new implementation)
void drawObservingList(const QList< SkyObject * > &obs) override
Draw the symbols for the observing list.
static void initStarImages()
Recalculates the star pixmaps.
static void releaseImageCache()
Release the image cache.
void setPen(const QPen &pen) override
Set the pen of the painter.
bool drawEarthShadow(KSEarthShadow *shadow) override
Draw the earths shadow on the moon (red-ish)
bool drawConstellationArtImage(ConstellationsArt *obj) override
Draw a ConstellationsArt object.
void drawFlags() override
Draw flags.
bool drawSupernova(Supernova *sup) override
Draw a Supernova.
bool drawHips(bool useCache=false) override
drawMosaicPanel Draws mosaic panel in planning or operation mode.
bool drawSatellite(Satellite *sat) override
Draw a satellite.
void begin() override
Begin painting.
Represents the supernova object.
This is just a container that holds information needed to do projections.
An angle, stored as degrees, but expressible in many ways.
static constexpr double PI
PI is a const static member; it's public so that it can be used anywhere, as long as dms....
QString i18n(const char *text, const TYPE &arg...)
int horizontalAdvance(QChar ch) const const
const_reference at(qsizetype i) const const
qsizetype size() const const
bool begin(QPaintDevice *device)
const QBrush & brush() const const
void drawArc(const QRect &rectangle, int startAngle, int spanAngle)
void drawConvexPolygon(const QPoint *points, int pointCount)
void drawEllipse(const QPoint ¢er, int rx, int ry)
void drawImage(const QPoint &point, const QImage &image)
void drawLine(const QLine &line)
void drawPixmap(const QPoint &point, const QPixmap &pixmap)
void drawPoint(const QPoint &position)
void drawPolygon(const QPoint *points, int pointCount, Qt::FillRule fillRule)
void drawPolyline(const QPoint *points, int pointCount)
void drawText(const QPoint &position, const QString &text)
void fillRect(const QRect &rectangle, QGradient::Preset preset)
const QFont & font() const const
QFontMetrics fontMetrics() const const
const QPen & pen() const const
void scale(qreal sx, qreal sy)
void setBrush(Qt::BrushStyle style)
void setFont(const QFont &font)
void setOpacity(qreal opacity)
void setPen(Qt::PenStyle style)
void setRenderHint(RenderHint hint, bool on)
void translate(const QPoint &offset)
QRect viewport() const const