From b0918628b40c22923e599b02a6987ac47ab5afcf Mon Sep 17 00:00:00 2001 From: maj00r Date: Tue, 27 Oct 2026 19:41:50 +0100 Subject: [PATCH] fix(editor): a curve traced from the end of the diverging track of a switch with one point clicked goes on with the curve of the switch as far as abreast of the point, seen from its centre, and ends on it there, instead of turning into a straight where the straight to the point left it: the curve is held to where it was clicked, a point inside it as well. Selftest: one point after P4 of a Rz 60E1-300-1:9 laid R 300 m on to 238.36 13.31 for a point at 240 8, to 243.31 14.88 for one at 240 25, the curvature at P4 going on within 0.5 % --- application/editormodelay.cpp | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/application/editormodelay.cpp b/application/editormodelay.cpp index 934bbce6..25ea4052 100644 --- a/application/editormodelay.cpp +++ b/application/editormodelay.cpp @@ -1148,8 +1148,8 @@ 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}; @@ -1157,25 +1157,21 @@ bool editor_mode::lay_line(std::vector const &Points, std::vectory * 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) + auto const outward{plan_of(Points[1]) - centre}; + if (glm::length(outward) > 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()) + // how far round the curve turns to there + auto sweep{std::fmod(side * (std::atan2(outward.y, outward.x) - std::atan2(from.y - centre.y, from.x - centre.x)), 2.0 * glm::pi())}; + if (sweep < 0.0) + sweep += 2.0 * glm::pi(); + if (sweep > 1e-3 && sweep < 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); + bends.push_back({lifted(from + *along * (radius * std::tan(0.5 * sweep)), anchor.y), curve, false}); + anchor = lifted(centre + glm::normalize(outward) * radius, Points[1].y); + along = turned(*along, side * sweep); i = last; continue; }