2

This question already has an answer here:

I want to create a loop over an false-position algorithm But I have two problems with \pgfmathsetmacro.

(1) The curly parentheses does not allow `\pgfmathsetmacro` to evaluate

In the code below, my \XM will not be defined if I insert the curly parenthesis there. This problem prevent me from using \foreach

(2) If the variable is redefined, it plots from the new position instead of the 
value where the plot was issued. 

This forces me to defined new variable which is not a good way.

What should I do ??

Here is the code

\documentclass[]{standalone}
\usepackage{pst-all}
\usepackage{graphicx}
\usepackage{tikz}
\usepackage{verbatim}
\usepackage{pgfplots}   
\usepackage{tikz-dimline}   
\usepackage{ifthen}
\usetikzlibrary{patterns}
\usetikzlibrary{arrows}
% Adapted from the 'patterns' library: enlarged the distance between the lines from 4pt to 10pt
\pgfdeclarepatternformonly{north east lines wide}{\pgfqpoint{-1pt}{-1pt}}{\pgfqpoint{10pt}{10pt}}{\pgfqpoint{9pt}{9pt}}%
{
\pgfsetlinewidth{0.4pt}
\pgfpathmoveto{\pgfqpoint{0pt}{0pt}}
\pgfpathlineto{\pgfqpoint{9.1pt}{9.1pt}}
\pgfusepath{stroke}
}

\tikzset{%
body/.style={inner sep=0pt,outer sep=0pt,shape=rectangle,draw,thick,pattern=north east lines wide},
dimen/.style={<->,>=latex,thin,every rectangle node/.style={fill=white,midway,font=\sffamily}},
symmetry/.style={dashed,thin},
}

\definecolor{gray3}{RGB}{50, 50, 50}
\definecolor{gray2}{RGB}{100, 100, 100}
\definecolor{gray1}{RGB}{150, 150, 150}

\definecolor{red3}{RGB}{255, 0, 0}
\definecolor{red2}{RGB}{220, 70, 91}
\definecolor{red1}{RGB}{255, 120, 120}

\begin{document}

    %the plotting function
\def\FunctionF(#1){(sin(3*#1*180.0/3.1415)-0.1)}%
\newcommand*{\FunctionFGnuplot}{ (sin(3*x)-0.1)}%
\newcommand\XL{0.1}
\newcommand\XR{2.0}
%----two beginning points leftmost and rightnost
\pgfmathsetmacro{\YL}{\FunctionF(\XL)}
\pgfmathsetmacro{\YR}{\FunctionF(\XR)}  

    \begin{tikzpicture}

\begin{axis}[
trig format plots=rad,
axis lines = middle,
enlargelimits,
, ymin=-1,ymax=1.0, restrict y to domain=-3:3,
xlabel=$x$,ylabel=$y$, 
every axis x label/.style={
at={(ticklabel* cs:1.025)},
anchor=north east,
}
,every axis y label/.style={
at={(ticklabel* cs:1.025)},
anchor=east,
}
]

\addplot[color=blue,domain=\XL:\XR,line width = 1.0,samples=64]{ \FunctionFGnuplot};
%---two beginning points
\addplot[mark=*,color=blue] coordinates {(\XL,\YL)};
\addplot[mark=*,color=blue] coordinates {(\XR,\YR)};


%---the straight line joining two points. 
%   The x-intersection will be the new xm   


% Line1
\draw [line width = 0.25] (axis cs:\XL,\YL)--(axis cs:\XR,\YR);


%%------------------- Problem with  {}   here -----------------
%% Problem 1:
%% If I open the curly bracket below here \XM will not be defined no matter
%% where I close it


\pgfmathsetmacro{\XM}{  \XL - \YL* (\XR-\XL ) / (\YR-\YL)  }    ;
    \pgfmathsetmacro{\YM}{\FunctionF(\XM)}  ;
      %\addplot[mark=*,color=gray1] coordinates {(\XM,0)};
      \node[gray,below] at (axis cs:\XM,0){$x_m^1$};
    %----------------------------------------------------------------


    \addplot[mark=*,color=red1] coordinates {(\XM,\YM   )}; 

\draw [->,line width = 0.25] (axis cs:\XM,0) to   (axis cs:\XM,\YM/2);  
\draw [-, line width = 0.25] (axis cs:\XM,0) to   (axis cs:\XM,\YM);    

%--------------------------------------------------------------------------
%Problem 2: Line1 is not drawn immeadiately when it was defined above.
%           But it wait until \XL was redefined here.
%           Instead of having a line joining two blue dots,
%           I got something else. 
\pgfmathsetmacro{\XLL}{ ifthenelse( \YL*\YM <0, \XL, \XM)};
\pgfmathsetmacro{\XRR}{ ifthenelse( \YL*\YM <0, \XM, \XR)}; 
\pgfmathsetmacro{\YLL}{ ifthenelse( \YL*\YM <0, \YL, \YM)};
\pgfmathsetmacro{\YRR}{ ifthenelse( \YL*\YM <0, \YM, \YR)}; 


    %----------------second loop
\draw [line width = 0.25] (axis cs:\XLL,\YLL)--(axis cs:\XRR,\YRR);
\pgfmathsetmacro{\XMM}{  \XLL - \YLL* (\XRR-\XLL ) / (\YRR-\YLL)  } ;
    \pgfmathsetmacro{\YMM}{\FunctionF(\XMM)}    ;
    %\addplot[mark=*,color=gray2] coordinates {(\XMM,0)};
          \node[gray,above] at (axis cs:\XMM,0){$x_m^2$};

    \addplot[mark=*,color=red2] coordinates {(\XMM,\YMM )}; 
\draw [->,line width = 0.25] (axis cs:\XMM,0) to   (axis cs:\XMM,\YMM/2);   
\draw [-, line width = 0.25] (axis cs:\XMM,0) to   (axis cs:\XMM,\YMM); 

\pgfmathsetmacro{\XLLL}{ ifthenelse( \YLL*\YMM <0, \XLL, \XMM)};
\pgfmathsetmacro{\XRRR}{ ifthenelse( \YLL*\YMM <0, \XMM, \XRR)};    
\pgfmathsetmacro{\YLLL}{ ifthenelse( \YLL*\YMM <0, \YLL, \YMM)};
\pgfmathsetmacro{\YRRR}{ ifthenelse( \YLL*\YMM <0, \YMM, \YRR)};    

%----------------third loop 

\draw [line width = 0.25] (axis cs:\XLLL,\YLLL)--(axis cs:\XRRR,\YRRR);
\pgfmathsetmacro{\XMMM}{  \XLLL - \YLLL* (\XRRR-\XLLL ) / (\YRRR-\YLLL)  }  ;
    \pgfmathsetmacro{\YMMM}{\FunctionF(\XMMM)}  ;

    %\addplot[mark=*,color=gray3] coordinates {(\XMMM,0)};  
              \node[gray, above right, node distance = 1cm] at (axis cs:\XMMM,0){$x_m^3$};
    \addplot[mark=*,color=red3] coordinates {(\XMMM,\YMMM   )}; 

\draw [->,line width = 0.25] (axis cs:\XMMM,0) to   (axis cs:\XMMM,\YMMM/2);    
\draw [-, line width = 0.25] (axis cs:\XMMM,0) to   (axis cs:\XMMM,\YMMM);      

\draw [line width = 0.25] (axis cs:\XLLL,\YLLL)--(axis cs:\XRRR,\YRRR); 


\pgfmathsetmacro{\XLLLL}{ ifthenelse( \YLLL*\YMMM <0, \XLLL, \XMMM)};
\pgfmathsetmacro{\XRRRR}{ ifthenelse( \YLLL*\YMMM <0, \XMMM, \XRRR)};   
\pgfmathsetmacro{\YLLLL}{ ifthenelse( \YLLL*\YMMM <0, \YLLL, \YMMM)};
\pgfmathsetmacro{\YRRRR}{ ifthenelse( \YLLL*\YMMM <0, \YMMM, \YRRR)};   
%----------------fourth loop    
\pgfmathsetmacro{\XMMMM}{  \XLLLL - \YLLLL* (\XRRRR-\XLLLL ) / (\YRRRR-\YLLLL)  }   ;


     \addplot[mark=*,color=black] coordinates {(\XMMMM,0)};
\end{axis}

    \end{tikzpicture}
\end{document}

marked as duplicate by gernot says Reinstate Monica, Stefan Pinnow, T. Verron, user13907, Andrew Swann Nov 8 '16 at 11:11

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • you might want to reduce the code to something just related to your problem, the rest does not seem relevant to the problem you ask about. – daleif Nov 8 '16 at 9:44
  • There are to issues. The minor one is that all assignments and definitions by tikz, pgfplots, pgfmath etc are local to the current group (which is a good thing). This means that when you enclose a group of definitions into curly braces, they will not exist outside of the braces. The major issue in your approach is that pgfplots does not evaluate variables in \draw commands and the like immediately, but delays the \draws until the end of the axis where the variables have changed/lost their values. – gernot says Reinstate Monica Nov 8 '16 at 10:06
  • 4
    The solution: Expand variables in \draw statements immediately. For foreach loops there is a pgfplots replacement that does this implicitly. For details see "\foreach not behaving in axis environment", "Why doesn't a \foreach variable work in \draw in an \axis?" and/or "Use macro to draw inside pgfplot/axis". – gernot says Reinstate Monica Nov 8 '16 at 10:09