void gfx_gradient_table::build_table(void) { quick_sort(m_color_profile, offset_less); m_color_profile.cut_at(remove_duplicates(m_color_profile, offset_equal)); if (m_color_profile.size() >= 2) { unsigned int i; unsigned int start = uround(m_color_profile[0].offset * color_table_size); unsigned int end = 0; color_type c = m_color_profile[0].color; for (i = 0; i < start; i++) { m_color_table[i] = c; } for (i = 1; i < m_color_profile.size(); i++) { end = uround(m_color_profile[i].offset * color_table_size); color_interpolator ci(m_color_profile[i-1].color, m_color_profile[i].color, end - start + 1); while (start < end) { m_color_table[start] = ci.color(); ++ci; ++start; } } c = m_color_profile.last().color; for (; end < m_color_table.size(); end++) { m_color_table[end] = c; } } }
void WindArrowRenderer::Draw(Canvas &canvas, const Angle screen_angle, const SpeedVector wind, const PixelPoint pos, const PixelRect rc, WindArrowStyle arrow_style) { // Draw arrow (and tail) const unsigned length = uround(Quadruple(wind.norm)); DrawArrow(canvas, pos, wind.bearing - screen_angle, length, arrow_style); // Draw wind speed label StaticString<12> buffer; buffer.Format(_T("%i"), iround(Units::ToUserWindSpeed(wind.norm))); canvas.SetTextColor(COLOR_BLACK); canvas.Select(*look.font); const unsigned offset = uround(M_SQRT2 * wind.norm); BulkPixelPoint label[] = { { 18, -26 - int(offset) }, }; PolygonRotateShift(label, ARRAY_SIZE(label), pos, wind.bearing - screen_angle); TextInBoxMode style; style.align = TextInBoxMode::Alignment::CENTER; style.vertical_position = TextInBoxMode::VerticalPosition::CENTERED; style.shape = LabelShape::OUTLINED; TextInBox(canvas, buffer, label[0].x, label[0].y, style, rc); }
void HorizonRenderer::Draw(Canvas &canvas, const PixelRect &rc, const HorizonLook &look, const AttitudeState &attitude) { /* This feature of having a backup artificial horizon based on inferred orientation from GPS and vario data is useful, and reasonably well tested, but has the issue of potentially invalidating use of XCSoar in FAI contests due to rule ref Annex A to Section 3 (2010 Edition) 4.1.2 "No instruments permitting pilots to fly without visual reference to the ground may be carried on board, even if made unserviceable." The quality of XCSoar's pseudo-AH is arguably good enough that this violates the rule. We need to seek clarification as to whether this is the case or not. */ const RasterPoint center = rc.GetCenter(); const int radius = std::min(rc.right - rc.left, rc.bottom - rc.top) / 2 - Layout::Scale(1); auto bank_degrees = attitude.IsBankAngleUseable() ? attitude.bank_angle.Degrees() : 0.; auto pitch_degrees = attitude.IsPitchAngleUseable() ? attitude.pitch_angle.Degrees() : 0.; auto phi = Clamp(bank_degrees, -89., 89.); auto alpha = Angle::acos(Clamp(pitch_degrees / 50, -1., 1.)); auto sphi = Angle::HalfCircle() - Angle::Degrees(phi); auto alpha1 = sphi - alpha; auto alpha2 = sphi + alpha; // draw sky part canvas.Select(look.sky_pen); canvas.Select(look.sky_brush); canvas.DrawSegment(center.x, center.y, radius, alpha2, alpha1, true); // draw ground part canvas.Select(look.terrain_pen); canvas.Select(look.terrain_brush); canvas.DrawSegment(center.x, center.y, radius, alpha1, alpha2, true); // draw aircraft symbol canvas.Select(look.aircraft_pen); canvas.DrawLine(center.x + radius / 2, center.y, center.x - radius / 2, center.y); canvas.DrawLine(center.x, center.y - radius / 4, center.x, center.y); // draw 45 degree dash marks const int rr2p = uround(radius * M_SQRT1_2) + Layout::Scale(1); const int rr2n = rr2p - Layout::Scale(2); canvas.DrawLine(center.x + rr2p, center.y - rr2p, center.x + rr2n, center.y - rr2n); canvas.DrawLine(center.x - rr2p, center.y - rr2p, center.x - rr2n, center.y - rr2n); }
void AngleConfigElement::Write(XmlWriter& writer, xmlNode* father) const { if (*m_val != m_def) { int val = uround(ToDegree*(*m_val)); writer.WriteElement(father, m_name, int2str(val), m_attribute); } }
void InfoBoxContentWindArrow::OnCustomPaint(Canvas &canvas, const PixelRect &rc) { const auto &info = CommonInterface::Calculated(); const auto pt = rc.GetCenter(); const unsigned padding = Layout::FastScale(10u); unsigned size = std::min(rc.GetWidth(), rc.GetHeight()); if (size > padding) size -= padding; // Normalize the size because the Layout::Scale is applied // by the DrawArrow() function again size = size * 100 / Layout::Scale(100); auto angle = info.wind.bearing - CommonInterface::Basic().attitude.heading; const int length = std::min(size, std::max(10u, uround(Quadruple(info.wind.norm)))); const int offset = -length / 2; auto style = CommonInterface::GetMapSettings().wind_arrow_style; WindArrowRenderer renderer(UIGlobals::GetLook().wind_arrow_info_box); renderer.DrawArrow(canvas, pt, angle, length, style, offset); }
void AverageVarioComputer::Compute(const MoreData &basic, bool circling, bool last_circling, VarioInfo &vario_info) { const fixed dt = delta_time.Update(basic.time, fixed(1), fixed(0)); if (negative(dt) || circling != last_circling) { Reset(); vario_info.average = basic.brutto_vario; vario_info.netto_average = basic.netto_vario; return; } if (!positive(dt)) return; const unsigned Elapsed = uround(dt); if (Elapsed == 0) return; for (unsigned i = 0; i < Elapsed; ++i) { vario_30s_filter.Update(basic.brutto_vario); netto_30s_filter.Update(basic.netto_vario); } vario_info.average = vario_30s_filter.Average(); vario_info.netto_average = netto_30s_filter.Average(); }
void Vega::VolatileData::CopyFrom(const DerivedInfo &calculated) { stf = uround(calculated.V_stf * 10); terrain_altitude = iround(calculated.terrain_altitude); circling = calculated.circling; }
void HorizonRenderer::Draw(Canvas &canvas, const PixelRect &rc, const NMEAInfo &Basic) { /* This feature of having a backup artificial horizon based on inferred orientation from GPS and vario data is useful, and reasonably well tested, but has the issue of potentially invalidating use of XCSoar in FAI contests due to rule ref Annex A to Section 3 (2010 Edition) 4.1.2 "No instruments permitting pilots to fly without visual reference to the ground may be carried on board, even if made unserviceable." The quality of XCSoar's pseudo-AH is arguably good enough that this violates the rule. We need to seek clarification as to whether this is the case or not. */ RasterPoint center; center.y = (rc.top + rc.bottom) / 2; center.x = (rc.left + rc.right) / 2; const int radius = min(rc.right - rc.left, rc.bottom - rc.top) / 2 - Layout::Scale(1); Pen hpHorizonSky(Layout::Scale(1), DarkColor(Graphics::skyColor)); Brush hbHorizonSky(Graphics::skyColor); Pen hpHorizonGround(Layout::Scale(1), DarkColor(Graphics::GroundColor)); #define fixed_div fixed(1.0 / 50.0) #define fixed_89 fixed_int_constant(89) fixed phi = max(-fixed_89, min(fixed_89, Basic.acceleration.bank_angle.Degrees())); fixed alpha = fixed_rad_to_deg * acos(max(-fixed_one,min(fixed_one, Basic.acceleration.pitch_angle.Degrees() * fixed_div))); fixed sphi = fixed_180 - phi; Angle alpha1 = Angle::Degrees(sphi - alpha); Angle alpha2 = Angle::Degrees(sphi + alpha); // draw sky part canvas.Select(hpHorizonSky); canvas.Select(hbHorizonSky); canvas.DrawSegment(center.x, center.y, radius, alpha2, alpha1, true); // draw ground part canvas.Select(hpHorizonGround); canvas.Select(Graphics::hbGround); canvas.DrawSegment(center.x, center.y, radius, alpha1, alpha2, true); // draw aircraft symbol Pen aircraft_pen(Layout::Scale(2), COLOR_BLACK); canvas.Select(aircraft_pen); canvas.line(center.x + radius / 2, center.y, center.x - radius / 2, center.y); canvas.line(center.x, center.y - radius / 4, center.x, center.y); // draw 45 degree dash marks const UPixelScalar rr2p = uround(radius * fixed_sqrt_half) + Layout::Scale(1); const UPixelScalar rr2n = rr2p - Layout::Scale(2); canvas.line(center.x + rr2p, center.y - rr2p, center.x + rr2n, center.y - rr2n); canvas.line(center.x - rr2p, center.y - rr2p, center.x - rr2n, center.y - rr2n); }
/** * Set the QNH setting of the V7 vario */ static inline bool SetQNH(Port &port, OperationEnvironment &env, const AtmosphericPressure &qnh) { char buffer[100]; unsigned QNHinPascal = uround(qnh.GetPascal()); sprintf(buffer, "PLXV0,QNH,W,%u", QNHinPascal); return PortWriteNMEA(port, buffer, env); }
//--------------------------------------------------------------------- line_profile_aa::value_type* line_profile_aa::profile(double w) { m_subpixel_width = uround(w * subpixel_scale); unsigned size = m_subpixel_width + subpixel_scale * 6; if (size > m_profile.size()) { m_profile.resize(size); } return &m_profile[0]; }
char * FormatIGCLocation(char *buffer, const GeoPoint &location) { char latitude_suffix = location.latitude.IsNegative() ? 'S' : 'N'; unsigned latitude = (unsigned)uround(fabs(location.latitude.Degrees() * 60000)); char longitude_suffix = location.longitude.IsNegative() ? 'W' : 'E'; unsigned longitude = (unsigned)uround(fabs(location.longitude.Degrees() * 60000)); sprintf(buffer, "%02u%05u%c%03u%05u%c", latitude / 60000, latitude % 60000, latitude_suffix, longitude / 60000, longitude % 60000, longitude_suffix); return buffer + strlen(buffer); }
gcc_const static unsigned AngleToIndex(Angle a) { fixed i = ROUTEPOLAR_POINTS * (fixed(1.25) - a.AsBearing().Radians() / fixed_two_pi); assert(positive(i)); return uround(i) % ROUTEPOLAR_POINTS; }
static void Main() { Angle value = Angle::Zero(); if (!AngleEntryDialog(_T("The caption"), value)) return; printf("%u\n", uround(value.Degrees())); }
static char * igc_format_location(char *buffer, const GeoPoint &location) { char latitude_suffix = negative(location.Latitude.value_native()) ? 'S' : 'N'; unsigned latitude = (unsigned)uround(fabs(location.Latitude.value_degrees() * 60000)); char longitude_suffix = negative(location.Longitude.value_native()) ? 'W' : 'E'; unsigned longitude = (unsigned)uround(fabs(location.Longitude.value_degrees() * 60000)); sprintf(buffer, "%02u%05u%c%03u%05u%c", latitude / 60000, latitude % 60000, latitude_suffix, longitude / 60000, longitude % 60000, longitude_suffix); return buffer + strlen(buffer); }
bool CAI302Device::PutBallast(fixed Ballast) { unsigned ballast = uround(Ballast * 100); char szTmp[32]; sprintf(szTmp, "!g,b%u\r", ballast); port.Write(szTmp); return true; }
bool CAI302Device::PutBugs(fixed Bugs) { unsigned bugs = uround(Bugs * 100); char szTmp[32]; sprintf(szTmp, "!g,u%u\r", bugs); port.Write(szTmp); return true; }
bool CAI302Device::PutMacCready(fixed MacCready) { unsigned mac_cready = uround(Units::ToUserUnit(MacCready * 10, Unit::KNOTS)); char szTmp[32]; sprintf(szTmp, "!g,m%u\r", mac_cready); port.Write(szTmp); return true; }
//curve4_inc void curve4_inc::init(scalar x1, scalar y1, scalar x2, scalar y2, scalar x3, scalar y3, scalar x4, scalar y4) { m_start_x = x1; m_start_y = y1; m_end_x = x4; m_end_y = y4; scalar dx1 = x2 - x1; scalar dy1 = y2 - y1; scalar dx2 = x3 - x2; scalar dy2 = y3 - y2; scalar dx3 = x4 - x3; scalar dy3 = y4 - y3; scalar len = (Sqrt(dx1 * dx1 + dy1 * dy1) + Sqrt(dx2 * dx2 + dy2 * dy2) + Sqrt(dx3 * dx3 + dy3 * dy3)) * FLT_TO_SCALAR(0.25f) * m_scale; m_num_steps = uround(len); if (m_num_steps < 4) { m_num_steps = 4; } scalar subdivide_step = FLT_TO_SCALAR(1.0f) / m_num_steps; scalar subdivide_step2 = subdivide_step * subdivide_step; scalar subdivide_step3 = subdivide_step * subdivide_step * subdivide_step; scalar pre1 = FLT_TO_SCALAR(3.0f) * subdivide_step; scalar pre2 = FLT_TO_SCALAR(3.0f) * subdivide_step2; scalar pre4 = FLT_TO_SCALAR(6.0f) * subdivide_step2; scalar pre5 = FLT_TO_SCALAR(6.0f) * subdivide_step3; scalar tmp1x = x1 - x2 * FLT_TO_SCALAR(2.0f) + x3; scalar tmp1y = y1 - y2 * FLT_TO_SCALAR(2.0f) + y3; scalar tmp2x = (x2 - x3) * FLT_TO_SCALAR(3.0f) - x1 + x4; scalar tmp2y = (y2 - y3) * FLT_TO_SCALAR(3.0f) - y1 + y4; m_saved_fx = m_fx = x1; m_saved_fy = m_fy = y1; m_saved_dfx = m_dfx = (x2 - x1) * pre1 + tmp1x * pre2 + tmp2x * subdivide_step3; m_saved_dfy = m_dfy = (y2 - y1) * pre1 + tmp1y * pre2 + tmp2y * subdivide_step3; m_saved_ddfx = m_ddfx = tmp1x * pre4 + tmp2x * pre5; m_saved_ddfy = m_ddfy = tmp1y * pre4 + tmp2y * pre5; m_dddfx = tmp2x * pre5; m_dddfy = tmp2y * pre5; m_step = m_num_steps; }
static void PaintWaypoint(Canvas &canvas, const RECT rc, const struct WayPointSelectInfo &info) { const Waypoint &way_point = *info.way_point; int w0, w1, w2, w3, x; w0 = rc.right - rc.left - Layout::FastScale(4); w1 = canvas.text_width(_T("XXX")); w2 = canvas.text_width(_T(" 000km")); w3 = canvas.text_width(_T(" 000")_T(DEG)); x = w0 - w1 - w2 - w3; canvas.text_clipped(rc.left + Layout::FastScale(2), rc.top + Layout::FastScale(2), x - Layout::FastScale(5), way_point.Name.c_str()); TCHAR buffer[12]; buffer[0] = '\0'; buffer[1] = '\0'; buffer[2] = '\0'; if (way_point.Flags.Home) buffer[0] = 'H'; else if (way_point.Flags.Airport) buffer[0] = 'A'; else if (way_point.Flags.LandPoint) buffer[0] = 'L'; if (way_point.Flags.TurnPoint) { if (buffer[0] == '\0') buffer[0] = 'T'; else buffer[1] = 'T'; } // left justified canvas.text(rc.left + x, rc.top + Layout::FastScale(2), buffer); // right justified after waypoint flags Units::FormatUserDistance(info.Distance, buffer, sizeof(buffer) / sizeof(buffer[0])); x = w0 - w3 - canvas.text_width(buffer); canvas.text(rc.left + x, rc.top + Layout::FastScale(2), buffer); // right justified after distance _stprintf(buffer, _T("%u")_T(DEG), uround(info.Direction.value_degrees())); x = w0 - canvas.text_width(buffer); canvas.text(rc.left + x, rc.top + Layout::FastScale(2), buffer); }
bool WesterboerDevice::PutMacCready(fixed _mac_cready, OperationEnvironment &env) { /* 0 .. 60 -> 0.0 .. 6.0 m/s */ unsigned mac_cready = std::min(uround(_mac_cready * 10), 60u); char buffer[64]; sprintf(buffer, "$PWES4,,%02u,,,,,,,", mac_cready); AppendNMEAChecksum(buffer); strcat(buffer, "\r\n"); port.Write(buffer); return true; }
bool WesterboerDevice::PutMacCready(fixed _mac_cready) { /* "0 .. 60 in 5-er Schritten" */ unsigned mac_cready = std::min(uround(_mac_cready * 10 / 5) * 5, 60u); char buffer[64]; sprintf(buffer, "$PWES4,,%02u,,,,,,,", mac_cready); AppendNMEAChecksum(buffer); strcat(buffer, "\r\n"); port.Write(buffer); return true; }
void Angle::ToDMS(int &dd, int &mm, int &ss, bool &is_positive) const { is_positive = !negative(value); unsigned value = uround(AbsoluteDegrees() * 3600); ss = value % 60; value /= 60; mm = value % 60; value /= 60; dd = value; }
static TCHAR * GetDirectionData(int DirectionFilterIdx) { static TCHAR sTmp[12]; if (DirectionFilterIdx == 0) { _stprintf(sTmp, _T("%c"), '*'); } else if (DirectionFilterIdx == 1) { _stprintf(sTmp, _T("HDG(%u")_T(DEG)_T(")"), uround(XCSoarInterface::Basic().Heading.as_bearing().value_degrees())); } else _stprintf(sTmp, _T("%d")_T(DEG), DirectionFilter[DirectionFilterIdx]); return sTmp; }
void FormatTimeLong(TCHAR* buffer, fixed _time) { if (negative(_time)) { *buffer++ = _T('-'); _time = -_time; } const BrokenTime time = BrokenTime::FromSecondOfDayChecked((unsigned)_time); _time -= fixed((int)_time); unsigned millisecond = uround(_time * 1000); _stprintf(buffer, _T("%02u:%02u:%02u.%03u"), time.hour, time.minute, time.second, millisecond); }
void WarningComputer::Update(const ComputerSettings &settings_computer, const MoreData &basic, const DerivedInfo &calculated, AirspaceWarningsInfo &result) { if (!basic.time_available) return; const fixed dt = delta_time.Update(basic.time, fixed(1), fixed(20)); if (negative(dt)) /* time warp */ Reset(); if (!positive(dt)) return; airspaces.SetFlightLevels(settings_computer.pressure); AirspaceActivity day(calculated.date_time_local.day_of_week); airspaces.SetActivity(day); if (!settings_computer.airspace.enable_warnings || !basic.location_available || !basic.NavAltitudeAvailable()) { if (initialised) { initialised = false; protected_manager.Clear(); } return; } const AircraftState as = ToAircraftState(basic, calculated); ProtectedAirspaceWarningManager::ExclusiveLease lease(protected_manager); lease->SetConfig(settings_computer.airspace.warnings); if (!initialised) { initialised = true; lease->Reset(as); } if (lease->Update(as, settings_computer.polar.glide_polar_task, calculated.task_stats, calculated.circling, uround(dt))) result.latest.Update(basic.clock); }
void FormatTimeLong(TCHAR* buffer, fixed _time) { bool _negative = negative(_time); _time = fabs(_time); const BrokenTime time = BrokenTime::FromSecondOfDayChecked((unsigned)_time); _time -= fixed((int)_time); unsigned millisecond = uround(_time * 1000); _stprintf(buffer, _negative ? _T("-%02u:%02u:%02u.%03u") : _T("%02u:%02u:%02u.%03u"), time.hour, time.minute, time.second, millisecond); }
inline void GlideComputerAirData::AverageClimbRate(const NMEAInfo &basic, DerivedInfo &calculated) { if (basic.airspeed_available && positive(basic.indicated_airspeed) && positive(basic.true_airspeed) && basic.total_energy_vario_available && !calculated.circling && (!basic.acceleration.available || !basic.acceleration.real || fabs(basic.acceleration.g_load - fixed(1)) <= fixed(0.25))) { // TODO: Check this is correct for TAS/IAS fixed ias_to_tas = basic.indicated_airspeed / basic.true_airspeed; fixed w_tas = basic.total_energy_vario * ias_to_tas; calculated.climb_history.Add(uround(basic.indicated_airspeed), w_tas); } }
gcc_const static BrokenTime BreakHourOfDay(fixed t) { /* depending on the time zone, the SunEphemeris library may return a negative time of day; the following check catches this before we cast the value to "unsigned" */ if (negative(t)) t += fixed(24); unsigned i = uround(t * 3600); BrokenTime result; result.hour = i / 3600; i %= 3600; result.minute = i / 60; result.second = i % 60; return result; }
//------------------------------------------------------------------------ void curve3_inc::init(double x1, double y1, double x2, double y2, double x3, double y3) { m_start_x = x1; m_start_y = y1; m_end_x = x3; m_end_y = y3; double dx1 = x2 - x1; double dy1 = y2 - y1; double dx2 = x3 - x2; double dy2 = y3 - y2; double len = sqrt(dx1 * dx1 + dy1 * dy1) + sqrt(dx2 * dx2 + dy2 * dy2); m_num_steps = uround(len * 0.25 * m_scale); if(m_num_steps < 4) { m_num_steps = 4; } double subdivide_step = 1.0 / m_num_steps; double subdivide_step2 = subdivide_step * subdivide_step; double tmpx = (x1 - x2 * 2.0 + x3) * subdivide_step2; double tmpy = (y1 - y2 * 2.0 + y3) * subdivide_step2; m_saved_fx = m_fx = x1; m_saved_fy = m_fy = y1; m_saved_dfx = m_dfx = tmpx + (x2 - x1) * (2.0 * subdivide_step); m_saved_dfy = m_dfy = tmpy + (y2 - y1) * (2.0 * subdivide_step); m_ddfx = tmpx * 2.0; m_ddfy = tmpy * 2.0; m_step = m_num_steps; }
void WarningComputer::Update(const ComputerSettings &settings_computer, const MoreData &basic, const MoreData &last_basic, const DerivedInfo &calculated, AirspaceWarningsInfo &result) { if (!basic.HasTimeAdvancedSince(last_basic) || !clock.check_advance(basic.time)) return; airspaces.set_flight_levels(settings_computer.pressure); AirspaceActivity day(calculated.date_time_local.day_of_week); airspaces.set_activity(day); if (!settings_computer.airspace.enable_warnings || !basic.location_available || !basic.NavAltitudeAvailable()) { if (initialised) { initialised = false; protected_manager.clear(); } return; } const AircraftState as = ToAircraftState(basic, calculated); ProtectedAirspaceWarningManager::ExclusiveLease lease(protected_manager); if (!initialised) { initialised = true; lease->Reset(as); } if (lease->Update(as, settings_computer.glide_polar_task, calculated.task_stats, calculated.circling, uround(basic.time - last_basic.time))) result.latest.Update(basic.clock); }