Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I would like to make the small loop around the circle (loop above) a bit rounder and nicer.

below is a short example of my code:

 \documentclass{scrbook}
 \usepackage{tikz}
 \usetikzlibrary{positioning,automata}
 \begin{document}

 \begin{tikzpicture}[shorten >=1pt,auto]
   \tikzstyle{place}=[circle,thick,draw=blue!75,fill=blue!20,minimum
                      size=6mm]
   \node[place] (foo) [label=above left:Foo] {$1$};
   \path[->] (foo) edge  [loop above] node {1} ();
  \end{tikzpicture}
 \end{document}
share|improve this question
    
Somewhat related tex.stackexchange.com/questions/7774/… –  N.N. Nov 19 '11 at 21:45
add comment

3 Answers

I tried some time ago to create a loop like a circle (exactly an arc of a circle, a bit rounder and nicer). I didn't find a easy way to do this, but here is the code I wrote to such loops.

First code: I used only TikZ but I used an empirical method to calculate some of the lengths. The macro \tikzAngleOfLine gives me the angle of a line. If \AngleEndis greater than \AngleSart a problem appears. In the second code example I give a solution to this.

\documentclass[a4paper]{article}
\usepackage{tikz}
\usetikzlibrary{arrows,calc} 

\newcommand{\tikzAngleOfLine}{\tikz@AngleOfLine}
\def\tikz@AngleOfLine(#1)(#2)#3{%
\pgfmathanglebetweenpoints{%
\pgfpointanchor{#1}{center}}{%
\pgfpointanchor{#2}{center}}
\pgfmathsetmacro{#3}{\pgfmathresult}%
}

\begin{document} 

\begin{tikzpicture}[scale=1.5,>=stealth']
\node [circle,draw,minimum size=2cm](A) {first node};
\node [circle,minimum size=3cm](B) at ([{shift=(60:1)}]A){};
\coordinate  (C) at (intersection 2 of A and B);
\coordinate  (D) at (intersection 1 of A and B);
 \tikzAngleOfLine(B)(D){\AngleStart}
 \tikzAngleOfLine(B)(C){\AngleEnd}
\draw[red,thick,->]%
   let \p1 = ($ (B) - (D) $), \n2 = {veclen(\x1,\y1)}
   in   
     (B) ++(60:\n2) node[fill=white]{$\alpha$}
     (D) arc (\AngleStart-360:\AngleEnd:\n2); % -360 only if  \AngleStart>\AngleEnd
 \end{tikzpicture}  

\end{document}

The result is output of code

Second code: Here I used some macros from the tkz-euclide package. The idea is to build an orthogonal circle to the first node.

\documentclass{article}
\usepackage{tkz-euclide}
\usetkzobj{all} 
\usetikzlibrary{through}  
\newcommand{\tikzAngleOfLine}{\tikz@AngleOfLine}
\def\tikz@AngleOfLine(#1)(#2)#3{%
\pgfmathanglebetweenpoints{%
\pgfpointanchor{#1}{center}}{%
\pgfpointanchor{#2}{center}}
\pgfmathsetmacro{#3}{\pgfmathresult}%
} 

\def\roundloop[#1]#2#3{%
 \coordinate (rla) at (#2.east); 
 \path   (#2)--++(#1) coordinate (rlb);
 \tkzTgtFromP(#2,rla)(rlb)            
 \node (rlb) at (rlb) [circle through={(tkzFirstPointResult)}] {};
 \coordinate  (rlc) at (intersection 2 of #2 and rlb);
 \coordinate  (rld) at (intersection 1 of #2 and rlb);         
 \tikzAngleOfLine(rlb)(rld){\AngleStart}
 \tikzAngleOfLine(rlb)(rlc){\AngleEnd} 
 \tikzAngleOfLine(#2)(rlb){\AngleLabel}
 \ifdim\AngleStart pt<\AngleEnd pt
 \draw[red,thick,->]%
   let \p1 = ($ (rlb) - (rld) $), \n2 = {veclen(\x1,\y1)}
   in   
     (rlb) ++(\AngleLabel:\n2) node[fill=white]{#3}
     (rld) arc (\AngleStart:\AngleEnd:\n2); 
 \else 
  \draw[red,thick,->]%
   let \p1 = ($ (rlb) - (rld) $), \n2 = {veclen(\x1,\y1)}
   in   
     (rlb) ++(\AngleLabel:\n2) node[fill=white]{#3}
     (rld) arc (\AngleStart-360:\AngleEnd:\n2); 
   \fi 
  }
\begin{document}

\begin{tikzpicture} 
  \node[circle,draw] (O){first node}; 
  \roundloop[180:2]{O}{$\alpha$}
   \roundloop[0:1]{O}{$\beta$}  
     \roundloop[60:3]{O}{$\delta$}
   \roundloop[-120:4]{O}{$\gamma$} 
\end{tikzpicture} 

\end{document}  

output of code

share|improve this answer
1  
very nice solution. In my tikz picture i draw lines from node "A" to node "B". If i would like to use your concept and to place my number (in your example, $\alpha$, $\beta$, etc.) in the middle of the line. How should i change your code? –  Eagle Nov 22 '11 at 12:56
add comment

There are four parameters that you can play with to adjust the loop size and shape. You can set the in and out angles, and also the minimum length for a loop and its looseness. See Section 50.4 of the TikZ documentation for more detail:

\documentclass{scrbook}
\usepackage{tikz}
\usetikzlibrary{positioning,automata}
\begin{document}

\tikzset{every loop/.style={min distance=10mm,in=0,out=60,looseness=10}}
 \begin{tikzpicture}[shorten >=1pt,auto]
   \tikzstyle{place}=[circle,thick,draw=blue!75,fill=blue!20,minimum
                      size=6mm]
   \node[place] (foo) [label=above left:Foo] {$1$};
   \path[->] (foo) edge  [loop above] node {1} ();
  \end{tikzpicture}
 \end{document}

output of code

I've used \tikzset to set them globally in this example; you can also add the .style specification to an individual tikzpicture or set the parameters for a single loop.

share|improve this answer
add comment

You could adjust angles and looseness for example this way:

\path[->,every loop/.style={looseness=10}] (foo)
         edge  [in=120,out=60,loop] node {1} (); 

loop example

share|improve this answer
    
how do i place the number above the loop? –  Eagle Nov 19 '11 at 22:04
1  
@Eagle by node[above] {1}. –  Stefan Kottwitz Nov 19 '11 at 22:09
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.