Ejemplo n.º 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;
}
Ejemplo n.º 2
0
// HeadWind error will be shown as -999
// These values are all in m/s
// We can have a serious problem when the headwind is so strong that the
// aircraft is actually flying backwards. 
// In such case, the heading will show correctly and the pilot should see
// that there is a problem.
//
// A positive value indicates a headwind, and a negative value indicates a tailwind.
//
void CalculateHeadWind(NMEA_INFO *Basic, DERIVED_INFO *Calculated) {

  static double CrossBearingLast= -1.0;
  static double WindSpeedLast= -1.0;

  if (Basic->NAVWarning) {
	Calculated->HeadWind  = -999;
	return;
  }

  double CrossBearing;
  CrossBearing = AngleLimit360(Calculated->Heading - Calculated->WindBearing);

  #if 1 // vector wind
  if ((CrossBearing != CrossBearingLast)||(Calculated->WindSpeed != WindSpeedLast)) {
	Calculated->HeadWind = Calculated->WindSpeed * fastcosine(CrossBearing);
	// CrossWind = WindSpeed * fastsine(CrossBearing);  UNUSED
	CrossBearingLast = CrossBearing;
	WindSpeedLast = Calculated->WindSpeed;
  }
  #else
  if (Basic->AirspeedAvailable) {
	Calculated->HeadWind = Basic->TrueAirspeed - Basic->Speed;
  } else {
	// for estimated IAS, this is also vector wind
	Calculated->HeadWind = Calculated->TrueAirspeedEstimated - Basic->Speed;
  }
  #endif
  //StartupStore(_T("..... CrossBearing=%f  hdwind=%f windspeed=%f\n"),CrossBearing,Calculated->HeadWind, Calculated->WindSpeed);

}
Ejemplo n.º 3
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;

}
Ejemplo n.º 4
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;
		}
	}
  }
}
Ejemplo n.º 5
0
//
// Since many functions call LatLon2screen, and only a few need multimap checks for display angle,
// we separate functions to avoid slow downs. First used by CalculateScreenPositionsGroundline
//
void MapWindow::LatLon2ScreenMultimap(pointObj *ptin, POINT *ptout, const int n, const int skip) {
  static double lastangle = -1;
  static int cost=1024, sint=0;

  LKASSERT(Current_Multimap_TopZoom!=0);

  const double mDisplayAngle = Current_Multimap_TopAngle;
  if(mDisplayAngle != lastangle) {
	lastangle = mDisplayAngle;
	int deg = DEG_TO_INT(AngleLimit360(mDisplayAngle));
	cost = ICOSTABLE[deg];
	sint = ISINETABLE[deg];
  }

  const int xxs = Current_Multimap_TopOrig.x*1024-512;
  const int yys = Current_Multimap_TopOrig.y*1024+512;
  const double mDrawScale = Current_Multimap_TopZoom;
  const double mPanLongitude = PanLongitude;
  const double mPanLatitude = PanLatitude;
  pointObj* p = ptin;
  const pointObj* ptend = ptin+n;

  while (p<ptend) {
    int Y = Real2Int((mPanLatitude-p->y)/mDrawScale);
    int X = Real2Int((mPanLongitude-p->x)*fastcosine(p->y)/mDrawScale);
    ptout->x = (xxs-X*cost + Y*sint)/1024;
    ptout->y = (Y*cost + X*sint + yys)/1024;
    ptout++;
    p+= skip;
  }
}
Ejemplo n.º 6
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;

}
Ejemplo n.º 7
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;
}
Ejemplo n.º 8
0
void MapWindow::LatLon2Screen(const double &lon, const double &lat, POINT &sc) {
  int Y = Real2Int((PanLatitude-lat)*zoom.DrawScale());
  int X = Real2Int((PanLongitude-lon)*fastcosine(lat)*zoom.DrawScale());
    
  irotate(X, Y, DisplayAngle);
    
  sc.x = Orig_Screen.x - X;
  sc.y = Orig_Screen.y + Y;
}
Ejemplo n.º 9
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);
        }
    }
}
Ejemplo n.º 10
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;
}
Ejemplo n.º 11
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;
}
Ejemplo n.º 12
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;
}
Ejemplo n.º 13
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;
}
Ejemplo n.º 14
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);

}
Ejemplo n.º 15
0
void Statistics::RenderTask(LKSurface& Surface, const RECT& rc, const bool olcmode)
{
  int i, j;
  unsigned int ui;
double fXY_Scale = 1.5;
  double lat1 = 0;
  double lon1 = 0;
  double lat2 = 0;
  double lon2 = 0;
  double x1, y1, x2=0, y2=0;
  double lat_c, lon_c;
  double aatradius[MAXTASKPOINTS];

  // find center
  ResetScale();

  if ( (!ValidTaskPoint(0) || !ValidTaskPoint(1)) && !olcmode)
  {
	DrawNoData(Surface,rc);
	return;
  }

  for (i=0; i<MAXTASKPOINTS; i++)
  {
    aatradius[i]=0;
  }
  bool nowaypoints = true;

  for (i=0; i<MAXTASKPOINTS; i++)
  {
    if (ValidTaskPoint(i))
    {
      lat1 = WayPointList[Task[i].Index].Latitude;
      lon1 = WayPointList[Task[i].Index].Longitude;
      ScaleYFromValue(rc, lat1);
      ScaleXFromValue(rc, lon1);
      nowaypoints = false;
    }
  }

  if (nowaypoints )
  {
    DrawNoData(Surface, rc);
    return;
  }

  CPointGPSArray trace;
  CContestMgr::Instance().Trace(trace);
  for(ui=0; ui<trace.size(); ui++)
  {
    lat1 = trace[ui].Latitude();
    lon1 = trace[ui].Longitude();
    ScaleYFromValue(rc, lat1);
    ScaleXFromValue(rc, lon1);
  }
  const auto hfOldU = Surface.SelectObject(LK8InfoNormalFont);

  lat_c = (y_max+y_min)/2;
  lon_c = (x_max+x_min)/2;

  int nwps = 0;

  // find scale
  ResetScale();

  lat1 = GPS_INFO.Latitude;
  lon1 = GPS_INFO.Longitude;
  x1 = (lon1-lon_c)*fastcosine(lat1);
  y1 = (lat1-lat_c);
  ScaleXFromValue(rc, x1*fXY_Scale);
  ScaleYFromValue(rc, y1*fXY_Scale);



  for (i=0; i<MAXTASKPOINTS; i++)
  {
    if (ValidTaskPoint(i))
    {
      nwps++;
      lat1 = WayPointList[Task[i].Index].Latitude;
      lon1 = WayPointList[Task[i].Index].Longitude;
      x1 = (lon1-lon_c)*fastcosine(lat1);
      y1 = (lat1-lat_c);
      ScaleXFromValue(rc, x1*fXY_Scale);
      ScaleYFromValue(rc, y1*fXY_Scale);

      if (AATEnabled)
      {
	    double aatlat;
	    double aatlon;
	    double bearing;
	    double radius;

        if (ValidTaskPoint(i+1))
        {
          if (Task[i].AATType == SECTOR)
            radius = Task[i].AATSectorRadius;
          else
            radius = Task[i].AATCircleRadius;

          for (j=0; j<4; j++)
          {
            bearing = j*360.0/4;
            FindLatitudeLongitude(WayPointList[Task[i].Index].Latitude, WayPointList[Task[i].Index].Longitude, bearing, radius,  &aatlat, &aatlon);
            x1 = (aatlon-lon_c)*fastcosine(aatlat);
            y1 = (aatlat-lat_c);
            ScaleXFromValue(rc, x1);
            ScaleYFromValue(rc, y1);
            if (j==0)
            {
              aatradius[i] = fabs(aatlat-WayPointList[Task[i].Index].Latitude);
            }
          }
        }
        else
        {
          aatradius[i] = 0;
        }
      }
    }
  }


  for(ui=0; ui<trace.size(); ui++)
  {
    lat1 = trace[ui].Latitude();
    lon1 = trace[ui].Longitude();
    x1 = (lon1-lon_c)*fastcosine(lat1);
    y1 = (lat1-lat_c);
    ScaleXFromValue(rc, x1*fXY_Scale);
    ScaleYFromValue(rc, y1*fXY_Scale);
  }

  ScaleMakeSquare(rc);


  // draw aat areas
    if (AATEnabled)
    {
      for (i=MAXTASKPOINTS-1; i>0; i--)
      {
	    if (ValidTaskPoint(i))
	    {
		  lat1 = WayPointList[Task[i-1].Index].Latitude;
		  lon1 = WayPointList[Task[i-1].Index].Longitude;
		  lat2 = WayPointList[Task[i].Index].Latitude;
		  lon2 = WayPointList[Task[i].Index].Longitude;
		  x1 = (lon1-lon_c)*fastcosine(lat1);
		  y1 = (lat1-lat_c);
		  x2 = (lon2-lon_c)*fastcosine(lat2);
		  y2 = (lat2-lat_c);

#ifdef HAVE_HATCHED_BRUSH 
		  Surface.SelectObject(MapWindow::GetAirspaceBrushByClass(AATASK));
#else
                  Surface.SelectObject(LKBrush_Yellow);
#endif
		  Surface.SelectObject(LK_WHITE_PEN);
		  if (Task[i].AATType == SECTOR)
		  {
			Surface.Segment((long)((x2-x_min)*xscale+rc.left+BORDER_X),(long)((y_max-y2)*yscale+rc.top),(long)(aatradius[i]*yscale),rc,	Task[i].AATStartRadial,	Task[i].AATFinishRadial);
		  }
		  else
		  {
	        Surface.DrawCircle((long)((x2-x_min)*xscale+rc.left+BORDER_X), (long)((y_max-y2)*yscale+rc.top),  (long)(aatradius[i]*yscale), true);
	      }
        }
      }
    }

  if (!AATEnabled)
  {
	for (i=MAXTASKPOINTS-1; i>0; i--)
	{
	  if (ValidTaskPoint(i) && ValidTaskPoint(i-1))
	  {
		lat1 = WayPointList[Task[i-1].Index].Latitude;
		lon1 = WayPointList[Task[i-1].Index].Longitude;
		if (!ValidTaskPoint(1) ) {
		  lat2 = GPS_INFO.Latitude;
		  lon2 = GPS_INFO.Longitude;
		}
		else
		{
		  lat2 = WayPointList[Task[i].Index].Latitude;
		  lon2 = WayPointList[Task[i].Index].Longitude;
		}
		x1 = (lon1-lon_c)*fastcosine(lat1);
		y1 = (lat1-lat_c);
		x2 = (lon2-lon_c)*fastcosine(lat2);
		y2 = (lat2-lat_c);

	//	DrawLine(hdc, rc, x1, y1, x2, y2, STYLE_DASHGREEN);
		if( ValidTaskPoint(4) && i <2)
			goto skip_FAI;
#ifndef UNDITHER
		RenderFAISector ( Surface, rc, lat1, lon1, lat2, lon2, lat_c, lon_c,1, RGB_LIGHTYELLOW );
	    RenderFAISector ( Surface, rc, lat1, lon1, lat2, lon2, lat_c, lon_c,0, RGB_LIGHTCYAN   );
#else
		RenderFAISector ( Surface, rc, lat1, lon1, lat2, lon2, lat_c, lon_c,1, RGB_LIGHTGREY );
	    RenderFAISector ( Surface, rc, lat1, lon1, lat2, lon2, lat_c, lon_c,0, RGB_GREY   );
#endif
	    skip_FAI:
		DrawLine(Surface, rc, x1, y1, x2, y2, STYLE_DASHGREEN);
		Surface.Segment((long)((x2-x_min)*xscale+rc.left+BORDER_X),(long)((y_max-y2)*yscale+rc.top),(long)(aatradius[i]*yscale),rc,	Task[i].AATStartRadial,	Task[i].AATFinishRadial);
	  }
	}

	if(	 ValidTaskPoint(1) && ValidTaskPoint(3))
	{
	  lat1 = WayPointList[Task[3].Index].Latitude;
	  lon1 = WayPointList[Task[3].Index].Longitude;
	  lat2 = WayPointList[Task[1].Index].Latitude;
	  lon2 = WayPointList[Task[1].Index].Longitude;
          #ifndef UNDITHER
	  RenderFAISector ( Surface, rc, lat1, lon1, lat2, lon2, lat_c, lon_c,1, RGB_LIGHTYELLOW );
	  RenderFAISector ( Surface, rc, lat1, lon1, lat2, lon2, lat_c, lon_c,0, RGB_LIGHTCYAN   );
          #else
	  RenderFAISector ( Surface, rc, lat1, lon1, lat2, lon2, lat_c, lon_c,1, RGB_LIGHTGREY );
	  RenderFAISector ( Surface, rc, lat1, lon1, lat2, lon2, lat_c, lon_c,0, RGB_GREY   );
          #endif
	}
  }
	// draw task lines and label
	for (i=MAXTASKPOINTS-1; i>0; i--)
	{
	  if (ValidTaskPoint(i) && ValidTaskPoint(i-1))
	  {
		lat1 = WayPointList[Task[i-1].Index].Latitude;
		lon1 = WayPointList[Task[i-1].Index].Longitude;
		if (!ValidTaskPoint(1) ) {
		  lat2 = GPS_INFO.Latitude;
		  lon2 = GPS_INFO.Longitude;
		}
		else
		{
		  lat2 = WayPointList[Task[i].Index].Latitude;
		  lon2 = WayPointList[Task[i].Index].Longitude;
		}
		x1 = (lon1-lon_c)*fastcosine(lat1);
		y1 = (lat1-lat_c);
		x2 = (lon2-lon_c)*fastcosine(lat2);
		y2 = (lat2-lat_c);

		DrawLine(Surface, rc, x1, y1, x2, y2, STYLE_BLUETHIN);
                #if (WINDOWSPC>0)
	    Surface.SetBackgroundOpaque();
                #endif
		TCHAR text[100];
		 Surface.SetTextColor(RGB_BLUE);
/*
		if ((i==nwps-1) && (Task[i].Index == Task[0].Index))
		{
		  _stprintf(text,TEXT("%0d"),1);
		  DrawLabel(hdc, rc, text, x1+(x2-x1)/2, y1+(y2-y1)/2);
		}
		else */
		{
		  _stprintf(text,TEXT("%0d"),i);
		  DrawLabel(Surface, rc, text, x1+(x2-x1)/2, y1+(y2-y1)/2);
		}

		if ((i==ActiveTaskPoint)&&(!AATEnabled))
		{
		  lat1 = GPS_INFO.Latitude;
		  lon1 = GPS_INFO.Longitude;
		  x1 = (lon1-lon_c)*fastcosine(lat1);
		  y1 = (lat1-lat_c);
		  DrawLine(Surface, rc, x1, y1, x2, y2,  STYLE_REDTHICK);
		}
	  }
	}
	
	// draw aat task line
	
	if (AATEnabled)
	{
	  for (i=MAXTASKPOINTS-1; i>0; i--)
	  {
		if (ValidTaskPoint(i) && ValidTaskPoint(i-1))
		{
		  if (i==1)
		  {
			lat1 = WayPointList[Task[i-1].Index].Latitude;
			lon1 = WayPointList[Task[i-1].Index].Longitude;
		  }
		  else
		  {
			lat1 = Task[i-1].AATTargetLat;
			lon1 = Task[i-1].AATTargetLon;
		  }
		  lat2 = Task[i].AATTargetLat;
		  lon2 = Task[i].AATTargetLon;
	
		  x1 = (lon1-lon_c)*fastcosine(lat1);
		  y1 = (lat1-lat_c);
		  x2 = (lon2-lon_c)*fastcosine(lat2);
		  y2 = (lat2-lat_c);

		  DrawLine(Surface, rc,   x1, y1, x2, y2,  STYLE_REDTHICK);
		}
	  }
	}

	  DrawXGrid(Surface, rc, 1.0, 0, STYLE_THINDASHPAPER, 1.0, false);
	  DrawYGrid(Surface, rc, 1.0, 0, STYLE_THINDASHPAPER, 1.0, false);


  Surface.SelectObject(hfOldU);
  // Draw aircraft on top
  lat1 = GPS_INFO.Latitude;
  lon1 = GPS_INFO.Longitude;
  x1 = (lon1-lon_c)*fastcosine(lat1);
  y1 = (lat1-lat_c);
  Surface.SetBackgroundTransparent();
  DrawLabel(Surface, rc, TEXT("+"), x1, y1);
}
Ejemplo n.º 16
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);
}
Ejemplo n.º 17
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;
}
Ejemplo n.º 18
0
int RenderFAISector (LKSurface& Surface, const RECT& rc , double lat1, double lon1, double lat2, double lon2, int iOpposite , const LKColor& fillcolor)
{

POINT Pt1;
float fFAI_Percentage = FAI_NORMAL_PERCENTAGE;
double fDist_a, fDist_b, fDist_c, fAngle;
int i;

int iPolyPtr=0;
double lat_d,lon_d;
double alpha, fDistTri, cos_alpha=0;
POINT apSectorPolygon[MAX_FAI_SECTOR_PTS+1];
DistanceBearing(lat1, lon1, lat2, lon2, &fDist_c, &fAngle);

if(fabs(fDist_c) < 1000.0)  /* distance too short for a FAI sector */
	return -1;


double fDistMax = fDist_c/FAI_NORMAL_PERCENTAGE;
double fDistMin = fDist_c/(1.0-2.0*FAI28_45Threshold);
double fDelta_Dist = 2.0* fDist_c*fFAI_Percentage / (double)(FAI_SECTOR_STEPS-1);
double fA, fB;
double fMinLeg, fMaxLeg,fDiff=0;
double dir = -1.0;
BOOL bBigFAISector = false;

if(fDistMax > FAI28_45Threshold)
{
  bBigFAISector = true;
  fDistMax = fDist_c/FAI_BIG_PERCENTAGE;
}

if(fDistMin < FAI28_45Threshold)
{
  fDistMin = fDist_c/(1.0-2.0*FAI_NORMAL_PERCENTAGE);
}


if (iOpposite >0)
{
  dir = 1.0;
}

//#define  HELP_LINES
#ifdef HELP_LINES
  int x2,y2, style;
  FindLatitudeLongitude(lat1, lon1, AngleLimit360 (fAngle), fDist_c/2, &lat_d, &lon_d);
  x1 = (lon_d - lon_c)*fastcosine(lat_d);
  y1 = (lat_d - lat_c);
  FindLatitudeLongitude(lat_d, lon_d, AngleLimit360 (fAngle-90.0), fDist_c, &lat_d, &lon_d);
  x2 = (lon_d - lon_c)*fastcosine(lat_d);
  y2 = (lat_d - lat_c);
  Surface.DrawLine(rc, x1, y1, x2, y2, style);
#endif

  /********************************************************************
   * right below threshold 1
   ********************************************************************/
  fA = 	fDistMin;
  if(fDistMax > FAI28_45Threshold)
    fB = FAI28_45Threshold;
  else
	fB = fDistMax ;


  if(fA<fB)
  {
	fDelta_Dist =(fB-fA)/ (double)(FAI_SECTOR_STEPS-1);
	fDistTri = fA;
    for(i =0 ;i < FAI_SECTOR_STEPS; i++)
    {
	  fDist_a = FAI_NORMAL_PERCENTAGE * fDistTri;
	  fDist_b = fDistTri - fDist_a - fDist_c;

	  LKASSERT(fDist_c*fDist_b!=0);
	  cos_alpha = ( fDist_b*fDist_b + fDist_c*fDist_c - fDist_a*fDist_a )/(2.0*fDist_c*fDist_b);
	  alpha = acos(cos_alpha)*180/PI * dir;
	  FindLatitudeLongitude(lat1, lon1, AngleLimit360( fAngle + alpha ) , fDist_b, &lat_d, &lon_d);

	  MapWindow::LatLon2Screen(lon_d, lat_d,  Pt1);
	  LKASSERT(iPolyPtr < MAX_FAI_SECTOR_PTS);
	  apSectorPolygon[iPolyPtr++] = Pt1;


      fDistTri += fDelta_Dist;
    }
  }

  /********************************************************************
   * right  threshold extender 2
   ********************************************************************/
if(fDistMin < FAI28_45Threshold)
  if(bBigFAISector && (fDistMin < FAI28_45Threshold))
  {
	fMaxLeg = FAI28_45Threshold*FAI_BIG_MAX_PERCENTAGE;
	fMinLeg = FAI28_45Threshold*FAI_BIG_PERCENTAGE;
	fA = FAI28_45Threshold*FAI_NORMAL_PERCENTAGE;
	fB = FAI28_45Threshold-fMaxLeg-fDist_c;

	if(fB < fMinLeg)
	  fB = fMinLeg;

	fDist_a = fA;
	fDelta_Dist =  (fB-fA) / (double)(FAI_SECTOR_STEPS-1);
    for(i =0 ;i < FAI_SECTOR_STEPS; i++)
    {
	  fDist_b = FAI28_45Threshold - fDist_a - fDist_c;
  	  LKASSERT(fDist_c*fDist_b!=0);
	  cos_alpha = ( fDist_b*fDist_b + fDist_c*fDist_c - fDist_a*fDist_a )/(2.0*fDist_c*fDist_b);
	  alpha = acos(cos_alpha)*180/PI * dir;
	  FindLatitudeLongitude(lat1, lon1, AngleLimit360( fAngle + alpha ) , fDist_b, &lat_d, &lon_d);
	  MapWindow::LatLon2Screen(lon_d, lat_d,  Pt1);
	  LKASSERT(iPolyPtr < MAX_FAI_SECTOR_PTS);
	  apSectorPolygon[iPolyPtr++] = Pt1;

	  fDist_a += fDelta_Dist;
    }
  }
  /********************************************************************
   * right  above threshold  3
   ********************************************************************/
  if(bBigFAISector)
  {
    fA = 	FAI28_45Threshold;
    if(fDistMin > fA)
	  fA= fDistMin;
    fB =fDist_c/(1- FAI_BIG_PERCENTAGE-FAI_BIG_MAX_PERCENTAGE);

    if(fA < fB)
    {
      fDelta_Dist =(fB-fA)/ (double)(FAI_SECTOR_STEPS-1);
      fDistTri = fA;
      for(i =0 ;i < FAI_SECTOR_STEPS; i++)
      {
  	    fMaxLeg = fDistTri*FAI_BIG_MAX_PERCENTAGE;
	    fMinLeg = fDistTri*FAI_BIG_PERCENTAGE;
	    fDist_a = fDistTri-fMinLeg-fDist_c;;
	    fDist_b = fMinLeg;

	    if(fDist_a > fMaxLeg)
	    {
	      fDiff =  fDist_a - fMaxLeg;
	      fDist_b+=fDiff;
	      fDist_a-=fDiff;
	    }

	    LKASSERT(fDist_c*fDist_b!=0);
	    cos_alpha = ( fDist_a*fDist_a + fDist_c*fDist_c - fDist_b*fDist_b )/(2.0*fDist_c*fDist_a);
	    alpha = acos(cos_alpha)*180/PI * dir;
	    FindLatitudeLongitude(lat1, lon1, AngleLimit360( fAngle + alpha ) , fDist_a, &lat_d, &lon_d);
		MapWindow::LatLon2Screen(lon_d, lat_d,  Pt1);
		LKASSERT(iPolyPtr < MAX_FAI_SECTOR_PTS);
	    apSectorPolygon[iPolyPtr++] = Pt1;


	    fDistTri += fDelta_Dist;
      }
    }
  }
/********************************************************************
 * TOP limited round 4
 ********************************************************************/
  if(fDistMax <= FAI28_45Threshold)
	fDist_b = fDistMax*(1.0-2*FAI_NORMAL_PERCENTAGE);
  else
	fDist_b = fDistMax*FAI_BIG_MAX_PERCENTAGE;

  fDist_a = fDistMax-fDist_b-fDist_c;
  fDelta_Dist =  (fDist_a-fDist_b) / (double)(FAI_SECTOR_STEPS-1);
  for(i =0 ;i < FAI_SECTOR_STEPS; i++)
  {
	LKASSERT(fDist_c*fDist_b!=0);
	cos_alpha = ( fDist_b*fDist_b + fDist_c*fDist_c - fDist_a*fDist_a )/(2.0*fDist_c*fDist_b);
	alpha = acos(cos_alpha)*180/PI * dir;
	FindLatitudeLongitude(lat1, lon1, AngleLimit360( fAngle + alpha ) , fDist_b, &lat_d, &lon_d);

	MapWindow::LatLon2Screen(lon_d, lat_d,  Pt1);
	LKASSERT(iPolyPtr < MAX_FAI_SECTOR_PTS);
    apSectorPolygon[iPolyPtr++] = Pt1;


    fDist_a -= fDelta_Dist;
    fDist_b += fDelta_Dist;
  }

/********************************************************************
 * calc left leg
 ********************************************************************/

/********************************************************************
 * LEFT above threshold 5
 ********************************************************************/
  if(bBigFAISector)
  {
    fB = FAI28_45Threshold;
    if( fB < fDistMin)
	  fB = fDistMin;

    fA =fDist_c/(1- FAI_BIG_PERCENTAGE-FAI_BIG_MAX_PERCENTAGE);

    if(fA >= fB)
    {
      fDelta_Dist =(fA-fB)/ (double)(FAI_SECTOR_STEPS-1);
      fDistTri = fA;
      for(i =0 ;i < FAI_SECTOR_STEPS; i++)
      {
	    fMaxLeg = fDistTri*FAI_BIG_MAX_PERCENTAGE;
	    fMinLeg = fDistTri*FAI_BIG_PERCENTAGE;
	    fDist_a = fDistTri-fMinLeg-fDist_c;
	    fDist_b = fMinLeg;

	    if(fDist_a > fMaxLeg)
	    {
	      fDiff =  fDist_a - fMaxLeg;
	      fDist_b+=fDiff;
	      fDist_a-=fDiff;
  	    }

	    LKASSERT(fDist_c*fDist_b!=0);
	    cos_alpha = ( fDist_b*fDist_b + fDist_c*fDist_c - fDist_a*fDist_a )/(2.0*fDist_c*fDist_b);
	    alpha = acos(cos_alpha)*180/PI * dir;
	    FindLatitudeLongitude(lat1, lon1, AngleLimit360( fAngle + alpha ) , fDist_b, &lat_d, &lon_d);
		MapWindow::LatLon2Screen(lon_d, lat_d,  Pt1);
		LKASSERT(iPolyPtr < MAX_FAI_SECTOR_PTS);
	    apSectorPolygon[iPolyPtr++] = Pt1;


	    fDistTri -= fDelta_Dist;
     }
    }
  }

  /********************************************************************
   * LEFT threshold extender 6
   ********************************************************************/
if(fDistMin < FAI28_45Threshold)
  if((fDistMin < FAI28_45Threshold) && (FAI28_45Threshold < fDistMax))
  {
	fMaxLeg = FAI28_45Threshold*FAI_BIG_MAX_PERCENTAGE;
	fMinLeg = FAI28_45Threshold*FAI_BIG_PERCENTAGE;
	fA = FAI28_45Threshold*FAI_NORMAL_PERCENTAGE;
	fB = FAI28_45Threshold-fMaxLeg-fDist_c;

	if(fB < fMinLeg)
	  fB = fMinLeg;

	fDist_b = fB;
	fDelta_Dist =  (fA-fB) / (double)(FAI_SECTOR_STEPS-1);

    for(i =0 ;i < FAI_SECTOR_STEPS; i++)
    {
	  fDist_a = FAI28_45Threshold - fDist_b - fDist_c;
	  LKASSERT(fDist_c*fDist_b!=0);
	  cos_alpha = ( fDist_b*fDist_b + fDist_c*fDist_c - fDist_a*fDist_a )/(2.0*fDist_c*fDist_b);
	  alpha = acos(cos_alpha)*180/PI * dir;
	  FindLatitudeLongitude(lat1, lon1, AngleLimit360( fAngle + alpha ) , fDist_b, &lat_d, &lon_d);
	  MapWindow::LatLon2Screen(lon_d, lat_d,  Pt1);
	  LKASSERT(iPolyPtr < MAX_FAI_SECTOR_PTS);
	  apSectorPolygon[iPolyPtr++] = Pt1;

	  fDist_b += fDelta_Dist;
    }
  }


  /********************************************************************
   * LEFT below threshold 7
   ********************************************************************/
  fA = 	fDistMin;
  if(fDistMax > FAI28_45Threshold)
    fB = FAI28_45Threshold;
  else
	fB = fDistMax ;

  if(fA<fB)
  {
	fDelta_Dist =(fB-fA)/ (double)(FAI_SECTOR_STEPS-1);
	fDistTri = fB;
    for(i =0 ;i < FAI_SECTOR_STEPS; i++)
    {
	  fDist_b = FAI_NORMAL_PERCENTAGE * fDistTri;
	  fDist_a = fDistTri - fDist_b - fDist_c;

	  LKASSERT(fDist_c*fDist_b!=0);
	  cos_alpha = ( fDist_b*fDist_b + fDist_c*fDist_c - fDist_a*fDist_a )/(2.0*fDist_c*fDist_b);
	  alpha = acos(cos_alpha)*180/PI * dir;
	  FindLatitudeLongitude(lat1, lon1, AngleLimit360( fAngle + alpha ) , fDist_b, &lat_d, &lon_d);
	  MapWindow::LatLon2Screen(lon_d, lat_d,  Pt1);
	  LKASSERT(iPolyPtr < MAX_FAI_SECTOR_PTS);
	  apSectorPolygon[iPolyPtr++] = Pt1;
      fDistTri -= fDelta_Dist;
    }
  }

  /********************************************************************
   * low open PEAK round 8
   ********************************************************************/
  if(fDistMin >FAI28_45Threshold)
  {
	fDist_b = fDistMin*FAI_BIG_PERCENTAGE;
	fDist_a = fDistMin-fDist_b-fDist_c;
	fDelta_Dist =  (fDist_b-fDist_a) / (double)(FAI_SECTOR_STEPS-1);

	for(i =0 ;i < FAI_SECTOR_STEPS; i++)
	{
		LKASSERT(fDist_c*fDist_b!=0);
		cos_alpha = ( fDist_b*fDist_b + fDist_c*fDist_c - fDist_a*fDist_a )/(2.0*fDist_c*fDist_b);
		alpha = acos(cos_alpha)*180/PI * dir;
		FindLatitudeLongitude(lat1, lon1, AngleLimit360( fAngle + alpha ) , fDist_b, &lat_d, &lon_d);
		MapWindow::LatLon2Screen(lon_d, lat_d,  Pt1);
		LKASSERT(iPolyPtr < MAX_FAI_SECTOR_PTS);
	    apSectorPolygon[iPolyPtr++] = Pt1;

	    fDist_a += fDelta_Dist;
	    fDist_b -= fDelta_Dist;
	}
  }

  /********************************************************************
   * draw polygon
   ********************************************************************/
  LKPen   hpSectorPen(PEN_SOLID, IBLSCALE(2),  fillcolor );

  LKPen hpOldPen = Surface.SelectObject(hpSectorPen);
  LKBrush hpOldBrush = Surface.SelectObject(LKBrush_Hollow);

  Surface.Polygon(apSectorPolygon,iPolyPtr,rc);

  Surface.SelectObject(hpOldPen);
  Surface.SelectObject(hpOldBrush);
  hpSectorPen.Release();

  /********************************************************************
   * calc round leg grid
   ********************************************************************/
  hpSectorPen.Create(PEN_SOLID, (1), RGB_BLACK );
  Surface.SelectObject(hpSectorPen);
  Surface.SetTextColor(RGB_BLACK);
  double fTic= 1/DISTANCEMODIFY;
  if(fDist_c > 5/DISTANCEMODIFY)   fTic = 10/DISTANCEMODIFY;
  if(fDist_c > 50/DISTANCEMODIFY)  fTic = 25/DISTANCEMODIFY;
  if(fDist_c > 100/DISTANCEMODIFY) fTic = 50/DISTANCEMODIFY;
//  if(fDist_c > 200/DISTANCEMODIFY) fTic = 100/DISTANCEMODIFY;
  if(fDist_c > 500/DISTANCEMODIFY) fTic = 250/DISTANCEMODIFY;
  POINT line[2];
  BOOL bFirstUnit = true;
  LKASSERT(fTic!=0);
  fDistTri = ((int)(fDistMin/fTic)+1) * fTic ;
  LKFont hfOld = Surface.SelectObject(LK8PanelUnitFont);

int iCnt = 0;

  while(fDistTri <= fDistMax)
  {
    TCHAR text[180]; SIZE tsize;
	if(bFirstUnit)
	  _stprintf(text, TEXT("%i%s"), (int)(fDistTri*DISTANCEMODIFY), Units::GetUnitName(Units::GetUserDistanceUnit()));
	else
	  _stprintf(text, TEXT("%i"), (int)(fDistTri*DISTANCEMODIFY));
	bFirstUnit = false;
	Surface.GetTextSize(text, _tcslen(text), &tsize);

    int j=0;

	if(fDistTri < FAI28_45Threshold)
	{
	  fDist_b = fDistTri*FAI_NORMAL_PERCENTAGE;
	  fDist_a = fDistTri-fDist_b-fDist_c;
	  fDelta_Dist =  (fDist_a-fDist_b) / (double)(FAI_SECTOR_STEPS-1);
	}
	else
	{
      fMaxLeg = fDistTri*FAI_BIG_MAX_PERCENTAGE;
      fMinLeg = fDistTri*FAI_BIG_PERCENTAGE;
	  fA = fMaxLeg;
	  fB = fDistTri-fA-fDist_c;
	  fDist_a = fA;
	  fDist_b = fB;
	  if(fB < fMinLeg)
	  {
		  fDiff = fMinLeg-fB;
		  fB+=2*fDiff;
		  fDist_b += fDiff;
		  fDist_a -= fDiff;
	  }
	  if(fB > fMaxLeg)
	  {
		  fDiff =  fB - fMaxLeg;
		  fB+=2*fDiff;
		  fDist_b-=fDiff;
		  fDist_a+=fDiff;
	  }
	  fFAI_Percentage =  FAI_BIG_PERCENTAGE;
	  fDelta_Dist =  (fA-fB) / (double)(FAI_SECTOR_STEPS-1);
	}


    for(i =0 ;i < FAI_SECTOR_STEPS; i++)
    {
	  LKASSERT(fDist_c*fDist_b!=0);
	  cos_alpha = ( fDist_b*fDist_b + fDist_c*fDist_c - fDist_a*fDist_a )/(2.0*fDist_c*fDist_b);
	  alpha = acos(cos_alpha)*180/PI * dir;
	  FindLatitudeLongitude(lat1, lon1, AngleLimit360( fAngle + alpha ) , fDist_b, &lat_d, &lon_d);
	  MapWindow::LatLon2Screen(lon_d, lat_d,  line[0]);

      if(j> 0)
      {
  		ForcedClipping=true;
  		Surface.DrawLine(PEN_DASH, NIBLSCALE(1), line[0] , line[1] , RGB_BLACK, rc);
  		ForcedClipping=false;
      }


      if(j==0)
      {
    	Surface.DrawText(line[0].x, line[0].y, text, _tcslen(text));
    	j=1;

      }

//      TCHAR text[180]; SIZE tsize;
      if(iCnt==0)
        _stprintf(text, TEXT("%i%s"), (int)(fDistTri*DISTANCEMODIFY), Units::GetUnitName(Units::GetUserDistanceUnit()));
      else
        _stprintf(text, TEXT("%i"), (int)(fDistTri*DISTANCEMODIFY));
      Surface.GetTextSize(text, _tcslen(text), &tsize);
      if(i == 0)
        Surface.DrawText(line[0].x, line[0].y, text, _tcslen(text));

      if(iCnt > 1)
  	    if(i == FAI_SECTOR_STEPS-1)
  	      Surface.DrawText(line[0].x, line[0].y, text, _tcslen(text));

      if(iCnt > 2)
  	    if((i== (FAI_SECTOR_STEPS/2)))
  	      Surface.DrawText(line[0].x, line[0].y, text, _tcslen(text));

      line[1] =  line[0];



	  fDist_a -= fDelta_Dist;
	  fDist_b += fDelta_Dist;
    }
    fDistTri+=fTic;iCnt++;
 //   if((iCnt %2) ==0)
  //    DrawText(hdc, line[0].x, line[0].y, ETO_OPAQUE, NULL, text, _tcslen(text), NULL);
  }

Surface.SelectObject(hfOld);
Surface.SelectObject(hpOldPen);

return 0;
}
Ejemplo n.º 19
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;
}
Ejemplo n.º 20
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
  }

}
Ejemplo n.º 21
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);
}
Ejemplo n.º 22
0
/*****************************************************************
 * Alpha Lima splitted RenderContest from Render Task for CC
 * adding FAI Sector display
 ****************************************************************/
void Statistics::RenderContest(LKSurface& Surface, const RECT& rc)
{
if(contestType == CContestMgr::TYPE_FAI_TRIANGLE)
   RenderFAIOptimizer(Surface, rc);
else
{
  unsigned int ui;
  double fXY_Scale = 1.0;


  double lat1 = 0;
  double lon1 = 0;
  double lat2 = 0;
  double lon2 = 0;
  double  x1, y1, x2=0, y2=0;
  double lat_c, lon_c;

  ResetScale();


  CContestMgr::CResult result = CContestMgr::Instance().Result(contestType, true);
  const CPointGPSArray &points = result.PointArray();


  // find center

  CPointGPSArray trace;
  CContestMgr::Instance().Trace(trace);
  for(ui=0; ui<trace.size(); ui++)
  {
    lat1 = trace[ui].Latitude();
    lon1 = trace[ui].Longitude();
    ScaleYFromValue(rc, lat1);
    ScaleXFromValue(rc, lon1);
  }

  const auto hfOldU = Surface.SelectObject(LK8PanelUnitFont);
  lat_c = (y_max+y_min)/2;
  lon_c = (x_max+x_min)/2;


  // find scale
  ResetScale();

  lat1 = GPS_INFO.Latitude;
  lon1 = GPS_INFO.Longitude;
  x1 = (lon1-lon_c)*fastcosine(lat1);
  y1 = (lat1-lat_c);
  ScaleXFromValue(rc, x1*fXY_Scale);
  ScaleYFromValue(rc, y1*fXY_Scale);
  for(ui=0; ui<trace.size(); ui++)
  {
    lat1 = trace[ui].Latitude();
    lon1 = trace[ui].Longitude();
    x1 = (lon1-lon_c)*fastcosine(lat1);
    y1 = (lat1-lat_c);
    ScaleXFromValue(rc, x1*fXY_Scale);
    ScaleYFromValue(rc, y1*fXY_Scale);
  }

  ScaleMakeSquare(rc);



  // draw track
  for(ui=0; trace.size() && ui<trace.size()-1; ui++)
  {
    lat1 = trace[ui].Latitude();
    lon1 = trace[ui].Longitude();
    lat2 = trace[ui+1].Latitude();
    lon2 = trace[ui+1].Longitude();
    x1 = (lon1-lon_c)*fastcosine(lat1);
    y1 = (lat1-lat_c);
    x2 = (lon2-lon_c)*fastcosine(lat2);
    y2 = (lat2-lat_c);
    DrawLine(Surface, rc,  x1, y1, x2, y2, STYLE_MEDIUMBLACK);
  }
  // Draw aircraft on top
double  lat_p = GPS_INFO.Latitude;
double  lon_p = GPS_INFO.Longitude;
double  xp = (lon_p-lon_c)*fastcosine(lat_p);
double  yp = (lat_p-lat_c);


  if(result.Type() == contestType)
  {
    for(ui=0; ui<points.size()-1; ui++)
    {
      lat1 = points[ui].Latitude();
      lon1 = points[ui].Longitude();
      lat2 = points[ui+1].Latitude();
      lon2 = points[ui+1].Longitude();

      x1 = (lon1-lon_c)*fastcosine(lat1);
      y1 = (lat1-lat_c);
      x2 = (lon2-lon_c)*fastcosine(lat2);
      y2 = (lat2-lat_c);
      int style = STYLE_REDTHICK;
      if((result.Type() == CContestMgr::TYPE_OLC_FAI ||
          result.Type() == CContestMgr::TYPE_OLC_FAI_PREDICTED) &&
         (ui==0 || ui==3))
      {
        // triangle start and finish
        style = STYLE_DASHGREEN;
      }
      else if(result.Predicted() &&
              (result.Type() == CContestMgr::TYPE_OLC_FAI_PREDICTED ||
               ui == points.size() - 2))
      {
        // predicted edge
        style = STYLE_BLUETHIN;
      }

      if((result.Type() == CContestMgr::TYPE_FAI_3_TPS) ||// TYPE_FAI_3_TPS_PREDICTED
       (result.Type() == CContestMgr::TYPE_FAI_3_TPS_PREDICTED) )
      {
      }

      if((contestType != CContestMgr::TYPE_FAI_TRIANGLE) )
        DrawLine(Surface, rc, x1, y1, x2, y2, style);
    }


  if(result.Type() == CContestMgr::TYPE_OLC_FAI ||
     result.Type() == CContestMgr::TYPE_OLC_FAI_PREDICTED)
  {
    // draw the last edge of a triangle
    lat1 = points[1].Latitude();
    lon1 = points[1].Longitude();
    lat2 = points[3].Latitude();
    lon2 = points[3].Longitude();
    x1 = (lon1-lon_c)*fastcosine(lat1);
    y1 = (lat1-lat_c);
    x2 = (lon2-lon_c)*fastcosine(lat2);
    y2 = (lat2-lat_c);

    DrawLine(Surface, rc, x1, y1, x2, y2, result.Predicted() ? STYLE_BLUETHIN : STYLE_REDTHICK);

  }

  DrawXGrid(Surface, rc, 1.0, 0, STYLE_THINDASHPAPER, 1.0, false);
  DrawYGrid(Surface, rc, 1.0, 0, STYLE_THINDASHPAPER, 1.0, false);

  Surface.SelectObject(hfOldU);
  #ifndef UNDITHER
  Surface.SetTextColor(RGB_MAGENTA);
  #else
  Surface.SetTextColor(RGB_BLACK);
  #endif
  Surface.SetBackgroundTransparent();
  DrawLabel(Surface, rc, TEXT("O"), xp, yp);
}
}
}
Ejemplo n.º 23
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;
}
Ejemplo n.º 24
0
/*****************************************************************
 * Alpha Lima splitted RenderContest from Render Task for CC
 * adding FAI Sector display
 ****************************************************************/
void Statistics::RenderFAIOptimizer(LKSurface& Surface, const RECT& rc)
{

unsigned int ui;
double fXY_Scale = 1.0;
double lat0 = 0;
double lon0 = 0;
double lat1 = 0;
double lon1 = 0;
double lat2 = 0;
double lon2 = 0;
double x0, y0, x1, y1, x2=0, y2=0;
double lat_c, lon_c;
double  lat_p = GPS_INFO.Latitude;
double  lon_p = GPS_INFO.Longitude;
BOOL bFlat = false;
#define DRAWPERCENT
#ifdef DRAWPERCENT
double fTotalPercent = 1.0;
#endif

ResetScale();


  CContestMgr::CResult result = CContestMgr::Instance().Result(contestType, true);
  const CPointGPSArray &points = result.PointArray();
  if(contestType == CContestMgr::TYPE_FAI_TRIANGLE)
     fXY_Scale = 1.5;

  // find center
  double fTotalDistance = result.Distance();
 if (fTotalDistance < 1) fTotalDistance =1;
  CPointGPSArray trace;
  CContestMgr::Instance().Trace(trace);
  for(ui=0; ui<trace.size(); ui++)
  {
    lat1 = trace[ui].Latitude();
    lon1 = trace[ui].Longitude();
    ScaleYFromValue(rc, lat1);
    ScaleXFromValue(rc, lon1);
  }


  const auto hfOldU = Surface.SelectObject(LK8PanelUnitFont);
  BOOL bFAITri =  CContestMgr::Instance().FAI();
  double fDist, fAngle;
  lat_c = (y_max+y_min)/2;
  lon_c = (x_max+x_min)/2;

  double  xp = (lon_p-lon_c)*fastcosine(lat_p);
  double  yp = (lat_p-lat_c);

  // find scale
  ResetScale();

  lat1 = GPS_INFO.Latitude;
  lon1 = GPS_INFO.Longitude;
  x1 = (lon1-lon_c)*fastcosine(lat1);
  y1 = (lat1-lat_c);
  ScaleXFromValue(rc, x1*fXY_Scale);
  ScaleYFromValue(rc, y1*fXY_Scale);
  for(ui=0; ui<trace.size(); ui++)
  {
    lat1 = trace[ui].Latitude();
    lon1 = trace[ui].Longitude();
    x1 = (lon1-lon_c)*fastcosine(lat1);
    y1 = (lat1-lat_c);
    ScaleXFromValue(rc, x1*fXY_Scale);
    ScaleYFromValue(rc, y1*fXY_Scale);
  }

  ScaleMakeSquare(rc);

  if(result.Type() == contestType)
  {
    for(ui=0; ui<points.size()-1; ui++)
    {
      lat1 = points[ui].Latitude();
      lon1 = points[ui].Longitude();
      lat2 = points[ui+1].Latitude();
      lon2 = points[ui+1].Longitude();

      x1 = (lon1-lon_c)*fastcosine(lat1);
      y1 = (lat1-lat_c);
      x2 = (lon2-lon_c)*fastcosine(lat2);
      y2 = (lat2-lat_c);
      DistanceBearing(lat1, lon1, lat2, lon2, &fDist, &fAngle);

      if( (ui <points.size()-2) && !bFlat && ((fDist / fTotalDistance ) > 0.05) )
      {
		if(fDist > 5000)
		{
                  #ifndef UNDITHER
		  LKColor rgbCol = RGB_BLUE;
		  switch(ui)
		  {
			case 0: rgbCol = RGB_LIGHTYELLOW; break;
			case 1: rgbCol = RGB_LIGHTCYAN  ; break;
			case 2: rgbCol = RGB_LIGHTGREEN ; break;
			default:
			break;
		  }
                  #else
                  LKColor rgbCol = RGB_DARKBLUE;
                  switch(ui)
                  {
                      case 0: rgbCol = RGB_LIGHTGREY; break;
                      case 1: rgbCol = RGB_GREY  ; break;
                      case 2: rgbCol = RGB_MIDDLEGREY ; break;
                      default:
                      break;
                  }
                  #endif
		  RenderFAISector ( Surface, rc, lat1, lon1, lat2, lon2, lat_c, lon_c,1, rgbCol );
		  RenderFAISector ( Surface, rc, lat1, lon1, lat2, lon2, lat_c, lon_c,0, rgbCol );
		}
      }
      if((fDist / fTotalDistance ) > 0.45) /* prevent drawing almost same sectors */
    	bFlat = true;
    }

    // draw track
    for(ui=0; trace.size() && ui<trace.size()-1; ui++)
    {
      lat1 = trace[ui].Latitude();
      lon1 = trace[ui].Longitude();
      lat2 = trace[ui+1].Latitude();
      lon2 = trace[ui+1].Longitude();
      x1 = (lon1-lon_c)*fastcosine(lat1);
      y1 = (lat1-lat_c);
      x2 = (lon2-lon_c)*fastcosine(lat2);
      y2 = (lat2-lat_c);
      DrawLine(Surface, rc,  x1, y1, x2, y2, STYLE_MEDIUMBLACK);
    }



	for(ui=0; ui<points.size()-1; ui++)
	{
	  lat1 = points[ui].Latitude();
	  lon1 = points[ui].Longitude();
	  lat2 = points[ui+1].Latitude();
	  lon2 = points[ui+1].Longitude();

	  x1 = (lon1-lon_c)*fastcosine(lat1);
	  y1 = (lat1-lat_c);
	  x2 = (lon2-lon_c)*fastcosine(lat2);
	  y2 = (lat2-lat_c);
	  int style = STYLE_REDTHICK;

	  if((ui > 0) && (ui < 3))
	  {
		style = STYLE_BLUETHIN;
		DistanceBearing(lat1, lon1, lat2, lon2, &fDist, &fAngle);
	#ifdef DRAWPERCENT

		if((result.Distance()> 5000) && bFAITri)
		{
		  TCHAR text[180];
		  SIZE tsize;
		  fTotalPercent -= fDist/result.Distance();
		  _stprintf(text, TEXT("%3.1f%%"), (fDist/result.Distance()*100.0));
		  Surface.GetTextSize(text, _tcslen(text), &tsize);
                  #ifndef UNDITHER
		  Surface.SetTextColor(RGB_BLUE);
                  #else
		  Surface.SetTextColor(RGB_BLACK);
                  #endif
	      Surface.DrawText(ScaleX(rc, x1 +( x2-x1)/2)-tsize.cx/2,   ScaleY(rc,y1 + (y2-y1)/2), text, _tcslen(text));
	    }
	#endif

	    DrawLine(Surface, rc, x1, y1, x2, y2, style);
	  }
	}

    if(bFAITri)
    {
	  if(points.size() >3)
	  {

        if(ISPARAGLIDER)
        {
		  lat0 = CContestMgr::Instance().GetBestNearClosingPoint().Latitude();
		  lon0 = CContestMgr::Instance().GetBestNearClosingPoint().Longitude();
		  lat1 = CContestMgr::Instance().GetBestClosingPoint().Latitude();
		  lon1 = CContestMgr::Instance().GetBestClosingPoint().Longitude();
		  x1 = (lon0-lon_c)*fastcosine(lat0);
		  y1 = (lat0-lat_c);
		  x2 = (lon1-lon_c)*fastcosine(lat1);
		  y2 = (lat1-lat_c);
		  DrawLine(Surface, rc, x1, y1, x2, y2, STYLE_ORANGETHIN ); //result.Predicted() ? STYLE_BLUETHIN : STYLE_REDTHICK);
        }

	    lat1 = points[1].Latitude();
	    lon1 = points[1].Longitude();
	    lat2 = points[3].Latitude();
	    lon2 = points[3].Longitude();
	    x1 = (lon1-lon_c)*fastcosine(lat1);
	    y1 = (lat1-lat_c);
	    x2 = (lon2-lon_c)*fastcosine(lat2);
	    y2 = (lat2-lat_c);

	    DrawLine(Surface, rc, x1, y1, x2, y2, STYLE_THINDASHPAPER ); //result.Predicted() ? STYLE_BLUETHIN : STYLE_REDTHICK);
#ifdef DRAWPERCENT
	    TCHAR text[180];
	    SIZE tsize;
	    _stprintf(text, TEXT("%3.1f%%"), (fTotalPercent*100.0));
	    Surface.GetTextSize(text, _tcslen(text), &tsize);
            #ifndef UNDITHER
	    Surface.SetTextColor(RGB_LIGHTBLUE);
            #else
	    Surface.SetTextColor(RGB_RED);
            #endif
	    Surface.DrawText(ScaleX(rc, x1 +( x2-x1)/2)-tsize.cx/2,   ScaleY(rc,y1 + (y2-y1)/2), text, _tcslen(text));
#endif

	    lat0 = CContestMgr::Instance().GetClosingPoint().Latitude();
	    lon0 = CContestMgr::Instance().GetClosingPoint().Longitude();
	    x0 = (lon0-lon_c)*fastcosine(lat0);
	    y0 = (lat0-lat_c);
	    DrawLine(Surface, rc, xp, yp, x0, y0, STYLE_REDTHICK);
	  }
    }
  }




DrawXGrid(Surface, rc, 1.0, 0, STYLE_THINDASHPAPER, 1.0, false);
DrawYGrid(Surface, rc, 1.0, 0, STYLE_THINDASHPAPER, 1.0, false);
Surface.SetBackgroundTransparent();
#ifndef UNDITHER
Surface.SetTextColor(RGB_MAGENTA);
#else
Surface.SetTextColor(RGB_BLACK);
#endif
DrawLabel(Surface, rc, TEXT("O"), xp, yp);
Surface.SelectObject(hfOldU);

}
Ejemplo n.º 25
0
void LatLon2Flat(const GEOPOINT &location, POINT &screen)
{
  screen.x = (location.Longitude*fastcosine(location.Latitude)*100);
  screen.y = (location.Latitude*100);
}
Ejemplo n.º 26
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);
  }
Ejemplo n.º 27
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);
}
Ejemplo n.º 28
0
void LatLon2Flat(double lon, double lat, int *scx, int *scy) {
  *scx = (int)(lon*fastcosine(lat)*100);
  *scy = (int)(lat*100);
}
Ejemplo n.º 29
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);
    }
}