TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

In order to have a tikz picture adjust to some input values I have created something as the code below. In the code below the distance between A and C is twice as long as the distance between A and B as it should be. However, the number given ist not correct. Instead of 2*15 I would like to have 30.

\documentclass[tikz]{standalone}
\usepackage{tikz}
\usepackage[utf8]{inputenc}
\usetikzlibrary{calc}
\usetikzlibrary{backgrounds}
\newcommand{\Anton}{15}
\newcommand{\Berta}{\Anton*2} 
\begin{document}
\centering
\begin{tikzpicture}[x=1mm,y=1mm,scale=1] 
\tikzset{mystyle/.style={<->}}   
    \tikzset{every node/.style={fill=white, font=\normalsize}} 
\node (A) at (0,0){A};
\node (B) at (\Anton,0){B};
\node (C) at (-\Berta,0){C};
% Maße Vertikal
\path (A) edge [mystyle] node {\Anton} (B);
\path (A) edge [mystyle] node {\Berta} (C);
\end{tikzpicture}
\end{document}

gives:

Results as is

Is there a way to calculate the content of \Bertabefore using it as the lable on the \path?

Thanks!

share|improve this question
up vote 4 down vote accepted

Use \pgfmathsetmacro for a decimal number and \pgfmathtruncatemacro for an integer. Alternatively, if you want to handle both together, here's a variant of \pgfmathsetmacro. The way it works is as follows: our problem is that \pgfmathsetmacro\test{1+1} sets \test to 2.0. So my variant checks whether the result is of the form n.0 for some integer n, and if so drops the 0. Other decimals are left alone.

\documentclass[tikz]{standalone}
\usepackage{tikz}
\usepackage[utf8]{inputenc}
\usetikzlibrary{calc}
\usetikzlibrary{backgrounds}
\newcommand\mymathsetmacro[2]{\pgfmathparse{#2}\expandafter\mymathsetmacrohelper\pgfmathresult\nil\edef#1{\pgfmathresult}}
\def\mymathsetmacrohelper#1.#2#3\nil{\ifx0#2\ifx&#3& \def\pgfmathresult{#1}\fi \fi}
\newcommand{\Anton}{15}
\mymathsetmacro{\Berta}{\Anton*2}
\begin{document}
\centering
\begin{tikzpicture}[x=1mm,y=1mm,scale=1]
\tikzset{mystyle/.style={<->}}
    \tikzset{every node/.style={fill=white, font=\normalsize}}
\node (A) at (0,0){A};
\node (B) at (\Anton,0){B};
\node (C) at (-\Berta,0){C};
% Maße Vertikal
\path (A) edge [mystyle] node {\Anton} (B);
\path (A) edge [mystyle] node {\Berta} (C);
\end{tikzpicture}
\end{document} 
share|improve this answer
    
@cfr From my Layman's point of view this solution (usinge pgfmathtruncatemacroinstead of newcommandseems a lot simpler to create in the first place (and it is easyer to change my existing code to accomodate it). Could you try to explain the risks of this solution? – MatoBehr 7 hours ago
    
Wouldn't it be safer to always use \pgfmathsetmacroinstead of \pgfmathtruncatemacro in case I change one of the numbers to a decimal at some point? To answer this myself, the later may produce rather long number that do not look good at all. Could this be the reason why @cfr solution might be better? – MatoBehr 7 hours ago
1  
The frustrating thing about \pgfmathsetmacro is that \pgfmathsetmacro\test{1+1} sets \test to 2.0. If the values you are using are not always integers, then maybe it's better when they are integers to use \pgfmathsetmacro\test{int(formula)}. – Hood Chatham 49 mins ago
1  
See edit for a "best of both worlds" solution. – Hood Chatham 8 mins ago

I would do the whole thing with TikZ/PGF keys. If you want \Anton and \Berta available generally, you can use \tikzset{} in the preamble or at the beginning of the document.

There are various ways to do this. The way I've done it here involves setting up \Anton to store a simple value, defining an additional style (double trouble) to create \Berta from an argument using \pgfmathsetmacro, and then simply forwarding the value given to Anton to double trouble any time Anton is set.

This is more complicated to explain than to see in the code, I think!

\documentclass[tikz]{standalone}
\usepackage[utf8]{inputenc}
\tikzset{%
  % key Anton stores a value in \Anton
  Anton/.store in=\Anton,
  % key double trouble sets \Berta to twice the argument it is given
  double trouble/.code={%
    \pgfmathsetmacro\Berta{int(2*#1)}%
  },
  % any time the key Anton is used, the same value will be passed to double trouble
  Anton/.forward to=/tikz/double trouble,
  % make sure the key Anton is set to something so \Anton and \Berta have some default value
  Anton=15,
}
\begin{document}
\begin{tikzpicture}
  [
    x=1mm,
    y=1mm,
    mystyle/.style={<->},
    every node/.style={fill=white},
  ]
  \node (A) {A};
  \node (B) at (\Anton,0){B};
  \node (C) at (-\Berta,0){C};
  % Maße Vertikal
  % we can make this a bit more concise ...
  \path [mystyle] (A) edge node {\Anton} (B) edge node {\Berta} (C);
\end{tikzpicture}
\end{document}

Anton and Berta

The advantage of using TikZ keys is that the user interface is intuitive and that it is easy to modify the values between or within tikzpictures.

Adding the following after the above picture, for example, we change the value of both macros by setting Anton=10 and then modify them again for just one node, setting Anton=2, so that \Berta produces 4 while \Anton still produces 10 when creating the nodes on the final line.

\begin{tikzpicture}
  [
    x=1mm,
    y=1mm,
    mystyle/.style={draw=blue, thick, text=red},
    every node/.style={fill=white},
    Anton=10,
  ]
  \node (A) {A};
  \node (B) at (\Anton,0){B};
  \node (C) at (-\Berta,0){C};
  % Maße Verti
  % we can make this a bit more concise ...
  \path [mystyle] (A) edge node {\Anton} (B) edge node [Anton=2] {\Berta} (C);
\end{tikzpicture}

Anton and Berta

Note that the distances used are all based on the initial value. The macros differ only when creating the node containing \Berta.

Whether this is useful and how useful depends, obviously, on the real use case. But it the kind of thing which is often required in TikZ pictures and it is nice to keep that flexibility, even if it is not of any immediate use.

share|improve this answer
    
I don't really see the advantage of using \pgfkeys over directly making a macro do the same thing. I think the logic is easier to understand with a macro (and the code runs much faster, it doesn't usually matter much but \pgfkeys is not exactly efficient). Compare: \def\setAntonBerta#1{\def\Anton{#1}\pgfmathsetmacro\Berta{in‌​t(2*#1)}} – Hood Chatham 11 hours ago
1  
I don't think efficiency is such a consideration here as the difference will be negligible. TikZ is loaded anyway and the macros are wanted for use in a tikzpicture. This method makes it easy to customise the values. And I certainly would not recommend the use of \def in a LaTeX document unless it is unavoidable. \newcommand is certainly preferable. Not in terms of speed, but in terms of safety. The advantage of using keys is the user-interface. It is also a more contained approach, although that isn't really an issue here as far as we know. – cfr 11 hours ago
    
If you say Anton/.show code, you'll see that Anton=#1 leads to \def\Anton{#1}\pgfkeys {/tikz/double trouble={#1}}, so the keys method is using a \def inside. You want to overwrite the value of \Anton anyways, so I don't see the issue. – Hood Chatham 11 hours ago
    
@HoodChatham See edit. I think this is regrettable, myself, and that it would be better for PGF to be more careful. However, there isn't much choice, I suppose, if it is to be format-independent. – cfr 11 hours ago
1  
@HoodChatham But really, I think the reason to avoid \def has to do with habit. In that sense \tikzset does not have the same consequences. Although it could be argued that makes it all the more pernicious, of course. Anyway, my main reasons for doing it this way have to do with the user interface and flexibility. – cfr 11 hours ago

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.