2

I have nodes on a parametric path and I want to know witch node is the furthest from (0,0). I tried this ugly thing :

\documentclass[a4paper]{article}
\usepackage[marginparsep=3pt, top=2cm, bottom=1.5cm, left=1.5cm, right=1.5cm]{geometry}

\usepackage{tikz}
\usetikzlibrary{calc,intersections}

\tikzset{small dot/.style={fill=black,circle,scale=0.3},}


\newcommand{\CoorXY}[1]{%
\pgfmathsetmacro\PjX{3*cos(\A)}
\pgfmathsetmacro\PjY{5*sin(\A)}
\node[small dot,label={[font=\scriptsize]#1}] at (\PjX,\PjY) {}
}
\begin{document}
\begin{tikzpicture}

\def\tmpB{0}
\def\Max{0}
\foreach \A in {0,10,...,360} {
\CoorXY{\A} ;
\pgfmathparse{veclen(\PjX,\PjY)} ;
\let\tmpA\pgfmathresult ;
\pgfmathifthenelse{\tmpA>\tmpB}{\A}{\Max} ;
\let\Max\pgfmathresult ;
\pgfmathifthenelse{\tmpA>\tmpB}{\tmpA}{\tmpB} ;
\let\tmpB\pgfmathresult ;
\message{Max \tmpB pour \Max}
} 


\end{tikzpicture}
\end{document}

but it is not working. Any idea why, and there is certainly a better idea. Thank you.

3
  • 2
    Please make your code into a fully compilable MWE including \documentclass and the appropriate packages that sets up the problem. – Peter Grill Feb 26 '14 at 0:34
  • The document is complex and long, and it is not minimal. I put this ugly code just to show that I have work on a methode to find this node but the problem is in the tests. The syntax is easier in metapost for example. I can erase my code and just ask the question, if you prefer ? – Tarass Feb 26 '14 at 0:44
  • 2
    No, don't erase it, just take the time to convert it into something that executes. For instance, the code does not define \CoorXY, it does not include the required packages. While solving problems can be fun, setting them up is not. Then, those trying to help can simply cut and paste your MWE and get started on solving the problem. – Peter Grill Feb 26 '14 at 0:51
3

Here is one way to do it. The following prints:

enter image description here

Notes:

  • To simplify this example, I eliminated the need to extract coordinates and instead fed the separate x, y values into \foreach.
  • The \foreach executes its contents within a group, so if a value within an iteration needs to be saved one needs to do a \global type of assignment to retain the value between iterations.

Code:

\documentclass{article}
\usepackage{tikz}

%http://tex.stackexchange.com/questions/15297/how-to-test-if-a-number-is-negative
\newcommand\IfNonnegative[3]{% 
    \begingroup%
    \pgfmathparse{ifthenelse(#1>=0,1,0)}%
    \if\pgfmathresult 1 \relax%
            {#2}%
        \else%
            {#3}%
    \fi%
    \endgroup%
}%


\newcommand*{\FarthestNodeX}{0}%
\newcommand*{\FarthestNodeY}{0}%
\newlength{\ExcessDistanceOfThisNode}%
\begin{document}

\foreach \PjX/\PjY in {1/3, 1/3, 5/2, 3/3, 0/0} {
    \pgfmathsetlength{\ExcessDistanceOfThisNode}{veclen(\PjX,\PjY)-veclen(\FarthestNodeX,\FarthestNodeY)}
    \IfNonnegative{\ExcessDistanceOfThisNode}{
        \xdef\FarthestNodeX{\PjX}
        \xdef\FarthestNodeY{\PjY}
    }{}%
}

Farthest Node is at (\FarthestNodeX,\FarthestNodeY).
\end{document}
2
  • Thank you, but I don't want to know how far it is but who it is, his number in the list. I try to work with your answer. – Tarass Feb 26 '14 at 1:34
  • I replace the "let" in my example by "xdef" as in yours and in works just fine. Thank you again. I will look at the differnce between let, def, and xdef. – Tarass Feb 26 '14 at 1:41
2

The main problem with your current code is that the scope of the \let commands inside your foreach loop is only the current iteration. So at the beginning of the next iteration \tmpB and \Max are both 0. The easiest way to fix this is to declare these operation \global:

\documentclass[a4paper]{article}
\usepackage[marginparsep=3pt, top=2cm, bottom=1.5cm, left=1.5cm, right=1.5cm]{geometry}

\usepackage{tikz}
\usetikzlibrary{calc,intersections}

\tikzset{small dot/.style={fill=black,circle,scale=0.3},}

\newcommand{\CoorXY}[1]{%
\pgfmathsetmacro\PjX{3*cos(\A)}
\pgfmathsetmacro\PjY{5*sin(\A)}
\node [small dot,label={[font=\scriptsize]#1}] (n#1) at (\PjX,\PjY) {}
}
\begin{document}
\begin{tikzpicture}

\def\tmpB{0}
\def\Max{0}
\foreach \A in {0,10,...,360} {
\CoorXY{\A} ;
\pgfmathparse{veclen(\PjX,\PjY)} ;
\let\tmpA\pgfmathresult ;
\pgfmathifthenelse{\tmpA>\tmpB}{\A}{\Max} ;
\global\let\Max\pgfmathresult ;
\pgfmathifthenelse{\tmpA>\tmpB}{\tmpA}{\tmpB} ;
\global\let\tmpB\pgfmathresult ;
} 
\node (0,0) {Max \tmpB\ pour \Max};
\node [pin={MAX}] at (n\Max) {};

\end{tikzpicture}
\end{document}

For easy reference to each node I made them named nodes, so you can easily place a marker at the first node at the maximum distance.

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.