17
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-10-17 10:59:20 +02:00
Files
maszyna/editor/editorAlignment.hpp
maj00r 16c1ac4c7b feat(editor): two free ends joined without loops or forced curves, the shape from a free end on the wheel
- the join of two free ends (a drag from one onto the other, or a click of the lay tool on it) tries in turn: a straight when the joints check can't see the kinks (half its angle), one circular arc through both ends (a piece cut out of a curve comes back as it was, its cant kept), a curve with straights where the tangents meet, a reverse curve, and only then a free Bezier curve; a curve turning more than it needs to, sharper than 10 m or longer than three chords is never taken
- the transition curves eased out of a curved neighbour only when there's room for them between the ends, never crossing each other into a loop
- cant and transition curves recommended for the radius the curve really gets, at the speed of the joined track or of the tool and never above what the radius allows; the circular arc keeps at least max(20 m, 0.4 V) between the transitions, the cant lowered to what the shortened transitions can ramp, transitions under 1 m left out
- shapes from a free end: arc then straight, straight then arc, arc through the cursor, straight; Ctrl+wheel steps the radius, Shift+wheel the shape (at a free end: the other joins), the plain wheel still zooms; a click of the lay tool from a free end lays the shape and goes on from its end
- self-test commands join, layto and joints; Polish translation
2026-10-11 21:33:27 +02:00

237 lines
5.3 KiB
C++

/*
This Source Code Form is subject to the
terms of the Mozilla Public License, v.
2.0. If a copy of the MPL was not
distributed with this file, You can
obtain one at
http:
*/
#pragma once
#include <string>
#include <vector>
#include <glm/glm.hpp>
#include "world/Segment.h"
namespace alignment
{
enum class transition_shape
{
cubic_parabola,
clothoid
};
struct limits
{
double gauge{1500.0};
double unbalanced{0.6};
double cant_max{150.0};
double cant_rate{35.0};
double ramp_factor{10.0};
double jerk{0.3};
double vertical_factor{0.4};
double vertical_min{2000.0};
double tangent_min_time{0.0};
double arc_min{20.0};
double arc_min_factor{0.4};
};
struct compound_arc
{
double radius{600.0};
double transition{0.0};
double share{1.0};
};
struct vertex
{
glm::dvec2 position{0.0};
double offset{100.0};
double radius{1000.0};
double transition_in{0.0};
double transition_out{0.0};
double cant{0.0};
bool reverse_turn{false};
bool compound{false};
double share{1.0};
std::vector<compound_arc> arcs;
};
struct design
{
glm::dvec3 start{0.0};
glm::dvec3 end{0.0};
glm::dvec2 start_direction{0.0, 1.0};
glm::dvec2 end_direction{0.0, 1.0};
double start_grade{0.0};
double end_grade{0.0};
double start_radius{0.0};
double end_radius{0.0};
// length of the straight beyond the start and the end, which the curves can take over
double start_reserve{0.0};
double end_reserve{0.0};
std::vector<vertex> vertices;
transition_shape shape{transition_shape::cubic_parabola};
double speed{100.0};
int transition_pieces{1};
double arc_piece_angle{10.0};
limits norms;
};
struct recommendation
{
double cant_equilibrium{0.0};
double cant_min{0.0};
double cant{0.0};
double radius_min{0.0};
double transition{0.0};
};
recommendation recommend(double const Speed, double const Radius, limits const &Limits);
double transition_length(double const Speed, double const Radius, double const Cant, limits const &Limits);
double unbalanced_acceleration(double const Speed, double const Radius, double const Cant, limits const &Limits);
enum class element_kind
{
straight,
transition_in,
arc,
transition_out,
spiral
};
struct element
{
element_kind kind{element_kind::straight};
int vertex{-1};
double chainage{0.0};
double length{0.0};
double radius{0.0};
double transition{0.0};
int turn{0};
double cant{0.0};
double curvature_start{0.0};
double curvature_end{0.0};
double curvature_peak{0.0};
glm::dvec2 origin{0.0};
glm::dvec2 direction{0.0, 1.0};
glm::dvec2 normal{0.0};
};
struct curve_report
{
int vertex{-1};
double radius{0.0};
std::vector<double> radii;
double transition_in{0.0};
double transition_out{0.0};
double deflection{0.0};
double arc_length{0.0};
double tangent_in{0.0};
double tangent_out{0.0};
double unbalanced{0.0};
double cant_rate_in{0.0}, cant_rate_out{0.0};
double jerk_in{0.0}, jerk_out{0.0};
recommendation recommended;
};
struct profile_point
{
double chainage{0.0};
double elevation{0.0};
double radius{0.0};
double tangent{0.0};
};
struct result
{
bool valid{false};
transition_shape shape{transition_shape::cubic_parabola};
double gauge{1500.0};
std::vector<std::string> errors;
std::vector<std::string> warnings;
std::vector<glm::dvec2> vertices;
std::vector<double> vertex_chainages;
std::vector<double> vertex_elevations;
std::vector<element> elements;
std::vector<curve_report> curves;
std::vector<profile_point> profile;
double length{0.0};
glm::dvec3 start{0.0};
glm::dvec3 end{0.0};
double start_extension{0.0};
double end_extension{0.0};
};
result compute(design const &Design);
double speed_limit(double const Radius, limits const &Limits);
result compute_recommended(design &Design, bool const Transitions);
bool tangent_intersection(design const &Design, glm::dvec2 &Point);
bool collinear(design const &Design);
struct station
{
glm::dvec3 position{0.0};
glm::dvec3 direction{0.0};
double cant{0.0};
int turn{0};
};
station evaluate(result const &Result, double const Chainage);
double elevation(result const &Result, double const Chainage);
double grade(result const &Result, double const Chainage);
std::size_t minimum_pieces(result const &Result, design const &Design);
// Breaks: ascending chainages at which pieces have to end. Counts: least number of the pieces between the consecutive breaks,
// one more than the breaks; Intervals receives the number of the interval of each piece
std::vector<segment_data> pieces(result const &Result, design const &Design, std::size_t const Count, std::vector<double> const &Breaks = {}, std::vector<std::size_t> const &Counts = {},
std::vector<std::size_t> *Intervals = nullptr);
struct join_end
{
glm::dvec3 position{0.0};
glm::dvec2 direction{0.0, 1.0};
double roll{0.0};
};
enum class join_kind
{
none,
straight,
arc,
curve,
reverse_curve,
bezier
};
struct join_request
{
join_end start;
join_end end;
double radius{0.0};
int variant{0};
bool transitions{false};
double speed{100.0};
double kink{0.1};
transition_shape shape{transition_shape::cubic_parabola};
limits norms;
};
struct join_result
{
join_kind kind{join_kind::none};
std::vector<segment_data> pieces;
double length{0.0};
double radius{0.0};
double cant{0.0};
double transition{0.0};
double speed{0.0};
int variants{0};
std::vector<std::string> warnings;
};
join_result join(join_request const &Request);
}