
노모그램이란 무엇입니까?
"ㅏ노모그램노모그래프, 정렬 차트 또는 아바크라고도 불리는 는 그래픽 계산 장치로, 함수의 대략적인 그래픽 계산을 허용하도록 설계된 2차원 다이어그램입니다.
예
이 노모그램 상단에 제시된 로켓 방정식은 왼쪽 눈금에서 오른쪽 눈금까지 선을 그리면 풀 수 있습니다. 용액은 중앙의 눈금에서 읽을 수 있습니다.
질문
LaTeX에서 위 그림을 어떻게 재현할 수 있나요? TikZ 접근 방식이 있습니까?
보너스 질문
LaTeX로 임의의 노모그램을 어떻게 만들 수 있나요?
추가 정보
위 그림은 다음을 사용하여 생성되었습니다.http://pynomo.org/wiki/index.php?title=Main_Page
노모그래피에 대한 추가 정보:http://www.slideshare.net/arulalan/nomography
답변1
부인 성명
이를 시작점으로 삼아 솔루션이 모든 경우에 실제로 작동하도록 하려면 수행해야 할 몇 가지 작업이 있습니다. 즉:
- 나머지(최대/최소)!=0인 경우를 처리합니다.
최소 처리!=0최소에서 최대까지 외에 최대에서 최소까지 규모를 처리합니다.
가능성:
\documentclass[tikz,border=10pt]{standalone}
\usepackage{pdftexcmds,etoolbox}
\makeatletter
\newif\ifroundedenabled%
\newif\ifscalemaxtomin%
\newif\ifscalefromzero%
\pgfkeys{/nomogram/.cd,
% keys for a single diagram
part 1/.style={},
part 2/.style={},
part 3/.style={},
single diagram/.cd,
scale max to min/.is if=scalemaxtomin,
scale max to min=false,
scale from zero/.is if=scalefromzero,
scale from zero=true,
at pos/.store in=\dgrposition,
at pos={(0,0)},
height/.store in=\dgrheight,
height=10cm,
min value/.store in=\minval,
min value=0,
max value/.store in=\maxval,
max value=10,
step/.store in=\incstep,
step=1,
horizontal rule width/.store in=\horulewidth,
horizontal rule width=1cm,
min step/.store in=\minstep,
min step={\incstep/2},
minor tick rule width/.store in=\minortickrulewidth,
minor tick rule width=3mm,
little tick rule width/.store in=\litteltickrulewidth,
little tick rule width=1mm,
tick direction/.store in=\tickpos,
tick direction=left,
label above/.store in=\lababove,
label above={},
label sloped/.store in=\labsloped,
label sloped={},
label above rotation/.store in=\rotation,
label above rotation=0,
diagram/.code={
\path \dgrposition node(A){};
\pgfgetlastxy{\xA}{\yA};
\ifscalemaxtomin%
\pgfmathsetmacro\sndval{\maxval-\incstep}
\foreach \y[count=\yi from 0] in {\maxval,\sndval,...,\minval}{
\global\let\maxitems\yi%
}%
\else%
\pgfmathsetmacro\sndval{\minval+\incstep}
\foreach \y[count=\yi from 0] in {\minval,\sndval,...,\maxval}{
\global\let\maxitems\yi%
}%
\fi
\draw(\xA,\yA)--++(0,\dgrheight)
node[pos=0.5,sloped,above]{\labsloped}
node[above,rotate=\rotation,transform shape]{\lababove};% vertical line+above label
\pgfmathsetmacro\actualstep{\dgrheight/\maxitems}%
% little ticks
\pgfmathsetmacro\littletickstep{\actualstep/10}
\foreach \y in {0,\littletickstep,...,\dgrheight}{
\ifnum\pdf@strcmp{\tickpos}{left}=\z@%
\draw(\xA,\yA+\y pt) --++(-\litteltickrulewidth,0);
\fi%
\ifnum\pdf@strcmp{\tickpos}{right}=\z@%
\draw(\xA,\yA+\y pt) --++(\litteltickrulewidth,0);
\fi%
}%
% min step
\pgfmathsetmacro\mintickstep{\actualstep/2}
\ifscalemaxtomin%
\foreach \y [count=\yi from 0,
evaluate=\yi as \ytext using ((\maxval-\yi*\incstep+\yi*\incstep/2))]
in {0,\mintickstep,...,\dgrheight}{%
\ifnumodd{\yi}{% true
\ifnum\pdf@strcmp{\tickpos}{left}=\z@%
\draw (\xA,\yA+\y pt) --++(-\minortickrulewidth,0)
node[left,font=\footnotesize]{\pgfmathprintnumber{\ytext}};
\fi%
\ifnum\pdf@strcmp{\tickpos}{right}=\z@%
\draw (\xA,\yA+\y pt) --++(\minortickrulewidth,0)
node[right,font=\footnotesize]{\pgfmathprintnumber{\ytext}};
\fi%
}{}%
}%
\else%
\foreach \y [count=\yi from 0,
evaluate=\yi as \ytext using ((\yi*\incstep+2*\minval)/2)] in
{0,\mintickstep,...,\dgrheight}{%
\ifnumodd{\yi}{% true
\ifnum\pdf@strcmp{\tickpos}{left}=\z@%
\draw (\xA,\yA+\y pt) --++(-\minortickrulewidth,0)
node[left,font=\footnotesize]{\pgfmathprintnumber{\ytext}};
\fi%
\ifnum\pdf@strcmp{\tickpos}{right}=\z@%
\draw (\xA,\yA+\y pt) --++(\minortickrulewidth,0)
node[right,font=\footnotesize]{\pgfmathprintnumber{\ytext}};
\fi%
}{}%
}%
\fi%
% main step
\ifscalemaxtomin%
\ifscalefromzero%
\foreach \y[count=\yi from 0,
evaluate=\yi as \ytext using (\maxval-\yi*\incstep)] in
{0,\actualstep,...,\dgrheight}{%
\ifnum\pdf@strcmp{\tickpos}{left}=\z@%
\pgfkeys{/pgf/number format/.cd,fixed,precision=2}
\draw (\xA,\yA+\y pt) --++(-\horulewidth,0)
node[left]{\pgfmathprintnumber{\ytext}};
\fi%
\ifnum\pdf@strcmp{\tickpos}{right}=\z@%
\pgfkeys{/pgf/number format/.cd,fixed,precision=2}
\draw (\xA,\yA+\y pt) --++(\horulewidth,0)
node[right]{\pgfmathprintnumber{\ytext}};
\fi%
}%
\else%
\foreach \y[count=\yi from 0,
evaluate=\yi as \ytext using (\maxval-\yi*\incstep)] in
{0,\actualstep,...,\dgrheight}{%
\ifnum\pdf@strcmp{\tickpos}{left}=\z@%
\pgfkeys{/pgf/number format/.cd,fixed,precision=2}
\draw (\xA,\yA+\y pt) --++(-\horulewidth,0)
node[left]{\pgfmathprintnumber{\ytext}};
\fi%
\ifnum\pdf@strcmp{\tickpos}{right}=\z@%
\pgfkeys{/pgf/number format/.cd,fixed,precision=2}
\draw (\xA,\yA+\y pt) --++(\horulewidth,0)
node[right]{\pgfmathprintnumber{\ytext}};
\fi%
}%
\fi%
\else%
\ifscalefromzero%
\foreach \y[count=\yi from 0,
evaluate=\yi as \ytext using (\yi*\sndval+\minval)] in
{0,\actualstep,...,\dgrheight}{%
\ifnum\pdf@strcmp{\tickpos}{left}=\z@%
\pgfkeys{/pgf/number format/.cd,fixed,precision=2}
\draw (\xA,\yA+\y pt) --++(-\horulewidth,0)
node[left]{\pgfmathprintnumber{\ytext}};
\fi%
\ifnum\pdf@strcmp{\tickpos}{right}=\z@%
\pgfkeys{/pgf/number format/.cd,fixed,precision=2}
\draw (\xA,\yA+\y pt) --++(\horulewidth,0)
node[right]{\pgfmathprintnumber{\ytext}};
\fi%
}%
\else%
\foreach \y[count=\yi from 0,
evaluate=\yi as \ytext using (\yi*\incstep+\minval)] in
{0,\actualstep,...,\dgrheight}{%
\ifnum\pdf@strcmp{\tickpos}{left}=\z@%
\pgfkeys{/pgf/number format/.cd,fixed,precision=2}
\draw (\xA,\yA+\y pt) --++(-\horulewidth,0)
node[left]{\pgfmathprintnumber{\ytext}};
\fi%
\ifnum\pdf@strcmp{\tickpos}{right}=\z@%
\pgfkeys{/pgf/number format/.cd,fixed,precision=2}
\draw (\xA,\yA+\y pt) --++(\horulewidth,0)
node[right]{\pgfmathprintnumber{\ytext}};
\fi%
}%
\fi%
\fi%
}%
}
% that's just an alias for \node
\def\drawnomogrampart{\tikz@path@overlay{node}}
\makeatother
\begin{document}
\begin{tikzpicture}
\drawnomogrampart[/nomogram/single diagram/.cd,
height=7cm,
min value=50,
max value=130,
step=10,
label above=$\Delta v$,
scale from zero=false,
diagram]{};
\begin{scope}[rotate=-30,transform shape]
\drawnomogrampart[/nomogram/single diagram/.cd,
horizontal rule width=0.5cm,
height=8cm,
min value=0,
max value=0.901,% for rounding purposes
step=0.1,
label above rotation=30,
label above={$M_f=1-\textrm{e}^{-\Delta v/9.81*I_{sp}}$},
label sloped={Mass Fraction $(M_f)$},
tick direction=right,
diagram]{};
\end{scope}
\drawnomogrampart[/nomogram/single diagram/.cd,
scale from zero=false,
height=7cm,
scale max to min=true,
min value=400,
max value=2000,
step=200,
at pos={(7,0)},
tick direction=right,
label above=IPS (s),
diagram]{};
\end{tikzpicture}
\end{document}
결과:
답변2
를 사용한 계산의 정밀도 문제로 인해 TikZ
접근 방식을 변경하고 작은 pearl
스크립트를 사용하여 이 계산을 수행했습니다. 다음으로 실행pdflatex -shell-script
나는 decorations.markings
모든 유형의 경로에서 졸업을 하기 위해 도서관을 사용합니다. (더 이상 점수 문제가 누적되지 않습니다).
코드에 몇 가지 설명을 넣으려고 했습니다.
코드 :
\documentclass[tikz,margin=2pt]{standalone}
\usetikzlibrary{calc}
\usetikzlibrary{decorations.markings,intersections}
%%%% ---- Use path several times
%%%% ---- thanks to Andrew Stacey
\makeatletter
\tikzset{
use path for main/.code={%
\tikz@addmode{%
\expandafter\pgfsyssoftpath@setcurrentpath\csname tikz@intersect@path@name@#1\endcsname
}%
},
use path for actions/.code={%
\expandafter\def\expandafter\tikz@preactions\expandafter{\tikz@preactions\expandafter\let\expandafter\tikz@actions@path\csname tikz@intersect@path@name@#1\endcsname}%
},
use path/.style={%
use path for main=#1,
use path for actions=#1,
}
}
\pgfkeys{/MonoG/.cd,
% foot of the scale
path/.store in=\p@th,
path={(0,0)--(0,10)},
% minimale value
min/.store in=\Min,
min=0,
% maximale value
max/.store in=\Max,
max=10,
% Major graduation Step
step/.store in=\Step,
step=1,
% Big ticks
% tick length
big ticks/.store in=\BTick,
big ticks=.7,
% font (whatever compatible with tikz font parameter)
big ticks font/.store in=\BFont,
big ticks font=\small,
% line width
big ticks width/.store in=\BWidth,
big ticks width=thick,
% medium ticks (same choices)
med ticks/.store in=\MTick,
med ticks=.4,
med ticks font/.store in=\MFont,
med ticks font=\footnotesize,
med ticks width/.store in=\MWidth,
med ticks width=thin,
% small ticks
small ticks/.store in=\STick,
small ticks=.2,
small ticks width/.store in=\SWidth,
small ticks width=very thin,
% number of sublevel of small tick
small ticks level/.store in=\STlevel,
small ticks level=1,
% tick direction
tick direction/.store in=\TickPos,
tick direction=right,
% bottom label
bottom label/.store in=\BotLabel,
bottom label={},
% midway label
midway label/.store in=\MidLabel,
midway label={},
% top label
top label/.store in=\TopLabel,
top label={},
% Reverse graduation
reverse/.store in=\Reverse,
reverse=false,
diagram/.code={%
% draw the path and place the nodes for labelling
\draw[\BWidth,name path=Path] \p@th
node[pos=1,above] (MnAbove) {\TopLabel}
node[midway,sloped,above] (MnMid) {\MidLabel}
node[pos=0,below] (MnBelow) {\BotLabel} ;
% left right position flag
\ifnum\pdf@strcmp{\TickPos}{left}=\z@%
\def\TPos{1}
\fi%
\ifnum\pdf@strcmp{\TickPos}{right}=\z@%
\def\TPos{-1}
\fi%
% reverse scale flag
\def\Rev{1}
\ifnum\pdf@strcmp{\Reverse}{true}=\z@%
\def\Rev{-1}
\fi%
% set the style for the tick labels
\tikzset{Big/.style={font=\BFont,\TickPos,transform shape,rotate=-90},
Med/.style={font=\MFont,\TickPos,transform shape,rotate=-90},
/pgf/decoration/reset marks % Reset marks each time
% to avoid accumulation problems
} ;
% Call of external calculation script
\immediate\write18{%
./script.pl \Min\space%
\Max\space%
\Step\space%
\STlevel\space\STick\space > Sortie.tex}
\input{Sortie}
}
}
\makeatother
\begin{document}
\begin{tikzpicture}
\path[/MonoG/.cd,
step=5,
min=5,
max=25.01,
path={(4,0) parabola (8,10)},
diagram
] ;
\path[/MonoG/.cd,
step=1000,
max=4500,
tick direction=left,
small ticks=.2,
small ticks level=2,
top label=$\Delta_V$,
diagram
] ;
% to avoid 5.10e-2
\pgfkeys{/pgf/number format/.cd,fixed,precision=3}
\path[/MonoG/.cd,
path={(11,0)--(11,10)},
step=100,
max=800,
min=199.9,
reverse=true,
small ticks level=2,
small ticks = .3,
top label=IPS (s),
diagram
] ;
\path[/MonoG/.cd,
step=.1,
max=.9,
path={(0,0)--(4,10)},
midway label=Mass Fraction $(M_f)$,
top label={$M_f=1-\textrm{e}^{-\Delta v/9.81*I_{sp}}$},
diagram
] ;
\end{tikzpicture}
\begin{tikzpicture}
\path[/MonoG/.cd,
step=10,
max=12,
small ticks level=2,
diagram
] ;
\path[/MonoG/.cd,
step=1,
max=10.01,
min=0,
tick direction=left,
diagram
] ;
\path[/MonoG/.cd,
path={(3,0)--(3,10)},
min=.2,
step=5,
max=9.7,
diagram
] ;
\path[/MonoG/.cd,
tick direction=left,
path={(3,0)--(3,10)},
min=-5,
step=5,
max=15,
diagram
] ;
\path[/MonoG/.cd,
path={(12,0) arc (0:180:3)},
min=0,
step=30,
small ticks level=2,
max=180.01,
diagram
] ;
\end{tikzpicture}
\end{document}
스크립트pearl
#!/usr/bin/perl -w
use POSIX "fmod" ;
$Min = $ARGV[0] ; # Minimum
$Max = $ARGV[1] ; # Maximum
$Step = $ARGV[2] ; # Step of graduation
$Level = $ARGV[3] ; # level of small ticks default 1
$TickL = $ARGV[4] ; # length of small ticks (1st level)
$Coeff = $Max-$Min ; # Scale on the path from 0 to 1
$Begin = $Min - fmod($Min,$Step) ; # Calculation of the place
if ( $Begin < $Min ) { # of the first Label
$Begin += $Step ; }
$X = $Begin ;
$Y = ($X - $Min) / $Coeff ;
print "\\begin{scope}[decoration={markings," ;
while ($X <= $Max) {
print "mark=at position $Y*\\Rev with {\\draw[\\BWidth] (0,0) --++ (0,\\BTick*\\TPos) node[Big] {\\pgfmathprintnumber{$X}} ;},\n" ;
$X += $Step ;
$Y = ($X - $Min) / $Coeff ;
}
print "}]\n" ;
print "\\draw[postaction={decorate},use path=Path];\n" ;
print "\\end{scope}\n" ;
## half step
$X = $Begin - $Step/2 ; # Calculation of
if ( $X < $Min ) { $X += $Step ; } # the first Label
$Y = ($X - $Min) / $Coeff ;
print "\\begin{scope}[decoration={markings," ;
while ($X <= $Max) {
print "mark=at position $Y*\\Rev with {\\draw[\\MWidth] (0,0) --++ (0,\\MTick*\\TPos) node[Med] {\\pgfmathprintnumber{$X}} ;},\n" ;
$X += $Step ;
$Y = ($X - $Min) / $Coeff ;
}
print "}]\n" ;
print "\\draw[postaction={decorate},use path=Path];\n" ;
print "\\end{scope}\n" ;
## 10e ...
$Step /= 10 ;
$Begin = $Min - fmod($Min,$Step) ; # Calculation of
if ( $Begin < $Min ) { # the first Label
$Begin += $Step ; }
if ( $Begin < $Min ) { $Begin += $Step ; } # the first Label
for (my $i = 1; $i <= $Level ; $i++) {
$X = $Begin ;
$Y = ($X - $Min) / $Coeff ;
print "\\begin{scope}[decoration={markings," ;
while ($X <= $Max) {
print "mark=at position $Y*\\Rev with {\\draw[very thin] (0,0) --++ (0,$TickL*\\TPos) ;},\n" ;
$X += $Step ;
$Y = ($X - $Min) / $Coeff ;
}
print "}]\n" ;
print "\\draw[postaction={decorate},use path=Path];\n" ;
print "\\end{scope}\n" ;
$Step /= 2 ;
$TickL /= 2 ;
}