3

I wish to draw an object with tikz by a macro, therefore I have to calculate expressions like:

defined by:

\newcommand{\myhexagon}{2}{...}

\newcommand{\myobject}{2}{
 \myheaxgon{#1}{0.5*#2}
 \myhexagon{0.89*#1-4mm}{0.79*(#1-(0.89*#1-4mm))+#2}}
}

called by (e.g):

\myobject{2cm}{3mm}
\myobject{12mm}{3mm}

I've tried to solve with

\newcommand{\myobject}{2}{
 \def\const{0.89}
 \def\constII{0.79}

 \myheaxgon{#1}{0.5*#2}
 \myheaxgon{\the\dimexpr \const#1 -4mm\relax}{\the\dimexpr\constII\the\dimexpr#1-\the\dimexpr\const#1-4mm\relax\relax+#2\relax}
}

(viz. replace '0.89*' by '\const' and '()' by '\the\dimexpr ... \relax') but I failed. Does anyone have some idea?

  • 1
    Can you provide an MWE? – jon Dec 29 '16 at 6:08
  • For a start \newcommand{\myobject}{2}{ must be \newcommand{\myobject}[2]{ (square brackets around the number of parameters. Same for myhexagon. – Piet van Oostrum Dec 29 '16 at 12:35
5

Let's analyze what happens with \myobject{2cm}{3mm}. First the inner \dimexpr:

\the\dimexpr\const#1-4mm\relax

Macro parameter substitution is just that: text substitution. So when #1=2cm this becomes

\the\dimexpr\0.892cm-4mm\relax

not a multiplcation. If you want to multiply \const with #1, use \const\dimexpr#1\relax, like you have done with \constII. So the inner one becomes:

\the\dimexpr\const\dimexpr#1\relax-4mm\relax

With these parameters the value becomes 39.26477pt.

Now we substitute this is the outer expression. This will become then:

\the\dimexpr\constII\the\dimexpr#1-39.26477pt\relax+#2\relax

Now substitute the parameters and you get:

\the\dimexpr0.79\the\dimexpr2cm-39.26477pt\relax+3mm\relax

Now again we have an inner expression:

\the\dimexpr2cm-39.26477pt\relax

This gives 42.9589pt. But note: because you use \the, you get a text, not a length value. So with the textual substitution in the outer expression, you get:

\the\dimexpr0.7942.9589pt+3mm\relax

And instead of a multiplication, you get an illegal number with two decimal points. Lesson: don't use \the inside expressions.

With these corrections the final expression becomes:

\the\dimexpr\constII\dimexpr#1-\dimexpr\const\dimexpr#1\relax-4mm\relax\relax+#2\relax

which gives 22.47186pt. Whether that is the expected answer, I don't know.

3

Just use pgfmath if you are using TikZ anyway. Just insert your mathematical expression in \pgfmathparse (even including dimensions) and retrieve the result from \pgfmathresult (in pt).

\documentclass{article}
\usepackage{tikz}
\begin{document}

\newcommand\myhexagon[2]{%
  \pgfmathparse{#1}\pgfmathresult\
  and
  \pgfmathparse{#2}\pgfmathresult\par
}

\newcommand\myobject[2]{%
  \myhexagon{#1}{0.5*#2}%
  \myhexagon{0.89*#1-4mm}{0.79*(#1-(0.89*#1-4mm))+#2}%
}

\myobject{2cm}{3mm}
\myobject{12mm}{3mm}

\end{document}

enter image description here

3

A solution with xparse and expl3, which features a powerful and expandable module for floating point computations.

\documentclass{article}

\usepackage{tikz}
\usepackage{xparse}

\ExplSyntaxOn
\DeclareExpandableDocumentCommand{\fpdim}{m}
 {
  \fp_to_dim:n { round(#1,5) }
 }
\ExplSyntaxOff

\newcommand{\const}{0.89}
\newcommand{\constII}{0.79}

\setlength\parindent{0pt}

\begin{document}

\section{Henri}

\newcommand\henriobject[2]{%
  \henrihexagon{#1}{0.5*#2}%
  \henrihexagon{\const*#1-4mm}{\constII*(#1-(\const*#1-4mm))+#2}%
}
\newcommand\henrihexagon[2]{%
  \pgfmathparse{#1}\pgfmathresult\
  and
  \pgfmathparse{#2}\pgfmathresult\par
}

\henriobject{2cm}{3mm}
\henriobject{12mm}{3mm}

\section{Piet}

\newcommand{\pietobject}[2]{%
  \piethexagon{\the\dimexpr#1\relax}{\the\dimexpr0.5\dimexpr#2\relax\relax}%
  \piethexagon{%
    \the\dimexpr\const\dimexpr#1\relax-4mm\relax
  }{%
    \the\dimexpr\constII\dimexpr#1-(\const\dimexpr#1\relax-4mm)\relax+#2\relax
  }%
}
\newcommand{\piethexagon}[2]{%
  #1 and #2\par
}

\pietobject{2cm}{3mm}
\pietobject{12mm}{3mm}

\section{\texttt{expl3}}

\newcommand{\myobject}[2]{%
  \myhexagon{\fpdim{#1}}{\fpdim{0.5*#2}}%
  \myhexagon
    {\fpdim{\const*#1-4mm}}
    {\fpdim{\constII*(#1-(\const*#1-4mm))+#2}}%
}
\newcommand{\myhexagon}[2]{%
  #1 and #2\par
}

\myobject{2cm}{3mm}
\myobject{12mm}{3mm}

\end{document}

enter image description here

Note that the results are much alike to each other, with differences only at the fourth decimal digit.

The big differences is that the solutions with xparse and \dimexpr are fully expandable, whereas the one with \pgfmathparse isn't.

The xparse syntax is much more friendly than \dimexpr, essentially identical to the one for \pgfmathparse.

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.