mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-10-17 03:59:19 +02:00
feat(track): a check rail is held to its running rail by spacer blocks every 0.5 m along its straight part, laid in the same way as the spacers of a guard rail at a wide crossing, below the head from the web of the running rail to the face of the check rail, so the flangeway stays open above them; a check rail replaced by a wing rail gets none; the spacing of spacers and castings is shared by guard rails and check rails
This commit is contained in:
@@ -126,6 +126,12 @@ bool replaced_check( std::vector<check_rail> const &Checks, double const Wingend
|
||||
return false;
|
||||
}
|
||||
|
||||
bool replaced_by_wing( check_rail const &Check, knots::line const &Wingends ) {
|
||||
|
||||
auto farend { 0.0 };
|
||||
return std::any_of( Wingends.begin(), Wingends.end(), [&]( glm::dvec2 const &Wing ) { return replaced_check( { Check }, Wing.x, Wing.y, farend ); } );
|
||||
}
|
||||
|
||||
// gauge line of a rail of a track, along a path of a switch from past its blades when Blades
|
||||
gauge_line const &rail_line( TTrack const &Track, int const Path, int const Side, bool const Blades ) {
|
||||
|
||||
|
||||
@@ -607,19 +607,15 @@ void TTrack::rail_layer::lay_guards() {
|
||||
void TTrack::rail_layer::lay_checks() {
|
||||
|
||||
auto const &shape { m_drawing.checkshapes[ m_side > 0 ? 0 : 1 ] };
|
||||
auto const &wingends { ours( m_layout.wingends ) };
|
||||
for( auto const &check : m_layout.checks[ m_path ][ m_side > 0 ] ) {
|
||||
auto const replaced { std::any_of( wingends.begin(), wingends.end(), [&]( glm::dvec2 const &Wing ) {
|
||||
auto farend { 0.0 };
|
||||
return replaced_check( { check }, Wing.x, Wing.y, farend ); } ) };
|
||||
auto const a { std::max( check.from, m_from ) };
|
||||
auto const b { std::min( check.to, m_length ) };
|
||||
if( replaced || b - a <= 0.01 ) {
|
||||
if( replaced_by_wing( check, ours( m_layout.wingends ) ) || b - a <= 0.01 ) {
|
||||
continue;
|
||||
}
|
||||
piece(
|
||||
shape,
|
||||
{ .from = a, .to = b, .offsets = flared( check.from, check.to, std::min( 0.6, 0.4 * ( check.to - check.from ) ), 0.0, check.flarefrom, check.flareto ), .capfrom = a > 0.0 || check.from >= 0.0, .capto = check.to <= m_length, .rolled = false },
|
||||
{ .from = a, .to = b, .offsets = flared( check.from, check.to, check_flare( check ), 0.0, check.flarefrom, check.flareto ), .capfrom = a > 0.0 || check.from >= 0.0, .capto = check.to <= m_length, .rolled = false },
|
||||
{ a, b, { a == check.from ? check.frombend : 0.0 }, { b == check.to ? check.tobend : 0.0 } } );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ double constexpr casting_reach { 0.3 };
|
||||
double constexpr square_slope { 3.0 };
|
||||
double constexpr spacer_length { 0.12 };
|
||||
double constexpr spacer_pitch { 0.5 };
|
||||
double constexpr check_flangeway { 0.041 };
|
||||
|
||||
// where the inner rails of the two paths of a switch cross, found from their gauge lines behind the blades
|
||||
struct switch_frog {
|
||||
@@ -87,6 +88,10 @@ struct check_rail {
|
||||
double tobend { 0.0 };
|
||||
};
|
||||
using check_rail_set = std::array<std::array<std::vector<check_rail>, 2>, 2>; // path, right side
|
||||
inline double check_flare( check_rail const &Check ) {
|
||||
|
||||
return std::min( guard_flare, 0.4 * ( Check.to - Check.from ) );
|
||||
}
|
||||
// a rail broken where another one crosses it: the part coming from below ends at end, the part going on starts at start
|
||||
struct rail_cut {
|
||||
double at { 0.0 };
|
||||
|
||||
@@ -142,17 +142,10 @@ track_rails::rail_cut corner_cut( track_rails::rail_crossing const &Crossing, do
|
||||
return cut;
|
||||
}
|
||||
|
||||
std::vector<track_rails::rail_fill> guard_fills( track_rails::guard_rail const &Guard, track_rails::rail_size const &Size ) {
|
||||
std::vector<track_rails::rail_fill> spacer_fills( track_rails::rail_fill const &Whole, double const From, double const To, knots::line const &Castings ) {
|
||||
|
||||
auto const offset { Size.web - ( flangeway + Size.head ) };
|
||||
auto const flare { std::min( guard_flare, 0.25 * ( Guard.to - Guard.from ) ) };
|
||||
track_rails::rail_fill whole;
|
||||
whole.web = true;
|
||||
whole.lift = ( Guard.through ? 0.0 : -0.001 );
|
||||
whole.inner = { { Guard.from, offset - ( Guard.flarefrom ? 0.02 : 0.0 ) }, { Guard.from + flare, offset }, { Guard.to - flare, offset }, { Guard.to, offset - ( Guard.flareto ? 0.02 : 0.0 ) } };
|
||||
whole.outer = { { Guard.from, Size.web }, { Guard.to, Size.web } };
|
||||
knots::line pieces;
|
||||
for( auto const &casting : Guard.castings ) {
|
||||
for( auto const &casting : Castings ) {
|
||||
if( false == pieces.empty() && casting.x <= pieces.back().y ) {
|
||||
pieces.back().y = std::max( pieces.back().y, casting.y );
|
||||
}
|
||||
@@ -161,14 +154,14 @@ std::vector<track_rails::rail_fill> guard_fills( track_rails::guard_rail const &
|
||||
}
|
||||
}
|
||||
knots::line spacers;
|
||||
auto const place = [&]( double const From, double const To, double const Step ) {
|
||||
auto const count { static_cast<int>( std::floor( ( To - From - 0.5 * spacer_length ) / spacer_pitch ) ) };
|
||||
auto const place = [&]( double const Start, double const End, double const Step ) {
|
||||
auto const count { static_cast<int>( std::floor( ( End - Start - 0.5 * spacer_length ) / spacer_pitch ) ) };
|
||||
for( int i = 1; i <= count; ++i ) {
|
||||
auto const at { ( Step > 0.0 ? From : To ) + Step * i * spacer_pitch };
|
||||
auto const at { ( Step > 0.0 ? Start : End ) + Step * i * spacer_pitch };
|
||||
spacers.emplace_back( at - 0.5 * spacer_length, at + 0.5 * spacer_length );
|
||||
} };
|
||||
auto const first { Guard.from + spacer_length };
|
||||
auto const last { Guard.to - spacer_length };
|
||||
auto const first { From + spacer_length };
|
||||
auto const last { To - spacer_length };
|
||||
if( pieces.empty() ) {
|
||||
place( first - spacer_pitch, last, 1.0 );
|
||||
}
|
||||
@@ -184,9 +177,9 @@ std::vector<track_rails::rail_fill> guard_fills( track_rails::guard_rail const &
|
||||
pieces.insert( pieces.end(), spacers.begin(), spacers.end() );
|
||||
std::vector<track_rails::rail_fill> fills;
|
||||
for( auto const &piece : pieces ) {
|
||||
auto fill { whole };
|
||||
fill.from = std::max( piece.x, Guard.from );
|
||||
fill.to = std::min( piece.y, Guard.to );
|
||||
auto fill { Whole };
|
||||
fill.from = std::max( piece.x, From );
|
||||
fill.to = std::min( piece.y, To );
|
||||
fill.capfrom = true;
|
||||
fill.capto = true;
|
||||
if( fill.to - fill.from > 0.01 ) {
|
||||
@@ -196,6 +189,29 @@ std::vector<track_rails::rail_fill> guard_fills( track_rails::guard_rail const &
|
||||
return fills;
|
||||
}
|
||||
|
||||
std::vector<track_rails::rail_fill> guard_fills( track_rails::guard_rail const &Guard, track_rails::rail_size const &Size ) {
|
||||
|
||||
auto const offset { Size.web - ( flangeway + Size.head ) };
|
||||
auto const flare { std::min( guard_flare, 0.25 * ( Guard.to - Guard.from ) ) };
|
||||
track_rails::rail_fill whole;
|
||||
whole.web = true;
|
||||
whole.lift = ( Guard.through ? 0.0 : -0.001 );
|
||||
whole.inner = { { Guard.from, offset - ( Guard.flarefrom ? 0.02 : 0.0 ) }, { Guard.from + flare, offset }, { Guard.to - flare, offset }, { Guard.to, offset - ( Guard.flareto ? 0.02 : 0.0 ) } };
|
||||
whole.outer = { { Guard.from, Size.web }, { Guard.to, Size.web } };
|
||||
return spacer_fills( whole, Guard.from, Guard.to, Guard.castings );
|
||||
}
|
||||
|
||||
std::vector<track_rails::rail_fill> check_fills( track_rails::check_rail const &Check, track_rails::rail_size const &Size ) {
|
||||
|
||||
auto const from { Check.from + check_flare( Check ) };
|
||||
auto const to { Check.to - check_flare( Check ) };
|
||||
track_rails::rail_fill whole;
|
||||
whole.web = true;
|
||||
whole.inner = { { from, -check_flangeway }, { to, -check_flangeway } };
|
||||
whole.outer = { { from, Size.web }, { to, Size.web } };
|
||||
return spacer_fills( whole, from, to, {} );
|
||||
}
|
||||
|
||||
bool goes_through( TTrack const &Track, TTrack const &Other ) {
|
||||
|
||||
if( Track.name() != Other.name() ) {
|
||||
@@ -468,6 +484,16 @@ rail_layout TTrack::rail_planner::lay_out() {
|
||||
if( m_track.eType == tt_Switch ) {
|
||||
switch_frog();
|
||||
}
|
||||
for( int path = 0; path < 2; ++path ) {
|
||||
for( int side = 0; side < 2; ++side ) {
|
||||
for( auto const &check : m_layout.checks[ path ][ side ] ) {
|
||||
if( false == replaced_by_wing( check, m_layout.wingends[ path ][ side ] ) ) {
|
||||
auto const fills { check_fills( check, m_size ) };
|
||||
m_layout.fills[ path ][ side ].insert( m_layout.fills[ path ][ side ].end(), fills.begin(), fills.end() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return m_layout;
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ int path_count( TTrack const &Track );
|
||||
TTrack *path_neighbour( TTrack const &Track, int const Path, int const End );
|
||||
double knuckle_bend( double const Into );
|
||||
bool replaced_check( std::vector<check_rail> const &Checks, double const Wingend, double const Direction, double &Far );
|
||||
bool replaced_by_wing( check_rail const &Check, knots::line const &Wingends );
|
||||
gauge_line const &rail_line( TTrack const &Track, int const Path, int const Side, bool const Blades );
|
||||
check_rail_set const &rail_checks( TTrack &Track );
|
||||
glm::dvec3 rail_point( TTrack const &Track, int const Path, int const Side, double const Distance, double const Lateral );
|
||||
|
||||
Reference in New Issue
Block a user