17
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-10-17 21:29:19 +02:00
Files
maszyna/TURNOUT_REDESIGN.md
maj00r 2376e4867b Editor: rebuild the plan library around a solved document, and bend turnouts onto curves
The library was a heap of half-built services - fitting, parallelism, niwelety,
an SVG writer - that never met each other. In their place is one authored
Document and one solver that lays it whole: tracks as element chains, turnouts
placed on them, and a Solution that is rebuilt from scratch every time and never
fed back into the document. What cannot be laid comes back as a diagnostic with
the number in it rather than as silence or a fitted-away error.

Turnouts are dimensioned the way the drawings dimension them. The blade follows
Koc's rys. 5.9 - the curve is theoretically tangent to the opornica at PR, the
blade starts at a with a planed nose of d, and A is where the rail stands u
thick - and a + d derived that way lands on his tablica 5.1. Bending follows
5.3.6: it rotates the triangle OBC about the centre of the turnout, so the
tangent t and the crossing angle stand and both radii follow from them. That is
Koc's (5.7) and (5.8) without coding either, and it puts a symmetrically bent
Rz 49E1-190-1:9 on the catalogue's Rlus 49E1-380,292-1:9. A rozjazd standing on
a curve is bent onto it; one on a track drawn straight can carry a bend of its
own. The szyny laczace take up the difference, because the switch and the frog
are only bent, not re-cut.

The plan panel draws all of it: the catalogue drawing of a type with its
construction points, the theoretical arc dashed where no rail runs, and the
blade nose as the straight it is cut as. Dragging a straight now stops where it
would pull the track out from under a turnout.

File format goes to m0s 6. Versions 3 to 5 still open.
2026-08-29 19:32:46 +02:00

6.9 KiB

Rozjazdy — jak to powinno być zrobione

Dokument projektowy, nie opis stanu. TURNOUT_SPEC.md mówi, co edytor oddaje runtime'owi; ten mówi, jak edytor powinien trzymać rozjazd u siebie, bo obecny model się nie broni i każda kolejna funkcja jest w nim przypadkiem szczególnym.

1. Co jest dziś

Fakty, nie opinie:

  • NiweletaSpec = lista prostych zakotwiczonych w XY + fits w lukach między kolejnymi prostymi. Krzywa nie jest bytem — jest wynikiem wpasowania w lukę.
  • Junction (rozjazd) to relacja na niwelecie zasadniczej: stacja + liczby katalogowe. Kładzie własną ścieżkę odgałęzienia (lay_turnout), ale ta ścieżka nie należy do żadnej niwelety — jest rysowana osobno z JunctionGeom.
  • Odnoga to osobna niweleta, przypinana sztywno do krzyżownicy przy każdym rozwiązaniu (pin_branch_to_frog).
  • Równolegle istnieje BasketDraft (395 linii) — drugi, własny mechanizm budowania krzywych, nie przechodzący przez model luk.
  • Junction niesie jednocześnie liczby katalogowe (skos, R, długość, iglica) i swobodną krzywą wewnętrzną (GapFit curve z dowolnym koszem).
  • Rozjazdy są serializowane pozycyjnie i ręcznie. pre_blade, blade_angle i blade_length nie są zapisywane w ogóle — doszły do modelu i wypadły z pliku.

2. Cztery przyczyny źródłowe

2.1. Geometria rozjazdu leży poza grafem toru. Tor zasadniczy nie jest dzielony (słusznie), ale odgałęzienie rozjazdu nie należy do niczego, a odnoga jest osobnym bytem. Ciągłość między krzyżownicą a odnogą nie wynika z konstrukcji, tylko z doklejania jej z powrotem przy każdym solve. Stąd błąd „odnoga uciekła 1,4 km", stąd konieczność oddawania pinned do dokumentu, stąd szkic startujący ze starego miejsca.

2.2. Krzywa jest obywatelem drugiej kategorii. Model brzmi „proste i luki między nimi". Wszystko, co nie jest łukiem między dwiema prostymi, wymaga wyjątku: ukryta prosta-prowadnica, tryb 5, BasketDraft. Dlatego „dodaj łuk wprost z krzyżownicy" było trudne — w danych nie ma jak powiedzieć „element: łuk, zaczyna się tutaj".

2.3. Dwa źródła prawdy o współrzędnych. Dokument trzyma to, co narysowane; solver trzyma przypięte i przycięte (rendered_straights). GUI czyta raz jedno, raz drugie. Stąd łuk startujący z azymutem 0 i cała rodzina błędów „to nie jest tam, gdzie jest narysowane".

2.4. Typ katalogowy zmieszany z egzemplarzem. „Rz 1:9 R190" ma geometrię określoną przez typ. Pozwalanie, by egzemplarz miał dowolny łuk koszowy w środku, jest bez sensu — a jednocześnie to, co naprawdę jest swobodne (dokąd biegnie tor za krzyżownicą), było najtrudniejsze do edycji. Skutek uboczny: każda liczba katalogowa to kolejne pole doklejane do formatu pliku.

3. Model docelowy

3.1. KR jest prostą (zrobione)

Najprostsze możliwe ujęcie, i to ono wygrało: koniec rozjazdu to zwyczajna prosta, tylko inaczej związana niż narysowana ręcznie.

StraightSpec {
    ...
    int frog_of;   // indeks rozjazdu, którego KR opuszcza ta prosta; -1 = zwykła
}

Początek i kierunek pisze solver z krzyżownicy, długość zostaje jej własna. I to wszystko — łuk za rozjazdem przestaje istnieć jako pojęcie. Jest fitem w luce między dwiema prostymi, jak każdy inny: to samo combo, ten sam promień, ten sam kosz, ten sam komunikat „does not fit".

Styczność w krzyżownicy nie jest pilnowana, tylko wynika: prosta z KR leży na stycznej, a fit między prostymi jest styczny z definicji.

Skasowało to: przypinanie całej odnogi, tryb 5, ukrytą kotwicę, LeadArc, StartPose i cały pose_fitter. Odnoga przestała być bytem specjalnym — jest niweletą, której pierwsza prosta ma jedną więź więcej.

Efekt uboczny, ważniejszy niż czystość: to, co narysowane, zostaje tam, gdzie narysowane. Wcześniej cała odnoga jechała sztywno za krzyżownicą.

3.2. Element (do zrobienia, ale już nie dla rozjazdów)

„Proste i luki" nadal wymaga wyjątku wszędzie tam, gdzie krzywa ma istnieć sama z siebie — stąd BasketDraft. Docelowo prosta, łuk i klotoida są równorzędnymi elementami ciągu, a to, co dziś robi szkic kosza, jest zwykłym dokładaniem elementów. Rozjazdów to już nie dotyczy: 3.1 załatwiło je bez tego.

3.3. Rozjazd jako urządzenie typu (do zrobienia)

Rozdzielić dwie rzeczy, dziś zlepione w Junction:

TurnoutType {                    // katalog, dane z Id-1, niezmienne
    name, crossing_n, radius, length,
    pre_blade, blade_angle, blade_length, rail_profile
}

TurnoutPlacement {               // to, co edytuje użytkownik
    type : TurnoutTypeRef        // po nazwie, nie przez kopiowanie liczb
    on : AlignmentRef, station, hand : L|P, facing
}

Strefa rozjazdu jest nienaruszalna, bo jest egzemplarzem typu. Nie da się jej edytować, bo nie ma czego — liczby należą do typu. Rozjazd nietypowy to własny typ, nie dowolność w egzemplarzu.

Serializacja przestaje puchnąć: egzemplarz zapisuje type po nazwie plus umiejscowienie. Nowa liczba katalogowa (jak dzisiejsze blade_angle, które wciąż nie trafia do pliku) idzie do katalogu i nie dotyka formatu.

4. Co to naprawia — konkretnie

dzisiejszy problem dlaczego znika
odnoga ucieka / dryfuje od krzyżownicy start odnogi jest referencją do portu
szkic z azymutem 0 nie ma drugiego źródła współrzędnych
„robi się sztywna prosta" za rozjazdem pierwszy element odnogi może być łukiem
łuk wymaga dwóch prostych element powstaje z pozy i punktu
kosz w środku „Rz 1:9" geometria wewnętrzna należy do typu
liczby iglicy nie zapisują się egzemplarz odwołuje się do typu po nazwie
BasketDraft obok modelu kosz to ciąg elementów-łuków, nic osobnego

5. Etapy

  1. Odnoga przestaje być przypinana — zrobione przez 3.1: frog_of. Zniknęły pin_branch_to_frog, tryb 5, ukryta kotwica, LeadArc i pose_fitter.
  2. Typ oddzielony od umiejscowienia (3.3). Katalog Id-1 jako dane; egzemplarz trzyma nazwę typu. Naprawia przy okazji serializację liczb iglicy.
  3. Elementy pierwszej kategorii (3.2) i wycofanie BasketDraft — 395 linii równoległego świata.

6. Co zostaje bez zmian

Warto powiedzieć wprost, bo to nie jest przepisywanie wszystkiego:

  • domain::lay_turnout i cała geometria rozjazdu — dobre, zostaje.
  • TurnoutPart i punkty konstrukcyjne (JunctionMark) — zostają.
  • fit_arc_from_pose, fit_arc_from_pose_through — to są właściwe prymitywy nowego modelu, przechodzą nietknięte.
  • GapFitter i fitowanie między prostymi — zostaje, jako jeden ze sposobów wyznaczania elementu swobodnego.
  • Rysowanie szyn, kafle, georeferencja — bez związku.

Do wyrzucenia jest przede wszystkim klej: przypinanie, ukryte prowadnice, tryb 5 jako wyjątek i BasketDraft.