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.

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.

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

5 Answers 5

up vote 10 down vote accepted

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} 
share|improve this answer
    
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 at 22:04
    
@JasonS I updated my answer, was it something like that you had in mind? –  Torbjørn T. May 30 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}

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

share|improve this answer

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

share|improve this answer

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

share|improve this answer

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

share|improve this answer

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.