2

This my first question here, so I hope that I present it in an appropriate form.

At the moment I'm generating lots of schematics using the TikZ-package and it's calc-Library. Therefore I use coordinates very often and in some cases I've to set either the x-coordinate or the y-coordinate to zero. What I use so far:

([yscale=0](coordiantes))

It works flawlessly so I'd like to create a custom command for that. This works to but when I'm trying to use this custom command inside a calculation LaTeX gives me an error:

\xCo {westPoint}$) to (westPoint); Paragraph ended before \tikz@cc@parse@factor was complete.

I already tried to solve the problem by trying brackets in several constellations, but this didn't bring an improvement either.

This is my MWE with the three usage scenarios (direct coordinate manipulation, custom command as well as custom command in calculation)

\documentclass{article}

%My needed packages
\usepackage{tikz}
\usetikzlibrary{calc}

%My custom command
\newcommand{\xCo}[1]{([yscale=0]#1)}

\begin{document}

\begin{tikzpicture}
%Defining coordinates
 \coordinate (westPoint) at (3,2.5);
 \coordinate (eastPoint) at (6,2.5);
% 
%Calculate the (x,0)-coordinates of 'westPoint' 
\coordinate (bottomPointA) at ($([yscale=0]westPoint)$);
%Drawing a simple line --> bottom point coordinates work
\draw (bottomPointA) to (eastPoint);
%
% NEXT VERSION --> custom command
%Drawing a simple line --> bottom point coordinates work
\draw \xCo{westPoint} to (westPoint);

%NOT working part:
\draw ($(0,1)+\xCo{westPoint}$) to (westPoint);


 \end{tikzpicture}

\end{document}

I hope that someone can tell me why this problem appears and how to solve it. Maybe there's another solution better than mine, so this also would be of interest to me.

Another problem that sounded similar was: Using a macro inside a Tikz coordinate calculation But this example is really complex and I'm not sure, if it's a similar problem like mine.

Best regard, MrMinion

P.S.: I already know and used the let \p{name} in ().... access via \x{name} or \y{name} solution, which is not that convenient as I'm only able to use the points inside one path. If someone knows how to use them 'globally', I'd appreciate it :).

  • Try \coordinate (bottomPointA) at (westPoint |- 0,0);... – Paul Gaborit Jan 25 '18 at 14:42
  • Try also \draw \xCo{westPoint} ++(0,1) to (westPoint);... – Paul Gaborit Jan 25 '18 at 14:44
  • Perfect :) Thank you. This solves my initial problem flawlessly! – MrMinion Jan 26 '18 at 11:27
  • Another idea is to use \tikzset{xCo/.style={yscale=0}} at the beginning of the document and then say e.g., ($(0,1)+[xCo](westPoint)$) – Hood Chatham Jan 27 '18 at 0:43
1

Here's a solution that modifies the tikz calc library to expand macros.

Note that this doesn't work with coordinate factors because tikzcalc scans for a literal *( to determine where a factor ends, and so the ( cannot be hidden in a macro (so 2*\xCo{point} will cause an error). There's no way to fix that without making the factor parser much slower and more complicated. It's my belief that it works with the rest of the calc syntax.

\documentclass{article}
\usepackage{etoolbox}
%My needed packages
\usepackage{tikz}
\usetikzlibrary{calc}

%My custom command
\newcommand{\xCo}[1]{([yscale=0]#1)}


\makeatletter
%% Patch a bunch of tikzcalc commands to use romannumeral trick to f expand macros
\patchcmd\tikz@cc@add{\tikz@cc@factororcoordinate}{\expandafter\tikz@cc@factororcoordinate\romannumeral-`0}{}{\error}
\patchcmd\tikz@cc@sub{\tikz@cc@factororcoordinate}{\expandafter\tikz@cc@factororcoordinate\romannumeral-`0}{}{\error}
\let\origtikz@cc@scan@rot\tikz@cc@scan@rot
\def\tikz@cc@scan@rot#1{%
    \expandafter\origtikz@cc@scan@rot\expandafter#1\romannumeral-`0%
}
\let\origtikz@cc@mid@nonactive\tikz@cc@mid@nonactive
\let\origtikz@cc@mid@active\tikz@cc@mid@active
\def\tikz@cc@mid@nonactive!{\expandafter\origtikz@cc@mid@nonactive\expandafter!\romannumeral-`0}
\edef\restorebang{\catcode`!=\the\catcode`!\relax}
\catcode`!=\active
\def\tikz@cc@mid@active!{\expandafter\origtikz@cc@mid@active\expandafter!\romannumeral-`0}
\restorebang
\makeatletter

\begin{document}

\begin{tikzpicture}
%Defining coordinates
 \coordinate (westPoint) at (3,2.5);
 \coordinate (eastPoint) at (6,2.5);
%
%Calculate the (x,0)-coordinates of 'westPoint'
\coordinate (bottomPointA) at ($([yscale=0]westPoint)$);
%Drawing a simple line --> bottom point coordinates work
\draw (bottomPointA) to (eastPoint);
%
% NEXT VERSION --> custom command
%Drawing a simple line --> bottom point coordinates work
\draw \xCo{westPoint} to (westPoint);

%% The following work due to my modification:
\draw ($(0,1)+\xCo{westPoint}$) to (westPoint);
\draw ($(1,1)+\xCo{westPoint}!0.5!(0,1)$) to (westPoint);
\draw ($(1,1)+2*(0,1)!0.5!\xCo{westPoint}$) to (westPoint);
\draw ($(1,1)+(2,0)!\xCo{westPoint}!(0,1)$) to (westPoint);

%% Does not work because it has a factor directly in front of \xCo:
%\draw ($2*\xCo{westPoint}$) to (westPoint);


 \end{tikzpicture}

\end{document} 

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.