TiKZ의 노드에 더 잘 맞는 라인

TiKZ의 노드에 더 잘 맞는 라인

저는 TiKZ의 오토마타 라이브러리를 사용하고 있으며 노드 사이에 18pt 두께의 선을 배치하고 있습니다. 문제는 선과 상태 사이의 경계가 잘 맞지 않는다는 것입니다.

여기에 이미지 설명을 입력하세요

나는 이것을 갖고 싶다

여기에 이미지 설명을 입력하세요

어떤 아이디어가 있나요?

다음은 첫 번째 것을 생성하는 최소한의 예입니다.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{automata}

\begin{document}

\begin{tikzpicture}[thick]
  \node[state] (1) {};
  \draw[-, blue!20, line width=18pt] (1) to (0,1);
\end{tikzpicture}

\end{document}

답변1

다음은 화살표 팁을 사용한 시도입니다.
(장식을 이용한 해결책도 있지만 화살표 팁보다 더 혼란스럽습니다.)

불행하게도 화살표 끝 은 선 끝에서 반원 Round Cap만 추가(또는 옵션으로 제거 )합니다. reversed선 너비가 원형 노드 반경의 두 배인 경우 이는 효과적입니다.

setup code화살표 끝 의 Hug Cap계산약간의 수학세 가지 값을 저장합니다.

  • 반경(화살표 키에서 가져옴 length),
  • 시간, 이것은 삽입(높이)이고,
  • 각도(결국 그려지는 호).

reversed, open, left등과 같은 옵션을 포함하도록 화살표 끝의 정의를 확장할 가능성이 있습니다 .

스타일 deround은 원형 노드의 반지름을 계산합니다. (이 답변은 라이브러리 circle connection bar의 스타일과 장식 에서 영감을 얻었지만 mindmap기존 노드에서 반경을 추출하기 위해 다른 접근 방식을 사용합니다.)

분명히 경로는 원 경계와 직교해야 합니다.

to이 솔루션은 / edge연산자 와 함께 사용해야 합니다 ( \tikztostart및를 사용하여 \tikztotarget반경 계산을 자동으로 수행합니다. (기본값) 외에는 사용하지 마십시오 line caps. butt이는 화살표 끝 정의 내에서 확인할 수도 있습니다.

선 너비가 직경보다 크고 반경이 매우 큰 경우에는 문제가 발생합니다(그런데 왜 이것을 사용합니까?).

암호

\documentclass[tikz]{standalone}
\usetikzlibrary{automata,arrows.meta}
\pgfdeclarearrow{
  name=Hug Cap,
  parameters=\the\pgfarrowlength,
  setup code={
    % h = r - .5 sqrt(4 r^2 - s^2)
    \pgfmathsetlengthmacro\pgfarrowh{\pgfarrowlength-.5*sqrt(4*\pgfarrowlength*\pgfarrowlength-\pgflinewidth*\pgflinewidth}
    % a = asin(s / (2 r))
    \pgfmathsetmacro\pgfarrowangle{asin(\the\pgflinewidth/(2*\the\pgfarrowlength))}
    \pgfarrowssavethe\pgfarrowlength % radius
    \pgfarrowssave\pgfarrowh         % h
    \pgfarrowssave\pgfarrowangle     % a
    \pgfarrowsupperhullpoint{0pt}{.5\pgflinewidth}
    \pgfarrowsupperhullpoint{\pgfarrowh}{.5\pgflinewidth}
    \pgfarrowssetlineend{.1pt}       % eeh :\
  },
  drawing code={
    \pgfpathmoveto{\pgfqpoint{\pgfarrowh}{-.5\pgflinewidth}}
    \pgfpatharc{180+\pgfarrowangle}{180-\pgfarrowangle}{\pgfarrowlength}
    \pgfpathlineto{\pgfqpoint{0pt}{.5\pgflinewidth}}
    \pgfpathlineto{\pgfqpoint{0pt}{-.5\pgflinewidth}}
    \pgfpathclose
    \pgfusepathqfill}}
\makeatletter
\def\qrr@tikz@circle{circle}
\newcommand*\qrr@getRadius[1]{%
  \def\qrr@radius{0pt}%
  \tikz@scan@one@point\pgfutil@firstofone(#1)\relax
  \iftikz@shapeborder
    \edef\qrr@shape{\csname pgf@sh@ns@\tikz@pp@name{\tikz@shapeborder@name}\endcsname}%
    \ifx\qrr@tikz@circle\qrr@shape
      % ah circle, get the radius!
      \begingroup
        \csname pgf@sh@np@\tikz@pp@name{\tikz@shapeborder@name}\endcsname
        \let\qrr@radius\radius
        \pgfmath@smuggleone\qrr@radius
      \endgroup
    \fi
  \fi}
\tikzset{
  deround/.style={
    /utils/exec={%
     \qrr@getRadius\tikztostart
     \ifdim\qrr@radius=0pt
       \def\qrr@arrowsettings{-}\else
       \edef\qrr@arrowsettings{{Hug Cap[length=+\qrr@radius]}-}\fi
     \qrr@getRadius\tikztotarget
     \ifdim\qrr@radius=0pt\else
       \edef\qrr@arrowsettings{\qrr@arrowsettings{Hug Cap[length=+\qrr@radius]}}\fi
   },
   arrows/.expanded=\qrr@arrowsettings}
}
\makeatother
\begin{document}
\begin{tikzpicture}[thick]
  \node[state]          (1) {};
  \node[state] at (2,1) (2) {abcdef};
  \path[line width=12pt, every edge/.append style=deround]
    (2) edge (1)
        edge[line width=10pt, red, out=150, in=90] (1);
  \path[line width=12pt] (1) edge[out=180-30, in=180+30, looseness=4, deround] (1);
\end{tikzpicture}
\end{document}

산출

여기에 이미지 설명을 입력하세요

답변2

방법을 찾았지만 표준적인 방법은 아닌 것 같습니다. 그냥 작동하는 방법입니다. 레이어를 사용하고 선 길이를 늘리는 것입니다.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{automata}

\begin{document}

\pgfdeclarelayer{bg}
\pgfsetlayers{bg,main}
\begin{tikzpicture}[thick]
  \node[state,fill=white] (1) {};
  \begin{pgfonlayer}{bg}
    \draw[-,shorten >=-4pt,shorten <=-4pt,blue!20, line width=18pt]
    (1) to (0,1);
  \end{pgfonlayer}
\end{tikzpicture}

\end{document}

결과

편집하다 아래 설명을 기반으로 한 두 번째 솔루션(긴 선 대신 좌표로 중심 사용)

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{automata}

\begin{document}

\pgfdeclarelayer{bg}
\pgfsetlayers{bg,main}
\begin{tikzpicture}[thick]
  \node[state,fill=white] (1) {};
  \begin{pgfonlayer}{bg}
    \draw[-,blue!20, line width=18pt]
    (1.center) to (0,1);
  \end{pgfonlayer}
\end{tikzpicture}

\end{document}

관련 정보