FlightGear next
CarrierDiagram.cxx
Go to the documentation of this file.
1// CarrierDiagram.cxx - part of GUI launcher using Qt5
2//
3// Written by Stuart Buchanan, started April 2020.
4//
5// Copyright (C) 2022 Stuart Buchanan <stuart13@gmail.com>
6//
7// This program is free software; you can redistribute it and/or
8// modify it under the terms of the GNU General Public License as
9// published by the Free Software Foundation; either version 2 of the
10// License, or (at your option) any later version.
11//
12// This program is distributed in the hope that it will be useful, but
13// WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15// General Public License for more details.
16//
17// You should have received a copy of the GNU General Public License
18// along with this program; if not, write to the Free Software
19// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20
21#include "CarrierDiagram.hxx"
22
23#include <limits>
24
25#include <QPainter>
26#include <QDebug>
27#include <QVector2D>
28#include <QMouseEvent>
29
31
33 BaseDiagram(pr)
34{
35}
36
41
43{
44 return QmlGeod(m_geod);
45}
46
47void CarrierDiagram::setGeod(const SGGeod &geod)
48{
49 m_Carrier.clear();
50 m_geod = geod;
51 m_projectionCenter = m_geod;
52 recomputeBounds(true);
53 emit locationChanged();
54}
55
57{
58 if (m_offsetEnabled == offset)
59 return;
60 m_offsetEnabled = offset;
61 recomputeBounds(true);
62 emit offsetChanged();
63}
64
66{
67 if (m_abeam == abeam)
68 return;
69 m_abeam = abeam;
70 recomputeBounds(true);
71 emit offsetChanged();
72}
73
75{
76 if (distanceNm == m_offsetDistance)
77 return;
78
79 m_offsetDistance = distanceNm;
80 update();
81 emit offsetChanged();
82}
83
84void CarrierDiagram::paintContents(QPainter *painter)
85{
86 QPointF base = project(m_geod);
87
88 SGGeod carrierPos = m_geod;
89
90 SGGeod aircraftPos = m_geod;
91 float aircraft_heading = 0;
92 if (m_offsetEnabled) {
93 // We don't actually know the eventual orientation of the carrier,
94 // so we place the aircraft relative to the aircraft carrier icon,
95 // which has the angled flight deck at 80 degrees (e.g. just N or E)
96 //
97 // There are two case:
98 // - On finals, which will be at -100 degrees, aircraft heading 80
99 // - Abeam on a left hand circuit, so offset 0 degrees,
100 // aircraft heading downwind -90 (note that this is parallel to the
101 // _carrier_, not the angled flightdeck)
102
103 float offset_heading = -100;
104 aircraft_heading = 80;
105
106 if (m_abeam) {
107 offset_heading = 0;
108 aircraft_heading = -90;
109 }
110
111 double d = m_offsetDistance.convertToUnit(Units::Kilometers).value * 1000;
112 SGGeod offsetGeod = SGGeodesy::direct(m_geod, offset_heading, d);
113 QPointF offset = project(offsetGeod);
114
115 QPen pen(Qt::green);
116 pen.setCosmetic(true);
117 painter->setPen(pen);
118 painter->drawLine(base, offset);
119
120 aircraftPos = offsetGeod;
121 } else {
122 // We're at a parking position or on the catapults, so simply rotate to
123 // match the carrier heading - E
124 aircraft_heading = 90;
125 }
126
127 paintCarrierIcon(painter, carrierPos, 0.0);
128 paintAirplaneIcon(painter, aircraftPos, aircraft_heading);
129}
130
132{
133 extendBounds(project(m_geod));
134
135// project four points around the base location at 20nm to give some
136// coverage
137 for (int i=0; i<4; ++i) {
138 SGGeod pt = SGGeodesy::direct(m_geod, i * 90, SG_NM_TO_METER * 20.0);
140 }
141
142 if (m_offsetEnabled) {
143 double d = m_offsetDistance.convertToUnit(Units::Kilometers).value * 1000;
144 float offset_heading = m_abeam ? 0 : -100; // See above for explanation
145 SGGeod offsetPos = SGGeodesy::direct(m_geod, offset_heading, d);
146 extendBounds(project(offsetPos));
147 }
148}
#define i(x)
BaseDiagram(QQuickItem *pr=nullptr)
void paintAirplaneIcon(QPainter *painter, const SGGeod &geod, int headingDeg)
SGGeod m_projectionCenter
void extendBounds(const QPointF &p, double radiusM=1.0)
QPointF project(const SGGeod &geod) const
void paintCarrierIcon(QPainter *painter, const SGGeod &geod, int headingDeg)
void recomputeBounds(bool resetZoom)
void doComputeBounds() override
void setOffsetEnabled(bool offset)
void setOffsetDistance(QuantityValue distance)
CarrierDiagram(QQuickItem *pr=nullptr)
void locationChanged()
void offsetChanged()
void setGeod(QmlGeod geod)
void setAbeam(bool abeam)
void paintContents(QPainter *) override
Expose an SGGeod as Qml-friendly class.
@ Kilometers