3

While writing a to operator for TikZ I struck upon the following problem, how does one assign a value to \pgf@x or it's relatives \pgf@xa, \pgf@xb and \pgf@xc ?

Originally I expected something like

...
% Determine the center of the chord connecting the co-ordinates
\pgfmathparse{#1*sin(\tikz@angle@c)}%
\pgf@xc=\pgfmathresult%
\pgfmathparse{#1*cos(\tikz@angle@c)}%
\pgf@yc=\pgfmathresult%
...

to work but this and a number of variations I tried using \let and even \relax failed to assign correctly.

In the, working, code below I have used \pgfsetmacro to assign the temporary values \ctr@x and \ctr@y which I then re-assign to \pgf@x and \pgf@y respectively.

\documentclass[tikz]{standalone}

\usetikzlibrary{calc}

\makeatletter
\tikzset{%
 arc over/.style={
  to path={%
   \pgfextra{%
    % Retrieve and assign the source co-ordinate
    \tikz@scan@one@point\pgf@process(\tikztostart)%
    \pgf@xa=\pgf@x\pgf@ya=\pgf@y%
    % Retrieve and assign the target co-ordinate
    \tikz@scan@one@point\pgf@process(\tikztotarget)%
    \pgf@xb=\pgf@x\pgf@yb=\pgf@y
    % Determine the slope of the chord connecting the co-ordinates
%    \pgfmathanglebetweenpoints{\tikztostart}{\tikztotarget}% This gave funny results
    \advance\pgf@x by-\pgf@xa%
    \advance\pgf@y by-\pgf@ya%
    \pgfmathatantwo{\the\pgf@y}{\the\pgf@x}%
%     \pgfmathparse{\pgfmathresult + pi/2}% This behaves wierdly
    \pgfmathMod@{\pgfmathresult}{360}%
    \pgfmathparse{\pgfmathresult - 90}% Perhaps one should account for sign e.g. +/- 90.
    \let\tikz@angle@c=\pgfmathresult%
    % Determine the center of the chord connecting the co-ordinates
    \pgfmathsetmacro{\ctr@x}{(\pgf@xa+\pgf@xb)/2}
    \pgfmathsetmacro{\ctr@y}{(\pgf@ya+\pgf@yb)/2}
    \pgf@xc=-\ctr@x\pgf@yc=-\ctr@y%
    % Offset the center by the assigned amount
    \pgfmathsetmacro{\ctr@x}{#1*sin(\tikz@angle@c)}
    \pgfmathsetmacro{\ctr@y}{#1*cos(\tikz@angle@c)}
    \advance\pgf@xc by\ctr@x pt%
    \advance\pgf@yc by\ctr@y pt%
    % Normalize the co-ordinates
    \advance\pgf@xa by-\pgf@xc%
    \advance\pgf@ya by-\pgf@yc%
    \advance\pgf@xb by-\pgf@xc%
    \advance\pgf@yb by-\pgf@yc%
    % Determine the start and end angles
    \pgfmathatantwo{\the\pgf@ya}{\the\pgf@xa}%
    \pgfmathMod@{\pgfmathresult}{360}%
    \let\tikz@angle@a=\pgfmathresult%
    \pgfmathatantwo{\the\pgf@yb}{\the\pgf@xb}%
    \pgfmathMod@{\pgfmathresult}{360}%
    \let\tikz@angle@b=\pgfmathresult%
    % Determine the radius of the arc to be drawn
    \pgfmathveclen{\pgf@xa}{\pgf@ya}%
    \let\tikz@radius=\pgfmathresult%
    % Define the arc that is to be drawn
    \edef\tikz@to@arc@path{ arc(\tikz@angle@a:\tikz@angle@b:\tikz@radius pt) }%\show\tikz@to@arc@path
   }%
   \tikz@to@arc@path
  }
 }
}
\makeatother

\begin{document}
\begin{tikzpicture}
\draw (9pt,0) to[arc over= 0.5em] (0,9pt)
      (9pt,0) -- (0,9pt)
      (  0,0) circle (10 pt);
\end{tikzpicture}
\end{document}

This seems like bad form and I was wondering if there is a better means of achieving this.

Co-incidently if one feels like providing a code review of sorts I would be most grateful, I'm not entirely familiar with the lower level TeX stuff and this is hopefully a small example that I might learn from.

My code is adapted from the answers of Mark Wibrows and Loop Space. This question is somewhat related but did not resolve my problem.

  • could it be that you meant \pgfmathparse ? – percusse Jan 13 '17 at 23:22
  • I did mean \pgfmathresult rather then \pgfmathparse{...}, the former results when one executes the latter. The trouble is I don't seem to be able to do the assignment e.g. should one use \pgf@x = \pgfmathresult or \let\pgf@x = \the\pgfmathresult ? I think I don't really understand why this is, from other programming experience this feels like I'm mismatching types i.e. Am I assigning a <dimen> to a <scalar> value or vice versa ? If so how would I know which is what and how to work around/with this ? – Carel Jan 15 '17 at 2:15
  • I was pointing to this part \pgfmath{#1*sin(\tikz@angle@c)}% – percusse Jan 15 '17 at 14:01
  • Oh dear, that was a typo. Fixed it now. – Carel Jan 15 '17 at 15:49
  • \pgfmathsetlength? – Symbol 1 Jan 28 '17 at 0:50
1

Replace

\pgfmathsetmacro{\ctr@x}{(\pgf@xa+\pgf@xb)/2}
\pgfmathsetmacro{\ctr@y}{(\pgf@ya+\pgf@yb)/2}
\pgf@xc=-\ctr@x\pgf@yc=-\ctr@y%

by

\pgfmathsetlength\pgf@xc{-(\pgf@xa+\pgf@xb)/2}
\pgfmathsetlength\pgf@yc{-(\pgf@ya+\pgf@yb)/2}

By the way, the third line, \pgf@xc=-\ctr@x\pgf@yc=-\ctr@y is where the pain come from: it actually assigns \pgf@xc to be -\ctr@x\pgf@yc and prints =-\ctr@y into some hbox.

  • I did see your comment when you posted it but was a bit busy at the time and subsequently forgot to revisit the problem. I'll be sure to do so over the weekend and let you know how it goes. In the interim I'll mark this as the answer to close the question. Thanks for the help. – Carel Apr 12 '17 at 2:40

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.