接上篇继续写~😄
文章目录
15、指定坐标(Specifying Coordinates)
这一节内容前面已经我们已经了解了一半了。
指定坐标的方法有:
(10pt,1cm)
这是直角坐标里的最简单粗暴的方法(10pt,1cm) --+ (5pt, -0.5cm)
这代表直角坐标系中画线,起点是(10pt,1cm)
,且为当前指定位置(specified position),终点是当前指定位置向水平轴正方向(右)移动 5 p t 5pt 5pt,向竖直轴负方向(下)移动 0.5 c m 0.5cm 0.5cm。
以上两种之前都讲过了,下面看三种新的。
(10pt,1cm) ++ (5pt,-0.5cm) -- (0,0)
,表示从(10pt,1cm)
先向水平轴正方向(右)移动 5 p t 5pt 5pt,向竖直轴负方向(下)移动 0.5 c m 0.5cm 0.5cm,在此过程中只移动位置,不画线,把新位置作为当前指定位置,然后画与(0,0)
的连线。(30:1)
表示极坐标中,极角为 3 0 ∘ 30^\circ 30∘,极径为 1 c m 1cm 1cm的点(记为点 M M M)。(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}
控制箭头的可选参数有length
和width
,这样来使用:
\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)
实施变换的对象是坐标系,即变换是对坐标系进行变换。主要有以下变换形式:
xshift
:水平平移yshift
:竖直平移rotate
:旋转xscale
:水平缩放,负数则意味着翻转ysclae
:竖直缩放,负数则意味着翻转xslant
:水平倾斜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从零开始(一)——实例之受力分析图绘制