From bfb045f2ad7beaafa2375cee85f03e525b7be9c9 Mon Sep 17 00:00:00 2001 From: maj00r Date: Mon, 26 Oct 2026 20:40:44 +0100 Subject: [PATCH] fix(editor): traced in the mode of a curve from the end of the diverging track of a switch, the line goes on with the curve of the switch: with a single point clicked the ghost was a straight right from P4, laid so with Enter, and points clicked on the photo a little off the curve gave way to the line from a straight there. One point after P4 lays the curve of the switch going on as far as the straight from it heads for the point; a curve going on from P4 which turns its way stays however loosely the points keep to it, the line from a straight taken only where they turn the other way. Selftest: one point after P4 laid R 300.9 going on, the curvature unbroken at the joint, where it was a straight before --- application/editormodelay.cpp | 41 +++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/application/editormodelay.cpp b/application/editormodelay.cpp index 80846e3e..ad7ad4f7 100644 --- a/application/editormodelay.cpp +++ b/application/editormodelay.cpp @@ -1045,7 +1045,7 @@ std::vector editor_mode::lay_pieces(std::vector const bool editor_mode::traced_from(std::vector const &Points, std::vector const &Modes, bool const AtEnd) { - if (Points.size() < 3) + if (Points.size() < (AtEnd ? 3u : 2u)) return false; auto const index{AtEnd ? Points.size() - 2 : std::size_t{1}}; return index < Modes.size() && Modes[index] == lay_mode::curve; @@ -1136,6 +1136,39 @@ bool editor_mode::lay_line(std::vector const &Points, std::vector 0.0 && tool.start.track != nullptr && tool.start.track->eType == tt_Switch) + { + auto const radius{design.start_radius}; + auto const side{design.start_turn > 0 ? 1.0 : -1.0}; + auto const from{plan_of(anchor)}; + glm::dvec2 const inward{-along->y * side, along->x * side}; + auto const centre{from + inward * radius}; + auto const point{plan_of(Points[1])}; + auto const outward{point - centre}; + auto const distance{glm::length(outward)}; + if (distance > radius + 0.5) + { + // where the straight to the point touches the circle, and how far round the curve turns to there + auto const heading{std::atan2(outward.y, outward.x) - side * std::acos(radius / distance)}; + glm::dvec2 const touch{centre + glm::dvec2{std::cos(heading), std::sin(heading)} * radius}; + auto turned{std::fmod(side * (heading - std::atan2(from.y - centre.y, from.x - centre.x)), 2.0 * glm::pi())}; + if (turned < 0.0) + turned += 2.0 * glm::pi(); + if (turned > 1e-3 && turned < glm::pi()) + { + alignment::vertex curve; + curve.radius = radius; + curve.cant = design.start_cant; + bends.push_back({lifted(from + *along * (radius * std::tan(0.5 * turned)), anchor.y), curve, false}); + anchor = Points[1]; + along = glm::normalize(point - touch); + i = last; + continue; + } + } + } // a bend of straights, or a point of a curve too alone to make one if (last == i || (last - i < 2 && false == reaching)) { @@ -1269,7 +1302,11 @@ bool editor_mode::lay_line(std::vector const &Points, std::vectorvalid && (fitted->rms > 0.08 || fitted->worst > 0.3)}; - if (other->valid && (false == fitted->valid || false == goes_on || (loose && other->rms < 0.75 * fitted->rms))) + // at the end of the diverging track of a switch the curve of the switch goes on wherever it turns its way, however loosely the + // points clicked on the photo keep to it + auto const switched = [](editor_track::snap_target const &Joint, bool const Curved) { return Curved && Joint.track != nullptr && Joint.track->eType == tt_Switch; }; + auto const obliged{switched(tool.start, base.start_curved) || switched(End, base.end_curved)}; + if (other->valid && (false == fitted->valid || false == goes_on || (loose && false == obliged && other->rms < 0.75 * fitted->rms))) { fitted = other; // the line laid from the end of the transition out of the curve, which lay_pieces lays before it