Modular arithmetic on node names in TikZ? - latex

Say I want to construct a circulant graph in TikZ, with a variable number of nodes, labelled v0, v1, ..., v_n-1 for some n of my choice (say, 5).
I'd like to be able to use the \foreach command in TikZ to iteratively (1) define the nodes, and (2) connect the nodes. I'd like to be able to connect v_i to v_(i+1) and v_i to v_{i+2}, say.
\foreach \i in {0, ..., 4}
{\path (\i*72:3) node (v\i) {};}
constructs the nodes perfectly. But then when I want to draw some lines,
\foreach \i \in {0, ..., 3}
{ \draw (v\i) -- (v{\i+1}); } ????
doesn't work. Nor does
\foreach \i / \j in {0/1, ..., 3/4}
{ \draw (v\i) -- (v{\j}); }
I get an error "no such shape v0" or something like that.
I know this must be totally easy to do, but I can't figure out how. Any suggestions?
As a followup, it would be nice to be able to connect v_i and v_{i+4} or something, with a single \foreach command, and have TikZ/pgf do the modular arithmetic for me without having to worry about spilling over.

This worked for me:
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{shapes,fit,arrows,positioning}
\tikzstyle{vertex} = [circle, draw, thick, text centered]
\tikzstyle{edge} = [draw, thick,->]
\begin{document}
\begin{tikzpicture}[scale=1]
\foreach \x in {0,...,6}
\node[vertex] (\x) at (\x*360/7:3) {v\x};
\foreach \x/\y in {0/1,1/2,2/3,3/4,4/5,5/6,6/0}
\draw[edge] (\x) to (\y);
\end{tikzpicture}
\end{document}
The syntax {0/1,...,5/6} did not work for me. But I admit, I spent a bit of time trying to find a good solution, and I'm still not totally satisfied.

Another solution, achieved editing the code by Steve Tjoa:
\documentclass[tikz,border=1mm]{standalone}
\usetikzlibrary{arrows}
\begin{document}
\begin{tikzpicture}[thick]
\foreach \x in {0,...,4}{%
\node [circle, draw] at (\x*72:3) {$v_{\x}$};
\draw [->] (\x*72+10:3) arc (\x*72+10:\x*72+62:3);
}
\end{tikzpicture}
\end{document}

Related

Increase spacing between itemize 'items' to avoid splitting pages

I'm currently working on some homework for my Theory of Computation course; right now I am creating state diagrams in LaTeX with the TikZ library (in Overleaf). We have a template file where problems are listed in an itemize block and I am inserting tikzpicture blocks to create the state diagrams in each of the item blocks.
\begin{itemize}
\item[a.] $\{w~|~w$ begins with a $\input{1}$ and ends with a $\input{0} \}$
\begin{figure}[ht]
\begin{tikzpicture}
\node[state, initial] (q0) {$q_0$};
\node[state, right of=q0] (q1) {$q_1$};
\node[state, below of=q1] (qR) {$q_R$};
\node[state, accepting, right of=q1] (q2) {$q_2$};
\draw (q0) edge[bend right, below] node{0} (qR)
(qR) edge[loop below] node{0,1} (qR)
(q0) edge[above] node{1} (q1)
(q1) edge[loop above] node{1} (q1)
(q1) edge[bend left, above] node{0} (q2)
(q2) edge[bend left, below] node{1} (q1)
(q2) edge[loop right] node{0} (q2);
\end{tikzpicture}
\end{figure}
... Cut some code out here to save space
\item[d.] The empty set
\begin{figure}[ht]
\begin{tikzpicture}
\node[state, initial] (q) {$q$};
\draw (q) edge[loop right, above] node{0,1} (q);
\end{tikzpicture}
\end{figure}
\end{itemize}
The thing that is bothering me, and I know it's not a huge deal and I'm just being anal, is that it comes out looking like this when compiled:
Is there a way I could change this code so that both the problem statement and my solution diagram will fit on the same page of the pdf? It really bothers me to look at it and I run into stuff like this a lot working with LaTeX. Thanks!
A \vbox might do what you want:
\item \vbox{
% the contents you want to enclose on the same page
}

Generating random points then connecting points less than certain distance away

I currently have the code below which produces the later output. I would like to generate the 10 points randomly as I already am. But instead of having blue dashed lines connecting to the the location (0,0), I want them to connect to the other dots if the distance is less than 4cm away.
I attempted things such as storing the data into arrays but updating and accessing the values was not working. I attempted nested for loops but handling the seed became difficult. What is a good way to do this?
\documentclass{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\draw[step=0.5cm,color=gray] (-2.5,-2.5) grid (2.5,2.5);
\pgfmathsetseed{2}
\foreach \x in {1,...,10}
{
\pgfmathrandominteger{\a}{-240}{240}
\pgfmathrandominteger{\b}{-240}{240}
\fill [color=red,anchor=center](\a*0.01,\b*0.01) circle (0.1);
% CHANGE HERE
\draw [color=blue,densely dotted] (\a*0.01,\b*0.01) -- (0.0,0.0);
};
\end{tikzpicture}
\end{document}
I seemed to have figured out a solution (not ideal but works for this case).
The key was to use the \pgfmathparse for performing the if statement to get a 0 or 1 to use in \ifnum.
\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{math}
\begin{document}
\begin{tikzpicture}
\draw[step=0.5cm,color=gray] (-2.5,-2.5) grid (2.5,2.5);
\pgfmathsetseed{2}
\foreach \x in {1,...,10}
{
\pgfmathrandominteger{\a}{-240}{240}
\pgfmathrandominteger{\b}{-240}{240}
\fill [color=red,anchor=center](\a*0.01,\b*0.01) circle (0.1);
\pgfmathsetseed{2}
\foreach \y in {0,...,\x}
{
\pgfmathrandominteger{\c}{-240}{240}
\pgfmathrandominteger{\d}{-240}{240}
\tikzmath{\i=(\a*0.01-\c*0.01)^2;}
\tikzmath{\j=(\b*0.01-\d*0.01)^2;}
\tikzmath{\k=\i+\j;}
\pgfmathparse{\k < 4.0 ? 1 : 0}
\ifnum\pgfmathresult=1
\draw [color=blue,densely dotted] (\a*0.01,\b*0.01) -- (\c*0.01,\d*0.01);
\fi
};
};
\end{tikzpicture}
\end{document}

TikZ - An arc with an arrow

I am learning Tikz and hope somebody can help me achieve the following i.e. I want to draw a directed arc between objects in an equation. Below is a picture of what I am trying to achieve.
I have also attached the code I have used so far:
\documentclass{article}
\usepackage{amsmath,amssymb,braket,tikz}
\usetikzlibrary{tikzmark,calc}
\begin{document}
\begin{tikzpicture}
$(x+2)(x+3)$
\end{tikzpicture}
\end{document}
I also suspect that there is a way to specify a line or arc, between elements e.g. numbers and letters, without explicitly stating the coordinates. Is this the case? If it were, it would simplify the things I'm trying to achieve.
Any help would be very much appreciated.
The following solution draws an arc above the formula using arc; the actual angles and lengths may have to be adjusted. To get coordinates relative to the formula, the formula is wrapped into the node formula.
\documentclass{article}
\usepackage{amsmath,amssymb,braket,tikz}
\usetikzlibrary{tikzmark,calc}
\begin{document}
\begin{tikzpicture}
\node (formula) [] {$(x+2)(x+3)$};
\draw[-latex,red] ($(formula.north west)+(.4,0)$) arc
[
start angle=160,
end angle=20,
x radius=0.5cm,
y radius =0.5cm
] ;
\end{tikzpicture}
\end{document}
Output:
Another possibility with the tikzmark library:
\documentclass{article}
\usepackage{amsmath,amssymb,braket,tikz}
\usetikzlibrary{tikzmark,calc}
\begin{document}
\begin{equation}
(\tikzmarknode{a}{x}+2)(\tikzmarknode{b}{x}+3)
\end{equation}
\tikz[remember picture, overlay]{\draw[-latex,red] ([yshift=0.1em]a.north) to[bend left] ([yshift=0.1em]b.north);}
\end{document}

How to draw nodes with "stubs" in Latex?

I'm trying to draw this in latex.
Anyone know how?
Use the calc-library and do the following:
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}
\node[draw=black, circle, fill=green] (A) at (0,0) {A};
\draw let \p1=(A) in (A) -- (\x1+40,\y1+10);
\end{tikzpicture}
\end{document}
Using the let-statement it allows you to specify a reference point (or even more) to use it's coordinates for further calculation.

How can I apply a style to existing tikz node on specific slides

This is what I'm trying to do
\begin{tikzpicture}
[node distance = 1cm, auto,font=\footnotesize,
% STYLES
every node/.style={node distance=1.3cm},
comment/.style={rectangle, inner sep= 5pt, text width=4cm, node distance=0.25cm, font=},
module/.style={rectangle, drop shadow, draw, fill=black!10, inner sep=5pt, text width=3cm, text badly centered, minimum height=0.8cm, font=\bfseries\footnotesize\sffamily,rounded corners},
selected/.style={fill=red!40}]
\node [module] (nodeA) {node A};
\node [module, below of=nodeA] (nodeA) {node B};
\only<1>{
\node [comment, text width=6cm, right=0.25 of nodeA] {short description of Node A};
\node [comment, text width=6cm, right=0.25 of nodeB] {short description of Node B};
}
\only<2>{
\node [selected] (nodeA) {};
\node [comment, text width=6cm, right=0.25 of nodeA] {long description of node A};
}
\only<3>{
\node [selected] (nodeB) {};
\node [comment, text width=6cm, right=0.25 of nodeA] {long description of node B};
}
\end{tikzpicture}
The problem is
\node [selected] (nodeB) {};
creates a new node, but I want it to apply the style for the existing node. Is there any way to do so?
Of course I could have copies of every node in selected state and not-selected state, but I really want to have a normal solution.
I don't think you can do this the way you want to (assuming I understand the question correctly), because once a node is drawn, there's no way to change its appearance. I'd suggest using Beamer's \alt macro:
\alt<2>{\node[module,selected] at (nodeA) {node A};}{\node[module] at (nodeA) {node A};}
\alt<3>{\node[module,selected] at (nodeB) {node B};}{\node[module] at (nodeB) {node B};}
\node[comment,text width=6cm,right=0.25 of nodeA]{\alt<2>{short description}{long description}};
\node[comment,text width=6cm,right=0.25 of nodeB]{\alt<3>{short description}{long description}};
Or something like that (you might have to tinker with the semicolons to get it to work, I can't test that at the moment).
Another option would be to actually just draw a new node. If you include
\node[module,selected] at (nodeA) {node A};
inside \only<2>, that will draw a node that looks just like node A, except with a red background, at the same position at node A. The new node will cover up the original node A.
Sometimes, to avoid repetitions, it may be nice to do something like this:
% #1 Overlay specs.
% #2 Style name.
% #4 Style properties.
\def\onlystyle<#1>#2#3{%
\alt<#1>{%
\tikzset{#2/.style = {#3}}
}{%
\tikzset{#2/.style = {}}
}%
}
Then, if you put, for example, this within a frame:
\onlystyle<2>{selected}{fill = red}
the style selected will be defined as fill = red on the second slide of the animation, and as a style with no effect whatsoever on every other slide. Then, you can write a readable figure such as:
\begin{tikzpicture}
\node at (0, 0) {A};
\node[selected] at (1, 0) {B};
\node at (2, 0) {C};
\end{tikzpicture}
and the “B” node will be highlighted on the second slide. This way, you don't have to copy-paste tons of node definitions.
Of course, it cannot be applied to every single animation need, but I like to keep this technique up my sleeve.
I found yet another solution, which has advantages (more functionality!) compared to all previous solutions, including the one I posted before.
First I mention the improved solution, then I explain why it actually shows more functionality than all other solutions.
The following solution, adapted from How can I make Beamer overlays with TikZ node attributes?, uses an additional tikz library and uses a parameter for the slide number-dependent attribute (for the slide numbers, of course). Note that the tikz setting has to be done outside the frame now.
\documentclass{beamer}
\usepackage{tikz}
\usetikzlibrary{overlay-beamer-styles}
\begin{document}
\begin{frame}{With code/node duplication (explicit frame numbers)}
\begin{tikzpicture}
[every node/.style={draw,circle},
redStyle/.style={fill=red},
blueStyle/.style={fill=blue}]
\node<1> [] (A) {A}; % no style
\node<2> [redStyle] (A) {A}; % red style
\node<3> [blueStyle] (A) {A}; % blue style
\node [right of=A] (B) {B};
\draw [-latex] (A) -- (B) ;
\end{tikzpicture}
\end{frame}
\tikzset{
every node/.style={draw,circle},
redStyle/.style={fill=red}, redStyle on/.style={alt=#1{redStyle}{}},
blueStyle/.style={fill=blue}, blueStyle on/.style={alt=#1{blueStyle}{}}}
\begin{frame}{\textbf{Without} code/node duplication (explicit frame numbers)}
\begin{tikzpicture}
\node [redStyle on=<2>,blueStyle on=<3>] (A) {A};
\node [right of=A] (B) {B};
\draw [-latex] (A) -- (B) ;
\end{tikzpicture}
\end{frame}
\tikzset{
every node/.style={draw,circle},
redStyle/.style={fill=red}, redStyle on/.style={alt=#1{redStyle}{}},
blueStyle/.style={fill=blue}, blueStyle on/.style={alt=#1{blueStyle}{}}}
\begin{frame}{\textbf{Without} code/node duplication (relative frame numbers)}
\begin{tikzpicture}
\node [redStyle on=<+(1)>,blueStyle on=<+(1)>] (A) {A};
\node [right of=A] (B) {B};
\draw [-latex] (A) -- (B) ;
\end{tikzpicture}
\end{frame}
\end{document}
Now the explanation why this solution is the best mentioned so far, i.e. which additional features it has and why (or when) they are relevant. Well, simply because the respective property does not have to show at the same slide number for different usages within the same frame. Simple example:
Let's say you have a simple tree, i.e. nodes with directed edges connecting them. Say you want to make some of the edges bold in specific slides. Of course you have multiple edges, so clearly they do not all become bold at the very same time! Some edges get bold at frame numbers m to n, others get bold at x and y. This can now be trivially realized with using the node (or edge, in this case) properties timedBold on=<m-n> and timedBold on=<x,y>.
Note that there is yet another possibility, which to me seems a bit better than the previous two suggestions, because it has less code duplication (compared to David Z's solution), and because (compared to Alice M.'s solution) you do not need to define a new command that you had to define outside the frame (though defining this additional command is probably not an issue to anybody). In principle, the following suggestion seems to be closely related to the suggestion by Alice M.
Anyway, the solution is a direct application of How to modify a node in TikZ when using beamer's overlays.
Is basically just re-defines a style based on the frame number. See the following minimal example, second or third frame. (I re-did the minimal example since I regard the given one extremely complicated; it was certainly not a minimal example, and also not working on its own.)
\documentclass{beamer}
\usepackage{tikz}
\begin{document}
\begin{frame}{With code/node duplication (explicit frame numbers)}
\begin{tikzpicture}
[every node/.style={draw,circle},
redStyle/.style={fill=red},
blueStyle/.style={fill=blue}]
\node<1> [] (A) {A}; % no style
\node<2> [redStyle] (A) {A}; % red style
\node<3> [blueStyle] (A) {A}; % blue style
\node [right of=A] (B) {B};
\draw [-latex] (A) -- (B) ;
\end{tikzpicture}
\end{frame}
\begin{frame}{\textbf{Without} code/node duplication (explicit frame numbers)}
\only<1>{\tikzset{colorStyle/.style={}}} % no style
\only<2>{\tikzset{colorStyle/.style={fill=red}}} % red style
\only<3>{\tikzset{colorStyle/.style={fill=blue}}} % blue style
\begin{tikzpicture}
[every node/.style={draw,circle}]
\node [colorStyle] (A) {A}; % frame-dependent style
\node [right of=A] (B) {B};
\draw [-latex] (A) -- (B) ;
\end{tikzpicture}
\end{frame}
\begin{frame}{\textbf{Without} code/node duplication (relative frame numbers)}
\only<+>{\tikzset{colorStyle/.style={}}} % no style
\only<+>{\tikzset{colorStyle/.style={fill=red}}} % red style
\only<+>{\tikzset{colorStyle/.style={fill=blue}}} % blue style
\begin{tikzpicture}
[every node/.style={draw,circle}]
\node [colorStyle] (A) {A}; % frame-dependent style
\node [right of=A] (B) {B};
\draw [-latex] (A) -- (B) ;
\end{tikzpicture}
\end{frame}
\end{document}

Resources