LaTeX中TikZ绘图备忘一
LaTeX中的TikZ绘图功能很强,为了方便以后用到的时候好查询,所以这里把自己绘制过的内容记录在CSDN博客中。
在以下环境测试过
- 操作系统:Ubuntu 16.04 64位桌面版
- LaTeX工具:TeXstudio 2.10.8
- 编译方式:LuaLaTeX
示例一、编译器结构图
原图选自裘巍老师所著的《编译器设计之路》。下面介绍我用LaTeX绘制的过程、代码与一些说明。
过程介绍:
- 包含tikz宏包,并且载入要使用的库。在本例中就是\usepackage{tikz}与\usetikzlibrary{positioning, arrows.meta}两条命令。在我使用的Ubuntu系统中,通过命令sudo apt install texlive-all安装,tikz的这些库就包含在其中(后面示例中用到的宏包与库也是如此)。我很久没有使用Windows,不清楚其下的情况。
- 先定义好需要的样式(style)。本例中先定义了要用到的方框与箭头的样式。当然,这是因为有现成的图形参照,如果没有也可后面再定义。先定义好需要的样式(style)。一般我会把style单独放在一个文件中由主文件来调用。
- 绘制方框。
- 绘制连线。
完整代码
\documentclass{article}
%
\usepackage{ctex}
\usepackage{geometry}
\usepackage[dvipsnames, svgnames, x11names]{xcolor}
\usepackage{tikz}
%
\usetikzlibrary{positioning, arrows.meta}
%
\begin{document}
%
% 定义方框样式
\tikzset{rect1/.style = {shape = rectangle,draw = green,text width = 3cm,align = center,minimum height = 1cm,}
}
% 定义箭头样式
\tikzset{arrow1/.style = {draw = purple, thick, -{Latex[length = 4mm, width = 1.5mm]},}
}
% 双箭头
\tikzset{arrow2/.style = {draw = purple, thick, {Latex[length = 4mm, width = 1.5mm]}-{Latex[length = 4mm, width = 1.5mm]},}
}
\begin{center}\begin{tikzpicture}% 绘制中间方框\node[rect1, fill = green!60!white](词法){词法分析};\node[rect1, fill = green!40!white, below = of 词法](语法){语法分析};\node[rect1, fill = green!20!white, below = of 语法, text width = 5cm](语义中间){语义分析、中间表示生成};\node[rect1, fill = green!60!black, below = of 语义中间](优化){\color{white}代码优化};\node[rect1, fill = green!30!black, below = of 优化](生成){\color{white}代码生成};% 绘制两侧方框\node[rectangle, fill = red!20!white, draw = red, text width = 0.7cm, minimum height = 4cm, align = center, left = 2cm of 语义中间](符号){符号表管理};\node[rectangle, fill = blue!20!white, draw = blue, text width = 0.7cm, minimum height = 4cm, align = center, right = 2cm of 语义中间](出错处理){出错处理};% 绘制中间连线\draw[arrow1](0, 50pt)node[right, yshift = -15pt]{输入源程序} -- (词法);\draw[arrow1](词法) -- node[right]{单词流}(语法);\draw[arrow1](语法) -- node[right]{文法}(语义中间);\draw[arrow1](语义中间) -- node[right]{中间表示}(优化);\draw[arrow1](优化) -- node[right]{优化后中间表示}(生成);\draw[arrow1](生成) -- node[right, yshift = 5pt, xshift = 5pt]{目标代码}++(0, -50pt);% 绘制两侧连线\draw[arrow2](符号) -- (词法.west);\draw[arrow2](符号) -- (语法.west);\draw[arrow2](符号) -- (语义中间);\draw[arrow2](符号) -- (优化.west);\draw[arrow2](符号) -- (生成.west);\draw[arrow2](出错处理) -- (词法.east);\draw[arrow2](出错处理) -- (语法.east);\draw[arrow2](出错处理) -- (语义中间);\draw[arrow2](出错处理) -- (优化.east);\draw[arrow2](出错处理) -- (生成.east);% 绘制虚线框\draw[thick, dashed, draw = purple](-125pt, 27pt)node[below right]{编译器前端} -- (125pt, 27pt) -- (125pt, -250pt) -- (-125pt, -250pt)node[above right]{编译器后端} -- (-125pt, 27pt);\draw[thick, dashed, draw = purple](-125pt, -135pt) -- (125pt, -135pt);\end{tikzpicture}\\\heiti 图 1-2 编译器结构图\songti
\end{center}
%
\end{document}
效果如下:
说明
1. 绘制方框的语句格式一般是:
\node[样式](名称){标题};
注意结尾的分号,绘制线条的语句最后先要加分号。名称是调用时使用,可以用汉字,标题是显示出来的文字,二者不一样。
2. 样式的内容挺多的,方框中一般会用到形状(shape)、边框颜色(draw)、填充色(fill)、宽度(text width)、最小高度(minimum height)。颜色方面可以参考xcolor宏包的说明文档。长度单位有好几个,我一般常用的是pt与cm,1pt=0.351mm。
3. 位置的表示也包含在样式定义中,一般形式是:方位 = 尺寸 of 参考对象。方位包括left、right、below、above、below left、below right、above left、above right 8种,要注意below left这样的顺序不能颠倒。
4. 这里我们绘制箭头的库选用的是arrows.meta(24种箭头),这个库比arrows(14种)要丰富些。箭头的形状有很多种,详情请参考arrows.meta的24种箭头。本例中箭头样式选的是Latex样式,其后的length = 4mm, width = 1.5mm代表箭头的长宽,可以通过这两个参数调整箭头的锋锐程度。大家可以根据需要设置。
5. 在线条上加文字的方法是通过加入node来实现,注意node在连线(即–)中的位置,如果放在–左边就表示文字是在线段的左边,反之在右边。实际上我们可以通过xshift、yshift两个参数来随意调整位置。
6. 语句:
\draw[arrow1](0, 50pt)node[right, yshift = -15pt]{输入源程序} -- (词法);
其中的(0, 50pt)是指在绝对坐标0, 50pt处开始绘制,图形坐标的原点(0, 0)就是代码中第一个方框的中心处。如果我们在(0, 50pt)前加两个加号,例如++(0, 50pt),那就变成了相对坐标,是相对于上一个节点。例如语句:
\draw[arrow1](生成) -- node[right, yshift = 5pt, xshift = 5pt]{目标代码}++(0, -50pt);
++(0, -50pt)的意思就是相对于“生成”这个节点向下移动50pt的坐标。当我们不清楚绝对坐标时就用相对坐标来绘制,挺方便的。
示例二、Pascal语言单元声明与变量声明格式示意图
完整代码
\documentclass{article}
%
\usepackage{ctex}
\usepackage{geometry}
\usepackage[dvipsnames, svgnames, x11names]{xcolor}
\usepackage{tikz}
%
\usetikzlibrary{positioning, arrows.meta, calc}
%
% 定义箭头样式
\tikzset{arrow1/.style = {draw = purple, thick, -{Latex[length = 4mm, width = 1.5mm]},}
}
% 非终端
\tikzset{nonterminal/.style = {rectangle,align = center,minimum size = 6mm,very thick,draw = red!50!black!50,top color = white,bottom color = red!50!black!20,}
}
% 终端
\tikzset{terminal/.style = {rectangle,align = center,minimum size = 6mm,rounded corners = 3mm,very thick,draw = black!50,top color = white,bottom color = black!20,}
}
%
\begin{document}
\begin{center}\begin{tikzpicture}[node distance = 0.5cm]\node[terminal, text width = 1.6cm](uses){USES};\node[nonterminal, text width = 1.6cm, right = 1cm of uses](unit){单元名};\node[terminal, right = 1cm of unit](semicolon){;};\node[terminal, below = of unit](comma){,};\draw[arrow1](uses)--(unit);\draw[arrow1](unit)--(semicolon);\draw[arrow1](semicolon)--++(30pt, 0);\draw[arrow1]($ (unit.east)+(3mm, 0) $)|-(comma);\draw[arrow1](comma)-|($ (unit.west)-(6mm, 0) $);\end{tikzpicture}
\end{center}
\begin{center}\begin{tikzpicture}\node[terminal, text width = 1.6cm](var){VAR};\node[nonterminal, text width = 1.6cm, right = 1cm of var](list){变量标识符列表};\node[terminal, right = 1cm of list](colon){:};\node[nonterminal, text width = 1.6cm, right = 1cm of colon](type){类型};\node[terminal, right = 1cm of type](semicolon1){;};\node[terminal, below = of list](semicolon2){;};\node[terminal, below = 2cm of colon](semicolon3){;};\draw[arrow1](var)--(list);\draw[arrow1](list)--(colon);\draw[arrow1](colon)--(type);\draw[arrow1](type)--(semicolon1);\draw[arrow1](semicolon1)--++(30pt, 0);\draw[arrow1]($ (list.east)+(3mm, 0) $)|-(semicolon2);\draw[arrow1](semicolon2)-|($ (list.west)-(6mm, 0) $);\draw[arrow1]($ (type.east)+(3mm, 0) $)|-(semicolon3);\draw[arrow1](semicolon3)-|($ (list.west)-(6mm, 0) $);\end{tikzpicture}
\end{center}
\end{document}
效果如下:
说明
1. 本例中因为使用了一些计算,所以引入了TikZ中的calc库,大家在usetikzlibrary命令处可以看见。
2. 圆角矩形的绘制就是加入rounded corners参数,当文字很少时,如上例中的分号与逗号,这个圆角矩形就变成了圆圈(实际上,这与minimum size的设置也有关)。
3. 从线段中间开始画线的方法,大家在代码中可以看见,代码意思很明显,不再解释。
4. 通过top color与bottom color的设置,实现了过渡效果。
5. 在语句“…(3mm, 0) $)|-(comma);”中,两个节点间的“|-”表示线段是先画竖线,再画横线,画多长,系统会自动判断。
6. 在“变量标识符列表”的定义语句中设置了text width参数,如果不设置的话,文字就不会换行。
示例三、Pascal语言单函数或过程声明格式示意图
代码
\hspace{-3cm}{
\begin{minipage}{15.4cm}\begin{tikzpicture}[node distance = 0.7cm]\node[terminal](function){FUNCTION};\node[nonterminal, right = of function](name1){函数名};\node[terminal, right = of name1](left){(};\node[terminal, right = of left](var){VAR};\node[nonterminal, right = of var](para){形参名};\node[terminal, right = of para](colon1){:};\node[nonterminal, right = of colon1](type1){类型名};\node[terminal, right = of type1](right){)};\node[terminal, right = of right](colon2){:};\node[nonterminal, right = of colon2](type2){类型名};\node[terminal, right = of type2](semicolon1){;};\node[terminal, below = of para](semicolon2){;};
% ----------------------------------------------------------\draw[arrow1](function)--(name1);\draw[arrow1](name1)--(left);\draw[arrow1](left)--(var);\draw[arrow1](var)--(para);\draw[arrow1](para)--(colon1);\draw[arrow1](colon1)--(type1);\draw[arrow1](type1)--(right);\draw[arrow1](right)--(colon2);\draw[arrow1](colon2)--(type2);\draw[arrow1](type2)--(semicolon1);\draw[arrow1]($ (var.west)+(-3mm, 0) $)--++(0, 6mm)-|($ (var.east)+(3mm, 0) $);\draw[arrow1]($ (type1.east)+(3mm, 0) $)|-(semicolon2);\draw[arrow1](semicolon2)-|($ (var.west)-(3mm, 0) $);\draw[arrow1]($ (name1.east)+(3mm, 0) $)--++(0, -20mm)-|($ (right.east)+(3mm, 0) $);
% ----------------------------------------------------------\node[nonterminal, below = 2.7cm of function, xshift = 1cm](description){说明部分};\node[terminal, right = of description](begin){BEGIN};\node[nonterminal, right = of begin, text width = 1.6cm](statement){语句};\node[terminal, right = of statement](semicolon3){;};\node[terminal, right = of semicolon3, text width = 1.6cm](end){END};\node[terminal, right = of end](semicolon4){;};
% ----------------------------------------------------------\draw[arrow1](description)--(begin);\draw[arrow1](begin)--(statement);\draw[arrow1](statement)--(semicolon3);\draw[arrow1](semicolon3)--(end);\draw[arrow1](end)--(semicolon4);\draw[arrow1](semicolon4)--++(30pt, 0);\draw[arrow1](semicolon1)--++(0, -2.5cm)-|(description);\draw[arrow1]($ (semicolon3.east)+(3mm, 0) $)--++(0, -6mm)-|($ (begin.east)+(3mm, 0) $);\end{tikzpicture}
\end{minipage}
效果如下:
说明
1. 此例的导言区部分与示例二的一样。
2. 因为这幅图比较长,正常的A4纸显示不全,所以我用\hspace{-3cm}命令向左边距移了3厘米以保证完整显示。
LaTeX中TikZ绘图备忘一相关推荐
- LaTeX中TikZ绘图备忘二
在以下环境测试过 操作系统:Ubuntu 16.04 64位桌面版 LaTeX工具:TeXstudio 2.10.8 编译方式:LuaLaTeX 示例四.chains库的使用 完整代码 \do ...
- Latex中TikZ绘制3D圆锥体
1.Latex代码 \documentclass{article} \usepackage{tikz} \begin{document} \pagestyle{empty} \begin{tikzpi ...
- C#的委托事件在winform窗体中实现传值备忘
用一个例子来说明吧,这样比较好明白一些. 就是打开主窗体,datagridview加载了一些数据,然后我们在打开的子窗体中,输入一些条件,让主窗体中的数据随着加载的条件来动态实现加载数据. 这就需要涉 ...
- Latex、Lyx学习备忘
XeLaTex序: % 中文 \usepackage{fontspec,xltxtra,xunicode} \XeTeXlinebreaklocale "zh" \XeTeXlin ...
- Latex中TikZ初步使用
## 线段和点 \documentclass{article}\usepackage{tikz}\begin{document}\begin{tikzpicture} \draw[gray, thic ...
- 学习中常用T-CODE备忘
/NEX 全退出 mm03 :查看物料 se11(查询表结构) se16(查询表数据) se37(查询function) se38(生成报表) bapi(查询接口) st05(数据跟踪) st12(性 ...
- Java如何获取JSON数据中的值 备忘
Java如何获取JSON数据中的值 取出JsonArray中的object(orderNo) 嵌套 JsonObeject { JsonObeject { JsonArray [Ob ...
- LaTeX TikZ绘图——组合数学中棋盘多项式的画法
写在前面 如题,最近组合数学作业需要画棋盘格,就是类似下面图1中的那样,但是网上找了各种中英文资料大多都不尽人意(画出来的都是真·国际象棋棋盘.....),经过不断的摸索与尝试,终于明白了Latex的 ...
- 怎样在电脑桌面设置便签备忘
有不少的办公人士在工作时使用的是电脑,并且工作记录软件选择的是便签,在便签中记录办公备忘待办.日程安排.会议内容等,现在一些多功能的便签软件不止可以记录,还可以提醒办公.协助管理工作时间.多人团队办公 ...
最新文章
- 2022-2028年中国智能眼镜行业深度调研及投资前景预测报告
- BAT架构师分享之:大型网站技术架构
- 【JDBC 报错】Connections could not be acquired from the underlying database!
- 基于时序数据的微内核预警引擎架构设计
- sql优化ppt_Spark优化 | Spark 3.0 中七个必须知道的 SQL 性能优化
- IntelliJ IDEA license server
- epoll和select的区别
- 作者:赵国栋(1974-),男,中关村大数据产业联盟秘书长,北京大数据研究院副院长,北京汇冠新 技术股份有限公司独立董事...
- EasyDSS RTMP流媒体解决方案之直播录像自动清理方案
- 20-172-040-安装-Flink单机安装 flink-1.7.2-bin-hadoop27-scala_2.11
- 【Shell脚本学习指南笔记】重定向文件描述符 21
- Ubuntu14.04开启wifi热点(亲测有效)
- 使用移远EC200N-CN模组PING谷歌
- Java多线程高并发编程中点点理解
- 大型架构.net平台篇(WEB层均衡负载nginx)
- FlightGear Flight Simulator
- ReportMachine通过嵌套表达式计算某个值。
- 为了强调低电平有效,有时也将反相器图形符号中表示反相的小圆圈画在输入端,例如上图的左边一列反相器的画法
- KILE 报 contains an incorrect path. 错误
- HDU - 1242