4 XCSoar Glide Computer - http://www.xcsoar.org/
5 Copyright (C) 2000-2013 The XCSoar Project
6 A detailed list of copyright holders can be found in the file "AUTHORS".
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 #include "HorizonRenderer.hpp"
25 #include "Screen/Canvas.hpp"
26 #include "Screen/Layout.hpp"
27 #include "Look/HorizonLook.hpp"
28 #include "NMEA/Attitude.hpp"
29 #include "Util/Clamp.hpp"
34 HorizonRenderer::Draw(Canvas
&canvas
, const PixelRect
&rc
,
35 const HorizonLook
&look
,
36 const AttitudeState
&attitude
)
39 This feature of having a backup artificial horizon based on inferred
40 orientation from GPS and vario data is useful, and reasonably well
41 tested, but has the issue of potentially invalidating use of XCSoar in
42 FAI contests due to rule ref Annex A to Section 3 (2010 Edition) 4.1.2
43 "No instruments permitting pilots to fly without visual reference to
44 the ground may be carried on board, even if made unserviceable." The
45 quality of XCSoar's pseudo-AH is arguably good enough that this
46 violates the rule. We need to seek clarification as to whether this
51 center
.y
= (rc
.top
+ rc
.bottom
) / 2;
52 center
.x
= (rc
.left
+ rc
.right
) / 2;
53 const int radius
= std::min(rc
.right
- rc
.left
, rc
.bottom
- rc
.top
) / 2
56 #define fixed_div fixed(1.0 / 50.0)
58 fixed bank_degrees
= attitude
.bank_angle_available
?
59 attitude
.bank_angle
.Degrees() : fixed(0);
61 fixed pitch_degrees
= attitude
.pitch_angle_available
?
62 attitude
.pitch_angle
.Degrees() : fixed(0);
64 fixed phi
= Clamp(bank_degrees
, fixed(-89), fixed(89));
65 Angle alpha
= Angle::acos(Clamp(pitch_degrees
* fixed_div
,
66 fixed(-1), fixed(1)));
67 Angle sphi
= Angle::HalfCircle() - Angle::Degrees(phi
);
68 Angle alpha1
= sphi
- alpha
;
69 Angle alpha2
= sphi
+ alpha
;
72 canvas
.Select(look
.sky_pen
);
73 canvas
.Select(look
.sky_brush
);
74 canvas
.DrawSegment(center
.x
, center
.y
, radius
, alpha2
, alpha1
, true);
77 canvas
.Select(look
.terrain_pen
);
78 canvas
.Select(look
.terrain_brush
);
79 canvas
.DrawSegment(center
.x
, center
.y
, radius
, alpha1
, alpha2
, true);
81 // draw aircraft symbol
82 canvas
.Select(look
.aircraft_pen
);
83 canvas
.DrawLine(center
.x
+ radius
/ 2, center
.y
, center
.x
- radius
/ 2, center
.y
);
84 canvas
.DrawLine(center
.x
, center
.y
- radius
/ 4, center
.x
, center
.y
);
86 // draw 45 degree dash marks
87 const UPixelScalar rr2p
= uround(radius
* fixed_sqrt_half
) + Layout::Scale(1);
88 const UPixelScalar rr2n
= rr2p
- Layout::Scale(2);
89 canvas
.DrawLine(center
.x
+ rr2p
, center
.y
- rr2p
,
90 center
.x
+ rr2n
, center
.y
- rr2n
);
91 canvas
.DrawLine(center
.x
- rr2p
, center
.y
- rr2p
,
92 center
.x
- rr2n
, center
.y
- rr2n
);