mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-10-28 16:57:29 +01:00
feat(editor): K on a track is a break of the grade, as a point of a road: the track split at the cursor, the point between the two at the height of the ground and the ballast there, each of them an even grade from its other end up to it
Selftest kbreak: K on the track nearest a point, logs the joint against the ground.
This commit is contained in:
@@ -5583,7 +5583,7 @@ void editor_mode::render_shortcuts_window()
|
||||
{"Ctrl+F", "Find a track by its name"},
|
||||
{"Shift+LMB", "Add a track to the selection, drag: a box"},
|
||||
{"RMB on a track", "What can be done with it"},
|
||||
{"K", "Split the selected track at the cursor"},
|
||||
{"K", "Split the selected track at the cursor, a break of the grade at the height of the ground"},
|
||||
{"L, LMB, LMB...", "Lay track: each click lays a piece and goes on from its end"},
|
||||
{"Drag from a free end", "Lead a track out of it; onto another free end: join the two"},
|
||||
{"Ctrl+wheel", "Laying: radius"},
|
||||
|
||||
@@ -65,6 +65,7 @@ editor_mode::selftest_result editor_mode::selftest_dispatch(std::string const &c
|
||||
// camera <x> <y> <z> <x> <y> <z> from the first point, looking at the second
|
||||
// select <track name>
|
||||
// selectat <x> <z> the path nearest the point, within 3 m, as a click on it
|
||||
// kbreak <x> <z> K on the track nearest the point: split there, a break of the grade at the height of the ground
|
||||
// blade [name] logs the blades of each switch cut from the rails: tip, 50 mm head, full head, heel, drop of the head, open flangeway, the gauge lines apart against x^2/2R, vertices in both positions
|
||||
// frog [name] logs where the inner rails of each switch cross: distance on both paths, 1:n, throat, nose, check rails
|
||||
// guards [name] logs each guard rail and what each of its ends and breaks is cut along; a fault when a cut is not along a rail or a glued end not on the guard rail of the other track
|
||||
|
||||
@@ -93,6 +93,37 @@ editor_mode::selftest_result editor_mode::selftest_scene(std::string const &comm
|
||||
WriteLog(format("SELFTEST selectat %.1f %.1f: %s", point.x, point.z, m_node != nullptr ? m_node->name().c_str() : "nothing"));
|
||||
return selftest_result::handled;
|
||||
}
|
||||
if (command == "kbreak")
|
||||
{
|
||||
// K on the track nearest the point: split there, the point between at the height of the ground and the ballast
|
||||
glm::dvec3 point{0.0};
|
||||
words >> point.x >> point.z;
|
||||
TTrack *nearest{nullptr};
|
||||
double distance{1e9};
|
||||
for (auto *track : simulation::Paths.sequence())
|
||||
if (track != nullptr && false == track->m_editorremoved && false == track->m_paths.empty() && track->eType == tt_Normal)
|
||||
if (auto const d{geometry::plan_distance(editor_track::point_at(*track, editor_track::nearest_parameter(*track, point)), point)}; d < distance)
|
||||
{
|
||||
distance = d;
|
||||
nearest = track;
|
||||
}
|
||||
if (nearest == nullptr || distance > 3.0)
|
||||
{
|
||||
WriteLog(format("SELFTEST kbreak %.1f %.1f: no track", point.x, point.z));
|
||||
return selftest_result::handled;
|
||||
}
|
||||
auto const tracks{simulation::Paths.sequence().size()};
|
||||
split_track_at(*nearest, point);
|
||||
auto const &path{nearest->m_paths.front()};
|
||||
auto const joint{path.points[segment_data::point::end]};
|
||||
std::vector<char> found;
|
||||
auto const ground{ground_heights({glm::dvec3{joint.x, joint.y + 50.0, joint.z}}, true, &found).front()};
|
||||
geometry::bezier const curve{path};
|
||||
auto const rise = [](glm::dvec3 const &Tangent) { return 1000.0 * Tangent.y / std::max(1e-9, glm::length(geometry::plan_of(Tangent))); };
|
||||
WriteLog(format("SELFTEST kbreak %s: %zu tracks more, joint %.2f %.3f %.2f, ground %.3f (found %d), grade %.2f -> %.2f permille", nearest->name().c_str(), simulation::Paths.sequence().size() - tracks, joint.x, joint.y, joint.z, ground, found[0], rise(curve.first(0.0)),
|
||||
rise(curve.first(1.0))));
|
||||
return selftest_result::handled;
|
||||
}
|
||||
if (command == "select")
|
||||
{
|
||||
std::string name;
|
||||
|
||||
@@ -1800,7 +1800,7 @@ std::vector<editor_mode::key_hint> editor_mode::track_key_hints(bool const All)
|
||||
{
|
||||
if (gizmo && m_gizmo_snap > 0.0f)
|
||||
hints.push_back({"Ctrl", format("gizmo snaps by %.2f m", m_gizmo_snap)});
|
||||
hints.push_back({"K", "split the path under the cursor"});
|
||||
hints.push_back({"K", "split the path under the cursor, a break of the grade at the height of the ground"});
|
||||
hints.push_back({"O", "top view"});
|
||||
hints.push_back({"Esc", "back to Select"});
|
||||
if (Global.EditorOrtho)
|
||||
|
||||
@@ -1076,6 +1076,22 @@ void editor_mode::split_track_at(TTrack &Track, glm::dvec3 const &Point)
|
||||
auto const before{editor_track::capture(Track)};
|
||||
if (auto *created{editor_track::split_path(Track, parameter)})
|
||||
{
|
||||
// a break of the grade, as a point of a road: the point between the two takes the height of the ground and the ballast
|
||||
// there, each of them an even grade from its other end up to it
|
||||
auto const &path{Track.m_paths.front()};
|
||||
auto const joint{path.points[segment_data::point::end]};
|
||||
auto const height{bed_height(joint, geometry::plan_of(geometry::bezier{path}.first(1.0)), &Track)};
|
||||
auto const none{std::numeric_limits<double>::quiet_NaN()};
|
||||
auto const unknown = [](std::vector<glm::dvec3> const &Points, std::vector<glm::dvec2> const &) { return std::vector<double>(Points.size(), std::numeric_limits<double>::quiet_NaN()); };
|
||||
for (auto *part : {&Track, created})
|
||||
{
|
||||
std::vector<segment_data> pieces{part->m_paths.front()};
|
||||
auto &points{pieces.front().points};
|
||||
points[part == &Track ? segment_data::point::end : segment_data::point::start].y = height;
|
||||
ground_follow::follow(pieces, {points[segment_data::point::start].y, none, points[segment_data::point::end].y, none}, unknown);
|
||||
part->m_paths.front() = pieces.front();
|
||||
}
|
||||
editor_track::commit({&Track, created});
|
||||
push_track_snapshot({{&Track, before}}, {created});
|
||||
straight_refresh();
|
||||
}
|
||||
@@ -1147,7 +1163,7 @@ void editor_mode::render_track_context()
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
ImGui::Separator();
|
||||
if (ImGui::MenuItem(STR_C("Split here"), "K", false, normal))
|
||||
if (ImGui::MenuItem(STR_C("Split here, a break of the grade"), "K", false, normal))
|
||||
split_track_at(*track, point);
|
||||
ImGui::Separator();
|
||||
if (ImGui::MenuItem(STR_C("Switch"), "T", false, normal || track->eType == tt_Switch))
|
||||
|
||||
@@ -240,8 +240,8 @@ msgstr "zastosuj"
|
||||
msgid "release the vertex"
|
||||
msgstr "puszcza wierzchołek"
|
||||
|
||||
msgid "split the path under the cursor"
|
||||
msgstr "podziel tor pod kursorem"
|
||||
msgid "split the path under the cursor, a break of the grade at the height of the ground"
|
||||
msgstr "podziel tor pod kursorem, załamanie niwelety na wysokości terenu"
|
||||
|
||||
msgid "top view"
|
||||
msgstr "widok z góry"
|
||||
@@ -1743,8 +1743,8 @@ msgstr "Rozstaw torów (m)"
|
||||
msgid "Speed check of the line"
|
||||
msgstr "Sprawdź prędkość linii"
|
||||
|
||||
msgid "Split here"
|
||||
msgstr "Podziel tutaj"
|
||||
msgid "Split here, a break of the grade"
|
||||
msgstr "Podziel tutaj, załamanie niwelety"
|
||||
|
||||
msgid "Step (m)"
|
||||
msgstr "Uskok (m)"
|
||||
@@ -4083,8 +4083,8 @@ msgstr "Przyciąganie do kroku z ustawień gizma"
|
||||
msgid "Split the road at the cursor, or make a point there"
|
||||
msgstr "Podziel drogę przy kursorze albo zrób tam punkt"
|
||||
|
||||
msgid "Split the selected track at the cursor"
|
||||
msgstr "Podziel zaznaczony tor przy kursorze"
|
||||
msgid "Split the selected track at the cursor, a break of the grade at the height of the ground"
|
||||
msgstr "Podziel zaznaczony tor przy kursorze, załamanie niwelety na wysokości terenu"
|
||||
|
||||
msgid "Takes the last change back"
|
||||
msgstr "Cofa ostatnią zmianę"
|
||||
|
||||
Reference in New Issue
Block a user