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 13 class 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. 22 class 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. 61 class ArtificialHorizon 62 { 63 public: ArtificialHorizon()64 ArtificialHorizon() {} 65 ~ArtificialHorizon(); 66 67 ArtificialHorizonEntity *findRegion(const QString ®ionName); 68 void addRegion(const QString ®ionName, bool enabled, const std::shared_ptr<LineList> &list, bool ceiling); 69 void removeRegion(const QString ®ionName, bool lineOnly = false); 70 bool enabled(int i) const; 71 void load(const QList<ArtificialHorizonEntity *> &list); 72 horizonList()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) const; 83 84 // returns the (highest) altitude constraint at the given azimuth. 85 // If there are no constraints, then it returns -90. 86 double altitudeConstraint(double azimuthDegrees) const; 87 88 // Finds the nearest enabled constraint at the azimuth and above or below (not not exactly at) 89 // the altitude given. 90 const ArtificialHorizonEntity *getConstraintAbove(double azimuthDegrees, double altitudeDegrees, 91 const ArtificialHorizonEntity *ignore = nullptr) const; 92 const ArtificialHorizonEntity *getConstraintBelow(double azimuthDegrees, double altitudeDegrees, 93 const ArtificialHorizonEntity *ignore = nullptr) const; 94 95 // Draw the blocked areas on the skymap using the SkyPainter. 96 // If painter is a nullptr, nothing is drawn. 97 // If regious is not a nullpointer, all the polygon coordinates are placed 98 // in the QList (for testing). 99 void drawPolygons(SkyPainter *painter, QList<LineList> *regions = nullptr); 100 101 private: 102 // Removes a call to KStars::Instance() which is not necessary in testing. setTesting()103 void setTesting() 104 { 105 testing = true; 106 } 107 void drawPolygons(int entity, SkyPainter *painter, QList<LineList> *regions = nullptr); 108 void drawSampledPolygons(int entity, double az1, double alt1, double az2, double alt2, 109 double sampling, SkyPainter *painter, QList<LineList> *regions); 110 bool computePolygon(int entity, double az1, double alt1, double az2, double alt2, 111 LineList *region); 112 113 QList<ArtificialHorizonEntity *> m_HorizonList; 114 bool testing { false }; 115 116 friend TestArtificialHorizon; 117 }; 118 119 /** 120 * @class ArtificialHorizon 121 * Represents custom area from the horizon upwards which represent blocked views from the vantage point of the user. 122 * Such blocked views could stem for example from tall trees or buildings. The user can define a series of line segments to 123 * represent the blocked areas. 124 * 125 * @author Jasem Mutlaq 126 * @version 0.1 127 */ 128 class ArtificialHorizonComponent : public NoPrecessIndex 129 { 130 public: 131 /** 132 * @short Constructor 133 * 134 * @p parent pointer to the parent SkyComposite object 135 * name is the name of the subclass 136 */ 137 explicit ArtificialHorizonComponent(SkyComposite *parent); 138 139 virtual ~ArtificialHorizonComponent() override; 140 141 bool selected() override; 142 void draw(SkyPainter *skyp) override; 143 setLivePreview(const std::shared_ptr<LineList> & preview)144 void setLivePreview(const std::shared_ptr<LineList> &preview) 145 { 146 livePreview = preview; 147 } setSelectedPreviewPoint(int index)148 void setSelectedPreviewPoint(int index) 149 { 150 selectedPreviewPoint = index; 151 } 152 void addRegion(const QString ®ionName, bool enabled, const std::shared_ptr<LineList> &list, bool ceiling); 153 void removeRegion(const QString ®ionName, bool lineOnly = false); 154 getHorizon()155 const ArtificialHorizon &getHorizon() 156 { 157 return horizon; 158 } 159 160 bool load(); 161 void save(); 162 163 protected: 164 void preDraw(SkyPainter *skyp) override; 165 166 private: 167 ArtificialHorizon horizon; 168 std::shared_ptr<LineList> livePreview; 169 int selectedPreviewPoint { -1 }; 170 171 friend class TestArtificialHorizon; 172 }; 173