17
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-10-17 07:29:20 +02:00
Files
maszyna/maj0sted/tests/test_parallelism.cpp
maj00r a083269867 Vendor the maj0sted track layout library and link it into the editor
Drop-in copy of C:\Users\maj00r\Projects\maj0sted-master minus its web/
directory - the WASM frontend is not being ported, the editor drives the
same C++ API natively. What is left is plain C++20 with no dependencies:
domain model (niweleta, plan and profile geometry, fitting, parallelism),
project serialization, rail sampling and the editor document.

src/web/ribbon.cpp was missing from the library source list; added, since
without it the ribbon symbols never make it into the archive.
2026-08-27 19:36:55 +02:00

86 lines
3.5 KiB
C++

#include <cmath>
#include "check.hpp"
#include "maj0sted/maj0sted.hpp"
using namespace maj0sted::domain;
namespace {
void mark_parallel_references_two_straights() {
// Two identified straights (typically from different niwelety).
const Straight origin{StraightId{10}, CartesianPosition{0.0, 0.0},
CartesianPosition{100.0, 0.0}};
const Straight parallel{StraightId{20}, CartesianPosition{0.0, 5.0},
CartesianPosition{100.0, 5.0}};
const TrackOffset offset{Length::from_metres(5.0), Side::Left};
const auto relation = ParallelismService::mark_parallel(origin, parallel, offset);
CHECK(relation.origin() == StraightId{10});
CHECK(relation.parallel() == StraightId{20});
CHECK(relation.offset().distance().metres() == 5.0);
CHECK(relation.offset().side() == Side::Left);
}
void marking_requires_identified_distinct_straights() {
const Straight anonymous{CartesianPosition{0.0, 0.0}, CartesianPosition{100.0, 0.0}};
const Straight a{StraightId{1}, CartesianPosition{0.0, 0.0},
CartesianPosition{100.0, 0.0}};
const Straight b{StraightId{2}, CartesianPosition{0.0, 5.0},
CartesianPosition{100.0, 5.0}};
const TrackOffset offset{Length::from_metres(5.0), Side::Left};
// A straight without an id cannot be referenced.
CHECK_THROWS(ParallelismService::mark_parallel(anonymous, b, offset));
CHECK_THROWS(ParallelismService::mark_parallel(a, anonymous, offset));
// A straight cannot be parallel to itself (same id).
const Straight a_again{StraightId{1}, CartesianPosition{0.0, 10.0},
CartesianPosition{100.0, 10.0}};
CHECK_THROWS(ParallelismService::mark_parallel(a, a_again, offset));
}
void offset_must_be_positive() {
CHECK_THROWS(TrackOffset(Length::from_metres(0.0), Side::Left));
}
void parallelism_geometry() {
const Straight origin{CartesianPosition{0.0, 0.0}, CartesianPosition{100.0, 0.0}};
const Straight same_direction{CartesianPosition{0.0, 5.0},
CartesianPosition{100.0, 5.0}};
const Straight opposite{CartesianPosition{100.0, 5.0}, CartesianPosition{0.0, 5.0}};
const Straight perpendicular{CartesianPosition{0.0, 0.0},
CartesianPosition{0.0, 50.0}};
CHECK(ParallelismService::are_parallel(origin, same_direction));
CHECK(ParallelismService::are_parallel(origin, opposite)); // anti-parallel lines
CHECK(!ParallelismService::are_parallel(origin, perpendicular));
// Derive a line 5 m to the LEFT of an east-going origin -> to the north (y = +5).
const Straight left = ParallelismService::derive_parallel_line(
origin, TrackOffset{Length::from_metres(5.0), Side::Left});
CHECK(std::abs(left.start().x() - 0.0) < 1e-9);
CHECK(std::abs(left.start().y() - 5.0) < 1e-9);
CHECK(std::abs(left.end().y() - 5.0) < 1e-9);
CHECK(ParallelismService::are_parallel(origin, left));
// To the RIGHT -> to the south (y = -5).
const Straight right = ParallelismService::derive_parallel_line(
origin, TrackOffset{Length::from_metres(5.0), Side::Right});
CHECK(std::abs(right.start().y() + 5.0) < 1e-9);
CHECK(std::abs(ParallelismService::perpendicular_distance(origin, same_direction) -
5.0) < 1e-9);
}
} // namespace
int main() {
RUN(mark_parallel_references_two_straights);
RUN(marking_requires_identified_distinct_straights);
RUN(offset_must_be_positive);
RUN(parallelism_geometry);
return REPORT();
}