Example #1
0
/*
 * VENTA3 This is a modified Segment() 
 */
int DrawArc(HDC hdc, long x, long y, int radius, RECT rc, 
	    double start,
	    double end)
{
  POINT pt[66];
  int i;
  int istart;
  int iend;

  rectObj rect;
  rect.minx = x-radius;
  rect.maxx = x+radius;
  rect.miny = y-radius;
  rect.maxy = y+radius;
  rectObj rcrect;
  rcrect.minx = rc.left;
  rcrect.maxx = rc.right;
  rcrect.miny = rc.top;
  rcrect.maxy = rc.bottom;

  if (msRectOverlap(&rect, &rcrect)!=MS_TRUE) {
    return FALSE;
  }

  // JMW added faster checking...

  start = AngleLimit360(start);
  end = AngleLimit360(end);

  istart = iround(start/360.0*64);
  iend = iround(end/360.0*64);

  int npoly = 0;

  if (istart>iend) {
    iend+= 64;
  }
  istart++;
  iend--;

  pt[npoly].x = x + (long) (radius * fastsine(start));
  pt[npoly].y = y - (long) (radius * fastcosine(start));
  npoly++;

  for(i=0;i<64;i++) {
    if (i<=iend-istart) {
      pt[npoly].x = x + (long) (radius * xcoords[(i+istart)%64]);
      pt[npoly].y = y - (long) (radius * ycoords[(i+istart)%64]);
      npoly++;
    }
  }
  pt[npoly].x = x + (long) (radius * fastsine(end));
  pt[npoly].y = y - (long) (radius * fastcosine(end));
  npoly++;
  if (npoly) {
    Polyline(hdc,pt,npoly); // TODO check ClipPolygon for HP31X
  }
  
  return TRUE;
}
Example #2
0
//
// The heading track line, like on Garmin units
//
void MapWindow::DrawHeading(HDC hdc, POINT Orig, RECT rc ) {

    if (DrawInfo.NAVWarning) return; // 100214

    if ( mode.Is(MapWindow::Mode::MODE_CIRCLING)) return;
    POINT p2;

    double tmp = 200000*zoom.ResScaleOverDistanceModify();
    if ( !( DisplayOrientation == TRACKUP || DisplayOrientation == NORTHCIRCLE || DisplayOrientation == TRACKCIRCLE )) {
        double trackbearing = DrawInfo.TrackBearing;
        p2.y= Orig.y - (int)(tmp*fastcosine(trackbearing));
        p2.x= Orig.x + (int)(tmp*fastsine(trackbearing));
    } else {
        p2.x=Orig.x;
        p2.y=Orig.y-(int)tmp;
    }

    // Reduce the rectangle for a better effect
    rc.top+=NIBLSCALE(5);
    rc.right-=NIBLSCALE(5);
    rc.bottom-=NIBLSCALE(5);
    rc.left+=NIBLSCALE(5);

    ForcedClipping=true;
    if (BlackScreen)
        _DrawLine(hdc, PS_SOLID, NIBLSCALE(1), Orig, p2, RGB_INVDRAW, rc); // 091109
    else
        _DrawLine(hdc, PS_SOLID, NIBLSCALE(1), Orig, p2, RGB_BLACK, rc);
    ForcedClipping=false;

}
Example #3
0
void MapWindow::CalculateOrigin(const RECT rc, POINT *Orig) {

  if (mode.Is(Mode::MODE_PAN)) {
	// North up
	DisplayAngle = 0.0;
	DisplayAircraftAngle = DrawInfo.TrackBearing;
	GliderCenter = true;
  } else {
	if (mode.Is(Mode::MODE_TARGET_PAN)) {
		CalculateOrientationTargetPan();
	} else {
		CalculateOrientationNormal();
	}
  }
  
  if(mode.Is(Mode::MODE_TARGET_PAN)) {
    if (ScreenLandscape) {
      Orig->x = (rc.left + rc.right - targetPanSize)/2;
      Orig->y = (rc.bottom + rc.top)/2;
    }
    else {
      Orig->x = (rc.left + rc.right)/2;
      Orig->y = (rc.bottom + rc.top + targetPanSize)/2;
    }
  }
  else if(mode.Is(Mode::MODE_PAN) || mode.Is(Mode::MODE_CIRCLING)) {
	Orig->x = (rc.left + rc.right)/2;
	Orig->y = (rc.bottom + rc.top)/2;
  } else {
	// automagic northup smart
	if (DisplayOrientation == NORTHSMART) { 
		double trackbearing = DrawInfo.TrackBearing;
		int middleXY,spanxy;
		if (ScreenLandscape) {
			middleXY=((rc.bottom-BottomSize)+rc.top)/2;
			spanxy=NIBLSCALE(50);
			Orig->y= middleXY + (int)(spanxy*fastcosine(trackbearing));
			// This was moving too much the map!
			// spanx=NIBLSCALE(40);
			// Orig->x= middleX - (int)(spanx*fastsine(trackbearing));
			Orig->x = (rc.left + rc.right)/2;
		} else {
			middleXY=(rc.left+rc.right)/2;
			spanxy=NIBLSCALE(50);
			Orig->x= middleXY - (int)(spanxy*fastsine(trackbearing));
			Orig->y = ((rc.bottom-BottomSize) + rc.top)/2;
		}
	} else {
		// 100924 if we are in north up autorient, position the glider in middle screen
		if ((zoom.Scale()*1.4) >= AutoOrientScale) {
			Orig->x = (rc.left + rc.right)/2;
			Orig->y=((rc.bottom-BottomSize)+rc.top)/2;
		} else {
			// else do it normally using configuration
			Orig->x = ((rc.right - rc.left )*GliderScreenPositionX/100)+rc.left;
			Orig->y = ((rc.top - rc.bottom )*GliderScreenPositionY/100)+rc.bottom;
		}
	}
  }
}
Example #4
0
void MapWindow::DrawHeadUpLine(HDC hdc, POINT Orig, RECT rc, double fMin, double fMax  ) {

  COLORREF rgbCol = RGB_BLACK;
  POINT p1, p2;
  double tmp = fMax*zoom.ResScaleOverDistanceModify();
  
  double trackbearing =  DisplayAircraftAngle+  (DerivedDrawInfo.Heading-DrawInfo.TrackBearing);
  p2.y= Orig.y - (int)(tmp*fastcosine(trackbearing));
  p2.x= Orig.x + (int)(tmp*fastsine(trackbearing));

  p1.y= Orig.y;
  p1.x= Orig.x;

  if (BlackScreen)
  rgbCol = RGB_INVDRAW;

  ForcedClipping=true;
  // Reduce the rectangle for a better effect
  rc.top+=NIBLSCALE(5);
  rc.right-=NIBLSCALE(5);
  rc.bottom-=NIBLSCALE(5);
  rc.left+=NIBLSCALE(5);
  _DrawLine(hdc, PS_SOLID, NIBLSCALE(1), p1, p2, rgbCol, rc);
  ForcedClipping=false;

}
Example #5
0
/*
 * VENTA3 This is a modified Segment()
 */
int LKSurface::DrawArc(long x, long y, int radius, const RECT& rc, double start, double end) {
    POINT pt[66];
    int i;
    int istart;
    int iend;

    if ((x - radius) > rc.right) return false;
    if ((x + radius) < rc.left) return false;
    if ((y - radius) > rc.bottom) return false;
    if ((y + radius) < rc.top) return false;

    // JMW added faster checking...

    start = AngleLimit360(start);
    end = AngleLimit360(end);

    istart = iround(start / 360.0 * 64);
    iend = iround(end / 360.0 * 64);

    int npoly = 0;

    if (istart > iend) {
        iend += 64;
    }
    istart++;
    iend--;

    pt[npoly].x = x + (long) (radius * fastsine(start));
    pt[npoly].y = y - (long) (radius * fastcosine(start));
    npoly++;

    for (i = 0; i < 64; i++) {
        if (i <= iend - istart) {
            pt[npoly].x = x + (long) (radius * xcoords[(i + istart) % 64]);
            pt[npoly].y = y - (long) (radius * ycoords[(i + istart) % 64]);
            npoly++;
        }
    }
    pt[npoly].x = x + (long) (radius * fastsine(end));
    pt[npoly].y = y - (long) (radius * fastcosine(end));
    npoly++;

    Polyline(pt, npoly, rc);

    return true;
}
Example #6
0
void MapWindow::DrawHeadUpLine(LKSurface& Surface, const POINT& Orig, const RECT& rc, double fMin, double fMax  ) {

    const double tmp = fMax*zoom.ResScaleOverDistanceModify();
    const double trackbearing =  DisplayAircraftAngle+  (DerivedDrawInfo.Heading-DrawInfo.TrackBearing);

    const POINT p2 = { Orig.x + (int)(tmp*fastsine(trackbearing)), Orig.y - (int)(tmp*fastcosine(trackbearing)) };

    const LKColor rgbCol = BlackScreen?RGB_INVDRAW:RGB_BLACK;

    // Reduce the rectangle for a better effect
    const RECT ClipRect = {rc.left+NIBLSCALE(5), rc.top+NIBLSCALE(5), rc.right-NIBLSCALE(5), rc.bottom-NIBLSCALE(5) };
    Surface.DrawLine(PEN_SOLID, NIBLSCALE(1), Orig, p2, rgbCol, ClipRect);
}
Example #7
0
void MapWindow::DrawFuturePos(LKSurface& Surface, const POINT& Orig, const RECT& rc, bool headUpLine) {
    if(DrawInfo.Speed < 13.88) return; //Don't continue if ground speed < 50 Km/h
    const double trackBearing = headUpLine ? DisplayAircraftAngle+(DerivedDrawInfo.Heading-DrawInfo.TrackBearing) : DrawInfo.TrackBearing;
    const double dist2min=120*DrawInfo.Speed*zoom.ResScaleOverDistanceModify(); // 2 min
    if(dist2min>=NIBLSCALE(3)) { //proceed only if the distance is not too small on the map
        const double dist5min=300*DrawInfo.Speed*zoom.ResScaleOverDistanceModify(); // 5 min
        const double dist10min=600*DrawInfo.Speed*zoom.ResScaleOverDistanceModify(); //10 min
        
        // Reduce the rectangle for a better effect
        const RECT ClipRect = (RECT){rc.left+NIBLSCALE(5), rc.top+NIBLSCALE(5), rc.right-NIBLSCALE(5), rc.bottom-NIBLSCALE(5) };

        POINT p1,p2;

        if( !MapWindow::mode.autoNorthUP() && !headUpLine && (DisplayOrientation==TRACKUP || DisplayOrientation==NORTHCIRCLE || DisplayOrientation==TARGETCIRCLE || DisplayOrientation==TARGETUP)) { //Track up map view
            p1.x=Orig.x-NIBLSCALE(4);
            p2.x=Orig.x+NIBLSCALE(4);
            p1.y=p2.y=Orig.y-(int)round(dist2min);
            Surface.DrawLine(PEN_SOLID,NIBLSCALE(1),p1,p2,BlackScreen?RGB_INVDRAW:RGB_BLACK,ClipRect);
            p1.y=p2.y=Orig.y-(int)round(dist5min);
            Surface.DrawLine(PEN_SOLID,NIBLSCALE(1),p1,p2,BlackScreen?RGB_INVDRAW:RGB_BLACK,ClipRect);
            p1.y=p2.y=Orig.y-(int)round(dist10min);
            Surface.DrawLine(PEN_SOLID,NIBLSCALE(1),p1,p2,BlackScreen?RGB_INVDRAW:RGB_BLACK,ClipRect);
        } else { //North up map view
            const double sin=fastsine(trackBearing);
            const double cos=fastcosine(trackBearing);
            double distXsin=dist2min*sin;
            double distXcos=dist2min*cos;
            const double tickXsin=NIBLSCALE(4)*sin;
            const double tickXcos=NIBLSCALE(4)*cos;
            p1.x=Orig.x+(int)round(distXsin-tickXcos);
            p1.y=Orig.y-(int)round(distXcos+tickXsin);
            p2.x=Orig.x+(int)round(distXsin+tickXcos);
            p2.y=Orig.y-(int)round(distXcos-tickXsin);
            Surface.DrawLine(PEN_SOLID,NIBLSCALE(1),p1,p2,BlackScreen?RGB_INVDRAW:RGB_BLACK,ClipRect);
            distXsin=dist5min*sin;
            distXcos=dist5min*cos;
            p1.x=Orig.x+(int)round(distXsin-tickXcos);
            p1.y=Orig.y-(int)round(distXcos+tickXsin);
            p2.x=Orig.x+(int)round(distXsin+tickXcos);
            p2.y=Orig.y-(int)round(distXcos-tickXsin);
            Surface.DrawLine(PEN_SOLID,NIBLSCALE(1),p1,p2,BlackScreen?RGB_INVDRAW:RGB_BLACK,ClipRect);
            distXsin=dist10min*sin;
            distXcos=dist10min*cos;
            p1.x=Orig.x+(int)round(distXsin-tickXcos);
            p1.y=Orig.y-(int)round(distXcos+tickXsin);
            p2.x=Orig.x+(int)round(distXsin+tickXcos);
            p2.y=Orig.y-(int)round(distXcos-tickXsin);
            Surface.DrawLine(PEN_SOLID,NIBLSCALE(1),p1,p2,BlackScreen?RGB_INVDRAW:RGB_BLACK,ClipRect);
        }
    }
}
Example #8
0
void frotate(float &xin, float &yin, const float &angle)
{
  float x= xin;
  float y= yin;
  static float lastangle = 0;
  static float cost=1,sint=0;

  if(angle != lastangle)
    {
      lastangle = angle;
      cost = (float)fastcosine(angle);
      sint = (float)fastsine(angle);
    }
  xin = x*cost - y*sint;
  yin = y*cost + x*sint;
}
Example #9
0
void rotate(double &xin, double &yin, const double &angle)
{
  double x= xin;
  double y= yin;
  static double lastangle = 0;
  static double cost=1,sint=0;

  if(angle != lastangle)
    {
      lastangle = angle;
      cost = (double)fastcosine(angle);
      sint = (double)fastsine(angle);
    }
  xin = x*cost - y*sint;
  yin = y*cost + x*sint;
}
Example #10
0
void frotatescale(float &xin, float &yin, const float &angle, const float &scale)
{
  float x= xin;
  float y= yin;
  static float lastangle = 0;
  static float lastscale = 0;
  static float cost=1,sint=0;

  if((angle != lastangle)||(scale != lastscale))
    {
      lastangle = angle;
      lastscale = scale;
      cost = (float)fastcosine(angle)*scale;
      sint = (float)fastsine(angle)*scale;
    }
  xin = x*cost - y*sint;
  yin = y*cost + x*sint;
}
Example #11
0
void rotatescale(double &xin, double &yin, 
		 const double &angle, const double &scale)
{
  double x= xin;
  double y= yin;
  static double lastangle = 0;
  static double lastscale = 0;
  static double cost=1,sint=0;

  if((angle != lastangle)||(scale != lastscale))
    {
      lastangle = angle;
      lastscale = scale;
      cost = (double)fastcosine(angle)*scale;
      sint = (double)fastsine(angle)*scale;
    }
  xin = x*cost - y*sint;
  yin = y*cost + x*sint;
}
Example #12
0
//
// The heading track line, like on Garmin units
//
void MapWindow::DrawHeading(HDC hdc, POINT Orig, RECT rc ) {

   if (GPS_INFO.NAVWarning) return; // 100214

   if (zoom.RealScale()>5 || mode.Is(MapWindow::Mode::MODE_CIRCLING)) return;
   POINT p2;

   double tmp = 12000*zoom.ResScaleOverDistanceModify();
   if ( !( DisplayOrientation == TRACKUP || DisplayOrientation == NORTHCIRCLE || DisplayOrientation == TRACKCIRCLE )) {
	double trackbearing = DrawInfo.TrackBearing;
	p2.y= Orig.y - (int)(tmp*fastcosine(trackbearing));
	p2.x= Orig.x + (int)(tmp*fastsine(trackbearing));
   } else {
	p2.x=Orig.x;
	p2.y=Orig.y-(int)tmp;
   }

   if (BlackScreen)
	   _DrawLine(hdc, PS_SOLID, NIBLSCALE(1), Orig, p2, RGB_INVDRAW, rc); // 091109
   else
	   _DrawLine(hdc, PS_SOLID, NIBLSCALE(1), Orig, p2, RGB_BLACK, rc);

}
Example #13
0
// Used by dlgTarget only
// A note about this function. We are changing map drawing parameters here, but we paint from the winmain thread.
// We are NOT using this from drawthread! the dialog target pan is sort of an hack, and not a good example.
// Do not consider emulating the target dialog, because it should be moved to draw thread somehow.
void MapWindow::SetTargetPan(bool do_pan, int target_point, DWORD dlgSize /* = 0 */)
{
  static double old_latitude;
  static double old_longitude;

  if(dlgSize)
    targetPanSize = dlgSize;

  if (!mode.Is(Mode::MODE_TARGET_PAN) || (TargetPanIndex != target_point)) {
    targetMoved = false;
  }

  TargetPanIndex = target_point;

  if (do_pan && !mode.Is(Mode::MODE_TARGET_PAN)) {
    old_latitude = PanLatitude;
    old_longitude = PanLongitude;
    mode.Special(do_pan ? Mode::MODE_SPECIAL_TARGET_PAN : Mode::MODE_SPECIAL_PAN, true);
    zoom.SwitchMode();
  }
  if (do_pan) {
    LockTaskData();
    if (ValidTaskPoint(target_point)) {
      PanLongitude = WayPointList[Task[target_point].Index].Longitude;
      PanLatitude = WayPointList[Task[target_point].Index].Latitude;
      if (target_point==0) {
        TargetZoomDistance = max(2e3, (double)StartRadius*2);
      } else if (!ValidTaskPoint(target_point+1)) {
        TargetZoomDistance = max(2e3, (double)FinishRadius*2);
      } else if (AATEnabled) {
        if (Task[target_point].AATType == SECTOR) {
          const double start = Task[target_point].AATStartRadial;
          const double finish = Task[target_point].AATFinishRadial;
          const double xs = fastsine(start);
          const double ys = fastcosine(start);
          const double xf = fastsine(finish);
          const double yf = fastcosine(finish);
          
          // calculate rectangle area taken by the sector
          const double top    = AngleInRange(start, finish, 0,   true) ?  1 : max(max(ys, yf), 0.0);
          const double right  = AngleInRange(start, finish, 90,  true) ?  1 : max(max(xs, xf), 0.0);
          const double bottom = AngleInRange(start, finish, 180, true) ? -1 : min(min(ys, yf), 0.0);
          const double left   = AngleInRange(start, finish, 270, true) ? -1 : min(min(xs, xf), 0.0);
          
          // get area center
          const double radius = Task[target_point].AATSectorRadius;
          const double x = (left + right) / 2;
          const double y = (top + bottom) / 2;
          double bearing, range;
          xXY_Brg_Rng(0, 0, x, y, &bearing, &range);
          
          // find area center geographic data
          FindLatitudeLongitude(WayPointList[Task[target_point].Index].Latitude,
                                WayPointList[Task[target_point].Index].Longitude,
                                bearing, range * radius, &PanLatitude, &PanLongitude);
          TargetZoomDistance = max(2e3, max(right - left, top - bottom) * radius);
        } else {
          TargetZoomDistance = max(2e3, Task[target_point].AATCircleRadius*2);
        }
      } else {
        TargetZoomDistance = max(2e3, (double)SectorRadius*2);
      }
    }
    UnlockTaskData();
  }
  else if (mode.Is(Mode::MODE_TARGET_PAN)) {
    PanLongitude = old_longitude;
    PanLatitude = old_latitude;
    mode.Special(Mode::MODE_SPECIAL_TARGET_PAN, do_pan);
    zoom.SwitchMode();
    }
  mode.Special(Mode::MODE_SPECIAL_TARGET_PAN, do_pan);
  }
Example #14
0
void MapWindow::DrawTRI(HDC hDC, const RECT rc)
{
  POINT Start;
  
  static short top=(((rc.bottom-BottomSize-(rc.top+TOPLIMITER)-BOTTOMLIMITER)/PANELROWS)+rc.top+TOPLIMITER)- (rc.top+TOPLIMITER);

  Start.y = ((rc.bottom-BottomSize-top)/2)+top-NIBLSCALE(10);
  Start.x = (rc.right - rc.left)/2;

  HPEN		hpBlack;
  HBRUSH	hbBlack;
  HPEN		hpWhite;
  HBRUSH	hbWhite;
  HPEN		hpBorder;
  HBRUSH	hbBorder;
  HPEN   hpOld;
  HBRUSH hbOld;

  // gauge size radius
  static int radius = NIBLSCALE(65);
  static int planesize = radius-NIBLSCALE(10);
  // planebody
  static int planeradius = NIBLSCALE(6);
  static int tailsize = planesize/4+NIBLSCALE(2);
  static int innerradius = radius - NIBLSCALE(8);
  static POINT d00[2][2],d15[2][4],d30[2][4], d45[2][4], d60[2][4];
  TCHAR Buffer[LKSIZEBUFFERVALUE];
  double beta=0.0;
  bool disabled=false;

  if (DoInit[MDI_DRAWTRI]) {

  top=(((rc.bottom-BottomSize-(rc.top+TOPLIMITER)-BOTTOMLIMITER)/PANELROWS)+rc.top+TOPLIMITER)- (rc.top+TOPLIMITER);
  radius = NIBLSCALE(65);
  planesize = radius-NIBLSCALE(10);
  planeradius = NIBLSCALE(6);
  tailsize = planesize/4+NIBLSCALE(2);
  innerradius = radius - NIBLSCALE(8);

  // [a][b]  a=0 external circle a=1 inner circle  b=1-4

  d00[0][0].x= Start.x - radius;
  d00[0][0].y= Start.y;
  d00[1][0].x= Start.x - innerradius;
  d00[1][0].y= Start.y;
  d00[0][1].x= Start.x + radius;
  d00[0][1].y= Start.y;
  d00[1][1].x= Start.x + innerradius;
  d00[1][1].y= Start.y;

  d15[0][0].x= Start.x - (long) (radius*fastcosine(15.0));
  d15[0][0].y= Start.y + (long) (radius*fastsine(15.0));
  d15[1][0].x= Start.x - (long) (innerradius*fastcosine(15.0));
  d15[1][0].y= Start.y + (long) (innerradius*fastsine(15.0));
  d15[0][1].x= Start.x - (long) (radius*fastcosine(15.0));
  d15[0][1].y= Start.y - (long) (radius*fastsine(15.0));
  d15[1][1].x= Start.x - (long) (innerradius*fastcosine(15.0));
  d15[1][1].y= Start.y - (long) (innerradius*fastsine(15.0));
  d15[0][2].x= Start.x + (long) (radius*fastcosine(15.0));
  d15[0][2].y= Start.y + (long) (radius*fastsine(15.0));
  d15[1][2].x= Start.x + (long) (innerradius*fastcosine(15.0));
  d15[1][2].y= Start.y + (long) (innerradius*fastsine(15.0));
  d15[0][3].x= Start.x + (long) (radius*fastcosine(15.0));
  d15[0][3].y= Start.y - (long) (radius*fastsine(15.0));
  d15[1][3].x= Start.x + (long) (innerradius*fastcosine(15.0));
  d15[1][3].y= Start.y - (long) (innerradius*fastsine(15.0));

  d30[0][0].x= Start.x - (long) (radius*fastcosine(30.0));
  d30[0][0].y= Start.y + (long) (radius*fastsine(30.0));
  d30[1][0].x= Start.x - (long) (innerradius*fastcosine(30.0));
  d30[1][0].y= Start.y + (long) (innerradius*fastsine(30.0));
  d30[0][1].x= Start.x - (long) (radius*fastcosine(30.0));
  d30[0][1].y= Start.y - (long) (radius*fastsine(30.0));
  d30[1][1].x= Start.x - (long) (innerradius*fastcosine(30.0));
  d30[1][1].y= Start.y - (long) (innerradius*fastsine(30.0));
  d30[0][2].x= Start.x + (long) (radius*fastcosine(30.0));
  d30[0][2].y= Start.y + (long) (radius*fastsine(30.0));
  d30[1][2].x= Start.x + (long) (innerradius*fastcosine(30.0));
  d30[1][2].y= Start.y + (long) (innerradius*fastsine(30.0));
  d30[0][3].x= Start.x + (long) (radius*fastcosine(30.0));
  d30[0][3].y= Start.y - (long) (radius*fastsine(30.0));
  d30[1][3].x= Start.x + (long) (innerradius*fastcosine(30.0));
  d30[1][3].y= Start.y - (long) (innerradius*fastsine(30.0));

  d45[0][0].x= Start.x - (long) (radius*fastcosine(45.0));
  d45[0][0].y= Start.y + (long) (radius*fastsine(45.0));
  d45[1][0].x= Start.x - (long) (innerradius*fastcosine(45.0));
  d45[1][0].y= Start.y + (long) (innerradius*fastsine(45.0));
  d45[0][1].x= Start.x - (long) (radius*fastcosine(45.0));
  d45[0][1].y= Start.y - (long) (radius*fastsine(45.0));
  d45[1][1].x= Start.x - (long) (innerradius*fastcosine(45.0));
  d45[1][1].y= Start.y - (long) (innerradius*fastsine(45.0));
  d45[0][2].x= Start.x + (long) (radius*fastcosine(45.0));
  d45[0][2].y= Start.y + (long) (radius*fastsine(45.0));
  d45[1][2].x= Start.x + (long) (innerradius*fastcosine(45.0));
  d45[1][2].y= Start.y + (long) (innerradius*fastsine(45.0));
  d45[0][3].x= Start.x + (long) (radius*fastcosine(45.0));
  d45[0][3].y= Start.y - (long) (radius*fastsine(45.0));
  d45[1][3].x= Start.x + (long) (innerradius*fastcosine(45.0));
  d45[1][3].y= Start.y - (long) (innerradius*fastsine(45.0));

  d60[0][0].x= Start.x - (long) (radius*fastcosine(60.0));
  d60[0][0].y= Start.y + (long) (radius*fastsine(60.0));
  d60[1][0].x= Start.x - (long) (innerradius*fastcosine(60.0));
  d60[1][0].y= Start.y + (long) (innerradius*fastsine(60.0));
  d60[0][1].x= Start.x - (long) (radius*fastcosine(60.0));
  d60[0][1].y= Start.y - (long) (radius*fastsine(60.0));
  d60[1][1].x= Start.x - (long) (innerradius*fastcosine(60.0));
  d60[1][1].y= Start.y - (long) (innerradius*fastsine(60.0));
  d60[0][2].x= Start.x + (long) (radius*fastcosine(60.0));
  d60[0][2].y= Start.y + (long) (radius*fastsine(60.0));
  d60[1][2].x= Start.x + (long) (innerradius*fastcosine(60.0));
  d60[1][2].y= Start.y + (long) (innerradius*fastsine(60.0));
  d60[0][3].x= Start.x + (long) (radius*fastcosine(60.0));
  d60[0][3].y= Start.y - (long) (radius*fastsine(60.0));
  d60[1][3].x= Start.x + (long) (innerradius*fastcosine(60.0));
  d60[1][3].y= Start.y - (long) (innerradius*fastsine(60.0));

  DoInit[MDI_DRAWTRI]=false;
  } // end dirty hack doinit

  //if (!CALCULATED_INFO.Flying) {
  // speed is in m/s
  if(DrawInfo.Speed <5.5 && !DrawInfo.GyroscopeAvailable)
    disabled=true; 

  if (disabled) {
	hpBlack = LKPen_Grey_N1;
	hbBlack = LKBrush_Grey;
  } else {
	hpBlack = LKPen_Black_N1;
	hbBlack = LKBrush_Black;
        beta = DrawInfo.GyroscopeAvailable ? DrawInfo.Roll : DerivedDrawInfo.BankAngle;
  }

  hpWhite = LKPen_White_N1;
  hbWhite = LKBrush_White;
  hpBorder = LKPen_Grey_N2;
  hbBorder = LKBrush_Grey;

  hpOld = (HPEN)SelectObject(hDC, hpWhite);
  hbOld = (HBRUSH)SelectObject(hDC, hbWhite);
  Circle(hDC, Start.x, Start.y, radius, rc, false, true );

  if(DrawInfo.AccelerationAvailable)
    DrawAcceleration(hDC, rc);

  SelectObject(hDC, hpBorder);
  SelectObject(hDC, hbBorder);
  Circle(hDC, Start.x, Start.y, radius+NIBLSCALE(2), rc, false, false );

  SelectObject(hDC, hpBlack);
  SelectObject(hDC, hbBlack); 
  Circle(hDC, Start.x, Start.y, planeradius, rc, false, true );

  _DrawLine(hDC, PS_SOLID, NIBLSCALE(1), d00[0][0], d00[1][0], RGB_BLUE,rc);
  _DrawLine(hDC, PS_SOLID, NIBLSCALE(1), d00[0][1], d00[1][1], RGB_BLUE,rc);
  _DrawLine(hDC, PS_SOLID, NIBLSCALE(1), d15[0][0], d15[1][0], RGB_BLUE,rc);
  _DrawLine(hDC, PS_SOLID, NIBLSCALE(1), d15[0][1], d15[1][1], RGB_BLUE,rc);
  _DrawLine(hDC, PS_SOLID, NIBLSCALE(1), d15[0][2], d15[1][2], RGB_BLUE,rc);
  _DrawLine(hDC, PS_SOLID, NIBLSCALE(1), d15[0][3], d15[1][3], RGB_BLUE,rc);
  _DrawLine(hDC, PS_SOLID, NIBLSCALE(1), d30[0][0], d30[1][0], RGB_BLUE,rc);
  _DrawLine(hDC, PS_SOLID, NIBLSCALE(1), d30[0][1], d30[1][1], RGB_BLUE,rc);
  _DrawLine(hDC, PS_SOLID, NIBLSCALE(1), d30[0][2], d30[1][2], RGB_BLUE,rc);
  _DrawLine(hDC, PS_SOLID, NIBLSCALE(1), d30[0][3], d30[1][3], RGB_BLUE,rc);
  _DrawLine(hDC, PS_SOLID, NIBLSCALE(1), d45[0][0], d45[1][0], RGB_BLUE,rc);
  _DrawLine(hDC, PS_SOLID, NIBLSCALE(1), d45[0][1], d45[1][1], RGB_BLUE,rc);
  _DrawLine(hDC, PS_SOLID, NIBLSCALE(1), d45[0][2], d45[1][2], RGB_BLUE,rc);
  _DrawLine(hDC, PS_SOLID, NIBLSCALE(1), d45[0][3], d45[1][3], RGB_BLUE,rc);
  _DrawLine(hDC, PS_SOLID, NIBLSCALE(1), d60[0][0], d60[1][0], RGB_BLUE,rc);
  _DrawLine(hDC, PS_SOLID, NIBLSCALE(1), d60[0][1], d60[1][1], RGB_BLUE,rc);
  _DrawLine(hDC, PS_SOLID, NIBLSCALE(1), d60[0][2], d60[1][2], RGB_BLUE,rc);
  _DrawLine(hDC, PS_SOLID, NIBLSCALE(1), d60[0][3], d60[1][3], RGB_BLUE,rc);

  POINT a1, a2;
  const double beta_sine = fastsine(beta);
  const double beta_cosine = fastcosine(beta);
  a1.x = Start.x - (long)(planesize * beta_cosine);
  a1.y = Start.y - (long)(planesize * beta_sine);
  a2.x = Start.x + (long)(planesize * beta_cosine);
  a2.y = Start.y + (long)(planesize * beta_sine);
    if (disabled) 
	_DrawLine(hDC, PS_SOLID, NIBLSCALE(4), a1, a2, RGB_GREY,rc);
    else
	_DrawLine(hDC, PS_SOLID, NIBLSCALE(4), a1, a2, RGB_BLACK,rc); 

  a1.x = Start.x;
  a1.y = Start.y;
  a2.x = Start.x + (long)(tailsize * beta_sine);
  a2.y = Start.y - (long)(tailsize * beta_cosine);
  if (disabled) 
	_DrawLine(hDC, PS_SOLID, NIBLSCALE(4), a1, a2, RGB_GREY,rc);
  else
	_DrawLine(hDC, PS_SOLID, NIBLSCALE(4), a1, a2, RGB_BLACK,rc);

  SelectObject(hDC, LK8TitleFont);
  int bankindy=Start.y-radius/2;
#ifndef __MINGW32__
  if (beta > 1)
	_stprintf(Buffer, TEXT("%2.0f\xB0"), beta);
  else if (beta < -1)
	_stprintf(Buffer, TEXT("%2.0f\xB0"), -beta);
  else
	_tcscpy(Buffer, TEXT("--"));
#else
  if (beta > 1)
	_stprintf(Buffer, TEXT("%2.0f°"), beta);
  else if (beta < -1)
	_stprintf(Buffer, TEXT("%2.0f°"), -beta);
  else
	_tcscpy(Buffer, TEXT("--"));
#endif

  LKWriteText(hDC, Buffer, Start.x , bankindy, 0, WTMODE_NORMAL, WTALIGN_CENTER, RGB_BLUE, false);

//  MapDirty = true;
//  if (!disabled) MapWindow::RefreshMap();


  SelectObject(hDC, hbOld);
  SelectObject(hDC, hpOld);
}
Example #15
0
void Heading(NMEA_INFO *Basic, DERIVED_INFO *Calculated)
{
  double x0, y0, mag=0;
  static double LastTime = 0;
  static double lastHeading = 0;
  static double lastSpeed = 0;

  if (DoInit[MDI_HEADING]) {
	LastTime = 0;
	lastHeading = 0;
	DoInit[MDI_HEADING]=false;
  }

  if ((Basic->Speed>0)||(Calculated->WindSpeed>0)) {

    x0 = fastsine(Basic->TrackBearing)*Basic->Speed;
    y0 = fastcosine(Basic->TrackBearing)*Basic->Speed;
    x0 += fastsine(Calculated->WindBearing)*Calculated->WindSpeed;
    y0 += fastcosine(Calculated->WindBearing)*Calculated->WindSpeed;

    Calculated->Heading = AngleLimit360(atan2(x0,y0)*RAD_TO_DEG);

    if (!Calculated->Flying) {
      // don't take wind into account when on ground
      Calculated->Heading = Basic->TrackBearing;
    }

    // calculate turn rate in wind coordinates
    if(Basic->Time > LastTime) {
      double dT = Basic->Time - LastTime;

      LKASSERT(dT!=0);
      Calculated->TurnRateWind = AngleLimit180(Calculated->Heading
                                               - lastHeading)/dT;

      lastHeading = Calculated->Heading;
    }

    if (ISCAR) {
	// On ground, TAS is GS. Wind gradient irrilevant, normally.
	Calculated->TrueAirspeedEstimated = Basic->Speed;
	LKASSERT(AirDensityRatio(Calculated->NavAltitude)!=0);
	Calculated->IndicatedAirspeedEstimated = Basic->Speed/AirDensityRatio(Calculated->NavAltitude);
    } else {
	// calculate estimated true airspeed
	mag = isqrt4((unsigned long)(x0*x0*100+y0*y0*100))/10.0;
	Calculated->TrueAirspeedEstimated = mag;
	LKASSERT(AirDensityRatio(Calculated->NavAltitude)!=0);
	Calculated->IndicatedAirspeedEstimated = mag/AirDensityRatio(Calculated->NavAltitude);
    }
    // estimate bank angle (assuming balanced turn)
    double angle = atan(DEG_TO_RAD*Calculated->TurnRateWind*
			Calculated->TrueAirspeedEstimated/9.81);

    Calculated->BankAngle = RAD_TO_DEG*angle;

    if (ISCAR) {
	if(Basic->Time > LastTime) {
		Calculated->Gload = ((Basic->Speed - lastSpeed) / (Basic->Time-LastTime))/9.81;
		lastSpeed=Basic->Speed;
	} else {
		Calculated->Gload = 0;
	}
    } else {
	Calculated->Gload = 1.0/max(0.001,fabs(cos(angle)));
    }

    LastTime = Basic->Time;

    // estimate pitch angle (assuming balanced turn)
/*
    Calculated->PitchAngle = RAD_TO_DEG*
      atan2(Calculated->GPSVario-Calculated->Vario,
           Calculated->TrueAirspeedEstimated);
*/
	// should be used as here only when no real vario available
    Calculated->PitchAngle = RAD_TO_DEG*	
      atan2(Calculated->Vario,
           Calculated->TrueAirspeedEstimated);

    // update zigzag wind
    if (  ((AutoWindMode==D_AUTOWIND_ZIGZAG) || (AutoWindMode==D_AUTOWIND_BOTHCIRCZAG))
        && (!ReplayLogger::IsEnabled()) ) {
      double zz_wind_speed;
      double zz_wind_bearing;
      int quality=0;
      quality = WindKalmanUpdate(Basic, Calculated, &zz_wind_speed, &zz_wind_bearing);

      if (quality>0) {

        SetWindEstimate(zz_wind_speed, zz_wind_bearing);
	Calculated->WindSpeed   = zz_wind_speed;
	Calculated->WindBearing = zz_wind_bearing;

/* 100118 redundant!! removed. TOCHECK *
        Vector v_wind;
        v_wind.x = zz_wind_speed*cos(zz_wind_bearing*3.1415926/180.0);
        v_wind.y = zz_wind_speed*sin(zz_wind_bearing*3.1415926/180.0);
        LockFlightData();
        if (windanalyser) {
	  windanalyser->slot_newEstimate(Basic, Calculated, v_wind, quality);
        }
        UnlockFlightData();
*/
      }
    }
  // else basic speed is 0 and there is no wind.. 
  } else { 
    Calculated->Heading = Basic->TrackBearing;
    Calculated->TrueAirspeedEstimated = 0; // BUGFIX 100318
    Calculated->IndicatedAirspeedEstimated = 0; // BUGFIX 100318
  }

}
Example #16
0
void LKSurface::Segment(long x, long y, int radius, const RECT& rc, double start, double end) {

    // JMW added faster checking...
    if ((x - radius) > rc.right) return;
    if ((x + radius) < rc.left) return;
    if ((y - radius) > rc.bottom) return;
    if ((y + radius) < rc.top) return;

    
    bool EmptySector = end == start;
    if(EmptySector) {
      RasterPoint pt[2];
      
      start = AngleLimit360(start);

      pt[0].x = x;
      pt[0].y = y;
      
      pt[1].x = x + (long) (radius * fastsine(start));
      pt[1].y = y - (long) (radius * fastcosine(start));
      
      Polyline(pt, array_size(pt), rc);
      
    } else {
      RasterPoint pt[68];

      start = AngleLimit360(start);
      end = AngleLimit360(end);

      const int istart = std::ceil(start / 360.0 * 64);
      const int iend = std::floor(((end > start) ? end : end + 360) / 360 * 64);

      int npoly = 0;

      // Center point
      pt[npoly].x = x;
      pt[npoly].y = y;
      npoly++;

      // first Segment point
      pt[npoly].x = x + (long) (radius * fastsine(start));
      pt[npoly].y = y - (long) (radius * fastcosine(start));
      npoly++;

      for (int i = 0; i < 64; i++) {
          if (i <= iend - istart) {
              pt[npoly].x = x + (long) (radius * xcoords[(i + istart) % 64]);
              pt[npoly].y = y - (long) (radius * ycoords[(i + istart) % 64]);
              npoly++;
          }
      }

      // Last Segment Point
      pt[npoly].x = x + (long) (radius * fastsine(end));
      pt[npoly].y = y - (long) (radius * fastcosine(end));
      npoly++;

      // Close Polygon ( center point )
      pt[npoly].x = x;
      pt[npoly].y = y;
      npoly++;
      
      assert(npoly <= (int)array_size(pt));
      
      Polygon(pt, npoly, rc);
    }
}
Example #17
0
int DrawCompassArc(HDC hdc, long x, long y, int radius, RECT rc,
	    double bearing)

{
		const int indicatorStep = 10;

		// For Oren: remember to always DeleteObject you create with Create, or in 1 hour any
		// device will run out of GDI space, including your PC...
		// Meanwhile, I have created LKObjects, so anytime we should use them . No need to delete them.
		//HPEN hPenBlack = ::CreatePen(PS_SOLID, (5), RGB(0x00,0x0,0x0));  
		//HPEN hPenWhite = (HPEN)CreatePen(PS_SOLID, (2), RGB(0xff,0xff,0xff));
		HPEN hPenBlack = LKPen_Black_N5;
		HPEN hPenWhite = LKPen_White_N2;
		HFONT oldfont;
		HPEN oldpen;

		oldpen=(HPEN) SelectObject(hdc, hPenBlack);
		DrawArc(hdc, x, y,radius, rc, 300, 60);

		int heading = (int)(bearing +0.5);

		// -----------Draw the detents around the circle-----------------------------

		double angleDiff = heading % indicatorStep;

		int screenAngle = (int)(300 - angleDiff);
		int curHeading = (int)(heading - 60 - angleDiff);
		TCHAR textBuffer[32];

		POINT pt[2];
		int i;

		oldfont=(HFONT)SelectObject(hdc, LK8MediumFont); // always remember to save object or we miss font 

		for(i = - 60; i<= 60;
				i+=indicatorStep,screenAngle += indicatorStep,curHeading += indicatorStep)
		{

			if ( (screenAngle < 300) && (screenAngle > 60) )
 			{
				continue;
			}

			screenAngle  = (int)AngleLimit360(screenAngle);

			pt[0].x = x + (long) (radius * fastsine(screenAngle) );
			pt[0].y = y - (long) (radius * fastcosine(screenAngle) );

			// The length of the tickmarks on the compass rose
			double tickLength;

			// Make sure the display heading is between 0 and 360
			int displayHeading = (int)AngleLimit360(curHeading);

			// If the heading is a multiple of ten, it gets a long tick
			if(displayHeading%30==0)
			{
				tickLength = 15;

				if(displayHeading%30==0)
				{

					int drawHdg = displayHeading/10;
					switch ( drawHdg )
					{
					case 0:
						wsprintf( textBuffer, _T("N"));
						break;
					case 9:
						wsprintf( textBuffer, _T("E"));
						break;
					case 18:
						wsprintf( textBuffer, _T("S"));
						break;
					case 27:
						wsprintf( textBuffer, _T("W"));
						break;
					default:
						wsprintf( textBuffer, _T("%d"), displayHeading/10 );
					}

					SIZE textSize;
					GetTextExtentPoint(hdc, textBuffer, _tcslen(textBuffer), &textSize);

					int textX = x + (long) ((radius - (textSize.cy/2)-2) * fastsine(screenAngle) ) - textSize.cx/2;
					int textY = y - (long) ((radius - (textSize.cy/2)-2) * fastcosine(screenAngle) );
					drawOutlineText(hdc,textX,textY ,textBuffer,RGB_WHITE);
				}
			}
			else // Otherwise it gets a short tick
				tickLength = 10;

			pt[1].x = x + (long) ((radius -tickLength) * fastsine(screenAngle) );
			pt[1].y = y - (long) ((radius -tickLength) * fastcosine(screenAngle) );
			SelectObject(hdc, hPenBlack);
			::Polyline(hdc,pt,2);
			SelectObject(hdc, hPenWhite);
			::Polyline(hdc,pt,2);
		}

		SelectObject(hdc, hPenWhite);
		DrawArc(hdc, x, y,radius, rc, 300, 60);
		SelectObject(hdc, oldfont);
		SelectObject(hdc, oldpen);
		return 0;
}
Example #18
0
void MapWindow::DrawTask(HDC hdc, RECT rc, const POINT &Orig_Aircraft) {
    int i;
    double tmp;

    COLORREF whitecolor = RGB_WHITE;
    COLORREF origcolor = SetTextColor(hDCTemp, whitecolor);
    HPEN oldpen = 0;
    HBRUSH oldbrush = 0;

    static short size_tasklines=0;

    if (DoInit[MDI_DRAWTASK]) {
switch (ScreenSize) {
case ss480x272:
case ss272x480:
case ss320x240:
case ss240x320:
size_tasklines=NIBLSCALE(4);
break;
default:
size_tasklines=NIBLSCALE(3);
break;
}
DoInit[MDI_DRAWTASK]=false;
    }

    if (!WayPointList) return;

    oldpen = (HPEN) SelectObject(hdc, hpStartFinishThick);
    oldbrush = (HBRUSH) SelectObject(hdc, GetStockObject(HOLLOW_BRUSH));

    LockTaskData(); // protect from external task changes

    for (i = 1; ValidTaskPoint(i); i++) {
        if (!ValidTaskPoint(i + 1)) { // final waypoint
            if (ActiveWayPoint > 1 || !ValidTaskPoint(2)) {
                // only draw finish line when past the first
                // waypoint. FIXED 110307: or if task is with only 2 tps
                DrawStartEndSector(hdc, rc, Task[i].Start, Task[i].End, Task[i].Index, FinishLine, FinishRadius);
            }
        } else { // normal sector
            if (AATEnabled != TRUE) {
                //_DrawLine(hdc, PS_DASH, NIBLSCALE(3), WayPointList[Task[i].Index].Screen, Task[i].Start, RGB_PETROL, rc);
                //_DrawLine(hdc, PS_DASH, NIBLSCALE(3), WayPointList[Task[i].Index].Screen, Task[i].End, RGB_PETROL, rc);
         // DrawDashLine(hdc, size_tasklines, WayPointList[Task[i].Index].Screen, Task[i].Start, RGB_PETROL, rc);
         // DrawDashLine(hdc, size_tasklines, WayPointList[Task[i].Index].Screen, Task[i].End, RGB_PETROL, rc);
            }

            int Type = 0;
            double Radius = 0.;
            GetTaskSectorParameter(i, &Type, &Radius);
            switch (Type) {
                case CIRCLE:
                    tmp = Radius * zoom.ResScaleOverDistanceModify();
                    Circle(hdc,
                            WayPointList[Task[i].Index].Screen.x,
                            WayPointList[Task[i].Index].Screen.y,
                            (int) tmp, rc, false, false);
                    break;
                case SECTOR:
                    tmp = Radius * zoom.ResScaleOverDistanceModify();
                    Segment(hdc,
                            WayPointList[Task[i].Index].Screen.x,
                            WayPointList[Task[i].Index].Screen.y, (int) tmp, rc,
                            Task[i].AATStartRadial - DisplayAngle,
                            Task[i].AATFinishRadial - DisplayAngle);
                    break;
                case DAe:
                    if (!AATEnabled) { // this Type exist only if not AAT task
                        // JMW added german rules
                        tmp = 500 * zoom.ResScaleOverDistanceModify();
                        Circle(hdc,
                                WayPointList[Task[i].Index].Screen.x,
                                WayPointList[Task[i].Index].Screen.y,
                                (int) tmp, rc, false, false);

                        tmp = 10e3 * zoom.ResScaleOverDistanceModify();

                        Segment(hdc,
                                WayPointList[Task[i].Index].Screen.x,
                                WayPointList[Task[i].Index].Screen.y, (int) tmp, rc,
                                Task[i].AATStartRadial - DisplayAngle,
                                Task[i].AATFinishRadial - DisplayAngle);
                    }
                    break;
                case LINE:
                    if (!AATEnabled) { // this Type exist only if not AAT task
                    	if(ISGAAIRCRAFT) {
                    		POINT start,end;
                    		double rotation=AngleLimit360(Task[i].Bisector-DisplayAngle);
                    		int length=14*ScreenScale; //Make intermediate WP lines always of the same size independent by zoom level
                    		start.x=WayPointList[Task[i].Index].Screen.x+(long)(length*fastsine(rotation));
                    		start.y=WayPointList[Task[i].Index].Screen.y-(long)(length*fastcosine(rotation));
                    		rotation=Reciprocal(rotation);
                    		end.x=WayPointList[Task[i].Index].Screen.x+(long)(length*fastsine(rotation));
                    		end.y=WayPointList[Task[i].Index].Screen.y-(long)(length*fastcosine(rotation));
                    		_DrawLine(hdc, PS_SOLID, NIBLSCALE(3), start, end, taskcolor, rc);
                    	} else _DrawLine(hdc, PS_SOLID, NIBLSCALE(3), Task[i].Start, Task[i].End, taskcolor, rc);
                    }
                    break;
                case CONE:
                    tmp = Radius * zoom.ResScaleOverDistanceModify();
                    int center_x = WayPointList[Task[i].Index].Screen.x;
                    int center_y = WayPointList[Task[i].Index].Screen.y;
                    Circle(hdc, center_x, center_y, (int) tmp, rc, false, false);
                    HPEN prevPen = (HPEN)::SelectObject(hdc, hpTerrainLine);
                    for( int j = 1; j < 5 && tmp > 0; ++j) {
                        Circle(hdc, center_x, center_y, tmp -= NIBLSCALE(5), rc, true, true);
                    }
                    ::SelectObject(hdc, prevPen);
                    break;
            }

            if (AATEnabled && !DoOptimizeRoute()) {
                // ELSE HERE IS *** AAT ***
                // JMW added iso lines
                if ((i == ActiveWayPoint) || (mode.Is(Mode::MODE_TARGET_PAN) && (i == TargetPanIndex))) {
                    // JMW 20080616 flash arc line if very close to target
                    static bool flip = false;

                    if (DerivedDrawInfo.WaypointDistance < AATCloseDistance()*2.0) {
                        flip = !flip;
                    } else {
                        flip = true;
                    }
                    if (flip) {
                        for (int j = 0; j < MAXISOLINES - 1; j++) {
                            if (TaskStats[i].IsoLine_valid[j]
                                    && TaskStats[i].IsoLine_valid[j + 1]) {
                                _DrawLine(hdc, PS_SOLID, NIBLSCALE(2),
                                        TaskStats[i].IsoLine_Screen[j],
                                        TaskStats[i].IsoLine_Screen[j + 1],
                                        RGB(0, 0, 255), rc);
                            }
                        }
                    }
                }
            }
        }
    }

    if ((ActiveWayPoint < 2) && ValidTaskPoint(0) && ValidTaskPoint(1)) {
        DrawStartEndSector(hdc, rc, Task[0].Start, Task[0].End, Task[0].Index, StartLine, StartRadius);
        if (EnableMultipleStartPoints) {
            for (i = 0; i < MAXSTARTPOINTS; i++) {
                if (StartPoints[i].Active && ValidWayPoint(StartPoints[i].Index)) {
                    DrawStartEndSector(hdc, rc, StartPoints[i].Start, StartPoints[i].End,
                            StartPoints[i].Index, StartLine, StartRadius);
                }
            }
        }
    }
    
    for (i = 0; ValidTaskPoint(i + 1); i++) {
        int imin = min(Task[i].Index, Task[i + 1].Index);
        int imax = max(Task[i].Index, Task[i + 1].Index);
        // JMW AAT!
        double bearing = Task[i].OutBound;
        POINT sct1, sct2;
        if (AATEnabled) {
            LatLon2Screen(Task[i].AATTargetLon,
                    Task[i].AATTargetLat,
                    sct1);
            LatLon2Screen(Task[i + 1].AATTargetLon,
                    Task[i + 1].AATTargetLat,
                    sct2);
            DistanceBearing(Task[i].AATTargetLat,
                    Task[i].AATTargetLon,
                    Task[i + 1].AATTargetLat,
                    Task[i + 1].AATTargetLon,
                    NULL, &bearing);

            // draw nominal track line
            DrawDashLine(hdc, NIBLSCALE(1), // 091217
                    WayPointList[imin].Screen,
                    WayPointList[imax].Screen,
                    taskcolor, rc);
        } else {
            sct1 = WayPointList[imin].Screen;
            sct2 = WayPointList[imax].Screen;
        }

        if ((i >= ActiveWayPoint && DoOptimizeRoute()) || !DoOptimizeRoute()) {
            POINT ClipPt1 = sct1, ClipPt2 = sct2;
            if(LKGeom::ClipLine((POINT) {rc.left, rc.top}, (POINT) {rc.right, rc.bottom}, ClipPt1, ClipPt2)) {
                DrawMulticolorDashLine(hdc, size_tasklines,
                        sct1,
                        sct2,
                        taskcolor, RGB_BLACK,rc);
                
                // draw small arrow along task direction
                POINT p_p;
                POINT Arrow[2] = {
                    {6, 6},
                    {-6, 6}
                };
                ScreenClosestPoint(sct1, sct2,
                        Orig_Aircraft, &p_p, NIBLSCALE(25));
                threadsafePolygonRotateShift(Arrow, 2, p_p.x, p_p.y, bearing - DisplayAngle);

                _DrawLine(hdc, PS_SOLID, size_tasklines-NIBLSCALE(1), Arrow[0], p_p, taskcolor, rc);
                _DrawLine(hdc, PS_SOLID, size_tasklines-NIBLSCALE(1), Arrow[1], p_p, taskcolor, rc);
            }
        }
    }
    
    // Draw DashLine From current position to Active TurnPoint center
    if(ValidTaskPoint(ActiveWayPoint)) {
        POINT ptStart;
        LatLon2Screen(DrawInfo.Longitude, DrawInfo.Latitude, ptStart);
        DrawDashLine(hdc, NIBLSCALE(1),
                    ptStart,
                    WayPointList[Task[ActiveWayPoint].Index].Screen,
                    taskcolor, rc);

    }

    {
        UnlockTaskData();
    }

    // restore original color
    SetTextColor(hDCTemp, origcolor);
    SelectObject(hdc, oldpen);
    SelectObject(hdc, oldbrush);
}
Example #19
0
rectObj MapWindow::CalculateScreenBounds(double scale, const RECT& rc) {
    // compute lat lon extents of visible screen
    rectObj sb;

    if (scale>= 1.0) {
        POINT screen_center;
        LatLon2Screen(PanLongitude,
                      PanLatitude,
                      screen_center);

        sb.minx = sb.maxx = PanLongitude;
        sb.miny = sb.maxy = PanLatitude;

        unsigned int dx, dy;
        unsigned int maxsc=0;
        dx = screen_center.x-rc.right;
        dy = screen_center.y-rc.top;
        maxsc = max(maxsc, dx*dx+dy*dy);
        dx = screen_center.x-rc.left;
        dy = screen_center.y-rc.top;
        maxsc = max(maxsc, dx*dx+dy*dy);
        dx = screen_center.x-rc.left;
        dy = screen_center.y-rc.bottom;
        maxsc = max(maxsc, dx*dx+dy*dy);
        dx = screen_center.x-rc.right;
        dy = screen_center.y-rc.bottom;
        maxsc = max(maxsc, dx*dx+dy*dy);
        maxsc = isqrt4(maxsc);

        for (int i=0; i<10; i++) {
            double ang = i*360.0/10;
            POINT p;
            double X, Y;
            p.x = screen_center.x + iround(fastcosine(ang)*maxsc*scale);
            p.y = screen_center.y + iround(fastsine(ang)*maxsc*scale);
            Screen2LatLon(p.x, p.y, X, Y);
            sb.minx = min(X, sb.minx);
            sb.miny = min(Y, sb.miny);
            sb.maxx = max(X, sb.maxx);
            sb.maxy = max(Y, sb.maxy);
        }

    } else {

        double xmin, xmax, ymin, ymax;
        int x, y;
        double X, Y;

        x = rc.left;
        y = rc.top;
        Screen2LatLon(x, y, X, Y);
        xmin = X;
        xmax = X;
        ymin = Y;
        ymax = Y;

        x = rc.right;
        y = rc.top;
        Screen2LatLon(x, y, X, Y);
        xmin = min(xmin, X);
        xmax = max(xmax, X);
        ymin = min(ymin, Y);
        ymax = max(ymax, Y);

        x = rc.right;
        y = rc.bottom;
        Screen2LatLon(x, y, X, Y);
        xmin = min(xmin, X);
        xmax = max(xmax, X);
        ymin = min(ymin, Y);
        ymax = max(ymax, Y);

        x = rc.left;
        y = rc.bottom;
        Screen2LatLon(x, y, X, Y);
        xmin = min(xmin, X);
        xmax = max(xmax, X);
        ymin = min(ymin, Y);
        ymax = max(ymax, Y);


        sb.minx = xmin;
        sb.maxx = xmax;
        sb.miny = ymin;
        sb.maxy = ymax;

    }

    return sb;
}
Example #20
0
bool DoTarget(NMEA_INFO *Basic, DERIVED_INFO *Calculated)
{
   double x0, y0, etas, ttgo=0;
   double bearing, distance;

   if (LKTargetIndex<0 || LKTargetIndex>=MAXTRAFFIC) return false;

   // DoTarget is called from MapWindow, in real time. We have enough CPU power there now

   #if 0
   if (  LastDoTarget > Basic->Time ) LastDoTarget=Basic->Time;
   // We calculate in real time, because PFLAA sentences are calculated too in real time
   if ( Basic->Time < (LastDoTarget+3.0) ) { 
	return false;
   }
   LastDoTarget=Basic->Time;
   #endif

   #ifdef DEBUG_LKT
   StartupStore(_T("... DoTarget Copy LKTraffic\n"));
   #endif
   //LockFlightData();
   memcpy(LKTraffic, Basic->FLARM_Traffic, sizeof(LKTraffic));
   //UnlockFlightData();

   if (LKTARG.ID <=0) return false;

   DistanceBearing(Basic->Latitude, Basic->Longitude, 
		LKTARG.Latitude, LKTARG.Longitude,
		&distance, &bearing);
   LKTARG.Distance=distance;
   LKTARG.Bearing=bearing;

   if (LKTARG.Speed>1) {
	x0 = fastsine(LKTARG.TrackBearing)*LKTARG.Speed;
	y0 = fastcosine(LKTARG.TrackBearing)*LKTARG.Speed;
	x0 += fastsine(Calculated->WindBearing)*Calculated->WindSpeed;
	y0 += fastcosine(Calculated->WindBearing)*Calculated->WindSpeed;
	// LKTARG.Heading = AngleLimit360(atan2(x0,y0)*RAD_TLK_DEG); // 101210 check
	etas = isqrt4((unsigned long)(x0*x0*100+y0*y0*100))/10.0;
	LKASSERT(AirDensityRatio(LKTARG.Altitude)!=0);
	LKTARG.EIAS = etas/AirDensityRatio(LKTARG.Altitude);
   } else {
	LKTARG.EIAS=0;
   }


   //double height_above_target = Calculated->NavAltitude - LKTARG.Altitude;

   // We DONT use EnergyHeight here because we are not considering the Target's TE either
   LKTARG.AltArriv = Calculated->NavAltitude - GlidePolar::MacCreadyAltitude(MACCREADY,
	distance,
	bearing,
	Calculated->WindSpeed, Calculated->WindBearing,
	0, 0,
	// final glide, use wind
	true, 
	&ttgo) - LKTARG.Altitude;
	
   // We CANNOT use RelativeAltitude because when ghost or zombie, it wont be updated in real time in respect
   // to OUR real position!! Lets use the last target altitude known.
   double relalt=Calculated->NavAltitude - LKTARG.Altitude;
   if (relalt==0)
	LKTARG.GR=999;
   else {
	// we need thus to invert the relative altitude
	LKTARG.GR=distance/(relalt);
   }


   return true;
}