17
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-10-30 22:30:28 +01:00

feat(editor): the plan shows which curve is edited: each named W1, W2... as its vertex is in the view, with its km and "Show in the view", which flies the camera over it; the part of it whose field the mouse is over or which is being edited (the whole curve, an arc of a compound one, the transition in, out or between two arcs) lit up in the view and named there with its radius, cant or length. The points clicked when a line is laid are kept with its design in the scenery ("click" lines, moved with it): the plan shows them in the colours of their departure and, while "Keep to the points clicked" is on, fits the radii of a curve whose transitions or cants are changed again to them, its transitions and cants as set; "Transitions for these cants" makes the transitions as long as the norms ask for at the radii and the cants set, an arc of a compound curve with no cant lengthening the ones either side of it. Unit test: 50 m between the arcs become 85 m, the curve 4 cm off the points clicked instead of 58

This commit is contained in:
maj00r
2026-10-25 00:11:58 +02:00
parent 2a399a92a5
commit aeef2cebb3
9 changed files with 633 additions and 68 deletions

View File

@@ -303,6 +303,49 @@ TEST_CASE("alignment: each arc of a compound curve has a cant of its own, ramped
CHECK(vertex.arcs.front().transition == doctest::Approx(alignment::transition_between(design.speed, 1.0 / 1200.0, 40.0, 1.0 / 700.0, 110.0, design.norms)));
}
TEST_CASE("alignment: an arc of a compound curve with no cant gets a longer transition, the curve fitted again to the points it was laid through") {
auto design{straights({600.0, 600.0}, {35.0 * pi / 180.0}, 100.0)};
auto &vertex{design.vertices.front()};
vertex.radius = 1200.0;
vertex.compound = true;
vertex.share = 0.5;
vertex.arcs = {{700.0, 0.0, 0.5}};
vertex.transition_in = vertex.transition_out = 80.0;
vertex.cant = 120.0;
alignment::recommend_between(vertex, design.speed, design.norms);
auto const line{alignment::compute(design)};
REQUIRE(line.valid);
auto const points{traced(line, 15.0, 0.0)};
auto const before{vertex.arcs.front().transition};
// the second arc with no cant, the first one keeping its own
auto lowered{design};
auto &shape{lowered.vertices.front()};
shape.first_cant = 70.0;
shape.arcs.front().cant = 0.0;
alignment::norm_transitions(shape, lowered.speed, lowered.norms);
auto const between{shape.arcs.front().transition};
CHECK(between == doctest::Approx(alignment::transition_between(lowered.speed, 1.0 / 1200.0, 70.0, 1.0 / 700.0, 0.0, lowered.norms)));
CHECK(between > before);
auto const departure = [&](alignment::design const &Design) {
double sum{0.0};
std::vector<glm::dvec2> plan(points.begin(), points.end());
for (auto const &projection : alignment::project(alignment::compute(Design), plan))
sum += projection.offset * projection.offset;
return std::sqrt(sum / static_cast<double>(points.size()));
};
auto const fit{alignment::refit_radii(lowered, 0, points)};
REQUIRE(fit.valid);
// the transitions and the cants as they were set, the radii moved to keep to the points
CHECK(fit.fitted.arcs.front().transition == doctest::Approx(between));
CHECK(fit.fitted.transition_in == doctest::Approx(shape.transition_in));
CHECK(fit.fitted.arcs.front().cant == doctest::Approx(0.0));
CHECK(fit.fitted.first_cant == doctest::Approx(70.0));
CHECK(fit.rms < departure(lowered));
CHECK(fit.rms < 0.3);
}
TEST_CASE("alignment: bends clicked close along a curve make one compound curve, not curves with short straights between them") {
// the points clicked in the scenery abc, at 60 km/h: from a straight along z into a curve to the left
alignment::design design;