使用一些 \def 变量计算坐标处绘制一个圆圈

使用一些 \def 变量计算坐标处绘制一个圆圈

我正在尝试通过一些简单的算术计算在某个特定坐标处绘制一个圆。我之所以尝试这样做,是因为最终我想改变线的倾斜度并计算与背景网格的一些交点。具体来说,我想在线和背景网格之间形成的每个线段的中点处绘制一个圆。

我已制作了最简单的例子来重现该问题。

\documentclass[]{standalone}

\usepackage{amssymb}
\usepackage{amsfonts}
\usepackage{amsmath,amsthm}
\usepackage{bm}
\usepackage{bbold}
\usepackage{stmaryrd}
\usepackage{rotating}
\usepackage{graphicx,color}
\usepackage{tikz}

% .... remarks
% \theoremstyle{remark} 
% \newtheorem{remark}{\bf Remark}
\newtheorem{testcase}{\bf Test case}

% .... bar charts and plots
\usepackage{pgfplots}
\pgfplotsset{compat = 1.10}
\usetikzlibrary{decorations.markings}
\usetikzlibrary{shapes,arrows}
\usetikzlibrary{shapes.geometric}
\usetikzlibrary{fit}                    
\usetikzlibrary{backgrounds}
\usetikzlibrary{patterns}

\begin{tikzpicture}
\def\Ax{0}
\def\Ay{0}
\def\Bx{20}
\def\By{20}

% mx + q
\def\Dy{\By - \Ay}
\def\Dx{\Bx - \Ax}
\def\m{(\Dy) / (\Dx) }
\def\q{\Ay -  \m*\Ax  }


\draw[black, step=4] (0,0) grid + (20,20);
\draw[very thick, black] (\Ax, \Ay) to  (\Bx, \By);

\def\ax{5}
\def\ay{\m * \ax + \q}
\draw[thin, blue, fill = blue] (\ax, \ay) circle (0.15);


\end{tikzpicture}

\end{document}

我不明白为什么我会收到一个相对于节点坐标的编译错误。

错误如下:

tikz 软件包错误:放弃此路径。您忘记了分号吗?\draw[thin, blue, fill = blue] (\ax, \ay)

答案1

我会简单地使用\pgfmathsetmacro而不是\def。所有事情最终都会\pgfmathparse(自动)完成,所以现在就计算,而不是以后再计算。

\documentclass[]{standalone}

\usepackage{amssymb}
\usepackage{amsfonts}
\usepackage{amsmath,amsthm}
\usepackage{bm}
\usepackage{bbold}
\usepackage{stmaryrd}
\usepackage{rotating}
\usepackage{graphicx,color}
\usepackage{tikz}

% .... remarks
% \theoremstyle{remark} 
% \newtheorem{remark}{\bf Remark}
\newtheorem{testcase}{\bf Test case}

% .... bar charts and plots
\usepackage{pgfplots}
\pgfplotsset{compat = 1.10}
\usetikzlibrary{decorations.markings}
\usetikzlibrary{shapes,arrows}
\usetikzlibrary{shapes.geometric}
\usetikzlibrary{fit}                    
\usetikzlibrary{backgrounds}
\usetikzlibrary{patterns}

\begin{document}

\begin{tikzpicture}
\def\Ax{0}
\def\Ay{0}
\def\Bx{20}
\def\By{20}

% mx + q
\pgfmathsetmacro{\Dy}{\By - \Ay}
\pgfmathsetmacro{\Dx}{\Bx - \Ax}
\pgfmathsetmacro{\m}{\Dy / \Dx}
\pgfmathsetmacro{\q}{\Ay -  \m*\Ax}


\draw[black, step=4] (0,0) grid + (20,20);
\draw[very thick, black] (\Ax, \Ay) to  (\Bx, \By);

\def\ax{5}
\def\ay{\m * \ax + \q}
\draw[thin, blue, fill = blue] (\ax, \ay) circle (0.15);

\end{tikzpicture}

\end{document}

答案2

虽然我同意 Andrew 的观点,认为这些\def做法不一定是好的做法,但我很遗憾(我真的是遗憾)不同意 Ti 的主要观点。Z 无法解析这些。它绝对可以。您只需添加括号,否则解析器会被括号弄糊涂。(内部 pgf 键也只是宏,所以显然 TiZ 能够解析宏。)

\documentclass[tikz,border=3mm]{standalone}
\begin{document}
\begin{tikzpicture}
\def\Ax{0}
\def\Ay{0}
\def\Bx{20}
\def\By{20}

% mx + q
\def\Dy{\By - \Ay}
\def\Dx{\Bx - \Ax}
\def\m{(\Dy) / (\Dx) }
\def\q{\Ay -  \m*\Ax  }
\draw[black, step=4] (0,0) grid + (20,20);
\draw[very thick, black] ({\Ax}, {\Ay}) to  ({\Bx}, {\By});
\def\ax{5}
\def\ay{\m * \ax + \q}
\draw[thin, blue, fill = blue] ({\ax},{\ay}) circle (0.15);
\end{tikzpicture}
\end{document}

在此处输入图片描述

关于最佳实践,像 Andrew 一样,我确实非常喜欢 pgf 键,但也可以只使用declare functions。(常量也是有效函数。)

\documentclass[tikz,border=3mm]{standalone}
\begin{document}
\begin{tikzpicture}[declare function={Ax=0;Ay=0;Bx=20;By=20;
    Dy=By-Ay;Dx=Bx-Ax;m=Dy/Dx;q=Ay-m*Ax;ax=5;ay=m*ax+q;}]
\draw[black, step=4] (0,0) grid + (20,20);
\draw[very thick, black] (Ax, Ay) to  (Bx,By);
\draw[thin, blue, fill = blue] (ax,ay) circle[radius=0.15];
\end{tikzpicture}
\end{document}

答案3

主要问题是无法与和扩展为tikz的表达式一起使用。[\ax\ay其实这并不完全正确。请参阅薛定谔的猫的答案。]例如,您有:

ay=0-20/20-0+5+20-0-20/20-0*0

您需要做的是强制评估这些表达式。我建议使用pgfkeys来存储和处理变量。设置它看起来很难理解,但一旦您读完它,语法就不那么复杂了。

\newcommand\Var[1]{\pgfkeysvalueof{/Variables/#1}}
\newcommand\SetVar[1]{\pgfkeys{/Variables, #1, Calc}}
\tikzset{/Variables/.is family, /Variables,
  Ax/.initial=0,
  Ay/.initial=0,
  Bx/.initial=20,
  By/.initial=20,
  Dx/.initial=20,
  Dy/.initial=20,
  ax/.initial=5,
  ay/.initial=5,
  m/.initial=1,
  q/.initial=0,
  Calc/.style = {
      Dx=\the\numexpr\Var{Bx}-\Var{Ax}\relax,
      Dy=\the\numexpr\Var{By}-\Var{Ay}\relax,
      m=\the\numexpr\Var{Dy}/\Var{Dx}\relax,
      q=\the\numexpr\Var{Ay}-\Var{m}*\Var{Ax}\relax,
      ay=\the\numexpr\Var{m}+\Var{ax}+\Var{q}\relax
  }
}

从问题的角度来看,最重要的一点是使用 来\numexpr评估表达式。其余代码的作用是,首先初始化变量AxAyBxByDxDyaxaymq定义一种Calc方法,根据 、 、 、 和 的当前值计算Dx、和。最后,Dy有两个辅助宏,用于访问变量的当前值和m设置新值 - 并自动应用以重新计算剩余值。qAxAyBxByaxay\Var\SetVarCalc

将这些放在一起得到下面的代码:

在此处输入图片描述

完整代码如下:

\documentclass[]{standalone}

\usepackage{amssymb}
\usepackage{amsfonts}
\usepackage{amsmath,amsthm}
\usepackage{bm}
\usepackage{bbold}
\usepackage{stmaryrd}
\usepackage{rotating}
\usepackage{graphicx,color}
\usepackage{tikz}

% .... remarks
% \theoremstyle{remark}
% \newtheorem{remark}{\bf Remark}
\newtheorem{testcase}{\bf Test case}

% .... bar charts and plots
\usepackage{pgfplots}
\pgfplotsset{compat = 1.10}
\usetikzlibrary{decorations.markings}
\usetikzlibrary{shapes,arrows}
\usetikzlibrary{shapes.geometric}
\usetikzlibrary{fit}
\usetikzlibrary{backgrounds}
\usetikzlibrary{patterns}

\newcommand\Var[1]{\pgfkeysvalueof{/Variables/#1}}
\newcommand\SetVar[1]{\pgfkeys{/Variables, #1, Calc}}
\tikzset{/Variables/.is family, /Variables,
  Ax/.initial=0,
  Ay/.initial=0,
  Bx/.initial=20,
  By/.initial=20,
  Dx/.initial=20,
  Dy/.initial=20,
  ax/.initial=5,
  ay/.initial=5,
  m/.initial=1,
  q/.initial=0,
  Calc/.style = {
      Dx=\the\numexpr\Var{Bx}-\Var{Ax}\relax,
      Dy=\the\numexpr\Var{By}-\Var{Ay}\relax,
      m=\the\numexpr\Var{Dy}/\Var{Dx}\relax,
      q=\the\numexpr\Var{Ay}-\Var{m}*\Var{Ax}\relax,
      ay=\the\numexpr\Var{m}+\Var{ax}+\Var{q}\relax
  }
}

\begin{document}

  \begin{tikzpicture}

    \draw[black, step=4] (0,0) grid + (20,20);

    % default
    \draw[very thick, black] (\Var{Ax}, \Var{Ay}) to  (\Var{Bx}, \Var{By});
    \draw[thin, blue, fill = blue] (\Var{ax}, \Var{ay}) circle (0.15);

    \SetVar{Ax=4,Ay=16, Bx=16, By=4}
    \draw[very thick, black] (\Var{Ax}, \Var{Ay}) to  (\Var{Bx}, \Var{By});
    \draw[thin, blue, fill = blue] (\Var{ax}, \Var{ay}) circle (0.15);

  \end{tikzpicture}

\end{document}

我不确定我是否明白您想要蓝点的位置,但两个点都符合您的计算。

相关内容