예제 #1
0
파일: Util.cpp 프로젝트: CnZoom/XcSoarPull
bool
Segment(Canvas &canvas, int x, int y, unsigned radius,
        Angle start, Angle end, bool horizon)
{
  // dont draw if out of view
  if (!IsCircleVisible(canvas, x, y, radius))
    return false;

  const int istart = NATIVE_TO_INT(start.Native());
  const int iend = NATIVE_TO_INT(end.Native());

  unsigned npoly = 0;
  RasterPoint pt[67];

  // add center point
  if (!horizon) {
    pt[0].x = x;
    pt[0].y = y;
    npoly = 1;
  }

  segment_poly(pt, x, y, radius, istart, iend, npoly);

  assert(npoly <= ARRAY_SIZE(pt));
  if (npoly)
    canvas.DrawTriangleFan(pt, npoly);

  return true;
}
예제 #2
0
파일: Util.cpp 프로젝트: damianob/xcsoar
bool
KeyHole(Canvas &canvas, PixelScalar x, PixelScalar y, UPixelScalar radius,
        Angle start, Angle end, UPixelScalar inner_radius)
{
  // dont draw if out of view
  PixelRect rc, bounds;
  SetRect(&rc, 0, 0, canvas.get_width(), canvas.get_height());
  SetRect(&bounds, x - radius, y - radius, x + radius, y + radius);
  if (!IntersectRect(&bounds, &bounds, &rc))
    return false;

  const int istart = NATIVE_TO_INT(start.Native());
  const int iend = NATIVE_TO_INT(end.Native());

  int npoly = 0;
  RasterPoint pt[66*2];

  segment_poly(pt, x, y, radius, istart, iend, npoly);
  segment_poly(pt, x, y, inner_radius, iend, istart, npoly);

  assert(npoly <= 66*2);
  if (npoly)
    canvas.DrawPolygon(pt, npoly);

  return true;
}
예제 #3
0
파일: Util.cpp 프로젝트: damianob/xcsoar
bool
Segment(Canvas &canvas, PixelScalar x, PixelScalar y, UPixelScalar radius,
        Angle start, Angle end, bool horizon)
{
  // dont draw if out of view
  PixelRect rc, bounds;
  SetRect(&rc, 0, 0, canvas.get_width(), canvas.get_height());
  SetRect(&bounds, x - radius, y - radius, x + radius, y + radius);
  if (!IntersectRect(&bounds, &bounds, &rc))
    return false;

  const int istart = NATIVE_TO_INT(start.Native());
  const int iend = NATIVE_TO_INT(end.Native());

  int npoly = 0;
  RasterPoint pt[66];

  // add center point
  if (!horizon) {
    pt[0].x = x;
    pt[0].y = y;
    npoly = 1;
  }

  segment_poly(pt, x, y, radius, istart, iend, npoly);

  assert(npoly <= 66);
  if (npoly)
    canvas.DrawTriangleFan(pt, npoly);

  return true;
}
예제 #4
0
파일: GeoClip.cpp 프로젝트: damianob/xcsoar
gcc_const
static GeoPoint
clip_latitude(const GeoPoint origin, const GeoPoint pt, Angle at)
{
  Angle dx = pt.longitude - origin.longitude;
  Angle dy = pt.latitude - origin.latitude;

  Angle ey = at - origin.latitude;
  Angle ex = ey * (dx.Native() / dy.Native());

  return GeoPoint(origin.longitude + ex, at);
}
예제 #5
0
파일: GeoClip.cpp 프로젝트: damianob/xcsoar
gcc_const
static GeoPoint
clip_longitude(const GeoPoint origin, const GeoPoint pt, Angle at)
{
  Angle dx = pt.longitude - origin.longitude;
  Angle dy = pt.latitude - origin.latitude;

  Angle ex = at - origin.longitude;
  Angle ey = ex * (dy.Native() / dx.Native());

  return GeoPoint(at, origin.latitude + ey);
}
예제 #6
0
파일: Math.cpp 프로젝트: MindMil/XCSoar
gcc_pure
static GeoPoint
IntermediatePoint(const GeoPoint &loc1, const GeoPoint &loc2,
                  Angle dthis, Angle dtotal)
{
  assert(loc1.IsValid());
  assert(loc2.IsValid());

  if (loc1.longitude == loc2.longitude &&
      loc1.latitude == loc2.latitude)
    return loc1;

  if (!positive(dtotal.Native()))
    return loc1;

  assert(dthis <= dtotal && !negative(dthis.Native()));

  const fixed A = (dtotal - dthis).sin();
  const fixed B = dthis.sin();

  const auto sc1 = loc1.latitude.SinCos();
  const fixed sin_loc1_lat = sc1.first, cos_loc1_lat = sc1.second;

  const auto sc2 = loc2.latitude.SinCos();
  const fixed sin_loc2_lat = sc2.first, cos_loc2_lat = sc2.second;

  const auto sc3 = loc1.longitude.SinCos();
  const fixed sin_loc1_lon = sc3.first, cos_loc1_lon = sc3.second;

  const auto sc4 = loc2.longitude.SinCos();
  const fixed sin_loc2_lon = sc4.first, cos_loc2_lon = sc4.second;

  const fixed a_cos_loc1_lat = SmallMult(A, cos_loc1_lat);
  const fixed b_cos_loc2_lat = SmallMult(B, cos_loc2_lat);

  const fixed x = SmallMult(a_cos_loc1_lat, cos_loc1_lon)
    + SmallMult(b_cos_loc2_lat, cos_loc2_lon);
  const fixed y = SmallMult(a_cos_loc1_lat, sin_loc1_lon)
    + SmallMult(b_cos_loc2_lat, sin_loc2_lon);
  const fixed z = SmallMult(A, sin_loc1_lat) + SmallMult(B, sin_loc2_lat);

  GeoPoint loc3;
  loc3.latitude = Angle::FromXY(TinyHypot(x, y), z);
  loc3.longitude = Angle::FromXY(x, y);
  loc3.Normalize(); // ensure longitude is within -180:180

#ifdef INSTRUMENT_TASK
  count_distbearing++;
#endif

  return loc3;
}
예제 #7
0
파일: Canvas.cpp 프로젝트: Adrien81/XCSoar
gcc_const
static std::pair<unsigned,unsigned>
AngleToDonutVertices(Angle start, Angle end)
{
  static constexpr Angle epsilon = Angle::FullCircle()
    / int(GLDonutVertices::CIRCLE_SIZE * 4u);

  const Angle delta = end - start;

  if (fabs(delta.AsDelta().Native()) <= epsilon.Native())
    /* full circle */
    return std::make_pair(0u, unsigned(GLDonutVertices::MAX_ANGLE));

  const unsigned istart = AngleToDonutVertex(start);
  unsigned iend = AngleToDonutVertex(end);

  if (istart == iend && delta > epsilon) {
    if (end - start >= Angle::HalfCircle())
      /* nearly full circle, round down the end */
      iend = GLDonutVertices::PreviousAngle(iend);
    else
      /* slightly larger than epsilon: draw at least two indices */
      iend = GLDonutVertices::NextAngle(iend);
  }

  return std::make_pair(istart, iend);
}
예제 #8
0
void
DigitEntry::SetLongitude(Angle value)
{
  // TODO: support all CoordinateFormats

  value = value.AsBearing();

  assert(length == 9);
  assert(columns[0].type == Column::Type::EAST_WEST);
  assert(columns[1].type == Column::Type::DIGIT19);
  assert(columns[2].type == Column::Type::DIGIT);
  assert(columns[4].type == Column::Type::DIGIT6);
  assert(columns[5].type == Column::Type::DIGIT);
  assert(columns[7].type == Column::Type::DIGIT6);
  assert(columns[8].type == Column::Type::DIGIT);

  columns[0].value = negative(value.Native());

  const fixed degrees = fabs(value.Degrees());
  const unsigned i_degrees = std::min(unsigned(degrees), 180u);
  const unsigned full_seconds = unsigned(degrees * 3600u) % 3600u;
  const unsigned minutes = std::min(full_seconds / 60u, 59u);
  const unsigned seconds = full_seconds % 60u;

  columns[1].value = i_degrees / 10;
  columns[2].value = i_degrees % 10;

  columns[4].value = minutes / 10;
  columns[5].value = minutes % 10;

  columns[7].value = seconds / 10;
  columns[8].value = seconds % 10;

  Invalidate();
}
예제 #9
0
파일: Canvas.cpp 프로젝트: Adrien81/XCSoar
gcc_const
static unsigned
AngleToDonutVertex(Angle angle)
{
  return GLDonutVertices::ImportAngle(NATIVE_TO_INT(angle.Native())
                                      + ARRAY_SIZE(ISINETABLE) * 3u / 4u,
                                      ARRAY_SIZE(ISINETABLE));
}
예제 #10
0
파일: Util.cpp 프로젝트: nkgautam/XCSoar
bool
Annulus(Canvas &canvas, PixelPoint center, unsigned radius,
        Angle start, Angle end, unsigned inner_radius)
{
  // dont draw if out of view
  if (!IsCircleVisible(canvas, center, radius))
    return false;

  const int istart = NATIVE_TO_INT(start.Native());
  const int iend = NATIVE_TO_INT(end.Native());

  unsigned npoly = 0;
  BulkPixelPoint pt[66*2];

  segment_poly(pt, center, radius, istart, iend, npoly);
  segment_poly(pt, center, inner_radius, iend, istart, npoly, false);

  assert(npoly <= ARRAY_SIZE(pt));
  if (npoly)
    canvas.DrawPolygon(pt, npoly);

  return true;
}
예제 #11
0
파일: Util.cpp 프로젝트: CnZoom/XcSoarPull
bool
KeyHole(Canvas &canvas, int x, int y, unsigned radius,
        Angle start, Angle end, unsigned inner_radius)
{
  // dont draw if out of view
  if (!IsCircleVisible(canvas, x, y, radius))
    return false;

  const int istart = NATIVE_TO_INT(start.Native());
  const int iend = NATIVE_TO_INT(end.Native());

  unsigned npoly = 0;
  RasterPoint pt[66*2];

  segment_poly(pt, x, y, radius, istart, iend, npoly);
  segment_poly(pt, x, y, inner_radius, iend, istart, npoly);

  assert(npoly < ARRAY_SIZE(pt));
  if (npoly)
    canvas.DrawPolygon(pt, npoly);

  return true;
}
예제 #12
0
파일: CaiLNav.cpp 프로젝트: Adrien81/XCSoar
static void
FormatLongitude(char *buffer, size_t buffer_size, Angle longitude)
{
  // Calculate Longitude sign
  char sign = negative(longitude.Native()) ? 'W' : 'E';

  double mlong(longitude.AbsoluteDegrees());

  int dd = (int)mlong;
  // Calculate minutes
  double mins = (mlong - dd) * 60.0;
  // Save the string to the buffer
  snprintf(buffer, buffer_size, "%02d%06.3f,%c", dd, mins, sign);
}
예제 #13
0
static int
Direction(const GeoPoint &p0, const GeoPoint &p1, const GeoPoint &p2,
          fixed tolerance)
{
  //
  // In this program we frequently want to look at three consecutive
  // points, p0, p1, and p2, and determine whether p2 has taken a turn
  // to the left or a turn to the right.
  //
  // We can do this by by translating the points so that p1 is at the origin,
  // then taking the cross product of p0 and p2. The result will be positive,
  // negative, or 0, meaning respectively that p2 has turned right, left, or
  // is on a straight line.
  //

  const Angle a = (p0.longitude - p1.longitude) * (p2.latitude - p1.latitude);
  const Angle b = (p2.longitude - p1.longitude) * (p0.latitude - p1.latitude);

  if (negative(tolerance))
    /* auto-tolerance - this has been verified by experiment */
    tolerance = std::max(fabs(a.Native()), fabs(b.Native())) / 10;

  return (a - b).Sign(tolerance);
}
예제 #14
0
void
DigitEntry::SetLongitude(Angle value, CoordinateFormat format)
{
  // Longitude in floating point degrees
  value = value.AsDelta();
  const fixed degrees = fabs(value.Degrees());

  // Check the first three columns here
  assert(columns[0].type == Column::Type::EAST_WEST);
  assert(columns[1].type == Column::Type::DIGIT19);
  assert(columns[2].type == Column::Type::DIGIT);
  columns[0].value = negative(value.Native());

  // Set up and check the remaining digits
  SetDigits(degrees, format, false);

  Invalidate();
}
예제 #15
0
void
UpdateInfoBoxCircleDiameter(InfoBoxData &data)
{
  if (!CommonInterface::Basic().airspeed_available.IsValid()) {
    data.SetInvalid();
    return;
  }

  const Angle turn_rate =
    CommonInterface::Calculated().turn_rate_heading_smoothed.Absolute();

  // deal with div zero and small turn rates
  if (turn_rate < Angle::Degrees(1)) {
    data.SetInvalid();
    return;
  }

  const fixed circle_diameter = CommonInterface::Basic().true_airspeed
     / turn_rate.Radians()
     * fixed(2); // convert turn rate to radians/s and double it to get estimated circle diameter

  if (circle_diameter > fixed (2000)){ // arbitrary estimated that any diameter bigger than 2km will not be interesting
    data.SetInvalid();
    return;
  }

  TCHAR buffer[32];
  Unit unit = FormatSmallUserDistance(buffer, circle_diameter, false, 0);
  data.SetValue (buffer);
  data.SetValueUnit(unit);

  const fixed circle_duration =
    Angle::FullCircle().Native() / turn_rate.Native();

  StaticString<16> duration_buffer;
  duration_buffer.Format(_T("%u s"), int(circle_duration));
  _tcscpy (buffer, duration_buffer);
  data.SetComment (buffer);
}
예제 #16
0
 gcc_pure
 int AngleToWidth(Angle angle) const {
   return (int)(angle.Native() * x_scale);
 }
예제 #17
0
 gcc_pure
 int AngleToHeight(Angle angle) const {
   return (int)(angle.Native() * y_scale);
 }
예제 #18
0
파일: Canvas.cpp 프로젝트: damianob/xcsoar
gcc_const
static unsigned
AngleToDonutVertex(Angle angle)
{
  return (NATIVE_TO_INT(angle.Native()) * 64 / 4096 + 48) & 0x3e;
}