使用 \if 将八个 TikZ 命令合并为一个

使用 \if 将八个 TikZ 命令合并为一个

我想结合我最近研究的两个问题中的功能(这里那里

也就是说,我想创建一个带有六个参数的命令:一个端点P、一个水平距离a、一个垂直距离b、一个水平方向(左或右)、一个垂直方向(上或下),最后是一个位置(线段的上方或下方),然后绘制相应的圆。2x2x2=8可能的圆弧如下图所示: 在此处输入图片描述

这八个圆弧中的每一条都可以用 TikZarc构造直接实现;半径为\frac{a^2+b^2}{2b},并且对于角度有以下对应表(其中\thetaacos(\frac{2ab}{a^2+b^2})):

在此处输入图片描述

使用 Qrrbrbirlbel 对上述问题之一的回答,很容易为这八种情况中的每一种构建一个临时命令,例如

\tikzset{
  rightupabovechord/.style args={#1:#2}{
    /utils/exec=%
      \pgfmathsetmacro\myTempVal{(#1)*(#1)/(#2)/2+(#2)/2}%
      \ifpgfmathunitsdeclared\edef\myTempVal{\myTempVal pt}\fi
      \pgfmathsetmacro\myTempAng{acos(2*(#1)*(#2)/((#1)*(#1)+(#2)*(#2)))},
    radius=\myTempVal, start angle=180-\myTempAng, end angle=90},
  rightupaboveafro/.style={insert path={arc[rightupabovechord={#1}]}},
  rightupabovechord a/.initial=, rightupabovechord b/.initial=,
  rightupabovechord do/.style={rightupabovechord={\pgfkeysvalueof{/tikz/rightupabovechord a}:\pgfkeysvalueof{/tikz/rightupabovechord b}}},
}

我也可以复制粘贴上述 8 次,然后针对每种情况重写命令,但这肯定是不好的做法,而且浪费时间。如何推广上述命令以涵盖所有情况?我唯一知道的是args={#1:#2}应该替换为args={#1:#2:#3:#4:#5},并且里面的代码/utils/exec应该包含几个\if。此时我陷入困境。

任何帮助均感激不尽。

为了回答下面的评论,这里是该问题的完整 LaTeX 源文件:

\documentclass{article}
\usepackage{tikz}

\tikzset{
  leftdownbelowchord/.style args={#1:#2}{
    /utils/exec=%
      \pgfmathsetmacro\myTempVal{(#1)*(#1)/(#2)/2+(#2)/2}%
      \ifpgfmathunitsdeclared\edef\myTempVal{\myTempVal pt}\fi
      \pgfmathsetmacro\myTempAng{acos(2*(#1)*(#2)/((#1)*(#1)+(#2)*(#2)))},
    radius=\myTempVal, start angle=360-\myTempAng, end angle=270},
  leftdownbelowafro/.style={insert path={arc[leftdownbelowchord={#1}]}},
  leftdownbelowchord a/.initial=, leftdownbelowchord b/.initial=,
  leftdownbelowchord do/.style={leftdownbelowchord={\pgfkeysvalueof{/tikz/leftdownbelowchord a}:\pgfkeysvalueof{/tikz/leftdownbelowchord b}}},
}

\tikzset{
  leftdownabovechord/.style args={#1:#2}{
    /utils/exec=%
      \pgfmathsetmacro\myTempVal{(#1)*(#1)/(#2)/2+(#2)/2}%
      \ifpgfmathunitsdeclared\edef\myTempVal{\myTempVal pt}\fi
      \pgfmathsetmacro\myTempAng{acos(2*(#1)*(#2)/((#1)*(#1)+(#2)*(#2)))},
    radius=\myTempVal, start angle=90, end angle=180-\myTempAng},
  leftdownaboveafro/.style={insert path={arc[leftdownabovechord={#1}]}},
  leftdownabovechord a/.initial=, leftdownabovechord b/.initial=,
  leftdownabovechord do/.style={leftdownabovechord={\pgfkeysvalueof{/tikz/leftdownabovechord a}:\pgfkeysvalueof{/tikz/leftdownabovechord b}}},
}


\tikzset{
  leftupbelowchord/.style args={#1:#2}{
    /utils/exec=%
      \pgfmathsetmacro\myTempVal{(#1)*(#1)/(#2)/2+(#2)/2}%
      \ifpgfmathunitsdeclared\edef\myTempVal{\myTempVal pt}\fi
      \pgfmathsetmacro\myTempAng{acos(2*(#1)*(#2)/((#1)*(#1)+(#2)*(#2)))},
    radius=\myTempVal, start angle=270, end angle=180+\myTempAng},
  leftupbelowafro/.style={insert path={arc[leftupbelowchord={#1}]}},
  leftupbelowchord a/.initial=, leftupbelowchord b/.initial=,
  leftupbelowchord do/.style={leftupbelowchord={\pgfkeysvalueof{/tikz/leftupbelowchord a}:\pgfkeysvalueof{/tikz/leftupbelowchord b}}},
}

\tikzset{
  leftupabovechord/.style args={#1:#2}{
    /utils/exec=%
      \pgfmathsetmacro\myTempVal{(#1)*(#1)/(#2)/2+(#2)/2}%
      \ifpgfmathunitsdeclared\edef\myTempVal{\myTempVal pt}\fi
      \pgfmathsetmacro\myTempAng{acos(2*(#1)*(#2)/((#1)*(#1)+(#2)*(#2)))},
    radius=\myTempVal, start angle=\myTempAng, end angle=90},
  leftupaboveafro/.style={insert path={arc[leftupabovechord={#1}]}},
  leftupabovechord a/.initial=, leftupabovechord b/.initial=,
  leftupabovechord do/.style={leftupabovechord={\pgfkeysvalueof{/tikz/leftupabovechord a}:\pgfkeysvalueof{/tikz/leftupabovechord b}}},
}


\tikzset{
  rightdownbelowchord/.style args={#1:#2}{
    /utils/exec=%
      \pgfmathsetmacro\myTempVal{(#1)*(#1)/(#2)/2+(#2)/2}%
      \ifpgfmathunitsdeclared\edef\myTempVal{\myTempVal pt}\fi
      \pgfmathsetmacro\myTempAng{acos(2*(#1)*(#2)/((#1)*(#1)+(#2)*(#2)))},
    radius=\myTempVal, start angle=180+\myTempAng, end angle=270},
  rightdownbelowafro/.style={insert path={arc[rightdownbelowchord={#1}]}},
  rightdownbelowchord a/.initial=, rightdownbelowchord b/.initial=,
  rightdownbelowchord do/.style={rightdownbelowchord={\pgfkeysvalueof{/tikz/rightdownbelowchord a}:\pgfkeysvalueof{/tikz/rightdownbelowchord b}}},
}

\tikzset{
  rightdownabovechord/.style args={#1:#2}{
    /utils/exec=%
      \pgfmathsetmacro\myTempVal{(#1)*(#1)/(#2)/2+(#2)/2}%
      \ifpgfmathunitsdeclared\edef\myTempVal{\myTempVal pt}\fi
      \pgfmathsetmacro\myTempAng{acos(2*(#1)*(#2)/((#1)*(#1)+(#2)*(#2)))},
    radius=\myTempVal, start angle=90, end angle=\myTempAng},
  rightdownaboveafro/.style={insert path={arc[rightdownabovechord={#1}]}},
  rightdownabovechord a/.initial=, rightdownabovechord b/.initial=,
  rightdownabovechord do/.style={rightdownabovechord={\pgfkeysvalueof{/tikz/rightdownabovechord a}:\pgfkeysvalueof{/tikz/rightdownabovechord b}}},
}


\tikzset{
  rightupbelowchord/.style args={#1:#2}{
    /utils/exec=%
      \pgfmathsetmacro\myTempVal{(#1)*(#1)/(#2)/2+(#2)/2}%
      \ifpgfmathunitsdeclared\edef\myTempVal{\myTempVal pt}\fi
      \pgfmathsetmacro\myTempAng{acos(2*(#1)*(#2)/((#1)*(#1)+(#2)*(#2)))},
    radius=\myTempVal, start angle=270, end angle=360-\myTempAng},
  rightupbelowafro/.style={insert path={arc[rightupbelowchord={#1}]}},
  rightupbelowchord a/.initial=, rightupbelowchord b/.initial=,
  rightupbelowchord do/.style={rightupbelowchord={\pgfkeysvalueof{/tikz/rightupbelowchord a}:\pgfkeysvalueof{/tikz/rightupbelowchord b}}},
}

\tikzset{
  rightupabovechord/.style args={#1:#2}{
    /utils/exec=%
      \pgfmathsetmacro\myTempVal{(#1)*(#1)/(#2)/2+(#2)/2}%
      \ifpgfmathunitsdeclared\edef\myTempVal{\myTempVal pt}\fi
      \pgfmathsetmacro\myTempAng{acos(2*(#1)*(#2)/((#1)*(#1)+(#2)*(#2)))},
    radius=\myTempVal, start angle=180-\myTempAng, end angle=90},
  rightupaboveafro/.style={insert path={arc[rightupabovechord={#1}]}},
  rightupabovechord a/.initial=, rightupabovechord b/.initial=,
  rightupabovechord do/.style={rightupabovechord={\pgfkeysvalueof{/tikz/rightupabovechord a}:\pgfkeysvalueof{/tikz/rightupabovechord b}}},
}







\begin{document}

\bigskip

\begin{tikzpicture}
\path (2cm,1cm) coordinate (P);
\path (P) node[anchor=north] {$P$};
\draw (P) node {$\bullet$};
\draw [->] (P) -- ++(3cm,0);
\draw [->] (P) -- ++(-3cm,0);
\draw [->] (P)++(3cm,0) -- ++(0,1cm);
\draw [->] (P)++(3cm,0) -- ++(0,-1cm);
\draw [->] (P)++(-3cm,0) -- ++(0,1cm);
\draw [->] (P)++(-3cm,0) -- ++(0,-1cm);
\path (P)++(2cm,0) node[anchor=south] {$a$};
\path (P)++(-2cm,0) node[anchor=south] {$a$};
\path (P)++(3cm,0.5cm) node[anchor=west] {$b$};
\path (P)++(3cm,-0.5cm) node[anchor=west] {$b$};
\path (P)++(-3cm,0.5cm) node[anchor=east] {$b$};
\path (P)++(-3cm,-0.5cm) node[anchor=east] {$b$};
\draw[blue,->] (P) [leftupbelowafro=3cm:1cm];
\draw[red,->] (P) [rightupbelowafro=3cm:1cm];
\draw[yellow,->] (P) [rightdownbelowafro=3cm:1cm];
\draw[green,->] (P) [leftdownbelowafro=3cm:1cm];
\draw (P)++(0,1.5cm) node {Arcs below};
\path (9cm,1cm) coordinate (Q);
\path (Q) node[anchor=north] {$P$};
\draw (Q) node {$\bullet$};
\draw [->] (Q) -- ++(3cm,0);
\draw [->] (Q) -- ++(-3cm,0);
\draw [->] (Q)++(3cm,0) -- ++(0,1cm);
\draw [->] (Q)++(3cm,0) -- ++(0,-1cm);
\draw [->] (Q)++(-3cm,0) -- ++(0,1cm);
\draw [->] (Q)++(-3cm,0) -- ++(0,-1cm);
\path (Q)++(2cm,0) node[anchor=south] {$a$};
\path (Q)++(-2cm,0) node[anchor=south] {$a$};
\path (Q)++(3cm,0.5cm) node[anchor=west] {$b$};
\path (Q)++(3cm,-0.5cm) node[anchor=west] {$b$};
\path (Q)++(-3cm,0.5cm) node[anchor=east] {$b$};
\path (Q)++(-3cm,-0.5cm) node[anchor=east] {$b$};
\draw[blue,->] (Q) [leftupaboveafro=3cm:1cm];
\draw[red,->] (Q) [rightupaboveafro=3cm:1cm];
\draw[yellow,->] (Q) [rightdownaboveafro=3cm:1cm];
\draw[green,->] (Q) [leftdownaboveafro=3cm:1cm];
\draw (Q)++(0,1.5cm) node {Arcs above};
\end{tikzpicture}

\bigskip

\begin{tabular}{|c|c|c|c|c|}
\hline
Horizontal direction & Vertical direction & Position & Start angle & End angle \\
\hline
Left & Down & Below &$360-\theta$ & $270$ \\
\hline
Left & Down & Above & $90$ & $180-\theta$ \\
\hline
Left & Up & Below &  $270$ & $180+\theta$ \\
\hline
Left & Up & Above & $\theta$ & $90$ \\
\hline
Right & Down & Below &  $180+\theta$ &  $270$ \\
\hline
Right & Down & Above & $90$ & $\theta$ \\
\hline
Right & Up & Below &  $270$ & $360-\theta$ \\
\hline
Right & Up & Above &  $180-\theta$ & $90$ \\
\hline
\end{tabular}


\end{document}

答案1

不完全是所需的,但差不多:

\documentclass[tikz,border=5]{standalone}
\usetikzlibrary{calc}
\tikzset{afro to/.style={to path={
  let \p1=($(\tikztotarget)-(\tikztostart)$),
      \n1={(\x1*\x1+\y1*\y1)/(2*\y1)},
      \n2={acos((2*\x1*\y1)/(\x1*\x1+\y1*\y1))},
      \n3={atan2(\y1,\x1)},
      \n3={int((\n3<0?\n3+360:\n3)/90)} in (\tikztostart) [afro #1]
  }},
  afro above/.style={insert path={
    \ifdim\n3<2pt arc (180-\n2:90:\n1) \else arc (270:360-\n2:\n1) \fi
  }},
  afro below/.style={insert path={
    \ifdim\n3<2pt arc (270:360-\n2:\n1) \else arc (180-\n2:90:\n1) \fi
  }}}
\begin{document}
\begin{tikzpicture}
  \draw [help lines] (-2cm,0) -- (2cm,0) (0,-1cm) -- (0,1cm);

  \draw [red]   (0,0) to [afro to=above] ( 2, 1);
  \draw [green] (0,0) to [afro to=above] (-2, 1);
  \draw [blue]  (0,0) to [afro to=above] (-2,-1);
  \draw [black] (0,0) to [afro to=above] ( 2,-1);

  \draw [red,   dashed] (0,0) to [afro to=below] ( 2, 1);
  \draw [green, dashed] (0,0) to [afro to=below] (-2, 1);
  \draw [blue,  dashed] (0,0) to [afro to=below] (-2,-1);
  \draw [black, dashed] (0,0) to [afro to=below] ( 2,-1);
\end{tikzpicture}
\end{document}

在此处输入图片描述

相关内容