Kstars

artificialhorizoncomponent.h
1/*
2 SPDX-FileCopyrightText: 2015 Jasem Mutlaq <mutlaqja@ikarustech.com>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5*/
6
7#pragma once
8
9#include "noprecessindex.h"
10
11#include <memory>
12
13class TestArtificialHorizon;
14
15// An ArtificialHorizonEntity is a set of Azimuth & Altitude values defining
16// a series of connected line segments. Assuming ceiling is false (the default)
17// these lines define a horizon--coordinates indicating where the view is blocked
18// (below the line segments, lower in altitude) and where it is not blocked
19// (above the line segments, higher altitude values). If ceiling is true, then
20// this definition is flipped--the sky higher in altitude than the line segments
21// is considered blocked.
22class ArtificialHorizonEntity
23{
24 public:
25 ArtificialHorizonEntity() = default;
26 ~ArtificialHorizonEntity();
27
28 QString region() const;
29 void setRegion(const QString &Region);
30
31 bool enabled() const;
32 void setEnabled(bool Enabled);
33
34 bool ceiling() const;
35 void setCeiling(bool value);
36
37 void clearList();
38 void setList(const std::shared_ptr<LineList> &list);
39 std::shared_ptr<LineList> list() const;
40
41 // Returns the altitude constraint for the azimuth angle (degrees).
42 // constraintExists will be set to false if there is no constraint for the azimuth.
43 double altitudeConstraint(double azimuthDegrees, bool *constraintExists) const;
44
45 private:
46 QString m_Region;
47 bool m_Enabled { false };
48 bool m_Ceiling { false };
49 std::shared_ptr<LineList> m_List;
50};
51
52// ArtificialHorizon can contain several ArtificialHorizonEntities. That is,
53// it can have several sets of connected line segments. Assuming all the entities
54// are not ceilings, then the view is considered blocked below the highest line
55// segment that intersects a given azimuth. If none of the line segments cross
56// a given azimuth, then the view is not blocked at any altitude for that azimuth.
57// Similarly, if there are only "ceiling" horizon entities, then the view is blocked
58// at altitudes above the lowest ceiling. If there are a mix of ceilings and standard
59// entities, then for the given azimuth, at an altitude A, the view is blocked if
60// either the closest line below is a ceiling, or if the closest line above is a non-ceiling.
62{
63 public:
66
67 ArtificialHorizonEntity *findRegion(const QString &regionName);
68 void addRegion(const QString &regionName, bool enabled, const std::shared_ptr<LineList> &list, bool ceiling);
69 void removeRegion(const QString &regionName, bool lineOnly = false);
70 bool enabled(int i) const;
71 void load(const QList<ArtificialHorizonEntity *> &list);
72
73 const QList<ArtificialHorizonEntity *> *horizonList() const
74 {
75 return &m_HorizonList;
76 }
77
78 // Returns true if one or more artificial horizons are enabled.
79 bool altitudeConstraintsExist() const;
80
81 // Returns true if the azimuth/altitude point is not blocked by the artificial horzon entities.
82 bool isVisible(double azimuthDegrees, double altitudeDegrees, QString *reason = nullptr) const;
83 // Like isVisible, but uses the cache if there are no ceiling constraints.
84 bool isAltitudeOK(double azimuthDegrees, double altitudeDegrees, QString *reason) const;
85
86 // returns the (highest) altitude constraint at the given azimuth.
87 // If there are no constraints, then it returns -90.
88 double altitudeConstraint(double azimuthDegrees) const;
89
90 // Finds the nearest enabled constraint at the azimuth and above or below (not not exactly at)
91 // the altitude given.
92 const ArtificialHorizonEntity *getConstraintAbove(double azimuthDegrees, double altitudeDegrees,
93 const ArtificialHorizonEntity *ignore = nullptr) const;
94 const ArtificialHorizonEntity *getConstraintBelow(double azimuthDegrees, double altitudeDegrees,
95 const ArtificialHorizonEntity *ignore = nullptr) const;
96
97 // Draw the blocked areas on the skymap using the SkyPainter.
98 // If painter is a nullptr, nothing is drawn.
99 // If regious is not a nullpointer, all the polygon coordinates are placed
100 // in the QList (for testing).
101 void drawPolygons(SkyPainter *painter, QList<LineList> *regions = nullptr);
102
103 private:
104 // Removes a call to KStars::Instance() which is not necessary in testing.
105 void setTesting()
106 {
107 testing = true;
108 }
109 void drawPolygons(int entity, SkyPainter *painter, QList<LineList> *regions = nullptr);
110 void drawSampledPolygons(int entity, double az1, double alt1, double az2, double alt2,
111 double sampling, SkyPainter *painter, QList<LineList> *regions);
112 bool computePolygon(int entity, double az1, double alt1, double az2, double alt2,
113 double sampling, LineList *region);
114
116 bool testing { false };
117
118 // Methods and data structure for precomputing altitudeConstraint(azimuth).
119 // This way, we don't traverse the potentially horizon list each time
120 // we query the horizon constraint.
121 void precomputeConstraints() const;
122 void resetPrecomputeConstraints() const;
123 double precomputedConstraint(double azimuth) const;
124 double altitudeConstraintInternal(double azimuthDegrees) const;
125 mutable QVector<double> precomputedConstraints;
126 bool noCeilingConstraints { true };
127 void checkForCeilings();
128 friend TestArtificialHorizon;
129};
130
131/**
132 * @class ArtificialHorizon
133 * Represents custom area from the horizon upwards which represent blocked views from the vantage point of the user.
134 * Such blocked views could stem for example from tall trees or buildings. The user can define a series of line segments to
135 * represent the blocked areas.
136 *
137 * @author Jasem Mutlaq
138 * @version 0.1
139 */
140class ArtificialHorizonComponent : public NoPrecessIndex
141{
142 public:
143 /**
144 * @short Constructor
145 *
146 * @p parent pointer to the parent SkyComposite object
147 * name is the name of the subclass
148 */
149 explicit ArtificialHorizonComponent(SkyComposite *parent);
150
151 virtual ~ArtificialHorizonComponent() override;
152
153 bool selected() override;
154 void draw(SkyPainter *skyp) override;
155
156 void setLivePreview(const std::shared_ptr<LineList> &preview)
157 {
158 livePreview = preview;
159 }
160 void setSelectedPreviewPoint(int index)
161 {
162 selectedPreviewPoint = index;
163 }
164 void addRegion(const QString &regionName, bool enabled, const std::shared_ptr<LineList> &list, bool ceiling);
165 void removeRegion(const QString &regionName, bool lineOnly = false);
166
167 const ArtificialHorizon &getHorizon()
168 {
169 return horizon;
170 }
171
172 bool load();
173 void save();
174
175 protected:
176 void preDraw(SkyPainter *skyp) override;
177
178 private:
179 ArtificialHorizon horizon;
180 std::shared_ptr<LineList> livePreview;
181 int selectedPreviewPoint { -1 };
182
183 friend class TestArtificialHorizon;
184};
Represents custom area from the horizon upwards which represent blocked views from the vantage point ...
A simple data container used by LineListIndex.
Definition linelist.h:25
SkyComposite * parent()
SkyComposite is a kind of container class for SkyComponent objects.
Draws things on the sky, without regard to backend.
Definition skypainter.h:40
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Jun 21 2024 12:01:00 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.