HorizonRenderer: use integer division
[xcsoar.git] / src / Renderer / HorizonRenderer.cpp
blobb7a94dd02d2aa60ac24ce3083912de7dad50fc90
1 /*
2 Copyright_License {
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"
31 #include <algorithm>
33 void
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
47 is the case or not.
50 RasterPoint center;
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
54 - Layout::Scale(1);
56 fixed bank_degrees = attitude.bank_angle_available ?
57 attitude.bank_angle.Degrees() : fixed(0);
59 fixed pitch_degrees = attitude.pitch_angle_available ?
60 attitude.pitch_angle.Degrees() : fixed(0);
62 fixed phi = Clamp(bank_degrees, fixed(-89), fixed(89));
63 Angle alpha = Angle::acos(Clamp(pitch_degrees / 50,
64 fixed(-1), fixed(1)));
65 Angle sphi = Angle::HalfCircle() - Angle::Degrees(phi);
66 Angle alpha1 = sphi - alpha;
67 Angle alpha2 = sphi + alpha;
69 // draw sky part
70 canvas.Select(look.sky_pen);
71 canvas.Select(look.sky_brush);
72 canvas.DrawSegment(center.x, center.y, radius, alpha2, alpha1, true);
74 // draw ground part
75 canvas.Select(look.terrain_pen);
76 canvas.Select(look.terrain_brush);
77 canvas.DrawSegment(center.x, center.y, radius, alpha1, alpha2, true);
79 // draw aircraft symbol
80 canvas.Select(look.aircraft_pen);
81 canvas.DrawLine(center.x + radius / 2, center.y, center.x - radius / 2, center.y);
82 canvas.DrawLine(center.x, center.y - radius / 4, center.x, center.y);
84 // draw 45 degree dash marks
85 const UPixelScalar rr2p = uround(radius * fixed_sqrt_half) + Layout::Scale(1);
86 const UPixelScalar rr2n = rr2p - Layout::Scale(2);
87 canvas.DrawLine(center.x + rr2p, center.y - rr2p,
88 center.x + rr2n, center.y - rr2n);
89 canvas.DrawLine(center.x - rr2p, center.y - rr2p,
90 center.x - rr2n, center.y - rr2n);