The preface

Prepare for an examination of some level of the exam, in the teaching material encountered a few have not quite understood, about the concept of hard disk: magnetic track, cylinder number, sector. However, there are no pictures in the textbook, so the physical forms of these concepts cannot be understood intuitively. There’s a nice sketch in the Wikipedia hard drive page, and I took a screenshot of it

The original image is an SVG image, which is essentially a bunch of instructions — otherwise known as a rendering. I am a language painter and wanted to see if I could draw a similar picture in code.

In the previous article, “Programmer’s Way of Drawing — A Primer on Graphic Tools”, I demonstrated several tools for writing code and drawing, but none of them are suitable for drawing geometry, so this time they are useless.

I was going to try using MetaPost, but since I’ve been “getting started” so many times, I’ll try something new this time. This time, I’ll draw it in LaTeX+TikZ.

What is TikZ and light speed gateway

TeX was invented by the author of TAOCP, and LaTeX was created by the author of Paxos, a rival algorithm Raft. These are great tools for writing resumes and essays for programmers. TikZ, on the other hand, is a macro package (TeX jargon) with easy-to-understand graphics in LaTeX. In short, TikZ has a custom “language” for drawing graphics in documents written in LaTeX.

I showed you how to draw a line segment, a circle, and an arc using TikZ. Save the following code to a file called three_in_one.tex

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes.geometric, arrows}
\begin{document}
\begin{tikzpicture}[scale=2]
  Draw a line segment that points from the origin to (1, 1)
  \draw (0, 0) -- (1, 1);
  Draw a circle with (1, 1) as the center and radius 2.
  \draw (1, 1) circle (2);
  Draw an arc with the origin as the center, radius 1, and opening Angle 30 degrees.
  \draw (1, 0) arc (0:30:1);
\end{tikzpicture}
\end{document}
Copy the code

Then compile it into a PDF file using Xelatex (available by installing TeXLive 2020)

xelatex three_in_one.tex
Copy the code

This gives you the three_in_one.pdf file. I converted it to a PNG file using ImageMagick for display in the article

convert three_in_one.pdf /tmp/three_in_one.png
Copy the code

The final image is below

Simple, like drawing a horse.

Now it’s time to try TikZ to recreate a Wikipedia hard drive diagram.

Let’s do concentric circles

The most striking thing in the original image is the dozen concentric circles. I’ll just draw six circles for simplicity. The radius difference of these six circles is 1pt (pt is the default length unit of TikZ), increasing from 3pt to 8pt, and their centers are all at the coordinate origin (0, 0).

%% to save space, only the TikZ part of the code is given.
\begin{tikzpicture}
  \draw (0, 0) circle (3);
  \draw (0, 0) circle (4);
  \draw (0, 0) circle (5);
  \draw (0, 0) circle (6);
  \draw (0, 0) circle (7);
  \draw (0, 0) circle (8);
\end{tikzpicture}
Copy the code

Let’s do a bisector

There are 12 line segments in the original drawing, dividing each circle into congruent 12 parts. From the previous section, we know that to draw a line segment with \draw, we need coordinates at both ends of the segment. Although you can use trigonometry to calculate cartesian coordinates for these points, you can specify them in TikZ with more convenient polar coordinates.

Take the first line segment encountered in the original figure in counterclockwise rotation from the X-axis as an example, its coordinates of the point on the circle of radius 3pt are (30:3) (30 is the Angle in polar coordinates, 3 is the radius length), and the coordinates of the point on the circle of radius 8pt are (30:8), Thus the line segment can be drawn with \draw (30:3) — (30:8).

The rest of the line segments can be drawn by adjusting the angles.

\begin{tikzpicture}
  \draw (0, 0) circle (3);
  \draw (0, 0) circle (4);
  \draw (0, 0) circle (5);
  \draw (0, 0) circle (6);
  \draw (0, 0) circle (7);
  \draw (0, 0) circle (8);

  \draw(3-0) - (0:8);\draw(o) - (");\draw(60:3) - (8) : 60;\draw(90:3) - (8) : 90.\draw(120:3) - (8) : 120.\draw(150:3) - (8) : 150.\draw(180:3) - (8) : 180.\draw(210:3) - (8) : 210.\draw(240:3) - (8) : 240.\draw(270:3) - (8) : 270.\draw(300:3) - (8) : 300.\draw(330:3) - (8) : 330.\end{tikzpicture}
Copy the code

To color chart

The rough skeleton of the original image has been drawn, now let’s try to color it in. In TikZ, a closed curve can be colored with the \fill command. For example, use \fill[red] (0, 0) — (1, 0) — (1, 1) — (0, 1) — cycle to color a square with 1pt side length at the lower left corner of the origin red.

Color area B in the original image first. Region B is a sector consisting of two 8pt radii and an arc with an Angle of 30 degrees. To describe this closed curve, use the arc command described in the Getting Started section.

\begin{tikzpicture}
  %% color area B.
  \fill[blue] (0, 0) -- (30:8) arc (30:60:8) -- cycle;

  \draw (0, 0) circle (3);
  \draw (0, 0) circle (4);
  \draw (0, 0) circle (5);
  \draw (0, 0) circle (6);
  \draw (0, 0) circle (7);
  \draw (0, 0) circle (8);

  \draw(3-0) - (0:8);\draw(o) - (");\draw(60:3) - (8) : 60;\draw(90:3) - (8) : 90.\draw(120:3) - (8) : 120.\draw(150:3) - (8) : 150.\draw(180:3) - (8) : 180.\draw(210:3) - (8) : 210.\draw(240:3) - (8) : 240.\draw(270:3) - (8) : 270.\draw(300:3) - (8) : 300.\draw(330:3) - (8) : 330.\end{tikzpicture}
Copy the code

The cycle at the end of the \fill command line means to return the curve to its starting point to form a closed shape. In addition, the \fill command needs to be written before the \draw command to prevent the blue paint from covering the arcs in the area.

For region C and region D, the method is the same, but the coordinates describing the closed curve are different.

\begin{tikzpicture}
  %% color area B.
  \fill[blue] (0, 0) -- (30:8) arc (30:60:8) -- cycle;
  %% color area C.
  \fill[purple] (30:4) -- (30:5) arc (30:60:5) -- (60:4) -- (60:4) arc (60:30:4);
  %% color area D.
  \fill[green] (240:6) -- (240:7) arc (240:330:7) -- (330:6) -- (330:6) arc (330:240:6);

  \draw (0, 0) circle (3);
  \draw (0, 0) circle (4);
  \draw (0, 0) circle (5);
  \draw (0, 0) circle (6);
  \draw (0, 0) circle (7);
  \draw (0, 0) circle (8);

  \draw(3-0) - (0:8);\draw(o) - (");\draw(60:3) - (8) : 60;\draw(90:3) - (8) : 90.\draw(120:3) - (8) : 120.\draw(150:3) - (8) : 150.\draw(180:3) - (8) : 180.\draw(210:3) - (8) : 210.\draw(240:3) - (8) : 240.\draw(270:3) - (8) : 270.\draw(300:3) - (8) : 300.\draw(330:3) - (8) : 330.\end{tikzpicture}
Copy the code

Color the ring

As the intelligent reader may have noticed, the circle of region A cannot be described in this way. Nevertheless have nothing to do with, should regard its only fluctuation half two parts, apply color respectively again can.

\begin{tikzpicture}
  %% the top half of the ring
  \fill[red] (4, 0) -- (5, 0) arc (0:180:5) -- (-4, 0) -- (-4, 0) arc (180:0:4);
  %% the lower half of the ring
  \fill[red] (4, 0) -- (5, 0) arc (360:180:5) -- (-4, 0) -- (-4, 0) arc (180:360:4);
  %% color area B.
  \fill[blue] (0, 0) -- (30:8) arc (30:60:8) -- cycle;
  %% color area C.
  \fill[purple] (30:4) -- (30:5) arc (30:60:5) -- (60:4) -- (60:4) arc (60:30:4);
  %% color area D.
  \fill[green] (240:6) -- (240:7) arc (240:330:7) -- (330:6) -- (330:6) arc (330:240:6);

  \draw (0, 0) circle (3);
  \draw (0, 0) circle (4);
  \draw (0, 0) circle (5);
  \draw (0, 0) circle (6);
  \draw (0, 0) circle (7);
  \draw (0, 0) circle (8);

  \draw(3-0) - (0:8);\draw(o) - (");\draw(60:3) - (8) : 60;\draw(90:3) - (8) : 90.\draw(120:3) - (8) : 120.\draw(150:3) - (8) : 150.\draw(180:3) - (8) : 180.\draw(210:3) - (8) : 210.\draw(240:3) - (8) : 240.\draw(270:3) - (8) : 270.\draw(300:3) - (8) : 300.\draw(330:3) - (8) : 330.\end{tikzpicture}
Copy the code

Polish it

The RGB values of each area in the original picture were checked with macOS’s “digital colorimeter”. Area A was about (236, 133, 130), area B was about (122, 127, 237), area C was about (131, 132, 139), and area D was about (0, 151, 27). Next I asked TikZ to fill four areas of the diagram with these four specified colors, first defining the names of the four new colors using LaTeX’s \definecolor command.

The following four lines of code precede the Document environment
\definecolorRGB} {areaA} {{236133130}\definecolorRGB} {areaB} {{122127237}\definecolor131,32,139 RGB} {areaC} {{}\definecolorRGB} {areaD} {{0151}Copy the code

Replace the color name in the \fill command

\begin{tikzpicture}
  %% the top half of the ring
  \fill[areaA] (4, 0) -- (5, 0) arc (0:180:5) -- (-4, 0) -- (-4, 0) arc (180:0:4);
  %% the lower half of the ring
  \fill[areaA] (4, 0) -- (5, 0) arc (360:180:5) -- (-4, 0) -- (-4, 0) arc (180:360:4);
  %% color area B.
  \fill[areaB] (0, 0) -- (30:8) arc (30:60:8) -- cycle;
  %% color area C.
  \fill[areaC] (30:4) -- (30:5) arc (30:60:5) -- (60:4) -- (60:4) arc (60:30:4);
  %% color area D.
  \fill[areaD] (240:6) -- (240:7) arc (240:330:7) -- (330:6) -- (330:6) arc (330:240:6);

  \draw (0, 0) circle (3);
  \draw (0, 0) circle (4);
  \draw (0, 0) circle (5);
  \draw (0, 0) circle (6);
  \draw (0, 0) circle (7);
  \draw (0, 0) circle (8);

  \draw(3-0) - (0:8);\draw(o) - (");\draw(60:3) - (8) : 60;\draw(90:3) - (8) : 90.\draw(120:3) - (8) : 120.\draw(150:3) - (8) : 150.\draw(180:3) - (8) : 180.\draw(210:3) - (8) : 210.\draw(240:3) - (8) : 240.\draw(270:3) - (8) : 270.\draw(300:3) - (8) : 300.\draw(330:3) - (8) : 330.\end{tikzpicture}
Copy the code

illustrated

All that remains to be copied is the text from the original image and the lines used to mark it. Lines are easy to draw by specifying coordinates and using the \draw command. For example, I could define four lines as follows, where the coordinates and the length of the line segments are purely personal preferences

\draw(75, 4.5) - (9) : 75;\draw(officers. 5), (or);\draw(he wakeneth mine. 5) - (both);\draw(285, 6.5) - (9) : 285;Copy the code

When the lines are drawn, add a caption to the “end” of each line, using TikZ’s Node feature. The usage is simple: the coordinates of the text need to be marked, followed by the keyword node, and a paragraph of text wrapped in curly braces

\documentclass{standalone}
\usepackage{tikz}
\usepackage{xeCJK}
\setCJKmainfont{Songti TC}
\usetikzlibrary{shapes.geometric, arrows}
\definecolorRGB} {areaA} {{236133130}\definecolorRGB} {areaB} {{122127237}\definecolor131,32,139 RGB} {areaC} {{}\definecolorRGB} {areaD} {{0151}\begin{document}
\begin{tikzpicture}
  %% the top half of the ring
  \fill[areaA] (4, 0) -- (5, 0) arc (0:180:5) -- (-4, 0) -- (-4, 0) arc (180:0:4);
  %% the lower half of the ring
  \fill[areaA] (4, 0) -- (5, 0) arc (360:180:5) -- (-4, 0) -- (-4, 0) arc (180:360:4);
  %% color area B.
  \fill[areaB] (0, 0) -- (30:8) arc (30:60:8) -- cycle;
  %% color area C.
  \fill[areaC] (30:4) -- (30:5) arc (30:60:5) -- (60:4) -- (60:4) arc (60:30:4);
  %% color area D.
  \fill[areaD] (240:6) -- (240:7) arc (240:330:7) -- (330:6) -- (330:6) arc (330:240:6);

  \draw (0, 0) circle (3);
  \draw (0, 0) circle (4);
  \draw (0, 0) circle (5);
  \draw (0, 0) circle (6);
  \draw (0, 0) circle (7);
  \draw (0, 0) circle (8);

  \draw(3-0) - (0:8);\draw(o) - (");\draw(60:3) - (8) : 60;\draw(90:3) - (8) : 90.\draw(120:3) - (8) : 120.\draw(150:3) - (8) : 150.\draw(180:3) - (8) : 180.\draw(210:3) - (8) : 210.\draw(240:3) - (8) : 240.\draw(270:3) - (8) : 270.\draw(300:3) - (8) : 300.\draw(330:3) - (8) : 330.\draw(75:4.5) -- (75:9) node {track};\draw(40:7.5) -- (40:9) node {sector};\draw(50:4.5) -- (50:9) node {sector};\draw(285:6.5) -- (285:9) node {cluster};\end{tikzpicture}
\end{document}
Copy the code

Note that I introduced the xeCJK macro package (\usepackage{xeCJK}) at the beginning of the source code, and specified the font for the Chinese content to be Song Typeface (\setCJKmainfont{Songti TC}), so that the compilation can be successful.

At this point, the reproduction is complete.

Afterword.

While this is just a sneak peek, TikZ has other, more complex and stunning graphics for those interested to check out. TikZ can also be “programmed”, with the following two lines of code being enough to bisect the 12 above

\foreach \xIn,30,60,90,120,150,180,210,240,270,300,330 {0}\draw (\x:3) -- (\x: 8);Copy the code

It’s up to you to explore TikZ’s more potential and fun.

Read the original