我想画一个角度发射器:
以下代码显示了我目前想到的,基本上什么都没有。我不知道如何以径向方式填充每个象限的单元格。我成功地绘制了某种矩形和圆形,但这个不行。
从 12 点开始逆时针旋转,外环的图案为 8f(满)-8e(空)个单元格,然后第二个外环的图案相同,偏移量为 4 个单元格,然后是 4f-4e,偏移量为 2 个单元格,内环具有 2f-2e 图案,偏移量为 1。
\documentclass[
a4paper
]{scrartcl}
\usepackage{
newtxtext,
amsmath,
}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usetikzlibrary{
external,
}
\listfiles
\begin{document}
\begin{center}
\begin{tikzpicture}[font=\small]
\draw[thick] (0,0) circle [radius=2cm];
\draw[thick] (0,0) circle [radius=4cm];
% \foreach \a in {2,2.5,...,4}
% \foreach \w in {0,22.5,45,...,337.5} {
% \fill ($(\w:\a;
% }
\end{tikzpicture}
\end{center}
\end{document}
答案1
这是一个外行人能想到的解决办法,不用填充,直接用 画圆弧就可以了line width=0.5cm
。
\documentclass[
a4paper
]{scrartcl}
\usepackage[T1]{fontenc}
\usepackage{tikz}
\begin{document}
\begin{center}
\begin{tikzpicture}[font=\small]
\foreach \x in {0,22.5,...,337.5}{
\draw (0,0) -- (\x:4cm);
}
\foreach \x in {2,2.5,...,4}{
\draw[thick] (0,0) circle [radius=\x cm];
}
\draw[thick,fill=white] (0,0) circle [radius=2cm];
\foreach \w/\t in {22.5/67.5,112.5/157.5,202.5/247.5,292.5/337.5} {
\draw[line width=0.5cm] (\w:2.25) arc(\w:\t:2.25);
}
\foreach \w/\t in {135/225,315/405} {
\draw[line width=0.5cm] (\w:2.75) arc(\w:\t:2.75);
}
\foreach \w/\t in {180/360} {
\draw[line width=0.5cm] (\w:3.25) arc(\w:\t:3.25);
}
\foreach \w/\t in {90/270} {
\draw[line width=0.5cm] (\w:3.75) arc(\w:\t:3.75);
}
\end{tikzpicture}
\end{center}
\end{document}
答案2
这里有一个起点。它基于杰克的轮盘
\documentclass[border=3mm]{standalone}
\usepackage{tikz}
\begin{document}
% The main macro
% #1 - List of value/color pairs
% #2 - inner radius
% #3 - outer radius
\newcommand{\wheelchart}[3]{
% Calculate total
\pgfmathsetmacro{\totalnum}{0}
\foreach \value/\colour in {#1} {
\pgfmathparse{\value+\totalnum}
\global\let\totalnum=\pgfmathresult
}
% Calculate the thickness and the middle line of the wheel
\pgfmathsetmacro{\wheelwidth}{(#3)-(#2)}
\pgfmathsetmacro{\midradius}{(#3+#2)/2}
% Rotate so we start from the top
\begin{scope}[rotate=90]
% Loop through each value set. \cumnum keeps track of where we are in the wheel
\pgfmathsetmacro{\cumnum}{0}
\foreach \value/\colour in {#1} {
\pgfmathsetmacro{\newcumnum}{\cumnum + \value/\totalnum*360}
% Draw the color segments.
\draw[draw, fill=\colour] (-\cumnum:#2) arc (-\cumnum:-\newcumnum:#2)--(-\newcumnum:#3) arc (-\newcumnum:-\cumnum:#3)--cycle;
% Set the old cumulated angle to the new value
\global\let\cumnum=\newcumnum
}
\end{scope}
}
\begin{tikzpicture}
\wheelchart{1/white,1/black,1/black,1/white,1/white,1/black,1/black,1/white,1/white,1/black,1/black,1/white,1/white,1/black,1/black,1/white}{3cm}{3.5cm}
\wheelchart{1/white,1/white,1/black,1/black,1/black,1/black,1/white,1/white,1/white,1/white,1/black,1/black,1/black,1/black,1/white,1/white}{3.5cm}{4cm}
\wheelchart{1/white,1/white,1/white,1/white,1/black,1/black,1/black,1/black,1/black,1/black,1/black,1/black,1/white,1/white,1/white,1/white}{4cm}{4.5cm}
\wheelchart{1/white,1/white,1/white,1/white,1/white,1/white,1/white,1/white,1/black,1/black,1/black,1/black,1/black,1/black,1/black,1/black}{4.5cm}{5cm}
\end{tikzpicture}
\end{document}
答案3
虽然不是最理想的,但这是一种指定满/空扇区的更简洁的方法。此外,它利用了默认的填充规则,因此在矩形覆盖层中创建了“孔”,因此无需用正确的颜色填充圆圈。
需要该库的最新 PGF 版本math
(这可能不是必需的,但提供了一种更简单的方法来定义/计算值)。
\documentclass[tikz,border=5]{standalone}
\usetikzlibrary{math}
\begin{document}
\begin{tikzpicture}[every sector/.style={draw}, sector-1/.style={fill=black}, sector-0/.style={fill=white}]
\tikzmath{%
\n = 16; \N = 4;
\R1 = 1; \R2 = 2;
\th = (\R2-\R1) / \N;
\st = 360 / \n;
\S = 1;
}
\foreach \s [count=\i from 0,
evaluate={\a=90+\i*\st; \r=\R2-floor(\i/\n)*\th;}] in
{%
1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,
0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,
0,0,1,1,1,1,0,0,0,0,1,1,1,1,0,0,
0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0%
}
\path [every sector/.try, sector-\s]
(\a:\r) arc (\a:\a+\st:\r) --
(\a+\st:\r-\th) arc (\a+\st:\a:\r-\th) -- cycle;
\filldraw [fill=white, rotate=\S*\st-\st/2]
(\R1-\th/2,-\th/2) rectangle (\R2+\th/2,\th/2)
\foreach \i in {1,...,\N}{ (\R1+\th*\i-\th/2,0) circle [radius=\th/3] };
\end{tikzpicture}
\end{document}
答案4
这是我使用 LuaLaTeX 和 TikZ 制作的解决方案,没有使用任何白色填充,并使用了一些反向剪辑,因此任何背景颜色都会通过孔显示出来(参见第二张图片):
\documentclass[a4paper]{article}
\usepackage{luacode}
\usepackage{tikz}
\usetikzlibrary{calc}
% inverse clipping from: http://tex.stackexchange.com/a/59168/8844
\tikzset{
invclip/.style={clip,%
insert path={{[reset cm] %
(-16383.99999pt,-16383.99999pt) rectangle (16383.99999pt,16383.99999pt)%
}}
}
}
\begin{luacode*}
function draw_figure()
tex.sprint([[\begin{tikzpicture}]])
tex.sprint([[\begin{scope}[rotate=11.25] ]])
tex.sprint([[\draw (2.25cm, 0.25cm) rectangle (4.75cm, -0.25cm)]])
tex.sprint([[(2.75cm, 0) circle [radius=0.15cm] ]])
tex.sprint([[(3.25cm, 0) circle [radius=0.15cm] ]])
tex.sprint([[(3.75cm, 0) circle [radius=0.15cm] ]])
tex.sprint([[(4.25cm, 0) circle [radius=0.15cm];]])
tex.sprint([[\end{scope}]])
-- inverse clipping from: http://tex.stackexchange.com/a/59168/8844
tex.sprint([[\begin{pgfinterruptboundingbox}]])
tex.sprint([[\path[invclip, rotate=11.25] (2.25cm, 0.25cm) rectangle (4.75cm, -0.25cm)]])
tex.sprint([[(2.75cm, 0) circle [radius=0.15cm] ]])
tex.sprint([[(3.25cm, 0) circle [radius=0.15cm] ]])
tex.sprint([[(3.75cm, 0) circle [radius=0.15cm] ]])
tex.sprint([[(4.25cm, 0) circle [radius=0.15cm];]])
tex.sprint([[\end{pgfinterruptboundingbox}]])
for radius = 2.5, 4.5, 0.5 do
tex.sprint([[\draw (0,0) circle [radius=]])
tex.sprint(radius)
tex.sprint([[cm];]])
end
for angle = 0, 359, 22.5 do
tex.sprint([[\draw[rotate=]])
tex.sprint(angle)
tex.sprint([[] (2.5cm, 0) -- (4.5cm, 0);]])
end
fillmatrix = {{0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0},
{1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1},
{0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1},
{0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0}}
cols = #fillmatrix[1]
rows = #fillmatrix
offset = 2.5
for i = 1, rows do
angle = 0
for j = 1, cols do
if fillmatrix[i][j] == 1 then
tex.sprint([[\fill ($(0, 0) + (]])
tex.sprint(angle)
tex.sprint([[:]])
tex.sprint(offset)
tex.sprint([[cm)$) arc (]])
tex.sprint(angle)
tex.sprint([[:]])
tex.sprint(22.5 + angle)
tex.sprint([[:]])
tex.sprint(offset)
tex.sprint([[cm) -- ($(0, 0) + (]])
tex.sprint(22.5 + angle)
tex.sprint([[:]])
tex.sprint(offset + 0.5)
tex.sprint([[cm)$) arc (]])
tex.sprint(22.5 + angle)
tex.sprint([[:]])
tex.sprint(angle)
tex.sprint([[:]])
tex.sprint(offset + 0.5)
tex.sprint([[cm) -- cycle;]])
end
angle = angle + 22.5
end
offset = offset + 0.5
end
-- naive filling solution:
-- for angle = 0, 359, 90 do
-- tex.sprint([[\fill[rotate=]])
-- tex.sprint(angle)
-- tex.sprint([[] ($(0, 0) + (22.5:2.5cm)$) arc (22.5:67.5:2.5cm) -- ($(0, 0) + (67.5:3.0cm)$) arc (67.5:22.5:3.0cm) -- cycle;]])
-- end
-- for angle = 0, 359, 180 do
-- tex.sprint([[\fill[rotate=]])
-- tex.sprint(angle)
-- tex.sprint([[] ($(0, 0) + (135:3.0cm)$) arc (135:225:3.0cm) -- ($(0, 0) + (225:3.5cm)$) arc (225:135:3.5cm) -- cycle;]])
-- end
-- tex.sprint([[\fill ($(0, 0) + (180:3.5cm)$) arc (180:360:3.5cm) -- ($(0, 0) + (360:4.0cm)$) arc (360:180:4.0cm) -- cycle;]])
-- tex.sprint([[\fill ($(0, 0) + (90:4.0cm)$) arc (90:270:4.0cm) -- ($(0, 0) + (270:4.5cm)$) arc (270:90:4.5cm) -- cycle;]])
tex.sprint([[\end{tikzpicture}]])
end
\end{luacode*}
\begin{document}
\luadirect{draw_figure()}
\end{document}
我将其变成了一个参数化函数,您可以在其中设置图表的内半径、外半径(以厘米为单位)的值,并设置标尺的位置。以下代码包含一些示例,但我也在这里展示了其中的一些。
\documentclass[a4paper]{article}
\usepackage{luacode}
\usepackage{tikz}
\usetikzlibrary{calc}
% inverse clipping from: http://tex.stackexchange.com/a/59168/8844
\tikzset{
invclip/.style={clip,%
insert path={{[reset cm] %
(-16383.99999pt,-16383.99999pt) rectangle (16383.99999pt,16383.99999pt)%
}}
}
}
\begin{luacode*}
function draw_chart(fillmatrix, inner_radius, outer_radius, ruler_step)
cols = #fillmatrix[1]
rows = #fillmatrix
angle_offset = 360 / cols
radius_offset = (outer_radius - inner_radius) / rows
tex.sprint([[\begin{tikzpicture}]])
if ruler_step >= 1 and ruler_step <= cols then
tex.sprint([[\begin{scope}[rotate=]])
tex.sprint(angle_offset * ruler_step - angle_offset / 2)
tex.sprint([[] ]])
tex.sprint([[\draw (]])
tex.sprint(inner_radius - radius_offset * 0.5)
tex.sprint([[cm, ]])
tex.sprint(radius_offset * 0.5)
tex.sprint([[cm) rectangle (]])
tex.sprint(outer_radius + radius_offset * 0.5)
tex.sprint([[cm, ]])
tex.sprint(radius_offset * -0.5)
tex.sprint([[cm)]])
for i = inner_radius, (outer_radius - radius_offset), radius_offset do
tex.sprint([[(]])
tex.sprint(i + radius_offset * 0.5)
tex.sprint([[cm, 0) circle [radius=]])
tex.sprint(radius_offset * 0.5 * 0.6)
tex.sprint([[cm] ]])
end
tex.sprint([[;]])
tex.sprint([[\end{scope}]])
-- inverse clipping from: http://tex.stackexchange.com/a/59168/8844
tex.sprint([[\begin{pgfinterruptboundingbox}]])
tex.sprint([[\path[invclip, rotate=]])
tex.sprint(angle_offset * ruler_step - angle_offset / 2)
tex.sprint([[] (]])
tex.sprint(inner_radius - radius_offset * 0.5)
tex.sprint([[cm, ]])
tex.sprint(radius_offset * 0.5)
tex.sprint([[cm) rectangle (]])
tex.sprint(outer_radius + radius_offset * 0.5)
tex.sprint([[cm, ]])
tex.sprint(radius_offset * -0.5)
tex.sprint([[cm)]])
for i = inner_radius, (outer_radius - radius_offset), radius_offset do
tex.sprint([[(]])
tex.sprint(i + radius_offset * 0.5)
tex.sprint([[cm, 0) circle [radius=]])
tex.sprint(radius_offset * 0.5 * 0.6)
tex.sprint([[cm] ]])
end
tex.sprint([[;]])
tex.sprint([[\end{pgfinterruptboundingbox}]])
end
for radius = inner_radius, outer_radius, radius_offset do
tex.sprint([[\draw (0,0) circle [radius=]])
tex.sprint(radius)
tex.sprint([[cm];]])
end
for angle = 0, 359, angle_offset do
tex.sprint([[\draw[rotate=]])
tex.sprint(angle)
tex.sprint([[] (]])
tex.sprint(inner_radius)
tex.sprint([[cm, 0) -- (]])
tex.sprint(outer_radius)
tex.sprint([[cm, 0);]])
end
radius = inner_radius
for i = 1, rows do
angle = 0
for j = 1, cols do
if fillmatrix[i][j] == 1 then
tex.sprint([[\fill ($(0, 0) + (]])
tex.sprint(angle)
tex.sprint([[:]])
tex.sprint(radius)
tex.sprint([[cm)$) arc (]])
tex.sprint(angle)
tex.sprint([[:]])
tex.sprint(angle + angle_offset)
tex.sprint([[:]])
tex.sprint(radius)
tex.sprint([[cm) -- ($(0, 0) + (]])
tex.sprint(angle + angle_offset)
tex.sprint([[:]])
tex.sprint(radius + radius_offset)
tex.sprint([[cm)$) arc (]])
tex.sprint(angle + angle_offset)
tex.sprint([[:]])
tex.sprint(angle)
tex.sprint([[:]])
tex.sprint(radius + radius_offset)
tex.sprint([[cm) -- cycle;]])
end
angle = angle + angle_offset
end
radius = radius + radius_offset
end
tex.sprint([[\end{tikzpicture}]])
end
\end{luacode*}
\begin{document}
\setlength{\parindent}{0pt}
With this code you can set the inner and outer radius of the chart, and also set the position of the ruler.
inner radius = 2.5cm\\
outer radius = 4.5cm\\
ruler position = 1
\luadirect{
fillmatrix = {{0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0},
{1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1},
{0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1},
{0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0}}
draw_chart(fillmatrix, 2.5, 4.5, 1)
}
inner radius = 1cm\\
outer radius = 3cm\\
ruler position = 10
\luadirect{draw_chart(fillmatrix, 1, 3, 10)}
You can disable the ruler, by setting its position to zero.
inner radius = 0cm\\
outer radius = 2cm\\
ruler position = 0
\luadirect{
fillmatrix = {{0, 0, 0, 0, 1, 1, 1, 1},
{0, 0, 1, 1, 0, 0, 1, 1},
{0, 1, 0, 1, 0, 1, 0, 1}}
draw_chart(fillmatrix, 0, 2, 0)
}
You can also use this chart to visualize binary numbers. The third 3 bit binary number (binary 010 = octal 2 = decimal 2 = hexadecimal 2):
\luadirect{draw_chart(fillmatrix, 1, 2, 3)}
The sixteenth 4 bit binary number (binary 1111 = octal 17 = decimal 15 = hexadecimal F):
\luadirect{
fillmatrix = {{0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1},
{0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1},
{0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1},
{0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}}
draw_chart(fillmatrix, 2, 3, 16)
}
The sixth 5 bit binary number (00101):
\luadirect{
fillmatrix = {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1},
{0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1},
{0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1},
{0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}}
draw_chart(fillmatrix, 3, 6, 6)
}
\end{document}
左边
- 内半径 = 1cm,外半径 = 3cm,标尺位置 = 10
正确的
- 内半径 = 2.5cm,外半径 = 4.5cm,标尺位置 = 1
您还可以使用此图表来可视化二进制数。
左边:
- 第三个 3 位二进制数(二进制 010 = 八进制 2 = 十进制 2 = 十六进制 2)
- 内半径 = 1cm,外半径 = 2cm,标尺位置 = 3
正确的:
- 第十六个 4 位二进制数(二进制 1111 = 八进制 17 = 十进制 15 = 十六进制 F)
- 内半径 = 2cm,外半径 = 3cm,标尺位置 = 16