
다음을 만족하는 트리를 만들고 싶습니다.
- 오른쪽으로 자랍니다.
- 첫 번째 자식은 0도에서 성장합니다(다음 자식은 시계 방향으로 성장).
- 모든 하위 노드는 동일한 수직에 있고 연속된 노드 사이의 거리는 항상 동일합니다.
전체적으로 제가 달성하고 싶은 것은 다음과 같습니다.
실제로 코드를 작성하는 쉬운 방법은 다음과 같습니다.
\documentclass{article}
\usepackage{tikz}
\tikzset{bcir/.style={circle,fill=black,
minimum size=4pt,inner sep=0},every node/.style={bcir}}
\begin{document}
\begin{tikzpicture}[x=3cm,y=2mm]
\node (A) {};
\foreach \i in {0,...,8} \node at (1,-\i) {} edge (A);
\end{tikzpicture}
\end{document}
그러나 나는 동일한 결과를 얻을 것으로 기대했던 다른 접근 방식을 시도했습니다.
\documentclass{article}
\usepackage{tikz}
\usepackage{fp}
\usetikzlibrary{fixedpointarithmetic}
\tikzset{bcir/.style={circle,fill=black,
minimum size=4pt,inner sep=0},every node/.style={bcir}}
\begin{document}
\begin{tikzpicture}[fixed point arithmetic]
\node {}
child[grow=\g,level distance=\l cm]
foreach \i [evaluate={
\k=tan(5)*\i;
\g=-atan(\k);
\l=3/cos(\g);
}] in {0,...,13} {node {}};
\end{tikzpicture}
\end{document}
위의 코드에서는 1) 첫 번째(수평) 자식의 레벨 거리가 3cm이고 2) 두 번째 자식이 -5도 성장한다고 가정했습니다. 이 두 가지 조건과 일부 기본 삼각법을 사용하면 먼저 연속 노드 사이의 형제 거리를 계산한 다음 모든 하위 노드에 대한 각도 g
및 레벨 거리를 계산할 수 있습니다.l
나는 내 매개변수화가 정확하다고 믿습니다. 그러나 일부 형제 각도/레벨 거리가 약간 벗어났습니다.
(다른 답변에 따라) 정확도를 향상시키기 위해 고정 소수점 산술 엔진을 사용했지만. 삼각함수를 Taylor 급수의 첫 번째 항으로 대체하더라도,
\begin{tikzpicture}[fixed point arithmetic]
\node {}
child[grow=\g,level distance=\l cm]
foreach \i [evaluate={
\k=tan(5)*\i;
\grad=\k-\k^3/3+\k^5/5-\k^7/7+\k^9/9;
\g=-deg(\grad);
\l=3/(1-\grad^2/2!+\grad^4/4!-\grad^6/6!);
}] in {0,...,8} {node {}};
\end{tikzpicture}
동일한 문제가 존재합니다(여기서는 시리즈가 수렴되도록 보장하기 위해 노드 수를 선택했습니다 atan
).
이러한 부정확성 문제를 극복하기 위해 내가 할 수 있는 일이 있습니까? 아니면 피할 수 없는 본질적인 TikZ 문제입니까? (내 접근 방식에 결함이 없다고 가정할 때 그렇습니다.)
답변1
이 경우 수학이 실패하는 이유는 잘 모르겠지만(그래야 한다고 생각하지만) TikZ/PGF가 수학을 수행하는 방식에는 문제가 없는 것 같습니다. 트리가 구성되는 방식과 관련이 있는 것 같습니다. .
안타깝게도 문제가 정확히 무엇인지는 알 수 없었지만 문제가 있다는 사실은~ 아니다수학적 계산 자체의 정확성은 트리 외부에서 동일한 계산을 사용하여 입증할 수 있습니다.
\documentclass[tikz, border=5]{standalone}
\tikzset{bcir/.style={circle,fill=black,
minimum size=4pt,inner sep=0}, every node/.style={bcir}}
\begin{document}
\begin{tikzpicture}[every node/.style={bcir, anchor=center}]
\node {} child [grow=\g, level distance=\l cm] foreach \i [evaluate={%
\k=tan(5)*\i; \g=-atan(\k); \l=3/cos(\g);}]
in {0,...,13} { node {} };
\foreach \i [evaluate={%
\k=tan(5)*\i; \g=-atan(\k); \l=3/cos(\g);}]
in {0,...,13} { \draw [red] (0,0) -- (\g:\l) node [bcir,fill=red]{}; }
\end{tikzpicture}
\end{document}
그래서 뭔가 다른 일이 벌어지고 있어야합니다.
어쨌든 나는 당신이 할 수 있는 일을 통해 많은 일을 하고 있다고 생각합니다.많이더 간단하게는 맞춤형 성장 기능을 사용합니다.
grow via three points
다음은 라이브러리 의 성장 함수 의 예를 보여줍니다 trees
.
\documentclass[tikz, border=5]{standalone}
\usetikzlibrary{trees}
\tikzset{bcir/.style={circle,fill=black,
minimum size=4pt,inner sep=0}, every node/.style={bcir}}
\begin{document}
\begin{tikzpicture}[grow via three points={%
one child at (3,0) and two children at (3,0) and (3,-1/4)
}]
\node {} child foreach \i in {0,...,13} { node {} };
\end{tikzpicture}
\end{document}
답변2
PSTricks 솔루션:
\documentclass{article}
\usepackage{multido}
\usepackage{pstricks}
\usepackage{xfp}
% parameters
\def\NoDots{9}
\def\Hori{4}
\def\Vert{3}
\begin{document}
\begin{pspicture}(\Hori,\Vert)
\psdot(0,\Vert)
\multido{\r = \Vert+-\fpeval{\Vert/(\NoDots-1)}}{\NoDots}{%
\psline(0,\Vert)(\Hori,\r)
\psdot(\Hori,\r)}
\end{pspicture}
\end{document}
\NoDots
매개변수( , \Hori
및 ) 의 값을 변경하기만 하면 \Vert
그에 따라 도면이 조정됩니다.
답변3
당신의 문제는 나를 궁금하게 만들었습니다. MetaPost는 또한 기본적으로 고정 소수점 산술을 사용합니다. 내부적으로 MetaPost는 2^(-16)
최대 . (최근부터 여러 부동 소수점 연산 모드로 전환하는 것이 가능해졌지만 여기서는 사용하지 않겠습니다.)2^12
2^15
그래서 저는 동일한 기능을 사용하여 두 번째 그래프의 MetaPost 버전을 만들고 정렬을 관찰하기로 결정했습니다. (LuaLaTeX로 처리됩니다.)
\documentclass[border=2mm]{standalone}
\usepackage{luamplib}
\mplibsetformat{metafun}
\begin{document}
\begin{mplibcode}
u := cm;
def dot(expr c) = drawdot c withpen pencircle scaled 3bp enddef;
beginfig(1);
dot(origin);
for i = 0 upto 13:
k := i*tand5; % or i*sind5/cosd5 with Plain MetaPost
g := -atan k ; % or -angle(1, k) with Plain MetaPost;
l := 3u/cosd g;
draw origin -- l*dir g;
dot(l*dir g);
endfor
endfig;
\end{mplibcode}
\end{document}
글쎄, 내가 볼 수 있는 한 그들은 올바르게 정렬된 것 같습니다.
따라서 이 경우에는 고정 소수점 산술 자체에 문제가 있는 것이 아니라 고정 소수점 라이브러리 tikz
(숫자를 표현하는 데 두 개의 몇 비트가 사용됩니까?)에 문제가 있는 것 같습니다. 또는 삼각 함수가 정의되는 방식으로.
어쨌든 (LuaTeX를 사용하여) 부동 소수점 연산으로 전환할 수 있다면 tikz
정확도가 크게 향상될 것입니다.