mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-10-31 05:20:52 +01:00
feat(editor): the hectometre posts go by the kilometrage of the line where the Kilometrage tool sets it, its jumps too, a post at a jump of the km on from it or of the km it is reached at, the km given at the point still there as a choice; the posts standing go with the place of their number nearest to them
This commit is contained in:
@@ -927,6 +927,86 @@ bool km_at(std::string const &Line, glm::dvec3 const &Point, double &Km, double
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string line_at(glm::dvec3 const &Point, double const Reach)
|
||||
{
|
||||
std::string result;
|
||||
auto nearest{Reach};
|
||||
for (auto const &line : lines())
|
||||
if (auto const *found{axis_of(line)}; found != nullptr)
|
||||
{
|
||||
double gap{0.0};
|
||||
chainage_at(*found, Point, gap);
|
||||
if (gap < nearest)
|
||||
{
|
||||
nearest = gap;
|
||||
result = line;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int growth_at(std::string const &Line, glm::dvec3 const &Point, glm::dvec2 const &Way, double const Reach)
|
||||
{
|
||||
auto const *found{axis_of(Line)};
|
||||
if (found == nullptr)
|
||||
return 0;
|
||||
double gap{0.0};
|
||||
auto const chainage{chainage_at(*found, Point, gap)};
|
||||
if (gap > Reach)
|
||||
return 0;
|
||||
return glm::dot(direction_on(*found, chainage) * static_cast<double>(found->growth), Way) >= 0.0 ? 1 : -1;
|
||||
}
|
||||
|
||||
std::vector<hectometre> hectometres(axis const &Axis)
|
||||
{
|
||||
std::vector<hectometre> result;
|
||||
std::vector<double> jumps;
|
||||
for (auto const &anchor : Axis.anchors)
|
||||
if (std::abs(anchor.after - anchor.before) >= 1e-6)
|
||||
jumps.push_back(anchor.chainage);
|
||||
auto const along = [&](std::vector<glm::dvec3> const &Points, std::vector<double> const &Km, std::vector<double> const &Chainage) {
|
||||
for (std::size_t i = 1; i < Points.size(); ++i)
|
||||
{
|
||||
auto const from{std::min(Chainage[i - 1], Chainage[i])};
|
||||
auto const to{std::max(Chainage[i - 1], Chainage[i])};
|
||||
if (std::any_of(jumps.begin(), jumps.end(), [&](double const Jump) { return Jump >= from - 1e-6 && Jump <= to + 1e-6; }))
|
||||
continue;
|
||||
auto const k0{Km[i - 1]};
|
||||
auto const k1{Km[i]};
|
||||
if (std::abs(k1 - k0) < 1e-9)
|
||||
continue;
|
||||
auto way{plan_of(Points[i] - Points[i - 1])};
|
||||
way = glm::length(way) > 1e-9 ? glm::normalize(way) : glm::dvec2{0.0, 1.0};
|
||||
auto const first{static_cast<int>(std::floor(std::min(k0, k1) * 10.0 + 1e-9)) + 1};
|
||||
auto const last{static_cast<int>(std::floor(std::max(k0, k1) * 10.0 + 1e-9))};
|
||||
for (auto number = first; number <= last && number < first + 10; ++number)
|
||||
result.push_back({glm::mix(Points[i - 1], Points[i], (number / 10.0 - k0) / (k1 - k0)), k1 > k0 ? way : -way, number});
|
||||
}
|
||||
};
|
||||
// at a jump the post of the km on from it, as the posts of a line built anew begin there, else of the km the jump is reached at
|
||||
for (auto const &anchor : Axis.anchors)
|
||||
{
|
||||
if (std::abs(anchor.after - anchor.before) < 1e-6)
|
||||
continue;
|
||||
auto const round = [](double const Km) { return std::abs(Km * 10.0 - std::round(Km * 10.0)) < 1e-4; };
|
||||
auto const km{round(anchor.after) ? anchor.after : anchor.before};
|
||||
if (round(km))
|
||||
result.push_back({point_on(Axis, anchor.chainage), direction_on(Axis, anchor.chainage) * static_cast<double>(Axis.growth), static_cast<int>(std::lround(km * 10.0))});
|
||||
}
|
||||
std::vector<double> km;
|
||||
for (auto const chainage : Axis.chainage)
|
||||
km.push_back(km_on(Axis, chainage));
|
||||
along(Axis.points, km, Axis.chainage);
|
||||
for (auto const &side : Axis.sides)
|
||||
{
|
||||
km.clear();
|
||||
for (auto const distance : side.along)
|
||||
km.push_back(km_on(Axis, side, distance));
|
||||
along(side.points, km, side.chainage);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
TTrack *track_near(glm::dvec3 const &Point, double const Reach)
|
||||
{
|
||||
TTrack *best{nullptr};
|
||||
|
||||
@@ -127,6 +127,20 @@ glm::dvec2 direction_on(axis const &Axis, double const Chainage);
|
||||
double km_on(axis const &Axis, axis::side const &Side, double const Along);
|
||||
// the km of the line at the point, when it lies within the reach of the axis
|
||||
bool km_at(std::string const &Line, glm::dvec3 const &Point, double &Km, double const Reach = 30.0);
|
||||
// the line whose axis, or a track running apart from it, passes nearest to the point within the reach, empty for none
|
||||
std::string line_at(glm::dvec3 const &Point, double const Reach = 30.0);
|
||||
// the km of the line rise along the way at the point: 1, against it: -1, 0 where the axis doesn't reach
|
||||
int growth_at(std::string const &Line, glm::dvec3 const &Point, glm::dvec2 const &Way, double const Reach = 30.0);
|
||||
// a hectometre the km of a line pass
|
||||
struct hectometre
|
||||
{
|
||||
glm::dvec3 at{0.0};
|
||||
glm::dvec2 rising{0.0, 1.0}; // the way the km rise there, in the plan
|
||||
int number{0}; // of the hectometres from km 0, 1043 for km 104,3
|
||||
};
|
||||
// the hectometres along the axis and along the tracks running apart from it; at a jump the one of the km on from it, else of
|
||||
// the km it is reached at, whichever is a whole hectometre
|
||||
std::vector<hectometre> hectometres(axis const &Axis);
|
||||
// the track nearest to the point in the plan within the reach, nullptr for none
|
||||
TTrack *track_near(glm::dvec3 const &Point, double const Reach);
|
||||
// the path of the track nearest to the point in the plan, On: the point of it nearest
|
||||
|
||||
Reference in New Issue
Block a user