From 62b0e925a7a0fe38f4d2b2af7b6b4df72a1df6a4 Mon Sep 17 00:00:00 2001 From: maj00r Date: Wed, 21 Oct 2026 17:34:19 +0200 Subject: [PATCH] feat(editor): the readout of a track being laid or led out of an end gives its rise, its grades and the speed of its arc Next to the length and the radius, the readout at the cursor shows the difference of height from the start to the end of the track about to be laid, the grade along it (one value or the range it goes over) and the speed the sharpest arc lets the trains through at within the cant and the unbalanced acceleration of the laying limits. The self-test layclicks logs it. --- application/editormodeselftestjoin.cpp | 9 ++++++ application/editormodetrack.cpp | 8 ++++-- application/editormodetrackshared.h | 38 ++++++++++++++++++++++++++ lang/editor_pl.po | 9 ++++++ 4 files changed, 62 insertions(+), 2 deletions(-) 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‰"