1

I'm trying to achieve the equivalent of the PSTricks \nccircle command which results in a circle shaped loop.

The ideal would be to have a command named /tikz/loop circle with an angle option as there are commands /tikz/loop, /tikz/loop above, …

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

Here is the outline of my research:

The red circle should be on top of the dashed circle.

enter image description here

\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}

  • Any reason that you cannot use PSTricks for the drawing? – user187802 Feb 09 '22 at 09:48
  • I want to be able to use pdflatex or lualatex directly. I'm trying to convert all my PSTricks figures to Tikz.

    Same question here, but I'm looking for a more precise answer that detects node edges.

    – Jean-Philippe Feb 10 '22 at 16:24
  • With an up-to-Date TeX distribution you can run lualatex with pstricks and get directly the pdf without ghostscript – user187802 Feb 10 '22 at 22:06

1 Answers1

1

A solution that uses the “intersections” library.

\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}

enter image description here