![TikZ 图形中高亮部分的对齐](https://linux22.com/image/469363/TikZ%20%E5%9B%BE%E5%BD%A2%E4%B8%AD%E9%AB%98%E4%BA%AE%E9%83%A8%E5%88%86%E7%9A%84%E5%AF%B9%E9%BD%90.png)
我正在尝试创建 TikZ 图表来表示 HDD 盘片。盘片上的轨道、扇区和块应突出显示。我从简单的手工计算渲染转向使用变量和计算的系统方法,它几乎可以正常工作。我遇到的问题是在“荧光笔”采取行动之前绘制的线条的匹配(如下图所示)。我摸索着这些值,找到了适合我的用例的组合,但我仍然感到疑惑,无法弄清楚错位从何而来。
附言:我正在使用 Overleaf 来编写和渲染 TeX 文件。
TikZ HDD 示意图:
% Hard disk drive platter
% Author: Tomáš Michalek
%
% This diagram attempts to create HDD platter with the selectable track,
% sector and block highlighting.
%
% Current version is quite fragile and any improvements are welcome
%
\documentclass[tikz,margin=10pt]{standalone}
\usepackage{tikz}
\usepackage{comment}
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% CUSTOMISATIONS
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\def\numTracks{8}
\def\numSectors{12}
\def\selectedTrack{6} % Track to highlight, negative values disable the selection
\def\selectedSector{0} % Sector to highlight, negative values disable the selection
\definecolor{baseColor}{RGB}{18, 54, 69} % Basic lines and borders
\definecolor{accentColor}{RGB}{1, 103, 143} % Selection
\definecolor{highlightColor}{RGB}{221, 109, 16} % Crossover of two selections
\pgfmathsetmacro\firstTrack{10cm}
\pgfmathsetmacro\lastTrack{2cm}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% CALCULATIONS
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\pgfmathtruncatemacro{\trackStepRange}{\firstTrack-\lastTrack}
\pgfmathsetmacro\trackStep{\trackStepRange/\numTracks}
\pgfmathsetmacro\sectorStep{360/\numSectors}
\pgfmathtruncatemacro{\selectedSectorStart}{-\sectorStep*\selectedSector} % natural rotation
\pgfmathtruncatemacro{\selectedBlockStart}{\firstTrack-\selectedTrack*\trackStep}
\pgfmathtruncatemacro{\selectedBlockEnd}{\selectedBlockStart-\trackStep}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% DRAWING
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Draw track lines
\foreach \track in {0,...,\numTracks} {
\draw [baseColor!20] (0,0) circle (\firstTrack-\track*\trackStep);
}
% Draw sector lines
\foreach \i in {0, \sectorStep, ..., 359}
\draw [baseColor!20] (\i:\firstTrack) -- (\i:\lastTrack);
\foreach \sector in {0, \sectorStep, ..., 359} {
\pgfmathparse{mod(\sector, \sectorStep*2)}
\pgfmathtruncatemacro{\remainder}{\pgfmathresult}
\ifnum\remainder=0
\pgfmathtruncatemacro{\sectorTint}{50};
\else
\pgfmathtruncatemacro{\sectorTint}{50}; %25
\fi
% If the `track` is selected, highlight it
\ifnum\selectedTrack>-1
\fill[accentColor!\sectorTint] (\sector:\selectedBlockStart) arc (\sector:\sector+\sectorStep:\selectedBlockStart) -- (\sector+\sectorStep:\selectedBlockEnd) arc (\sector+\sectorStep:\sector:\selectedBlockEnd) -- cycle;
\fi
}
% If the `sector` is selected, highlight it
\ifnum\selectedSector>-1
\fill[accentColor!30, rotate=\selectedSectorStart] (0:\firstTrack) arc (0:\sectorStep:\firstTrack) -- (\sectorStep:\lastTrack) arc (\sectorStep:0:\lastTrack) -- cycle;
\fi
% If both `sector` and `track` are selected, highlight `block`
\ifnum\selectedSector>-1
\ifnum\selectedTrack>-1
\fill[highlightColor!80, rotate=\selectedSectorStart] (0:\selectedBlockStart) arc (0:\sectorStep:\selectedBlockStart) -- (\sectorStep:\selectedBlockEnd) arc (\sectorStep:0:\selectedBlockEnd) -- cycle;
\fi
\fi
\end{tikzpicture}
\end{document}
答案1
cm
如果你从宏中删除单位\firstTrack
,\lastTrack
你的图表将绘制得更正确。现在大小不同,但可以通过以下方式再次调整扩展图表或改变坐标向量。
当您使用单位时,这些长度将转换为pt
s 和 ,您在其中使用\pgfmathtruncatemacro
。这将导致与 和 不同的结果\pgfmathsetmacro
,因为您也不使用\pgfmathsetlengthmacro
,单位将丢失,值将被解释为坐标 再次坐标系,将您的图表缩放到超出您实际想要的值(2厘米,10厘米)。
总之:
input converted
2cm 56.9055 pt
10cm 284.52756pt
10cm-2cm 227.62206pt
但是,\pgfmathtruncatemacro
值227
将被存储在其中\trackStepRange
,这将导致\trackStep
错误,然后所有依赖于它的其他事物也会出现错误。
话虽如此,我还是重写了你的图表,因为对我来说有点难以理解。不过,我相信这是相同的方法,只是我从内到外计算轨道。这让数学变得容易一些。
track 1 sector 0/.style=hdd sel block
我还有另一种方法的草稿,其中每个块都是单独绘制/填充的,并且在两个嵌套循环期间定义和访问一些样式。
如果您需要进一步着色/染色区域,该解决方案可能会更容易使用。
我们还可以使用heatmark
形状。
代码
\documentclass[tikz, margin=10pt]{standalone}
\definecolor {baseColor}{RGB}{ 18, 54, 69} % Basic lines and borders
\definecolor {accentColor}{RGB}{ 1, 103, 143} % Selection
\definecolor{highlightColor}{RGB}{221, 109, 16} % Crossover of two selections
\tikzset{
ring segment/.style n args={4}{insert path={% helpful
({#1}:{#4}) arc[start angle={#1}, end angle={#2}, radius={#4}]
-- ({#2}:{#3}) arc[start angle={#2}, end angle={#1}, radius={#3}] -- cycle}}}
\begin{document}
\begin{tikzpicture}[
hdd border/.style ={draw= baseColor!20},
hdd sel track/.style ={fill= accentColor!50},
hdd sel sector/.style={fill= accentColor!30},
hdd sel block/.style ={fill=highlightColor!80},
]
%% independent of selection
\newcommand*\numTracks{8}
\newcommand*\numSectors{12}
\newcommand*\baseR{2}
\newcommand*\stepR{.5}
\pgfmathsetmacro\maxR{\baseR+\numTracks*\stepR}
\pgfmathsetmacro\stepAngle{360/\numSectors}
%% dependent of selection
\newcommand*\selTrack{1}
\newcommand*\selSector{0}
\pgfmathsetmacro\selAngleL{\stepAngle*\selSector}
\pgfmathsetmacro\selAngleU{\selAngleL+\stepAngle}
\pgfmathsetmacro\selRadiusL{\baseR+\stepR*\selTrack}
\pgfmathsetmacro\selRadiusU{\selRadiusL+\stepR}
%% the drawing
\ifnum\selTrack>-1
\fill[hdd sel track, even odd rule]
circle [radius=\selRadiusU] circle [radius=\selRadiusL];
\fi
\ifnum\selSector>-1
\fill[hdd sel sector, ring segment=\selAngleL\selAngleU\baseR\maxR];
\fi
\ifnum\selTrack>-1 \ifnum\selSector>-1
\fill[hdd sel block, ring segment=\selAngleL\selAngleU\selRadiusL\selRadiusU];
\fi \fi
%% borders on top
\foreach \track in {0, ..., \numTracks}
\draw[hdd border] (0,0) circle[radius=\baseR+\track*\stepR];
\foreach[count=\i from 0] \sectors in {1, ..., \numSectors}
\draw[hdd border] (\i*\stepAngle:\baseR) -- (\i*\stepAngle:\maxR);
\end{tikzpicture}
\end{document}