我正在编写一个程序,用 绘制晶体单元pgf/tikz
。在这个项目的过程中,出现了一个问题,我应该使用pgf
基本层命令还是tikz
命令来绘制组成键和原子。对我来说,很明显有些事情,比如声明阴影等,需要在 中完成,pgf
但我要求的是使用基本层或tikz
命令可以实现完全相同结果的情况。在这种情况下,使用较低级别的基本层比使用命令是否有优势tikz
,或者是否等效?在哪些情况下我可以/应该使用pgfpicture
而不是tikzpicture
环境?
编辑:由于 @percusse 提到,答案可能取决于特定用例,我将提供一个小例子:我计划将我想要描绘的晶体单元中的原子绘制为具有球形阴影的圆圈。以下 MWE 包含两个版本的这种“原子”,它们看起来完全相同,一个仅使用基本层命令绘制,另一个使用tikz
命令绘制。为了简洁起见,我将它们放在同一个tikzpicture
环境中。那么问题是,基本层版本是否更容易调整或与 PDF 查看器更兼容,或者是否比版本有任何优势tikz
?就代码量和可读性而言,该tikz
版本显然更可取。
\documentclass{standalone}
\usepackage{tikz}
\begin{document}
\pgfdeclareradialshading{new}{\pgfqpoint{0bp}{0bp}}{%
color(0bp)=(blue);
color(6bp)=(blue!90!black);
color(20bp)=(black!75!blue);
color(30bp)=(black!85!blue)}
\begin{tikzpicture}
% tikz version
\begin{scope}
\clip (-1,0) circle (1cm);
\draw [fill=black!70] (0, 0) circle (1cm);
\begin{scope}[transform canvas={xshift=-1cm, rotate=45}]
\shade [shading=new] (0.00,0.50) ellipse (1.75 and 1.55);
\end{scope}
\node (nodename) at (-1, 0) [circle, minimum size = 2cm] {tikz};
\end{scope}
% Basic Layer version
\begin{pgfscope}
\pgfpathcircle{\pgfpoint{3cm}{0cm}}{1cm}
\pgfusepath{clip}
\begin{pgflowlevelscope}{\pgftransformshift{\pgfpoint{3cm}{0cm}}, \pgftransformrotate{45}}
\pgfpathellipse{\pgfpoint{0cm}{0.5cm}}
{\pgfpoint{1.75cm}{0cm}}
{\pgfpoint{0cm}{1.55cm}}
\pgfshadepath{new}{0}
\pgfusepath{}
\end{pgflowlevelscope}
\end{pgfscope}
{
\pgftransformshift{\pgfpoint{3cm}{0cm}}
\pgfset{minimum size=2cm}
\pgfnode{circle}{center}{pgf}{nodename}{
\pgfusepath{}}
}
\end{tikzpicture}
\end{document}
答案1
这是一个根据我自己的经验得出的有偏见的答案,所以请谨慎对待。
好吧,首先我们需要考虑到 PGF 才是关键。TikZ 只是 PR 部门,而且是一个非常棒的部门。TikZ 的整体理念与 TeX 和 LaTeX 非常相似,其中 PGF 就是 TeX。有时你必须去地下室修理锅炉等,但总的来说,它完全是为了方便用户而设计的。因此,TikZ 本身不是一个图形包,而顾名思义,它是 PGF 的前端。令人惊讶的是,几乎所有东西都转换为键值系统,这让生活变得非常轻松,直到 2005 年才出现这种情况。但据我所知,没有直接的 TikZ 命令可以通向驱动器特定的系统层。事实上,它必须通过软路径系统,所以我几乎可以肯定。
因为 PGF 是低级的,所以只需交换事物的顺序或添加一个简单的命令就会通过 PGF 产生很大的不同,然而,在直线上 TikZ 总是会获胜,因为剩下的部分仍然需要输入。可以说,有些东西很难映射到前端层,正如你所提到的,阴影或装饰等,所以有一部分 PGF 命令被遗漏了,这可能是值得一路使用 PGF 的原因。另一个问题是速度。TikZ 很大。我的意思是真的很大,所以跳过它会在编译时间方面产生很大的不同。此外,TikZ 通过逐个检查字母来解析语法以了解它是什么,这需要大量时间,路径流上的最短单词必须经过至少四五个ifnextchar
开关。相反,PGF 只与宏一起工作。
除此之外,我个人更喜欢将 TikZ 语法与 PGF 语法混合使用。但是,如果您正在设计一个将始终使用类似对象的包(例如阴影,如果遵循 PS 或 Dvi->PS 路线,它们大多无法重用),我建议直接进入系统级别进行对象重用和协议处理。它们更像是 CS 极客概念,我无法在这里公正对待。但即使是面向对象编程的可能性也存在。我几乎不记得 Andrew Stacey 对此做了一些工作。
在我看来,这里有一些不平凡的事情,我现在能记得住,除非你故意为它编写自己的库,否则不值得通过前端层 TikZ 进行攻击;
通过节点形状进行剪辑:这可能是一种设计选择,因为我看不出它为什么不包含在 TikZ 中。示例(窃自Tikz 使用另一个(内置)形状剪辑形状(英文):
\usetikzlibrary{shapes.callouts} \begin{tikzpicture} \pgfnode{cloud callout}{center}{}{nodename}{\pgfusepath{stroke,clip}} \fill[red] (-1mm,-4mm) rectangle (2.5mm,1mm); \end{tikzpicture}
弧线更加容易使用,并且种类繁多;特别
\pgfpatharctoprecomputed
是\pgfarcto
非常方便。有序路径和画布变换并驯服它们;TikZ 会为您转换特定对象的变换,例如节点形状等
transform shape
,但如果您想要先缩放然后倾斜并旋转然后缩小,除非您嵌套范围或非常小心地发出它们,否则它在 TikZ 中并不总是有效。它们非常容易处理\pgfgettransform
等。\pgfsettransform
长路径构造。使用 PGF 确实更快,因为坐标不通过 TikZ 解析。
有一些未记录的 PGF 命令,例如
\pgfmathanglebetweenpoints
和其他几个;)总是很有趣!