mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-11-01 01:09:04 +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:
@@ -59,7 +59,7 @@ TEST_CASE("uneven track: measures as the Id-14 limits for its value")
|
||||
{
|
||||
auto const sign{rail == 0 ? 1.0 : -1.0};
|
||||
auto const stray{track_uneven::field(point + across * (sign * 0.5 * gauge))};
|
||||
up[rail].push_back((stray.y - sign * 0.5 * track_uneven::level(point)) * amplitude);
|
||||
up[rail].push_back((stray.y - sign * 0.5 * track_uneven::level(point, across)) * amplitude);
|
||||
side[rail].push_back(glm::dot(stray, across) * amplitude);
|
||||
}
|
||||
middle.push_back(track_uneven::field(point).y * amplitude);
|
||||
@@ -102,7 +102,26 @@ TEST_CASE("uneven track: a place strays the same every time")
|
||||
CHECK(stray.x == doctest::Approx(0.309777548158).epsilon(1e-9));
|
||||
CHECK(stray.y == doctest::Approx(-0.295557487607).epsilon(1e-9));
|
||||
CHECK(stray.z == doctest::Approx(-0.328429734019).epsilon(1e-9));
|
||||
CHECK(track_uneven::level(place) == doctest::Approx(0.6 * -0.178598957983).epsilon(1e-9));
|
||||
CHECK(track_uneven::level(place, {1.0, 0.0, 0.0}) == doctest::Approx(0.53 * -0.178598957983).epsilon(1e-9));
|
||||
CHECK(track_uneven::level(place, {0.0, 0.0, 1.0}) == doctest::Approx(0.53 * -0.868291889902).epsilon(1e-9));
|
||||
}
|
||||
|
||||
TEST_CASE("uneven track: tracks laid towards each other meet at one cant")
|
||||
{
|
||||
// the same rail stays lower seen from either of them, and a path taken the other way sees the roll turned over
|
||||
glm::dvec3 const place{812.25, 0.0, 3071.5};
|
||||
glm::dvec3 const across{0.6, 0.0, -0.8};
|
||||
CHECK(track_uneven::level(place, -across) == doctest::Approx(-track_uneven::level(place, across)));
|
||||
CHECK(track_uneven::roll(place, -across, 1.435) == doctest::Approx(-track_uneven::roll(place, across, 1.435)));
|
||||
// and there's no step along a curve turning through the headings
|
||||
auto last{track_uneven::level(place, {1.0, 0.0, 0.0})};
|
||||
for (int step = 1; step <= 3600; ++step)
|
||||
{
|
||||
auto const heading{glm::two_pi<double>() * step / 3600.0};
|
||||
auto const value{track_uneven::level(place, {std::cos(heading), 0.0, std::sin(heading)})};
|
||||
REQUIRE(std::abs(value - last) < 0.002);
|
||||
last = value;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("uneven track: the field stays within its bound")
|
||||
|
||||
@@ -58,7 +58,7 @@ Każda składowa łączy się osobno:
|
||||
- **Tor z torem:** na styku obowiązuje mniejsza z dwóch wartości, a każdy tor dochodzi do niej płynnie na 20 m. Wolny koniec toru leży w projekcie.
|
||||
- **Rozjazd:** wszystkie jego drogi mają jedną wartość. Rozjazdy złączone bezpośrednio przyjmują najmniejszą ze swoich. Dołączony tor dochodzi do wartości rozjazdu, także większej od własnej. Tor bez danej składowej trzyma w niej cały rozjazd w projekcie.
|
||||
- **Styki:** zapadnięcia są co `fSoundDistance`, na długości 6 m, i biegną dalej przez kolejne tory o tym samym odstępie. Stukot osi wypada w miejscu zapadnięcia. Przy odstępie 6 m lub mniejszym oraz na rozjazdach zapadnięć nie ma.
|
||||
- **Przechyłka:** dolicza się do projektowej. Na rozjazdach tylko ta wynikająca z fal, bez osobnego siadania toków.
|
||||
- **Przechyłka:** dolicza się do projektowej. Jest pochyleniem w planie mapy, więc tory wpisane ku sobie spotykają się na tej samej przechyłce. Na rozjazdach tylko ta wynikająca z fal, bez osobnego siadania toków.
|
||||
|
||||
Za nierównością idą szyny, podsypka, `sleepermodel`, osie, przechył pudła i bujanie kabiny.
|
||||
|
||||
|
||||
@@ -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 ) };
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user