\dx==0
当为真时,以下代码将引发除以 0 的错误:
\pgfmathsetmacro{\rot}{(
\dx==0 ? (\dy > 0 ? 90 : -90) : (\dx>0 ? atan(\dy/\dx) : 180+atan(\dy/\dx))
)}
\rot
即使条件为真,代码设置\dx==0
也正确,但似乎解析器仍在继续分析错误子句,即使条件为真。有人知道我做错了什么吗?完整代码如下:
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\usepgfmodule{oo}
%http://tex.stackexchange.com/questions/33703/extract-x-y-coordinate-of-an-arbitrary-point-in-tikz
\makeatletter
\newcommand{\gettikzxy}[3]{%
\tikz@scan@one@point\pgfutil@firstofone#1\relax
\edef#2{\the\pgf@x}%
\edef#3{\the\pgf@y}%
}
\makeatother
\pgfooclass{rr}{
\method rr(#1,#2) { % The constructor; everything is done in here
% Here I can get named x and y coordinates
\gettikzxy{(#1)}{\spx}{\spy}
\gettikzxy{(#2)}{\epx}{\epy}
% I'd like named points to work with
\coordinate (Start) at (\spx, \spy) node[right]{start};
\coordinate (End) at (\epx, \epy);
% Find the length between start and end. Then the angle between x axis and Diff will be the rotation to apply.
\coordinate (Diff) at ($ (End)-(Start) $);
\gettikzxy{(Diff)}{\dx}{\dy}
\pgfmathparse{veclen(\dx, \dy)} \pgfmathresult
\let\length\pgfmathresult
\node[right] at (End) {\length};
\pgfmathsetmacro{\rot}{(
\dx==0 ? (\dy > 0 ? 90 : -90): (\dx>0 ? atan(\dy/\dx) : 180+atan(\dy/\dx))
)}
\begin{scope} [rotate around = {\rot:(\spx, \spy )}]
\draw ($ (Start)+(0,\hi) $) arc(90:270:\hi) -- +(\length pt, 0) arc(-90:90:\hi) -- cycle;
\end{scope}
}
}
\begin{document}
\begin{tikzpicture}
\coordinate (A) at (0,0);
\coordinate (B) at (0,16);
\def\hi{0.25}
\pgfoonew \AB=new rr(A,B);
\fill (A) circle (3pt);
\fill (B) circle (3pt);
\end{tikzpicture}
\end{document}
答案1
是的,简写符号的所有组成部分都会被求值,即使只有一个分支会跟随。以下简单公式会产生相同的错误:
\pgfmathparse{1==2 ? 3/0 : 4}\pgfmathresult
由于 1 不是 2,结果应该是 4,但编译器仍然评估 3/0。
解决这个问题的一个简单方法是使用 TeX 条件,除非必要,否则不会进行评估。因此,我们首先评估是否\dx==0
使用\pgfmathparse
,然后对 进行条件(使用 TeX 基元)\pgfmathresult
。
那是,
\pgfmathsetmacro{\rot}{(
\dx == 0 ? (\dy > 0 ? 90 : -90) : (\dx > 0 ? atan(\dy / \dx) : 180 + atan(\dy / \dx))
)}
变成
\pgfmathparse{\dx == 0}%
\ifnum\pgfmathresult=1 % \dx == 0
\pgfmathsetmacro{\rot}{\dy > 0 ? 90 : -90}
\else% \dx != 0
\pgfmathsetmacro{\rot}{\dx > 0 ? atan(\dy / \dx) : 180 + atan(\dy / \dx)}
\fi