我正在尝试通过一些简单的算术计算在某个特定坐标处绘制一个圆。我之所以尝试这样做,是因为最终我想改变线的倾斜度并计算与背景网格的一些交点。具体来说,我想在线和背景网格之间形成的每个线段的中点处绘制一个圆。
我已制作了最简单的例子来重现该问题。
\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 键也只是宏,所以显然 Ti钾Z 能够解析宏。)
\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 function
s。(常量也是有效函数。)
\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
评估表达式。其余代码的作用是,首先初始化变量Ax
、Ay
、Bx
、By
、Dx
、Dy
、ax
和ay
,m
并q
定义一种Calc
方法,根据 、 、 、 和 的当前值计算Dx
、和。最后,Dy
有两个辅助宏,用于访问变量的当前值和m
设置新值 - 并自动应用以重新计算剩余值。q
Ax
Ay
Bx
By
ax
ay
\Var
\SetVar
Calc
将这些放在一起得到下面的代码:
完整代码如下:
\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}
我不确定我是否明白您想要蓝点的位置,但两个点都符合您的计算。