diff --git a/application/editormodeselftestjoin.cpp b/application/editormodeselftestjoin.cpp index f645c522..46a2f94e 100644 --- a/application/editormodeselftestjoin.cpp +++ b/application/editormodeselftestjoin.cpp @@ -201,6 +201,15 @@ editor_mode::selftest_result editor_mode::selftest_join(std::string const &comma m_lay.mouse_snap = editor_track::find_free_end(nullptr, 1, point, 3.0, {}); m_lay.mouse = m_lay.mouse_snap.track != nullptr ? point : lay_bed(point); WriteLog(format("SELFTEST layclicks ground %.3f, track %.3f", point.y, m_lay.mouse.y)); + if (false == m_lay.points.empty()) + { + auto points{m_lay.points}; + points.push_back(m_lay.mouse_snap.track != nullptr ? m_lay.mouse_snap.position : m_lay.mouse); + m_lay.preview = lay_pieces(points, m_lay.mouse_snap, m_lay.preview_length, m_lay.preview_error); + auto readout{track_readout()}; + std::replace(readout.begin(), readout.end(), '\n', '|'); + WriteLog("SELFTEST layclicks readout: " + readout); + } lay_click(); WriteLog(format("SELFTEST layclicks %.1f %.1f: %s", point.x, point.z, m_lay.status.c_str())); } diff --git a/application/editormodetrack.cpp b/application/editormodetrack.cpp index fdc7de01..b7e01380 100644 --- a/application/editormodetrack.cpp +++ b/application/editormodetrack.cpp @@ -1771,7 +1771,9 @@ std::string editor_mode::track_readout() const return link_summary(target, link, editor_track::branch_radius(m_extend.track->m_paths[1])); if (snapped && pieces.empty()) return format(STR_C("no track fits to the end of %s"), name(target.track).c_str()); - auto text{radius > 0.0 ? format("L %.2f m R %.0f m", length, radius) : format("L %.2f m %s", length, STR_C("straight"))}; + auto text{radius > 0.0 ? format("L %.2f m R %.0f m", length, radius) + speed_of(radius, laying_norms()) : format("L %.2f m %s", length, STR_C("straight"))}; + if (auto const vertical{vertical_of(pieces)}; false == vertical.empty()) + text += "\n" + vertical; if (snapped) text += "\n" + format(STR_C("joins %s"), name(target.track).c_str()); if (false == reason.empty()) @@ -1797,9 +1799,11 @@ std::string editor_mode::track_readout() const radius = r; } if (radius > 0.0) - text = straight ? format("L %.1f m %s + R %.0f m", lay.preview_length, STR_C("straight"), radius) : format("L %.1f m R %.0f m", lay.preview_length, radius); + text = (straight ? format("L %.1f m %s + R %.0f m", lay.preview_length, STR_C("straight"), radius) : format("L %.1f m R %.0f m", lay.preview_length, radius)) + speed_of(radius, laying_norms()); else text = format("L %.1f m %s", lay.preview_length, STR_C("straight")); + if (auto const vertical{vertical_of(lay.preview)}; false == vertical.empty()) + text += "\n" + vertical; } if (false == lay.points.empty() && lay.mouse_snap.track != nullptr) text += "\n" + format(STR_C("joins %s"), name(lay.mouse_snap.track).c_str()); diff --git a/application/editormodetrackshared.h b/application/editormodetrackshared.h index 91ad98ca..9e60c62f 100644 --- a/application/editormodetrackshared.h +++ b/application/editormodetrackshared.h @@ -19,6 +19,9 @@ http://mozilla.org/MPL/2.0/. #include "world/Track.h" #include "imgui/imgui.h" +#include +#include +#include #include #include #include @@ -60,6 +63,41 @@ inline double piece_plan_radius(segment_data const &Path) return curve.plan_length() / turn; } +// the speed an arc of the radius lets the trains through at, within the cant and the unbalanced acceleration of the limits +inline std::string speed_of(double const Radius, alignment::limits const &Limits) +{ + auto const speed{std::floor(alignment::speed_limit(Radius, Limits) / 5.0) * 5.0}; + return speed > 0.0 ? format(STR_C(" (up to %.0f km/h)"), speed) : std::string{}; +} + +// the rise of the track from its start to its end, and the grades along it +inline std::string vertical_of(std::vector const &Pieces) +{ + double low{std::numeric_limits::max()}; + double high{std::numeric_limits::lowest()}; + for (auto const &piece : Pieces) + { + bezier const curve{piece}; + auto previous{curve.point(0.0)}; + for (int k = 1; k <= 8; ++k) + { + auto const next{curve.point(k / 8.0)}; + if (auto const run{plan_distance(previous, next)}; run > 1e-3) + { + low = std::min(low, (next.y - previous.y) / run * 1000.0); + high = std::max(high, (next.y - previous.y) / run * 1000.0); + } + previous = next; + } + } + if (low > high) + return {}; + auto const rise{bezier{Pieces.back()}.point(1.0).y - bezier{Pieces.front()}.point(0.0).y}; + if (high - low < 0.1) + return format(STR_C("height %+.2f m grade %+.1f per mille"), rise, (low + high) * 0.5); + return format(STR_C("height %+.2f m grade %+.1f to %+.1f per mille"), rise, low, high); +} + inline std::string lines_of(std::vector const &Texts) { std::string text; diff --git a/lang/editor_pl.po b/lang/editor_pl.po index 66516729..c84d879d 100644 --- a/lang/editor_pl.po +++ b/lang/editor_pl.po @@ -10090,3 +10090,12 @@ msgid_plural "Stopped: %zu chunks made stay" msgstr[0] "Przerwane: zrobiony %zu kafel zostaje" msgstr[1] "Przerwane: zrobione %zu kafle zostają" msgstr[2] "Przerwane: zrobionych %zu kafli zostaje" + +msgid " (up to %.0f km/h)" +msgstr " (do %.0f km/h)" + +msgid "height %+.2f m grade %+.1f per mille" +msgstr "różnica wysokości %+.2f m pochylenie %+.1f‰" + +msgid "height %+.2f m grade %+.1f to %+.1f per mille" +msgstr "różnica wysokości %+.2f m pochylenie od %+.1f do %+.1f‰"