11

Right now I have these defined:

\coordinate (Z1) at (0.9,0.5);
\coordinate (Z2) at (0.816,-0.112);
\coordinate (Z3) at (0.46848,-0.46336);

But I would really like to automate this to be:

enter image description here

so that I can just specify Z1 and then vary the α factor easily to get Z2 and Z3. (Right now α = 0.8)

What's the simplest way to do this? I know how to do some coordinate calculations but this is beyond my skillset right now.


edit: FWIW(For what it's worth) this can also be expressed as a coordinate transformation H = [1 alpha; -alpha 1]/(1+alpha^2) so maybe that's something worth using. I don't know how to force tikz to compute transformed coordinates.

  • Do you need to generalise this to any k, or will k be no larger than 3? – Torbjørn T. May 29 '14 at 22:43
  • I don't need to generalize, just get Z2 and Z3. – Jason S May 29 '14 at 22:57
  • It looks like a complex numbers calculation. Does tikz can do calculations directly with complex numbers ? – Tarass May 31 '14 at 11:05
9

You could do something like this:

\documentclass[border=3mm,tikz]{standalone}
\begin{document}
\begin{tikzpicture}
\pgfmathsetmacro{\Xi}{0.9}
\pgfmathsetmacro{\Yi}{0.5}
\pgfmathsetmacro{\Coeff}{0.8}

\pgfmathsetmacro{\Xii}{(\Xi+\Coeff*\Yi)/(1+\Coeff^2)}
\pgfmathsetmacro{\Yii}{(\Yi-\Coeff*\Xi)/(1+\Coeff^2)}
\pgfmathsetmacro{\Xiii}{(\Xii+\Coeff*\Yii)/(1+\Coeff^2)}
\pgfmathsetmacro{\Yiii}{(\Yii-\Coeff*\Xii)/(1+\Coeff^2)}

\coordinate (Z1) at (\Xi,\Yi);
\coordinate (Z2) at (\Xii,\Yii);
\coordinate (Z3) at (\Xiii,\Yiii);

\draw (Z1) -- (Z2) -- (Z3);

\end{tikzpicture}
\end{document}

Version with 4-argument macro:

\documentclass[tikz,border=2mm]{standalone}
\newcommand{\defcoords}[4][Z]{%
\pgfmathsetmacro{\Xi}{#2}
\pgfmathsetmacro{\Yi}{#3}
\pgfmathsetmacro{\Coeff}{#4}

\pgfmathsetmacro{\Xii}{(\Xi+\Coeff*\Yi)/(1+\Coeff^2)}
\pgfmathsetmacro{\Yii}{(\Yi-\Coeff*\Xi)/(1+\Coeff^2)}
\pgfmathsetmacro{\Xiii}{(\Xii+\Coeff*\Yii)/(1+\Coeff^2)}
\pgfmathsetmacro{\Yiii}{(\Yii-\Coeff*\Xii)/(1+\Coeff^2)}

\coordinate (#11) at (\Xi,\Yi);
\coordinate (#12) at (\Xii,\Yii);
\coordinate (#13) at (\Xiii,\Yiii);
}

\begin{document}
\begin{tikzpicture}
\defcoords{0.9}{0.5}{0.8}
\draw (Z1) -- (Z2) -- (Z3);

\defcoords[C]{0.9}{0.5}{2}
\draw (C1) -- (C2) -- (C3);
\end{tikzpicture}
\end{document} 
  • is there any way to do this, given Z1 as an input? (get its x and y coordinates and compute the Z2 and Z3 coordinates) – Jason S May 30 '14 at 22:04
  • @JasonS I updated my answer, was it something like that you had in mind? – Torbjørn T. May 30 '14 at 22:18
10

A solution using TikZ powerful let...in syntax, which produces a code short and readable:

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

\begin{document}
\def\nextZ#1{
\path let
      \p1 = (Z#1),
      \n1 = {(\x1+\coeff*\y1)/(1+\coeff^2)}, 
      \n2 = {(\y1-\coeff*\x1)/(1+\coeff^2)},
      \n3 = {int(#1+1)},
      \p2 = (\n1,\n2)
   in 
      (\p2) coordinate (Z\n3);
}

\begin{tikzpicture}[scale=2]
\coordinate (Z1) at (0.9,0.5);
\def\coeff{0.8}

\foreach \z in {1,2,3,4,5} {
 \fill[red] (Z\z) circle(2pt) node[black,above]{$Z_\z$};
  \nextZ\z
}

\end{tikzpicture}    
\end{document}

Result

9

A solution with Lua and LuaLaTeX:

\documentclass{article}
\usepackage{luacode}
\usepackage{tikz}

\begin{document}
\luaexec{
tp = tex.print
local alfa = 0.8
local k = 1 + (0.8 * 0.8)
x = {}
y = {}
x[1] = 0.9
y[1] = 0.5
for i = 2, 3 do
    x[i] = (x[i-1] + alfa * y[i-1]) / k
    y[i] = (y[i-1] - alfa * x[i-1]) / k
end
tp("\\begin{tikzpicture}[scale=3]")
tp("\\coordinate (Z1) at ("..x[1]..","..y[1]..");")
tp("\\coordinate (Z2) at ("..x[2]..","..y[2]..");")
tp("\\coordinate (Z3) at ("..x[3]..","..y[3]..");")
tp("\\draw[-latex] (Z1)node[left]{$Z1$}--(Z2) node[right]{$Z2$};")
tp("\\draw[-latex] (Z2)--(Z3) node[right]{$Z3$};")
tp("\\end{tikzpicture}")
}

\end{document}

enter image description here

For more then 3 coordinate calculations, say 10:

\documentclass{article}
\usepackage{luacode}
\usepackage{tikz}

\begin{document}
\luaexec{
tp = tex.print
tp("\\begin{tikzpicture}[scale=3]")
local n = 10 
local alfa = 0.8
local k = 1 + (0.8 * 0.8)
x = {}
y = {}
x[1] = 0.9
y[1] = 0.5
for i = 2, n do
    x[i] = (x[i-1] + alfa * y[i-1]) / k
    y[i] = (y[i-1] - alfa * x[i-1]) / k
tp("\\draw[-latex] ("..x[i-1]..","..y[i-1].."])--("..x[i]..","..y[i]..");")
end
tp("\\end{tikzpicture}")
}

\end{document}

enter image description here

7

Another possibility:

\documentclass[tikz,margin=5mm,convert=false]{standalone}
\newlength\px%
\newlength\py%

\newcommand\morecoords[3][3]{%
  \foreach[count=\j] \i in {2,...,#1}{%
    % get the coordinates of the previous point (unit: pt)
    \pgfextractx{\px}{\pgfpointanchor{#2\j}{center}}
    \pgfextracty{\py}{\pgfpointanchor{#2\j}{center}}
    % calculate the coordinates of the next point (unit: pt)
    \pgfmathsetmacro\nx{(\px+#3*\py)/(1+#3*#3)}
    \pgfmathsetmacro\ny{(\py-#3*\px)/(1+#3*#3)}
    % define the new coordinate
    \coordinate(#2\i)at(\nx pt,\ny pt);
  }
}
\begin{document}
\begin{tikzpicture}
  \draw[help lines,step=0.5](-1,-1) grid (1,1);
  \draw(0,-1)--(0,1)(-1,0)--(1,0);
  %
  \coordinate(Z1)at(.9,.5);% define Z1
  \morecoords{Z}{.8}% calculate Z2 and Z3
  \foreach[count=\i start=2] \j in {2,3}\draw[red,-latex](Z\i)--(Z\j);
  %
  \coordinate(P1)at(-.8,.8);% define P1
  \morecoords[10]{P}{.7}% calculate P2,...,P10
  \foreach[count=\i start=2] \j in {2,...,10}\draw[blue,-latex](P\i)--(P\j);
  %
  \coordinate(C1)at(-60:0.9);% define C1
  \morecoords[6]{C}{.9}% calculate C2,...,C6
  \foreach[count=\i start=2] \j in {2,...,6}\draw[green,-latex](C\i)--(C\j);
\end{tikzpicture}
\end{document}

enter image description here

6

I think a recursive formula needs a recursion :P

\documentclass[tikz]{standalone}

\def\myrecursion#1#2#3#4{%
  \ifnum#4>0\relax%
    \pgfmathsetmacro{\tempx}{(#1+#3*#2)/(1+(#3)^2)}
    \pgfmathsetmacro{\tempy}{(#2-#3*#1)/(1+(#3)^2)}
    \pgfmathtruncatemacro{\tempc}{(#4-1)}
    \draw[line cap=round,->,very thin] (#1 cm,#2 cm)--(\tempx cm,\tempy cm);
    \edef\temp{\noexpand\myrecursion{\tempx}{\tempy}{#3}{\tempc}}\temp%
  \fi%
}

\begin{document}
\begin{tikzpicture}
\myrecursion{0.9}{0.5}{0.8}{10}
\end{tikzpicture}
\end{document}

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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