TikZ从零开始(一)——A Picture for Karl‘s Students(下篇)

上篇继续写~😄

15、指定坐标(Specifying Coordinates)

这一节内容前面已经我们已经了解了一半了。
指定坐标的方法有:

  1. (10pt,1cm)这是直角坐标里的最简单粗暴的方法
  2. (10pt,1cm) --+ (5pt, -0.5cm)这代表直角坐标系中画线,起点是(10pt,1cm),且为当前指定位置(specified position),终点是当前指定位置向水平轴正方向(右)移动 5 p t 5pt 5pt,向竖直轴负方向(下)移动 0.5 c m 0.5cm 0.5cm

以上两种之前都讲过了,下面看三种新的。

  1. (10pt,1cm) ++ (5pt,-0.5cm) -- (0,0),表示从(10pt,1cm)先向水平轴正方向(右)移动 5 p t 5pt 5pt,向竖直轴负方向(下)移动 0.5 c m 0.5cm 0.5cm在此过程中只移动位置,不画线,把新位置作为当前指定位置,然后画与(0,0)的连线。
  2. (30:1)表示极坐标中,极角为 3 0 ∘ 30^\circ 30,极径为 1 c m 1cm 1cm的点(记为点 M M M)。
  3. (30:1 |- 0,0)表示(过上一条点 M M M的竖直线)与(过原点/极点的水平线)的交点,|为竖直之义,-为水平之义。

通过下面的两个例子对比说明+++的区别。
在这里插入图片描述

现在想在单位圆中表示出30 ∘ ^\circ 角的正弦线和余弦线,假定我们没有任何三角函数知识,甚至不知道 sin ⁡ 3 0 ∘ = 0.5 \sin30^\circ=0.5 sin30=0.5,就只能用上面介绍的新方法了。

We will work on this:
\begin{tikzpicture}[scale=3]
	\clip (-0.1,-0.2) rectangle (1.1,0.75);
	\draw [gray,very thin,step=.5] (-1.4,-1.4) grid (1.4,1.4);
	\draw (-1.5,0) -- (1.5,0);
	\draw (0,-1.5) -- (0,1.5);
	\draw (0,0) circle [radius=1];
	\shadedraw[left color=gray,right color=green,draw=green!50!black] (0,0)--(0.3,0.)arc[start angle=0, end angle=30, radius=.3]--cycle;
	\draw [red, very thick] (30:1) --+ (0,-.5);  % 画出向下移动0.5cm的轨迹
%		\draw [blue, very thick] (30:1) ++ (0,-0.5) -- (0,0);   % 画出(30°,1)正下方0.5cm处的点向原点/极点移动的轨迹
	\draw [blue, very thick] (30:1 |- 0,0)--(0,0);   % 与上一方法等价,画出水平线与竖直线交点向原点移动的轨迹
\end{tikzpicture}

在这里插入图片描述

16、交点(Intersecting Path)

现在我们想画出正切线,它是一条竖直线,过 ( 1 , 0 ) (1,0) (1,0),长度是 3 / 3 c m \sqrt{3}/3cm 3 /3cm,当然我们可以直接让TeX计算 tan ⁡ 3 0 ∘ \tan30^\circ tan30

\tikz \draw (1,0) --+ (0,{tan(30)});  % 花括号是必须的,保证其在数学环境中才能计算

但我们也可以通过构造交点来实现,因为正弦线的终点是 3 0 ∘ 30^\circ 30线与直线 x = 1 x=1 x=1的交点。
构造交点要在导言区导入TikZ的{intersections}库。
要想有交点,首先要有两条线,但我们并不想把这两条线画出来。回忆第9节线条裁剪中我们提到过,我们做\clip时其实是在做\path[clip],而在做\draw的时候其实是在做\path[draw],而我们如果不带任何参数的话就既不绘制也不裁剪,而是形成一条“隐形”的线,我们需要的就是这样的线,因此我们要用到\path命令,并且我们要给这两条隐形的线做标记,方便后面引用。

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{intersections}  % 导入相交库
\begin{document}	
	\begin{tikzpicture}[scale=4]
		\clip (-0.1,-0.2) rectangle (1.1,0.75);
		\draw [gray,very thin,step=.5] (-1.4,-1.4) grid (1.4,1.4);
		\draw (-1.5,0) -- (1.5,0);
		\draw (0,-1.5) -- (0,1.5);
		\draw (0,0) circle [radius=1];
		\shadedraw[left color=gray,right color=green,draw=green!50!black] (0,0)--(0.3,0.)arc[start angle=0, end angle=30, radius=.3]--cycle;
		\draw [red, very thick] (30:1) --+ (0,-.5);
		\draw [blue, very thick] (30:1 |- 0,0)--(0,0); 
		\path[name path=upward line] (1,0)--(1,1.5);  % 画一条invisible的竖直线
		\path[name path=sloped line] (0,0)--(30:1.5);  %画一条invisible的30°斜线
		\draw[name intersections={of=upward line and sloped line, by=x}][very thick,orange]  
		(1,0)--(x);  % of指定相交线,by指定交点,(x)圆括号不能少
	\end{tikzpicture}
\end{document}

在这里插入图片描述

17、添加箭头(Adding Arrow Tips)

这个特别easy,只要在\draw的可选参数中加入->(在终端加)或<-(在始端加)或<->(在两端都加)。
能加箭头的线条类型有很多,但也不是所有的都能加,一条经验法则是,我们只能给单个未封闭线(a single open line)加箭头,而对于矩形、圆形这种封闭线是无法添加的。

\begin{tikzpicture}[scale=0.5]
	\draw [<->] (-2,-1) --++(2,-1)--++(1,0.5)--++(0.5,-0.25) ;
	\draw [<->] (0,0) arc [start angle=0,end angle=120,radius=2];
\end{tikzpicture}

在这里插入图片描述
通过导入arrows.meta这个TikZ库我们还可以改变箭头的形状。比方说Stealth型(我个人觉得比较好看的类型)。

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{intersections,arrows.meta}
\begin{document}	
	\begin{tikzpicture}[scale=0.5,>=Stealth]
		\draw [<->] (-2,-1) --++(2,-1)--++(1,0.5)--++(0.5,-0.25) ;
		\draw [<<->] (0,0) arc [start angle=0,end angle=120,radius=2];
	\end{tikzpicture}
\end{document}

在这里插入图片描述
控制箭头的可选参数有lengthwidth,这样来使用:
\draw[-{Stealth[length=1mm,width=0.9mm]}] (0,0)--(1,0)
在箭头上添加文本,可以指定在哪个地方(very near end/near end/midway/near start/very near start),这个时候node在哪就跟参考系无关了,由指定的参数决定,这边要用到node的知识,建议先去看22、添加文本
在这里插入图片描述

18、作用域(Scoping)

tikzpicture后面设置可选参数,则参数作用于tikzpicture全局。若想局部批量改变线条样式,则可建立scope环境,如果在scope环境内裁剪clip,是不会影响到scope外部环境的。
在这里插入图片描述

19、变换(Transformations)

实施变换的对象是坐标系,即变换是对坐标系进行变换。主要有以下变换形式:

  1. xshift:水平平移
  2. yshift:竖直平移
  3. rotate:旋转
  4. xscale:水平缩放,负数则意味着翻转
  5. ysclae:竖直缩放,负数则意味着翻转
  6. xslant:水平倾斜
  7. yslant:竖直倾斜

例如,先画一条直线,再水平平移 2 p t 2pt 2pt,此时原点也跟着水平平移了 2 p t 2pt 2pt,所以再次执行同样的命令画出的线并不会重合,而是另一条距原线段距离 2 p t 2pt 2pt的平行线段。
在这里插入图片描述
另一个要提及的是所有坐标系或者是当前指定位置(通过++变换)变换在分号结束后,也就结束了,在一条新的绘图语句里,原点还是一开始的原点。

20、重复命令:for-循环(Repeating things: For-Loops)

感觉越往后写越觉得LaTeX像编程了。
下面咱们得给坐标系标注刻度线了,一个一个标很麻烦,可以用循环语句实现。用这个需要导入pgffor宏包。
基本语法:\foreach <variable> in {<list of values>} <commands>
P.S. 这个命令在tikzpicture环境外也能用

\usepackage{pgffor}
\begin{document}
\foreach \x in {-2,-1,0,1,2} {$x = \x$, }  % 如果没有花括号的话,重复部分就到分号为止
\end{document}

在这里插入图片描述
P.S. \x表示一个变量,而x是一个字符。

现在我们就可以添加刻度线啦

\begin{tikzpicture}[scale=4]
	\clip (-0.1,-0.2) rectangle (1.6,1.51);
	\draw [gray,very thin,step=.5] (-1.4,-1.4) grid (1.4,1.4);
	\draw[->] (-1.5,0) -- (1.5,0);
	\draw[->] (0,-1.5) -- (0,1.5);
	\draw (0,0) circle [radius=1];
	\shadedraw[left color=gray,right color=green,draw=green!50!black] (0,0)--(0.3,0.)arc[start angle=0, end angle=30, radius=.3]--cycle;
	\draw [red, very thick] (30:1) --+ (0,-.5);
	\draw [blue, very thick] (30:1 |- 0,0)--(0,0); 
	\path[name path=upward line] (1,0)--(1,1.5);
	\path[name path=sloped line] (0,0)--(30:1.5);
	\draw[name intersections={of=upward line and sloped line, by=x}][very thick,orange]
	(1,0)--(x);
	\foreach \x in {-1,-.5,.5} \draw (\x,-1pt)--(\x,1pt);
	\foreach \y in {-1,-.5,.5} \draw[yshift=\y cm] (-1pt,0)--(1pt,0);
\end{tikzpicture}

这里我们用了两种方法标刻度线,一种是在序列中存放刻度横坐标,然后直接在这些对应点上标注;还有一种是在序列中存放向待标刻度的点移动的距离(以原点为基准),注意变换完执行一次命令就失效了,下次又是从原点变换。
因为有网格,刻度不太清楚,所以用放大镜显示一下,以防你说我糊弄你🤭。
在这里插入图片描述
如果我们要标20个刻度线,是不是就要写{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}呢?当然不是啦,这也太累了叭。所以,比方说画15个圆。

\tikz \foreach \x in {1,...,15} \draw (\x,0) circle [radius=.4];

{1...15}表示1到15的自然数集合
在这里插入图片描述
学会了循环语句,就能玩弄一些骚图了~

\begin{tikzpicture}
	\foreach \x in {1,2,...,5,7,8,...,12}
	\foreach \y in {1,...,5}
	{
	\draw (\x,\y) +(-.5,-.5) rectangle ++(.5,.5);  % 第二个++是+也行,不信你试试
	\draw (\x,\y) node{\x,\y};
	}
\end{tikzpicture}

大体思路是从中心点向左下方移动定一个矩形顶角,再向右上方移动定另一个矩形顶角,从而构造一个矩形,然后用\node填充数值(这个在下一个教程会讲)。
在这里插入图片描述

22、添加文本(Adding Text)

标完刻度线,我们还得标刻度数字,才能构成完整的刻度。

添加文本的基本思路如下:当绘制线条时,TikZ可能会在途中遇到node关键字,该关键字后通常跟着一些可选参数,然后附上文本——node[options]{<text>},文本被置入一个TeX盒子然后放在当前位置。
在这里插入图片描述
P.S. \verb命令可以实现原文照排,即原样输出,常用于打印源代码、命令等。

verbatim adj. & adv. 一字不差的(地)

现在我们来标注数字。

\begin{tikzpicture}[scale=4]
%		\clip (-0.1,-0.2) rectangle (1.6,1.51);
% 	\draw [gray,very thin,step=.5] (-1.4,-1.4) grid (1.4,1.4);
	\draw[->] (-1.5,0) -- (1.5,0);
	\draw[->] (0,-1.5) -- (0,1.5);
	\draw (0,0) circle [radius=1];
	\shadedraw[left color=gray,right color=green,draw=green!50!black] (0,0)--(0.3,0.)arc[start angle=0, end angle=30, radius=.3]--cycle;
	\draw [red, very thick] (30:1) --+ (0,-.5);
	\draw [blue, very thick] (30:1 |- 0,0)--(0,0); 
	\path[name path=upward line] (1,0)--(1,1.5);
	\path[name path=sloped line] (0,0)--(30:1.5);
	\draw[name intersections={of=upward line and sloped line, by=x}][very thick,orange]
	(1,0)--(x);
	\foreach \x in {-1,-0.5,0.5} \draw (\x,-1pt)--(\x,1pt) node[anchor=north]{$\x$}  ;
	\foreach \y in {-1,-0.5,0.5,1} \draw[yshift=\y cm] (-1pt,0)--(1pt,0) node [anchor=east]{$\y$};
\end{tikzpicture}

node的可选参数中,我设定了anchor参数,该参数的作用是微调文本位置,anchor的本义是“锚”,想象有一个锚,假如它在北边(north),那我们的“船”(文本)就在南边(下方);假如它在西南(south west),那我们的“船”就在东北(右上方)。

但是!这方法也太特喵的反人类(counter-intuitive)了吧,我要标在上方,却要设置north;要标在东北,却得指定south west,怎么想都怪怪的哦。那么有没有更符合我们直觉的选项呢?答案当然是肯定的。below/above/right/left/above right/above left/below right/below left可以完全替代东南西北,并!且!指定这些选项时我们可以细化设定,比如在下方 1 p t 1pt 1pt的位置可以这么写:node[below=1pt],嘿嘿,这也太好了。
在这里插入图片描述
另外,node的定位是跟它在语句中的位置有关的,简而言之,node紧跟在哪个后面,就以哪个为参考系(除非你指定了midway very near end这种参数)。

  • 如果node紧跟在起点后,则相对位置以起点为参考系

    \draw [blue,very thick] (0,0)node[fill=white,below=0.1cm] {$ \cos\alpha $} -- (30:1 |- 0,0); 
    

    标注的 cos ⁡ α \cos\alpha cosα在起点正下方
    在这里插入图片描述

  • 如果node紧跟在连线--后,则相对位置以连线为参考系

    \draw [blue,very thick] (0,0)--node[fill=white,below=0.1cm]{$ \cos\alpha $}(30:1 |- 0,0); 
    

    为了更好地显示标注刻度的效果,我把网格线和裁剪命令都暂时去掉了。
    在这里插入图片描述
    标注的 cos ⁡ α \cos\alpha cosα恰在蓝线正下方

  • 如果node紧跟在终点后,则相对位置以终点为参考系

    \draw [blue,very thick] (0,0)--(30:1 |- 0,0)node[fill=white,below=0.1cm]{$ \cos\alpha $}; 
    

    在这里插入图片描述

为了让这张图看起来更“数学”,我们想要 0.5 0.5 0.5换成 1 2 \dfrac{1}{2} 21,有没有方法呢?
事实上,\foreach为我们提供了一种特殊的语法格式,使得我们可以指定两个或两个以上的变量,它们彼此用斜杠/分隔开。这样一来,变量遍历到的集合也必须有多个了。如果指定了两个变量\x / \y,那么集合里对应位置一般要这么写<first>/<second>;但有时候/<second>是可以省略不写的,此时意味着<second><first>相同。且看下面的实例。

\begin{tikzpicture}[scale=4]
	\clip (-0.1,-0.2) rectangle (1.6,1.51);
	\draw [gray,very thin,step=.5] (-1.4,-1.4) grid (1.4,1.4);
	\draw[->] (-1.5,0) -- (1.5,0);
	\draw[->] (0,-1.5) -- (0,1.5);
	\draw (0,0) circle [radius=1];
	\shadedraw[left color=gray,right color=green,draw=green!50!black] (0,0)--(0.3,0.)arc[start angle=0, end angle=30, radius=.3]--cycle;
	\draw [red, very thick] (30:1) --+ (0,-.5);
	\draw [blue, very thick] (30:1 |- 0,0)--(0,0); 
	\path[name path=upward line] (1,0)--(1,1.5);
	\path[name path=sloped line] (0,0)--(30:1.5);
	\draw[name intersections={of=upward line and sloped line, by=x}][very thick,orange]
	(1,0)--(x);
	\foreach \x/\t in {-1,-0.5/-\frac{1}{2},0.5/\frac{1}{2}} \draw (\x,-1pt)--(\x,1pt) node[below]{$\t$}  ;
	\foreach \y/\t in {-1,-0.5/-\frac{1}{2},0.5/\frac{1}{2},1} \draw[yshift=\y cm] (-1pt,0)--(1pt,0) node [left]{$\t$};
\end{tikzpicture}

现在加上了网格和裁剪
在这里插入图片描述
你可能会说,加上网格又不好看了,字和网格穿插在一起了,这好办,我们可以指定用白色填充节点:node[fill=white]

\begin{tikzpicture}[scale=3,>=Stealth]
	\clip (-0.1,-0.2) rectangle (1.6,1.51);
	\draw [gray,very thin,step=.5] (-1.4,-1.4) grid (1.4,1.4);
	\draw[->] (-1.5,0) -- (1.5,0);
	\draw[->] (0,-1.5) -- (0,1.5);
	\draw (0,0) circle [radius=1];
	\shadedraw[left color=gray,right color=green,draw=green!50!black] (0,0)--(0.3,0.)arc[start angle=0, end angle=30, radius=.3]--cycle;
	\draw [red, very thick] (30:1) --+ (0,-.5);
	\draw [blue, very thick] (30:1 |- 0,0)--(0,0); 
	\path[name path=upward line] (1,0)--(1,1.5);
	\path[name path=sloped line] (0,0)--(30:1.5);
	\draw[name intersections={of=upward line and sloped line, by=x}][very thick,orange]
	(1,0)--(x);
	\foreach \x/\t in {-1,-0.5/-\frac{1}{2},0.5/\frac{1}{2}} \draw (\x,-1pt)--(\x,1pt) node[below,fill=white]{$\t$}  ;
	\foreach \y/\t in {-1,-0.5/-\frac{1}{2},0.5/\frac{1}{2},1} \draw[yshift=\y cm] (-1pt,0)--(1pt,0) node [left,fill=white]{$\t$};
\end{tikzpicture}

在这里插入图片描述
看起来已经很不错了,对吗?不过还差一点儿,现在我们要做的是标注诸如 sin ⁡ α , cos ⁡ α \sin\alpha, \cos\alpha sinα,cosα这些数学符号。

\documentclass{article}
\usepackage{tikz,pgffor,amsmath} 
\usetikzlibrary{intersections,arrows.meta}
\begin{document}	
	\begin{tikzpicture}[scale=3,>=Stealth]
		\clip (-2,-0.2) rectangle (2,0.8);
		\draw [gray,very thin,step=.5] (-1.4,-1.4) grid (1.4,1.4);
		\draw[->] (-1.5,0) -- (1.5,0) coordinate(x axis);  %1
		\draw[->] (0,-1.5) -- (0,1.5) coordinate;  
		\draw (0,0) circle [radius=1];
		\shadedraw[left color=gray,right color=green,draw=green!50!black] (0,0)--(0.3,0.)arc[start angle=0, end angle=30, radius=.3]--cycle;
		\draw [red, very thick] (30:1) -- node[fill=white,left=1pt]{$\sin\alpha$}+ (0,-.5);
		\draw [blue, very thick] (30:1 |- x axis)-- node[fill=white,below=2pt]{$\cos\alpha$}(0,0);  % 2
		\path[name path=upward line] (1,0)--(1,1.5);
		\path[name path=sloped line] (0,0)--(30:1.5);
		\draw[name intersections={of=upward line and sloped line, by=intsct}] [very thick,orange]
		(1,0)--node[fill=white,right=1pt]
		{$
		\tan\alpha\color{black}=\dfrac{{\color{red}\sin\alpha}}{\color{blue}\cos\alpha}   %3
		$}(intsct)  
		;
		\draw (0,0)--(intsct);
		\foreach \x/\t in {-1,-0.5/-\frac{1}{2},1} \draw (\x,-1pt)--(\x,1pt) node[below,fill=white]{$\t$}  ;
		\foreach \y/\t in {-1,-0.5/-\frac{1}{2},0.5/\frac{1}{2},1} \draw[yshift=\y cm] (-1pt,0)--(1pt,0) node [left,fill=white]{$\t$};
	\end{tikzpicture}
\end{document}

在注释1处我们在\path命令结束前跟上了coordinate (<x axis>),这可以给我们的坐标设置别名,方便注释2处引用。注释3处,我们开始标注数学的三角函数符号,\color命令指定了符号颜色,使用了\dfrac命令使得分数不因行内公式被压缩(需在导言区导入amsmath宏包)。整体效果如下。
在这里插入图片描述
最后,让我们加上右侧的注释性文字。

\documentclass{article}
\usepackage{tikz,pgffor,amsmath}
\usetikzlibrary{intersections,arrows.meta}
\begin{document}	
	\begin{tikzpicture}
		[scale=3,line cap=round,
		% Styles
		axes/.style=,
		important line/.style={very thick},
		information text/.style={rounded corners,fill=red!10,inner sep=1ex}]
		% Colors
		\colorlet{anglecolor}{green!50!black}
		\colorlet{sincolor}{red}
		\colorlet{tancolor}{orange!80!black}
		\colorlet{coscolor}{blue}
		% The graphic
		\draw[help lines,step=0.5cm] (-1.4,-1.4) grid (1.4,1.4);
		\draw (0,0) circle [radius=1cm];
		\begin{scope}[axes]
		\draw[->] (-1.5,0) -- (1.5,0) node[right] {$x$} coordinate(x axis);
		\draw[->] (0,-1.5) -- (0,1.5) node[above] {$y$} coordinate(y axis);
		\foreach \x/\xtext in {-1, -.5/-\frac{1}{2}, 1}
		\draw[xshift=\x cm] (0pt,1pt) -- (0pt,-1pt) node[below,fill=white] {$\xtext$};
		\foreach \y/\ytext in {-1, -.5/-\frac{1}{2}, .5/\frac{1}{2}, 1}
		\draw[yshift=\y cm] (1pt,0pt) -- (-1pt,0pt) node[left,fill=white] {$\ytext$};
		\end{scope}
		\filldraw[fill=green!20,draw=anglecolor] (0,0) -- (3mm,0pt)
		arc [start angle=0, end angle=30, radius=3mm];
		\draw (15:2mm) node[anglecolor] {$\alpha$};
		\draw[important line,sincolor]
		(30:1cm) -- node[left=1pt,fill=white] {$\sin \alpha$} (30:1cm |- x axis);
		\draw[important line,coscolor]
		(30:1cm |- x axis) -- node[below=2pt,fill=white] {$\cos \alpha$} (0,0);
		\path [name path=upward line] (1,0) -- (1,1);
		\path [name path=sloped line] (0,0) -- (30:1.5cm);
		\draw [name intersections={of=upward line and sloped line, by=t}]
		[very thick,orange] (1,0) -- node [right=1pt,fill=white]
		{$\tan \alpha \color{black}=
		\dfrac{{\color{red}\sin \alpha}}{\color{blue}\cos \alpha}$} (t);
		\draw (0,0) -- (t);
		\draw[xshift=1.85cm]
		node[right,text width=6cm,information text]
		{
		The {\color{anglecolor} angle $\alpha$} is $30^\circ$ in the
		example ($\pi/6$ in radians). The {\color{sincolor}sine of
		$\alpha$}, which is the height of the red line, is
		\[
		{\color{sincolor} \sin \alpha} = 1/2.
		\]
		By the Theorem of Pythagoras ...
		};
	\end{tikzpicture}
\end{document}

这里的改动比较大,因为做了比较多的优化,主要是在开始的地方预设了样式、颜色,后面就可以直接引用。在加解释性文字的地方,我们指定了text width=6cm
在这里插入图片描述
第一个教程到这里就差不多结束啦,如果大家还觉得不过瘾的话,可以看看我这篇实例讲解:
TikZ从零开始(一)——实例之受力分析图绘制

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值