Kstars

dsosymbolnode.cpp
1/*
2 SPDX-FileCopyrightText: 2016 Artem Fedoskin <afedoskin3@gmail.com>
3 SPDX-License-Identifier: GPL-2.0-or-later
4*/
5
6#include "dsosymbolnode.h"
7
8#include "deepskyobject.h"
9#include "Options.h"
10#include "nodes/ellipsenode.h"
11
12#include <QSGFlatColorMaterial>
13
14void SymbolNode::updateSymbol(float x, float y, float e, float size)
15{
16 zoom = Options::zoomFactor();
17 x = 0;
18 y = 0;
19 isize = int(size);
20
21 dx1 = -0.5 * size;
22 dx2 = 0.5 * size;
23 dy1 = -1.0 * e * size / 2.;
24 dy2 = e * size / 2.;
25 x1 = x + dx1;
26 x2 = x + dx2;
27 y1 = y + dy1;
28 y2 = y + dy2;
29
30 dxa = -size / 4.;
31 dxb = size / 4.;
32 dya = -1.0 * e * size / 4.;
33 dyb = e * size / 4.;
34 xa = x + dxa;
35 xb = x + dxb;
36 ya = y + dya;
37 yb = y + dyb;
38}
39
40StarSymbol::StarSymbol(const QColor &color) : m_ellipse(new EllipseNode(color))
41{
42 appendChildNode(m_ellipse);
43}
44
45void StarSymbol::updateSymbol(float x, float y, float e, float size)
46{
47 SymbolNode::updateSymbol(x, y, e, size);
48 if (size < 2.)
49 size = 2.;
50 if (Options::useAntialias())
51 m_ellipse->updateGeometry(0, 0, size, e * size, false);
52 else
53 m_ellipse->updateGeometry(0, 0, int(size / 2), int(size / 2), false);
54}
55
56AsterismSymbol::AsterismSymbol(const QColor &color)
57{
58 e1 = new EllipseNode(color);
59 e2 = new EllipseNode(color);
60 e3 = new EllipseNode(color);
61 e4 = new EllipseNode(color);
62 e5 = new EllipseNode(color);
63 e6 = new EllipseNode(color);
64 e7 = new EllipseNode(color);
65 e8 = new EllipseNode(color);
74}
75
76void AsterismSymbol::updateSymbol(float x, float y, float e, float size)
77{
78 SymbolNode::updateSymbol(x, y, e, size);
79 psize = 2.;
80 if (size > 50.)
81 psize *= 2.;
82 if (size > 100.)
83 psize *= 2.;
84
85 e1->updateGeometry(xa, y1, psize, psize, true);
86 e2->updateGeometry(xb, y1, psize, psize, true);
87 e3->updateGeometry(xa, y2, psize, psize, true);
88 e4->updateGeometry(xb, y2, psize, psize, true);
89 e5->updateGeometry(x1, ya, psize, psize, true);
90 e6->updateGeometry(x1, yb, psize, psize, true);
91 e7->updateGeometry(x2, ya, psize, psize, true);
92 e8->updateGeometry(x2, yb, psize, psize, true);
93}
94
95GlobularClusterSymbol::GlobularClusterSymbol(const QColor &color) : e1(new EllipseNode(color))
96{
98
99 lines = new QSGGeometryNode;
100 appendChildNode(lines);
101
102 QSGGeometry *geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 0);
103 geometry->setDrawingMode(GL_LINES);
104 geometry->allocate(4);
105
106 lines->setGeometry(geometry);
107 lines->setFlag(QSGNode::OwnsGeometry);
108
109 QSGFlatColorMaterial *material = new QSGFlatColorMaterial;
110 material->setColor(color);
111 lines->setOpaqueMaterial(material);
112 lines->setFlag(QSGNode::OwnsMaterial);
113}
114
115void GlobularClusterSymbol::updateSymbol(float x, float y, float e, float size)
116{
117 SymbolNode::updateSymbol(x, y, e, size);
118
119 if (size < 2.)
120 size = 2.;
121 e1->updateGeometry(0, 0, size, e * size, false);
122
123 QSGGeometry::Point2D *vertex = lines->geometry()->vertexDataAsPoint2D();
124 //First line
125 vertex[0].set(dx1, 0);
126 vertex[1].set(dx2, 0);
127
128 //Second line
129 vertex[2].set(0, dy1);
130 vertex[3].set(0, dy2);
131
132 lines->markDirty(QSGNode::DirtyGeometry);
133}
134
135DarkNebulaSymbol::DarkNebulaSymbol(const QColor &color)
136{
137 lines = new QSGGeometryNode;
138 appendChildNode(lines);
139
140 QSGGeometry *geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 0);
141 geometry->setDrawingMode(GL_LINES);
142 geometry->allocate(8);
143
144 lines->setGeometry(geometry);
145 lines->setFlag(QSGNode::OwnsGeometry);
146
147 QSGFlatColorMaterial *material = new QSGFlatColorMaterial;
148 material->setColor(color);
149 lines->setOpaqueMaterial(material);
150 lines->setFlag(QSGNode::OwnsMaterial);
151}
152
153void DarkNebulaSymbol::updateSymbol(float x, float y, float e, float size)
154{
155 SymbolNode::updateSymbol(x, y, e, size);
156
157 QSGGeometry::Point2D *vertex = lines->geometry()->vertexDataAsPoint2D();
158 //First line
159 vertex[0].set(dx1, dy1);
160 vertex[1].set(dx2, dy1);
161
162 //Second line
163 vertex[2].set(dx2, dy1);
164 vertex[3].set(dx2, dy2);
165
166 //Third line
167 vertex[4].set(dx2, dy2);
168 vertex[5].set(dx1, dy2);
169
170 //Fourth line
171 vertex[6].set(dx1, dy2);
172 vertex[7].set(dx1, dy1);
173
174 lines->markDirty(QSGNode::DirtyGeometry);
175}
176
177PlanetaryNebulaSymbol::PlanetaryNebulaSymbol(const QColor &color)
178{
179 e1 = new EllipseNode(color);
180 appendChildNode(e1);
181
182 lines = new QSGGeometryNode;
183 appendChildNode(lines);
184
185 QSGGeometry *geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 0);
186 geometry->setDrawingMode(GL_LINES);
187 geometry->allocate(8);
188
189 lines->setGeometry(geometry);
190 lines->setFlag(QSGNode::OwnsGeometry);
191
192 QSGFlatColorMaterial *material = new QSGFlatColorMaterial;
193 material->setColor(color);
194 lines->setOpaqueMaterial(material);
195 lines->setFlag(QSGNode::OwnsMaterial);
196}
197
198void PlanetaryNebulaSymbol::updateSymbol(float x, float y, float e, float size)
199{
200 SymbolNode::updateSymbol(x, y, e, size);
201
202 if (size < 2.)
203 size = 2.;
204
205 e1->updateGeometry(0, 0, size, e * size, false);
206
207 QSGGeometry::Point2D *vertex = lines->geometry()->vertexDataAsPoint2D();
208 //First line
209 vertex[0].set(0., dy1);
210 vertex[1].set(0., dy1 - e * size / 2.);
211
212 //Second line
213 vertex[2].set(0., dy2);
214 vertex[3].set(0., dy2 + e * size / 2.);
215
216 //Third line
217 vertex[4].set(dx1, 0.);
218 vertex[5].set(dx1 - size / 2., 0.);
219
220 //Fourth line
221 vertex[6].set(dx2, 0.);
222 vertex[7].set(dx2 + size / 2., 0.);
223
224 lines->markDirty(QSGNode::DirtyGeometry);
225}
226
227SupernovaRemnantSymbol::SupernovaRemnantSymbol(const QColor &color)
228{
229 lines = new QSGGeometryNode;
230 appendChildNode(lines);
231
232 QSGGeometry *geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 0);
233 geometry->setDrawingMode(GL_LINES);
234 geometry->allocate(8);
235
236 lines->setGeometry(geometry);
237 lines->setFlag(QSGNode::OwnsGeometry);
238
239 QSGFlatColorMaterial *material = new QSGFlatColorMaterial;
240 material->setColor(color);
241 lines->setOpaqueMaterial(material);
242 lines->setFlag(QSGNode::OwnsMaterial);
243}
244
245void SupernovaRemnantSymbol::updateSymbol(float x, float y, float e, float size)
246{
247 SymbolNode::updateSymbol(x, y, e, size);
248
249 QSGGeometry::Point2D *vertex = lines->geometry()->vertexDataAsPoint2D();
250
251 //First line
252 vertex[0].set(0., dy1);
253 vertex[1].set(dx2, 0.);
254
255 //Second line
256 vertex[2].set(dx2, 0.);
257 vertex[3].set(0., dy2);
258
259 //Third line
260 vertex[4].set(0., dy2);
261 vertex[5].set(dx1, 0.);
262
263 //Fourth line
264 vertex[6].set(dx1, 0.);
265 vertex[7].set(0., dy1);
266
267 lines->markDirty(QSGNode::DirtyGeometry);
268}
269
270GalaxySymbol::GalaxySymbol(const QColor &color) : e1(new EllipseNode(color))
271{
272 appendChildNode(e1);
273}
274
275void GalaxySymbol::updateSymbol(float x, float y, float e, float size)
276{
277 SymbolNode::updateSymbol(x, y, e, size);
278
279 if (size < 1. && zoom > 20 * MINZOOM)
280 size = 3.; //force ellipse above zoomFactor 20
281 if (size < 1. && zoom > 5 * MINZOOM)
282 size = 1.; //force points above zoomFactor 5
283 if (size > 2.)
284 {
285 e1->updateGeometry(0, 0, size, e * size, false);
286 }
287 else if (size > 0.)
288 {
289 e1->updateGeometry(0, 0, 1, 1, false);
290 }
291}
292
293GalaxyClusterSymbol::GalaxyClusterSymbol(const QColor &color) : lines(new QSGGeometryNode)
294{
295 QSGGeometry *geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 0);
296 geometry->setDrawingMode(GL_LINES);
297 geometry->allocate(32);
298
299 lines->setGeometry(geometry);
300 lines->setFlag(QSGNode::OwnsGeometry);
301
302 QSGFlatColorMaterial *material = new QSGFlatColorMaterial;
303 material->setColor(color);
304 lines->setOpaqueMaterial(material);
305 lines->setFlag(QSGNode::OwnsMaterial);
306
307 appendChildNode(lines);
308}
309
310void GalaxyClusterSymbol::updateSymbol(float x, float y, float e, float size)
311{
312 SymbolNode::updateSymbol(x, y, e, size);
313
314 psize = 1.;
315 if (size > 50.)
316 psize *= 2.;
317
318 QSGGeometry::Point2D *vertex = lines->geometry()->vertexDataAsPoint2D();
319
320 vertex[0].set(xa - psize, y1);
321 vertex[1].set(xa + psize, y1);
322 vertex[2].set(xa, y1 - psize);
323 vertex[3].set(xa, y1 + psize);
324 vertex[4].set(xb - psize, y1);
325 vertex[5].set(xb + psize, y1);
326 vertex[6].set(xb, y1 - psize);
327 vertex[7].set(xb, y1 + psize);
328 vertex[8].set(xa - psize, y2);
329 vertex[9].set(xa + psize, y2);
330 vertex[10].set(xa, y2 - psize);
331 vertex[11].set(xa, y2 + psize);
332 vertex[12].set(xb - psize, y2);
333 vertex[13].set(xb + psize, y2);
334 vertex[14].set(xb, y2 - psize);
335 vertex[15].set(xb, y2 + psize);
336 vertex[16].set(x1 - psize, ya);
337 vertex[17].set(x1 + psize, ya);
338 vertex[18].set(x1, ya - psize);
339 vertex[19].set(x1, ya + psize);
340 vertex[20].set(x1 - psize, yb);
341 vertex[21].set(x1 + psize, yb);
342 vertex[22].set(x1, yb - psize);
343 vertex[23].set(x1, yb + psize);
344 vertex[24].set(x2 - psize, ya);
345 vertex[25].set(x2 + psize, ya);
346 vertex[26].set(x2, ya - psize);
347 vertex[27].set(x2, ya + psize);
348 vertex[28].set(x2 - psize, yb);
349 vertex[29].set(x2 + psize, yb);
350 vertex[30].set(x2, yb - psize);
351 vertex[31].set(x2, yb + psize);
352
353 lines->markDirty(QSGNode::DirtyGeometry);
354}
355
356DSOSymbolNode::DSOSymbolNode(DeepSkyObject *skyObject, const QColor &color)
357 : m_color(color), m_dso(skyObject)
358{
359}
360
362{
363 if (!m_symbol)
364 {
365 int type = m_dso->type();
366 switch (type)
367 {
368 case 0:
369 case 1:
370 //catalog star
371 m_symbol = new StarSymbol(m_color);
372 break;
373 case 3: //Open cluster; draw circle of points
374 case 13: // Asterism
375 m_symbol = new AsterismSymbol(m_color);
376 break;
377 case 4: //Globular Cluster
378 m_symbol = new GlobularClusterSymbol(m_color);
379 m_rotate = true;
380 break;
381 case 5: //Gaseous Nebula
382 case 15: // Dark Nebula
383 m_symbol = new DarkNebulaSymbol(m_color);
384 m_rotate = true;
385 break;
386 case 6: //Planetary Nebula
387 m_symbol = new PlanetaryNebulaSymbol(m_color);
388 m_rotate = true;
389 break;
390 case 7: //Supernova remnant
391 m_symbol = new SupernovaRemnantSymbol(m_color);
392 m_rotate = true;
393 break;
394 case 8: //Galaxy
395 case 16: // Quasar
396 m_symbol = new GalaxySymbol(m_color);
397 m_rotate = true;
398 break;
399 case 14: // Galaxy cluster - draw a circle of + marks
400 m_symbol = new GalaxyClusterSymbol(m_color);
401 m_rotate = true;
402 break;
403 default:
404 break;
405 }
406 if (m_symbol)
407 addChildNode(m_symbol);
408 }
409}
410
411void DSOSymbolNode::changePos(const QPointF &pos, float positionangle)
412{
413 QMatrix4x4 m(1, 0, 0, pos.x(), 0, 1, 0, pos.y(), 0, 0, 1, 0, 0, 0, 0, 1);
414 //FIXME: this is probably incorrect (inherited from drawDeepSkyImage())
415 if (m_rotate)
416 {
417 m.rotate(positionangle, 0, 0, 1);
418 }
419
420 setMatrix(m);
422}
423
424void DSOSymbolNode::update(float size, const QPointF &pos, float positionangle)
425{
426 initSymbol();
427
428 if (m_symbol)
429 {
430 m_symbol->updateSymbol(pos.x(), pos.y(), m_dso->e(), size);
431 show();
432 changePos(pos, positionangle);
433 }
434 else
435 {
436 qDebug() << "Symbol for object " << m_dso->name() << " wasn't created. Check DSOSymbolNode::initSymbol()";
437 }
438}
DSOSymbolNode(DeepSkyObject *skyObject, const QColor &color=QColor())
Constructor.
void changePos(const QPointF &pos, float positionangle)
Changes position and rotation angle of the symbol.
void initSymbol()
Create SymbolNode based on the type of m_dso.
QSGTransformNode derived node used to draw ellipses.
Definition ellipsenode.h:23
SkyObject * skyObject() const
returns SkyObject associated with this SkyNode
Definition skynode.h:86
virtual void show()
shows all child nodes (sets opacity of m_opacity to 1)
Definition skynode.cpp:27
virtual void update()
Updates coordinate of the object on SkyMapLite.
Definition skynode.h:48
virtual void updateSymbol(float x, float y, float e, float size)
Update size and the symbol itself.
void rotate(const QQuaternion &quaternion)
qreal x() const const
qreal y() const const
void setColor(const QColor &color)
void set(float x, float y)
void allocate(int vertexCount, int indexCount)
const AttributeSet & defaultAttributes_Point2D()
void setDrawingMode(unsigned int mode)
void appendChildNode(QSGNode *node)
void markDirty(DirtyState bits)
NodeType type() const const
void setMatrix(const QMatrix4x4 &matrix)
This file is part of the KDE documentation.
Documentation copyright © 1996-2025 The KDE developers.
Generated on Fri Jan 24 2025 11:53:02 by doxygen 1.13.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.