From 62f8932f158ba82874110db5f1cd13a535111dd2 Mon Sep 17 00:00:00 2001 From: maj00r Date: Fri, 23 Oct 2026 17:44:35 +0200 Subject: [PATCH] fix(sleepers): a rail with its check rail on the side away from a rail close beside, as the outer rails at the acute crossings of the slips with the blades outside of the diamond, in the fastening with its check rail, the rail beside in a plate of its own; a plate still lying over a fastening of more than a plate after the narrowing left out --- world/SleeperFastenings.cpp | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/world/SleeperFastenings.cpp b/world/SleeperFastenings.cpp index 72b084c7..c9cd5945 100644 --- a/world/SleeperFastenings.cpp +++ b/world/SleeperFastenings.cpp @@ -181,7 +181,24 @@ std::vector fastened_rails::on( beam const &Beam, beam_model const &M auto const &rail { rails[ index ] }; if( index + 1 < rails.size() && rails[ index + 1 ].at - rail.at < fastening_pair && rail.kind != role::stock && rails[ index + 1 ].kind != role::stock ) { auto const &other { rails[ index + 1 ] }; - if( other.at - rail.at < fastening_nose ) { + // a rail of the two with its check rail on the side away from the other one in the fastening with the check rail, + // the other one in a plate of its own + auto const away = [&]( hit const &Rail, double const Toward ) { + return Rail.kind == role::checked && glm::dot( Rail.inward, axis ) * Toward < 0.0; }; + auto const awayfirst { away( rail, 1.0 ) }; + auto const awaysecond { away( other, -1.0 ) }; + if( has( part_check ) && ( awayfirst || awaysecond ) ) { + auto const joined { other.at - rail.at < fastening_nose }; + for( auto const &[ one, checked ] : { std::make_pair( &rail, awayfirst ), std::make_pair( &other, awaysecond ) } ) { + if( checked ) { + result.push_back( { part_check, point( one->at ), one->inward, 1.f, static_cast( 0.5 * check_seats ) } ); + } + else if( false == joined ) { + result.push_back( { part_plate, point( one->at ), one->inward } ); + } + } + } + else if( other.at - rail.at < fastening_nose ) { result.push_back( { part_plate, point( 0.5 * ( rail.at + other.at ) ), rail.inward } ); } else if( has( part_check ) ) { @@ -307,6 +324,13 @@ void fastened_rails::fit( std::vector &Fastenings, beam const &Beam, } } return false; }; + auto const plates = [&]( std::pair const &Rail ) { + for( auto member { Rail.first }; member < Rail.second; ++member ) { + if( Fastenings[ order[ member ] ].part != part_plate ) { + return false; + } + } + return true; }; auto const extent = [&]( std::pair const &Rail ) { glm::dvec2 result { 0.0 }; for( auto member { Rail.first }; member < Rail.second; ++member ) { @@ -355,6 +379,16 @@ void fastened_rails::fit( std::vector &Fastenings, beam const &Beam, brace( second, 0 ); } } + // a rail in a plate still lying over the fastening of a rail beside held with more than a plate goes without its own + if( overlaps() ) { + if( plates( second ) && false == plates( first ) ) { + drop( second ); + continue; + } + if( plates( first ) && false == plates( second ) ) { + drop( first ); + } + } kept = index; } std::vector fitted;