Example #1
0
void
HorizonRenderer::Draw(Canvas &canvas, const PixelRect &rc, const NMEAInfo &Basic)
{
    /*
    This feature of having a backup artificial horizon based on inferred
    orientation from GPS and vario data is useful, and reasonably well
    tested, but has the issue of potentially invalidating use of XCSoar in
    FAI contests due to rule ref Annex A to Section 3 (2010 Edition) 4.1.2
    "No instruments permitting pilots to fly without visual reference to
    the ground may be carried on board, even if made unserviceable."  The
    quality of XCSoar's pseudo-AH is arguably good enough that this
    violates the rule.  We need to seek clarification as to whether this
    is the case or not.
    */

    RasterPoint center;
    center.y = (rc.top + rc.bottom) / 2;
    center.x = (rc.left + rc.right) / 2;
    const int radius = min(rc.right - rc.left, rc.bottom - rc.top) / 2 -
                       Layout::Scale(1);

    Pen hpHorizonSky(Layout::Scale(1), DarkColor(Graphics::skyColor));
    Brush hbHorizonSky(Graphics::skyColor);
    Pen hpHorizonGround(Layout::Scale(1), DarkColor(Graphics::GroundColor));

#define fixed_div fixed(1.0 / 50.0)
#define fixed_89 fixed_int_constant(89)

    fixed phi = max(-fixed_89,
                    min(fixed_89, Basic.acceleration.bank_angle.Degrees()));
    fixed alpha = fixed_rad_to_deg * acos(max(-fixed_one,min(fixed_one,
                                          Basic.acceleration.pitch_angle.Degrees() * fixed_div)));
    fixed sphi = fixed_180 - phi;
    Angle alpha1 = Angle::Degrees(sphi - alpha);
    Angle alpha2 = Angle::Degrees(sphi + alpha);

    // draw sky part
    canvas.Select(hpHorizonSky);
    canvas.Select(hbHorizonSky);
    canvas.DrawSegment(center.x, center.y, radius, alpha2, alpha1, true);

    // draw ground part
    canvas.Select(hpHorizonGround);
    canvas.Select(Graphics::hbGround);
    canvas.DrawSegment(center.x, center.y, radius, alpha1, alpha2, true);

    // draw aircraft symbol
    Pen aircraft_pen(Layout::Scale(2), COLOR_BLACK);
    canvas.Select(aircraft_pen);
    canvas.line(center.x + radius / 2, center.y, center.x - radius / 2, center.y);
    canvas.line(center.x, center.y - radius / 4, center.x, center.y);

    // draw 45 degree dash marks
    const UPixelScalar rr2p = uround(radius * fixed_sqrt_half) + Layout::Scale(1);
    const UPixelScalar rr2n = rr2p - Layout::Scale(2);
    canvas.line(center.x + rr2p, center.y - rr2p,
                center.x + rr2n, center.y - rr2n);
    canvas.line(center.x - rr2p, center.y - rr2p,
                center.x - rr2n, center.y - rr2n);
}
Example #2
0
void MapWindow::DrawHorizon(Canvas &canvas, const RECT rc)
{
  POINT Start;

  Start.y = IBLSCALE(55)+rc.top;
  Start.x = rc.right - IBLSCALE(19);
  if (SettingsMap().EnableVarioGauge && MapRectBig.right == rc.right)
    Start.x -= InfoBoxLayout::ControlWidth;

  Pen hpHorizonSky(IBLSCALE(1), Color(0x40,0x40,0xff));
  Brush hbHorizonSky(Color(0xA0,0xA0,0xff));
  Pen hpHorizonGround(IBLSCALE(1), Color(106,55,12));
  Brush hbHorizonGround(Color(157,101,60));

  int radius = IBLSCALE(17);
  double phi = max(-89,min(89,Calculated().BankAngle));
  double alpha = RAD_TO_DEG
    *acos(max(-1.0,min(1.0,Calculated().PitchAngle/50.0)));
  double alpha1 = 180-alpha-phi;
  double alpha2 = 180+alpha-phi;

  canvas.select(hpHorizonSky);
  canvas.select(hbHorizonSky);

  canvas.segment(Start.x, Start.y, radius, rc, alpha2, alpha1, true);

  canvas.select(hpHorizonGround);
  canvas.select(hbHorizonGround);

  canvas.segment(Start.x, Start.y, radius, rc, alpha1, alpha2, true);

  /*
  POINT a1, a2;
  a1.x = Start.x + fastsine(alpha1)*radius;
  a1.y = Start.y - fastcosine(alpha1)*radius;
  a2.x = Start.x + fastsine(alpha2)*radius;
  a2.y = Start.y - fastcosine(alpha2)*radius;

  ClipDrawLine(hDC, PS_SOLID, IBLSCALE(1),
            a1, a2, RGB(0,0,0));
  */

  Pen dash_pen(Pen::DASH, 2, Color(0, 0, 0));
  canvas.select(dash_pen);

  canvas.line(Start.x + radius / 2, Start.y, Start.x - radius / 2, Start.y);
  canvas.line(Start.x, Start.y - radius / 4, Start.x - radius / 2, Start.y);

  //

#define ROOT2 0.70711

  int rr2p = lround(radius*ROOT2+IBLSCALE(1));
  int rr2n = lround(radius*ROOT2);

  Pen penb1(Pen::SOLID, 1, Color(0,0,0));
  canvas.select(penb1);
  canvas.line(Start.x + rr2p, Start.y - rr2p, Start.x + rr2n, Start.y - rr2n);
  canvas.line(Start.x - rr2p, Start.y - rr2p, Start.x - rr2n, Start.y - rr2n);

  // JMW experimental, display stall sensor
  double s = max(0.0,min(1.0,Basic().StallRatio));
  long m = (long)((rc.bottom-rc.top)*s*s);

  Pen penr2(Pen::SOLID, 1, Color(0,0,0));
  canvas.select(penr2);
  canvas.line(rc.right - 1, rc.bottom - m,
              rc.right - 11, rc.bottom - m);
}