如何使用 TikZ 来模拟铁路规划?

如何使用 TikZ 来模拟铁路规划?

由于 LaTeX 可以做很多花哨的事情,那么是否有可能创建模型铁路的布局?我知道只有专用的(主要是 Windows)程序可以做到这一点,例如http://www.sandiasoftware.com/(以下图片来自该网站)

在此处输入图片描述

我认为TikZ这应该是可能的(对于 2D)。

答案1

有几种程序可以规划和建造模型铁路。看来您终于知道其中一种了。它们的一个优点是可以打印建造模型铁路所用零件的清单。

要使用 TikZ 创建布局计划,您必须编写新代码来使用 TikZ 布局计划。这并不容易,而且工作量很大(正如@MartinH 在其评论中所说的那样)。

我个人认为重新创建它是没有意义的。更好的方法是使用现有的程序并将结果包含在内\includegraphics。如果您对图片质量有疑问,请更改规划软件中用于保存计划的格式(更改为、、.jpg)。如果这不可能,请考虑更改模型铁路的规划程序。.pdf.epc

答案2

我最近遇到了这个问题,并记得我已经做过类似的事情。因此,我想与大家分享我的方法。总体思路是定义底层绘图机制和样式。然后,您需要为某个制造商(在我的情况下是 Märklin)定义特定轨道,然后就可以开始绘图了。

虽然绘制直线和曲线段非常简单,但绘制道岔却很棘手。由于我的解决方案只是一个概念验证,我应用了一种技术,其中只能从单端插入道岔,然后继续从直端绘制。弯曲端的位置被存储起来,您需要从那里开始绘制新的干线。在车站,这可能相当棘手,创建一种机制来定义要从哪一侧开始会很有用。此外,道岔的定义还没有像直线和曲线那样实现自动化。尽管如此,它表明这是可能的,但现在需要一种特殊的思维方式。

当然,你也可以将机车、货车、房屋和其他所有东西放在轨道上或轨道旁边。只需加载图像并正确缩放即可。这样就很容易确定轨道的长度是否足够等等。

这是我的结果,代码如下:

在此处输入图片描述

\documentclass[tikz,border=5mm]{standalone}

\usepackage[sfdefault,lining]{FiraSans}
\usepackage{siunitx}

\usetikzlibrary{decorations.markings,decorations.pathmorphing,decorations.pathreplacing,arrows.meta}

%Redefine font size
\renewcommand{\scriptsize}{\fontsize{1.5mm}{2mm}\selectfont}

%Starting angle
\newcommand{\currentangle}{180}

%Save and restore a position and an angle (for switches)
\newcommand{\storeLocation}[2]{coordinate(#1) \pgfextra{\pgfmathsetmacro\switchangle{\currentangle + #2} \expandafter\xdef\csname #1\endcsname{\switchangle}}}
\newcommand{\getLocation}[1]{\pgfextra{\renewcommand{\currentangle}{\csname #1\endcsname}} (#1)}
\newcommand{\getLocationInverted}[1]{\pgfextra{\renewcommand{\currentangle}{\csname #1\endcsname}\pgfmathsetmacro\currentangle{\currentangle + 180}} (#1)}

%Commands to create new track
\newcommand{\newTrack}[3][]{\renewcommand{\currentangle}{#2}\draw[line width=4,postaction=show track segments,#1] #3;}

%Commands to create new curved track
\newcommand{\curveL}[3]{arc (\currentangle-180:\currentangle - 180 + #2:#3) node[midway,sloped,white,font=\scriptsize]{#1} \pgfextra{\pgfmathsetmacro\currentangle{\currentangle + #2}}}
\newcommand{\curveR}[3]{arc (\currentangle:\currentangle - #2:#3) node[midway,sloped,white,font=\scriptsize]{#1} \pgfextra{\pgfmathsetmacro\currentangle{\currentangle - #2}}}
\newcommand{\newcurve}[4]{\expandafter\newcommand\csname #1L\endcsname{\curveL{#2}{#3}{#4}}\expandafter\newcommand\csname #1R\endcsname{\curveR{#2}{#3}{#4}}}

%Define curves for Märklin
\newcurve{s}{24130}{30}{36}
\newcurve{m}{24230}{30}{43.75}
\newcurve{l}{24330}{30}{51.5}
\newcurve{xl}{24430}{30}{57.93}
\newcurve{xxl}{24530}{30}{64.36}
\newcurve{wide}{24912}{12.1}{111.46}

%Commands to create new straight track
\newcommand{\newstraight}[3]{\expandafter\newcommand\csname #1\endcsname{-- ++(\currentangle - 90:#3) node[midway,sloped,white,font=\scriptsize]{#2}}}

%Define straights for Märklin
\newstraight{single}{24180}{18}
\newstraight{double}{24360}{36}

%Define switches
\newcommand{\wideSwitchL}[1]{coordinate(switchstart) arc (\currentangle-180:\currentangle - 180 + 12.1:111.46) \storeLocation{#1}{+12.1} (switchstart) -- ++(\currentangle-90:23.61) node[midway,sloped,white,font=\scriptsize]{24711}}

\newcommand{\wideSwitchR}[1]{coordinate(switchstart) arc (\currentangle:\currentangle - 12.1:111.46) \storeLocation{#1}{-12.1} (switchstart) -- ++(\currentangle-90:23.61) node[midway,sloped,white,font=\scriptsize]{24712}}

%Define special tracks (move to other commands)
\newcommand{\wideAddition}{-- ++(\currentangle - 90:7.08) node[midway,sloped,white,font=\scriptsize]{24071}}
\newcommand{\wideCorrection}{-- ++(\currentangle - 90:22.91) node[midway,sloped,white,font=\scriptsize]{24229}}
\newcommand{\widelength}{-- ++(\currentangle - 90:23.61) node[midway,sloped,white,font=\scriptsize]{24236}}

%Define how tracks should appear
\tikzset{
    show track segments/.style={
        decoration={
            show path construction,
            moveto code={},
            lineto code={
                \draw [{Tee Barb[line width=1pt,inset=0pt,length=0pt,width=12]}-{Tee Barb[line width=1pt,inset=0pt,length=0pt,width=12]}] (\tikzinputsegmentfirst) -- (\tikzinputsegmentlast);
            },
            curveto code={
                \draw [{Tee Barb[line width=1pt,inset=0pt,length=0pt,width=12]}-{Tee Barb[line width=1pt,inset=0pt,length=0pt,width=12]}] (\tikzinputsegmentfirst) .. controls
                (\tikzinputsegmentsupporta) and (\tikzinputsegmentsupportb)
                ..(\tikzinputsegmentlast);
            },
            closepath code={
                \draw [{Tee Barb[line width=1pt,inset=0pt,length=0pt,width=12]}-{Tee Barb[line width=1pt,inset=0pt,length=0pt,width=12]}] (\tikzinputsegmentfirst) -- (\tikzinputsegmentlast);
            }
        },decorate
    },
lok links/.style={anchor=west,inner sep=0pt,outer sep=0pt}
}

%Start drawing the layout
\begin{document}
    \begin{tikzpicture}[scale=0.1]
    
    %Measurements
    \draw[<->,xshift=-10mm] (0,-330) -- (0,0) node[midway,sloped,above]{\SI{330}{\centi\metre}};
    \draw[<->,yshift=10mm] (0,0) -- (330,0) node[midway,sloped,above]{\SI{330}{\centi\metre}};
    \draw[<->,xshift=10mm] (337,-30) -- (337,0) node[midway,sloped,below]{$\leq\SI{30}{\centi\metre}$};
    \draw[<->,yshift=-10mm] (0,-330) -- (30,-330) node[midway,sloped,below]{$\leq\SI{30}{\centi\metre}$};
    
    %Surface
    \fill[lightgray,text=red] (0,-330)node{1} -| ++(30,140)node{2} -- ++(-20,120)node{3} -- ++(40,40)node{4} -| ++(257,-110) -| ++(30,140)node{5} -| cycle;
    
    %Layout
    \draw[line width=4,orange,postaction=show track segments] (3,-67.36) \storeLocation{startpunkt}{0} \xxlR \xxlR \xxlR \wideSwitchR{StreckengleisHolzverladung} \double \double \double;
    
    \draw[line width=4,orange,postaction=show track segments] \getLocation{StreckengleisHolzverladung} \single \single \single \wideL \wideSwitchL{gleis2} \wideAddition coordinate(gleis3Zughalt) \wideCorrection \wideAddition \wideCorrection \wideCorrection \wideAddition \widelength \single \storeLocation{prellbock}{180};
    
    \draw[line width=4,orange,postaction=show track segments] \getLocation{prellbock} \single \wideSwitchR{prellbockweiche};
    
    \draw[line width=4,orange,postaction=show track segments] \getLocation{prellbockweiche} \wideAddition \wideL;
    
    \draw[line width=4,orange,postaction=show track segments] \getLocation{gleis2} \wideAddition \wideSwitchR{gleis1} \wideAddition \wideR \wideCorrection \wideAddition \widelength \single;
    
    \draw[line width=4,orange,postaction=show track segments] \getLocation{gleis1} \wideAddition \wideCorrection;
    

    
    \draw[line width=4,magenta,postaction=show track segments] \getLocationInverted{startpunkt} \wideSwitchL{gleisanschluss} \wideAddition \wideL \double \double \wideR \wideSwitchR{bahnhofgleis2} \wideAddition \wideR \double;
    
    \draw[line width=4,blue,postaction=show track segments] \getLocation{gleisanschluss} \wideAddition \double \double;
    
    \end{tikzpicture}
\end{document}

相关内容