17
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-11-02 16:19:13 +01:00

fix(track): the cross level of an uneven track goes by the place, not by how it was laid

Tracks laid towards each other settled to opposite sides: a step of cant
of twice the value at their joint, in the geometry and under the axles.
It's now a tilt of the plan, which reads the same from either track.
This commit is contained in:
maj00r
2026-10-31 18:23:19 +01:00
parent b2dcb8a42e
commit e74bbf951f
4 changed files with 32 additions and 11 deletions

View File

@@ -380,7 +380,7 @@ void TSegment::RaPositionGet(double const fDistance, glm::dvec3 &position, glm::
auto const amount { pOwner->uneven_at( fDistance ) };
rotation.x += static_cast<float>( track_uneven::stray_per_mm * (
amount.up * track_uneven::roll( position, across, gauge )
+ amount.cross * track_uneven::level( position ) / gauge ) );
+ amount.cross * track_uneven::level( position, across ) / gauge ) );
position += stray( position, fDistance );
}
@@ -411,7 +411,7 @@ void TSegment::settle_vertex( gfx::basic_vertex &Vertex, glm::dvec3 const &Origi
// the rails settling apart turn about the middle of the track, what's outside them follows the rail
auto const gauge { std::max( std::abs( pOwner->fTrackWidth ), 0.1f ) };
auto const across { std::clamp( glm::dot( Vertex.position - Position, Parallel ), -0.5f * gauge, 0.5f * gauge ) };
Vertex.position.y -= static_cast<float>( track_uneven::stray_per_mm * pOwner->uneven_at( Distance ).cross * track_uneven::level( Origin + glm::dvec3 { Position } ) * across / gauge );
Vertex.position.y -= static_cast<float>( track_uneven::stray_per_mm * pOwner->uneven_at( Distance ).cross * track_uneven::level( Origin + glm::dvec3 { Position }, glm::dvec3 { Parallel } ) * across / gauge );
Vertex.position += glm::vec3 { stray( Origin + glm::dvec3 { Vertex.position }, Distance ) };
}

View File

@@ -22,7 +22,7 @@ namespace track_uneven {
inline constexpr float most { 100.f }; // largest value of the attributes, mm
inline constexpr double stray_per_mm { 0.00145 }; // field amplitude per mm of "uneven", m
inline constexpr double cross_share { 0.6 }; // share of the field amplitude the rails settle apart by
inline constexpr double cross_share { 0.53 }; // share of the field amplitude the rails settle apart by
inline constexpr double fade { 20.0 }; // length over which a track goes from the value at its end to its own, m
inline constexpr double dip_share { 0.4 }; // joint dip depth per mm of "uneven", mm
inline constexpr double dip_reach { 3.0 }; // reach of the dip on each side of a joint, m
@@ -64,8 +64,9 @@ inline constexpr std::array<double, 8> wave_shares { 0.0721, 0.0997, 0.1344, 0.1
inline wave_set<8> const up_waves { make_waves( 0.0, wave_lengths, wave_shares ) };
inline wave_set<8> const x_waves { make_waves( 1.1, wave_lengths, wave_shares ) };
inline wave_set<8> const z_waves { make_waves( 2.3, wave_lengths, wave_shares ) };
// long waves only: with the short ones the cross level reaching its limit would break the limit of twist
inline wave_set<3> const cross_waves { make_waves<3>( 0.7, { 23.9, 31.7, 41.9 }, { 1.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0 } ) };
// the tilt along each axis of the plan. Long waves only: with the short ones the cross level reaching its limit would break the limit of twist
inline wave_set<3> const tilt_x_waves { make_waves<3>( 0.7, { 23.9, 31.7, 41.9 }, { 1.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0 } ) };
inline wave_set<3> const tilt_z_waves { make_waves<3>( 2.9, { 23.9, 31.7, 41.9 }, { 1.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0 } ) };
template <std::size_t Count>
double sum( wave_set<Count> const &Waves, glm::dvec3 const &Point ) {
@@ -83,10 +84,11 @@ inline glm::dvec3 field( glm::dvec3 const &Point ) {
return { sum( x_waves, Point ), sum( up_waves, Point ), sum( z_waves, Point ) };
}
// how much lower the right rail lies by settling apart, for an amplitude of 1. Follows the middle of a path, so plain tracks only
inline double level( glm::dvec3 const &Point ) {
// how much lower the rail towards Across lies by settling apart, for an amplitude of 1. A tilt of the plan, so tracks laid towards each
// other meet at one cant. Follows the middle of a path, so plain tracks only
inline double level( glm::dvec3 const &Point, glm::dvec3 const &Across ) {
return cross_share * sum( cross_waves, Point );
return cross_share * ( Across.x * sum( tilt_x_waves, Point ) + Across.z * sum( tilt_z_waves, Point ) );
}
// roll made by the field for an amplitude of 1; positive lowers the rail towards Across, as the roll of a path