# automatic tikz coordinate calculations

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:

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

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

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}


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}


-

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}


-

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}


-

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}


-