I am trying to draw a Bézier curve defined by five control points following the algorithm discussed here.
I generate the points of the curve with a \foreach loop: one point per iteration (also, from the second iteration onwards, I draw a line between the most recently generated point to the previous one.)
I can (implicitly) set the number of points generated by changing the value of the macro \step (see code below.) However, for certain values it works while for others it doesn't., resulting in an incomplete Bézier curve.
The number of iterations performed by \foreach is stored (hopefully correctly) in the counter ni whose value is printed in the image. From this we can see that:
\step expected-ni actual_ni
0.1 11 10
0.5 21 20
0.01 101 101 OK
0.001 1001 993 ???
What is going on? Where did I mess up?
Here is my (not so minimal) example: (It may take a while to compile)
\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}
\usepackage{ifthen}
\begin{document}
\begin{tikzpicture}[
ctrlpoint/.style={%
draw=#1,
circle,
inner sep=0,
minimum width=1ex,
},
ctrlpoint/.default={gray},
]
\def\xmax{10}
\def\ymax{5} % Now Copy the same picture for different numbers of Bézier points.
\newcounter{nc} % Number of Copies: count the Copies of the picture (x-, y-shifted via `scope').
\newcounter{ni} % Number of Iterations: measure how many times the \foreach loop is evaluated inside each picture.
\foreach \x/\y/\step in {0/0/1,13/0/0.5,0/6/.2,13/6/.125,0/12/.1111,13/12/.1,0/18/.05,13/18/.02,0/24/0.01,13/24/0.001}
{
\refstepcounter{nc}% Increment number of copies outside `scope'
\begin{scope}[xshift=\x cm,yshift=-\y cm]
\node [ctrlpoint] (p0) at (0,0) [label=left:$P_0$] {};
\node [ctrlpoint] (p1) at (-1,4) [label=120:$P_1$] {};
\node [ctrlpoint] (p2) at (5,\ymax) [label=above:$P_2$] {};
\node [ctrlpoint] (p3) at (8,0) [label=right:$P_3$] {};
\node [ctrlpoint] (p4) at (\xmax,4) [label=right:$P_4$] {};
\draw [gray] (p0) -- (p1) -- (p2) -- (p3) -- (p4);
\setcounter{ni}{0}% Reset Number of Iterations at each Copy.
\foreach \parameter in {0,\step,...,1} { % At each iteration a point belonging to the Bézier curve is generated.
\refstepcounter{ni} % If it is the 2nd time or more, draw a segment from current Bézier-point
\def\t{\parameter} % to the previous one (see end of scope.)
\path let % Each Copy has a different number of generated Bézier points,
\p0 = (p0), % implicitly defined by assignign \step.
\p1 = (p1), % At each iteration the macro \t is redefined overwriting the previous definition.
\p2 = (p2),
\p3 = (p3),
\p4 = (p4),
\p{01} = ($ (\p0) !\t! (\p1) $),
\p{12} = ($ (\p1) !\t! (\p2) $),
\p{23} = ($ (\p2) !\t! (\p3) $),
\p{34} = ($ (\p3) !\t! (\p4) $)
in
coordinate (q0) at (\p{01})
coordinate (q1) at (\p{12})
coordinate (q2) at (\p{23})
coordinate (q3) at (\p{34});
\path let
\p0 = (q0),
\p1 = (q1),
\p2 = (q2),
\p3 = (q3),
\p{01} = ($ (\p0) !\t! (\p1) $),
\p{12} = ($ (\p1) !\t! (\p2) $),
\p{23} = ($ (\p2) !\t! (\p3) $)
in
coordinate (r0) at (\p{01})
coordinate (r1) at (\p{12})
coordinate (r2) at (\p{23});
\path let
\p0 = (r0),
\p1 = (r1),
\p2 = (r2),
\p{01} = ($ (\p0) !\t! (\p1) $),
\p{12} = ($ (\p1) !\t! (\p2) $)
in
coordinate (s0) at (\p{01})
coordinate (s1) at (\p{12});
\path let
\p0 = (s0),
\p1 = (s1),
\p{01} = ($ (s0) !\t! (s1) $)
in
coordinate (t\theni) at (\p{01});
% \fill [blue] (t\theni) circle (1.5pt);
\ifthenelse{%
\theni > 1%
}{%
\draw [blue] (t\theni) -- (t\the\numexpr\theni-1);%
}{}
}
\node at (.33*\xmax,.4*\ymax) {Number of Iterations: \textbf{\theni}};
\end{scope}
}
\end{tikzpicture}
\end{document}
\stepin something likepgfmathprintnumber, as suggested in a comment to the linked question? Would it be effective at all? The macro should be redefined at each iteration, too. – Pier Paolo Jan 08 '15 at 01:17\foreach\x{0,...,\pgfmathresult}– percusse Jan 08 '15 at 01:50