![使用 LuaLaTeX 计算 TikZ 绘图中使用的长度(以厘米为单位)](https://linux22.com/image/324506/%E4%BD%BF%E7%94%A8%20LuaLaTeX%20%E8%AE%A1%E7%AE%97%20TikZ%20%E7%BB%98%E5%9B%BE%E4%B8%AD%E4%BD%BF%E7%94%A8%E7%9A%84%E9%95%BF%E5%BA%A6%EF%BC%88%E4%BB%A5%E5%8E%98%E7%B1%B3%E4%B8%BA%E5%8D%95%E4%BD%8D%EF%BC%89.png)
我想要完成的是计算以厘米为单位的长度,这是我绘制 TikZ 所需要的。计算本身并不简单(立方根,我将其转化为math.log
和math.exp
),因此我决定使用 Lua,它还允许我通过定义小数点的数量string.format
。通过这个计算,我想返回以厘米为单位的 LaTeX 长度定义。现在我终于找到了一个不成熟的解决方案,它似乎设置了长度,但由于某种原因,长度 dbe 仍然为零。按照 MWE,我也将命令打印到日志中,查看print(tmp)
调试,如果我直接按 Ctrl+C/Ctrl+V 此输出,长度定义就有效。将命令打印/返回给 LaTeX 哪里出了问题?
\documentclass{article}
\usepackage{luacode}
\usepackage{tikz}
\usetikzlibrary{fadings,shapes,calc}
% Define a variable as a length
\newcommand{\nvar}[2]{%
\newlength{#1}
\setlength{#1}{#2}
}
% Define a few constants for transmission line drawing
\nvar{\rx}{0.33333cm}
\nvar{\diameter}{0.6cm}
\nvar{\db}{2cm}
% calculate some other dimensions (cubic root using ln and e)
\begin{luacode}
rx=0.33333
db=2
dbe= math.exp(math.log(rx*db*db)/3)
tmp = "\\newlength{\\dbe}\\setlength{\\dbe}{" .. string.format("%.2f", dbe) .. "cm}"
print(tmp)
tex.print(tmp)
\end{luacode}
\begin{document}
The \LaTeX lengths:\\
\the\rx\\
\the\diameter\\
\the\db \\
\the\dbe
\begin{tikzpicture}
\colorlet{left}{black}
\tikzset{line core/.style={draw=red,ultra thick, circle,fill=orange,minimum height=\dbe,anchor=center},%
line conductor/.style={shading = axis,circle, left color=left, right color=left!30!white,shading angle=180, anchor=center, minimum height=\dbe}
}
% looping through available phases
\foreach \phase/\centreX/\centreY in{1/0/0,2/4/0,3/2/3}
{
\coordinate (centre\phase) at (\centreX,\centreY);
\node [line core] at (centre\phase) {};
% drawing a phase transmission line - need to add at least three or four conductors
\foreach \angle in {90,30,150}
{
\node [line conductor] at ($ (centre\phase) + (\angle:\diameter)$) {};
\node [line conductor] at ($ (centre\phase) + (-\angle:\diameter)$) {};
}
}
\end{tikzpicture}
\end{document}
print(tmp)
我在日志中得到的输出是:
\newlength{\dbe}\setlength{\dbe}{1.10cm}
编辑:通过 tlmgr 使用 MacTeX/TeXLive 2015 和所有最新软件包
答案1
打印如下字符串
\newlength{\dbe}\setlength\dbe{...}
与执行字符串中包含的指令不同。
由于您已经设置了实用程序宏\nvar
来定义长度变量并为新定义的变量赋值,因此我将采取以下策略:在 Lua 端组中,设置一个名为的函数,mycalc
该函数执行立方根计算并返回长度字符串。然后,使用\nvar
进行定义,\dbe
如下所示:
\nvar{\dbe}{\directlua{mycalc(0.33333,2,"cm")}}
请注意,在下面的代码中,我没有使用string.format
代码中的函数——我认为此时没有必要限制计算的精度。
\documentclass{article}
\usepackage{luacode}
\usepackage{tikz}
\usetikzlibrary{fadings,shapes,calc}
% Define a variable as a length
\newcommand{\nvar}[2]{\newlength{#1}\setlength{#1}{#2}}
%% Lua-side code
\begin{luacode}
function mycalc ( rx , db , unit )
return ( tex.sprint ( math.exp(math.log(rx*db*db)/3) .. unit ) )
end
\end{luacode}
% Define a few constants
\nvar{\rx}{0.33333cm}
\nvar{\diameter}{0.6cm}
\nvar{\db}{2cm}
\nvar{\dbe}{\directlua{mycalc(0.33333,2,"cm")}}
\begin{document}
\noindent
The \LaTeX\ lengths:\\
\the\rx\\
\the\diameter\\
\the\db \\
\the\dbe
\begin{tikzpicture}
\colorlet{left}{black}
\tikzset{line core/.style={draw=red,ultra thick, circle,fill=orange,minimum height=\dbe,anchor=center},%
line conductor/.style={shading = axis,circle, left color=left, right color=left!30!white,shading angle=180, anchor=center, minimum height=\dbe}
}
% looping through available phases
\foreach \phase/\centreX/\centreY in{1/0/0,2/4/0,3/2/3}
{
\coordinate (centre\phase) at (\centreX,\centreY);
\node [line core] at (centre\phase) {};
% drawing a phase transmission line - need to add at least three or four conductors
\foreach \angle in {90,30,150}
{
\node [line conductor] at ($ (centre\phase) + (\angle:\diameter)$) {};
\node [line conductor] at ($ (centre\phase) + (-\angle:\diameter)$) {};
}
}
\end{tikzpicture}
\end{document}
附录:在上述代码中,“变量”\rx
和\db
是硬编码的,因此必须在\nvar
设置 的调用中再次输入它们的值作为常量\dbe
。为了简化流程,可以将指令替换为
\nvar{\rx}{0.33333cm}
\nvar{\diameter}{0.6cm}
\nvar{\db}{2cm}
\nvar{\dbe}{\directlua{mycalc(0.33333,2,"cm")}}
和
\newcommand\rxval{0.33333}
\newcommand\dbval{2}
\nvar{\rx}{\rxval cm}
\nvar{\diameter}{0.6 cm}
\nvar{\db}{\dbval cm}
\nvar{\dbe}{\directlua{mycalc(\rxval,\dbval,"cm")}}
这样,只需要修改\rxval
,\dbval
为了修改\rx
,\db
,和 \dbe
。