穿过节点中心的圆形环路,相当于 PSTricks \nccircle 命令

穿过节点中心的圆形环路,相当于 PSTricks \nccircle 命令

我正在尝试实现与 PSTricks\nccircle命令等效的效果,从而产生一个圆形的循环。

理想的做法是有一个/tikz/loop circle以角度选项命名的命令,因为有命令/tikz/loop,,/tikz/loop above...

\begin{tikzpicture}
\node [draw] {Stuff} edge [loop circle, radius=10mm] node {ncircle} ();
\end{tikzpicture}

以下是我的研究概要:

红色圆圈应位于虚线圆圈的上方。

在此处输入图片描述

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

\begin{document}

\tikzset{% TikZ equivalent to the PSTricks \nccircle command
  circle angle/.initial={0},%
  circle radius/.initial={10mm},%
}
\newcommand{\circleangle}{\pgfkeysvalueof{/tikz/circle angle}}% start angle
\newcommand{\circleradius}{\pgfkeysvalueof{/tikz/circle radius}}%


\tikzstyle{label}=[black, sloped, anchor=south, pos=0.5]% label style

\makeatletter
\newcommand{\calcHeight}[2]{
    \pgfpointdiff{\pgfpointanchor{#1}{center}}{\pgfpointanchor{#2}{center}}
    \pgfmathsetlengthmacro{\myheight}{sqrt(pow(\circleradius,2) - pow(0.5*\pgf@x,2) - pow(0.5*\pgf@y,2))}
  }
  \makeatother
  
\newcommand{\ncircle}[3][]{% \ncircle[options]{node A}{label}
  \begin{tikzpicture}[remember picture,overlay,#1]
    \coordinate (p1) at (#2.\circleangle) ;% starting point
    \filldraw (p1) [blue] circle [radius=1pt];
    \coordinate (p2) at (#2.center) ;% node center
    \filldraw (p2) [green] circle [radius=1pt];
    \calcHeight{p1}{p2}% 
    \coordinate (p3) at ($(p1)!0.5!(p2)!\myheight!90:(p1)$) ;% circle center
    \filldraw (p3) [red] circle [radius=1pt];
    \draw[dashed,green] (p3) circle [radius=\circleradius] ;
    \pgfmathanglebetweenlines
    {\pgfpointanchor{p3}{center}}{\pgfpointanchor{p2}{center}}
    {\pgfpointanchor{p3}{center}}{\pgfpointanchor{p1}{center}}
    \let\myresult\pgfmathresult
    \draw[red, ->, >=stealth, thin, shorten <= 3pt, shorten >= 3pt]
    (#2.\circleangle) %[rotate around={0.5*\myresult:(p3)}]
    arc[start angle=\circleangle-90,delta angle=360-2*\myresult,radius=\circleradius]
    node[label,rotate={0.*\myresult}]{#3} ;
  \end{tikzpicture}}
 
\begin{tikzpicture}[remember picture,baseline]
  \draw[help lines,step=1,dashed] (0,0) grid (4,4);
  \node[draw,outer sep = 0pt,inner sep = 5mm] at (3,1) (NodeA) {Stuff};
\end{tikzpicture}

\ncircle[circle angle=60]{NodeA}{ncircle}

\end{document}

答案1

使用“交叉点”库的解决方案。

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{shapes}
\usetikzlibrary{intersections}

\begin{document}
\newif\ifswap
\tikzset{% TikZ equivalent to the PSTricks \ncbar command
  shortenA/.store in = \shortenA, shortenA = 0pt,% Shorten the path in the direction of A
  shortenB/.store in = \shortenB, shortenB = 0pt,% Shorten the path in the direction of B
  shorten/.style={shortenA=#1, shortenB=#1},
  circle angle/.store in = \circleangle, circle angle = 0,% angle of circle
  circle radius/.store in = \circleradius, circle radius = 7mm,% radius of circle
  swap/.is if=swap,% permutation between internal and external arc
  swap=false,
}

\newcommand{\ncircle}[3][]{% \ncircle[options]{same name path and name node}{label}
  \begin{scope}[#1]
    \coordinate (O) at ($(#2.center)+(\circleangle+90:\circleradius)$);
    \path[name path=circle] (O) circle [radius=\circleradius];
    \ifswap
    \path[name intersections={of=#2 and circle, by={B,A}}];
    \else
    \path[name intersections={of=#2 and circle, by={A,B}}];
    \fi
    \pgfmathanglebetweenpoints{\pgfpointanchor{O}{center}}{\pgfpointanchor{A}{center}}
    \pgfmathparse{\pgfmathresult+deg(\shortenA/\circleradius)}
    \let\startangle\pgfmathresult
    \pgfmathanglebetweenlines
    {\pgfpointanchor{O}{center}}{\pgfpointanchor{A}{center}}
    {\pgfpointanchor{O}{center}}{\pgfpointanchor{B}{center}}
    \pgfmathparse{\pgfmathresult-deg((\shortenA+\shortenB)/\circleradius)}
    \let\deltaangle\pgfmathresult
    \draw[->, >=stealth, thin] ($(O)+(\startangle:\circleradius)$)
    arc[start angle=\startangle,delta angle=\deltaangle,radius=\circleradius]
    node[label,sloped]{#3} ;
  \end{scope}}

\tikzstyle{label}=[draw,text=red,sloped,anchor=south,pos=0.5,inner sep =2pt]% label style

\begin{tikzpicture}
  \draw[help lines,step=1,dashed] (0,0) grid (4,3);
  \node[draw,ellipse,name path=NodeA,minimum width=2cm,align=center] at (3,1) (NodeA) {Stuff};
  \ncircle[circle angle=70,circle radius=12mm,shorten=1pt,swap=false]{NodeA}{ncircle}
\end{tikzpicture}

\end{document}

在此处输入图片描述

相关内容