![TikZ - 数独,圈出并用线连接一些单元格](https://linux22.com/image/261236/TikZ%20-%20%E6%95%B0%E7%8B%AC%EF%BC%8C%E5%9C%88%E5%87%BA%E5%B9%B6%E7%94%A8%E7%BA%BF%E8%BF%9E%E6%8E%A5%E4%B8%80%E4%BA%9B%E5%8D%95%E5%85%83%E6%A0%BC.png)
在下面的代码中,我希望能够在网格上从某个单元格到其他单元格绘制一些圆圈和线条,如下图所示。这是为了说明高级“链”技术。
预期产量
代码
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{backgrounds}
\usepackage{graphicx}
% Some customizable styles
\tikzset {
highlight/.style = {yellow, opacity=0.3},
digit/.style = {minimum height = 5mm, minimum width=5mm, anchor=center },
circle/.style = {draw=green!80!black, dotted, very thick},
cross/.style = {red, opacity=.5, shorten >=1mm, shorten <=1mm, very thick, line cap=round},
hint/.style={blue, font=\sf, minimum width=3mm, minimum height=3mm}
}
% Original code-----------------------------------------------------------
% Modified the \node to give a unique name to each one, which is the
% row number, a dash and the column number. E.g: 1-1, 4-5, etc.
\newcounter{row}
\newcounter{col}
\newcommand\setrow[9]{
\setcounter{col}{1}
\foreach \n in {#1, #2, #3, #4, #5, #6, #7, #8, #9} {
\edef\x{\value{col} - 0.5}
\edef\y{9.5 - \value{row}}
\node[digit,name={\arabic{row}-\arabic{col}}] at (\x, \y) {\n};
\stepcounter{col}
}
\stepcounter{row}
}
% New code -------------------------------------------------------------
\def\highlightcell#1#2{
\fill[highlight] (#1-#2.north west) rectangle (#1-#2.south east);
}
\def\circlecell#1#2{
\draw[circle] (#1-#2) circle(4mm);
}
\def\crosscell#1#2{
\draw[cross] (#1-#2.north west) -- (#1-#2.south east);
\draw[cross] (#1-#2.north east) -- (#1-#2.south west);
}
\def\highlightrow#1{
\fill[highlight] (#1-1.north west) rectangle (#1-9.south east);
}
\def\highlighcolumn#1{
\fill[highlight] (1-#1.north west) rectangle (9-#1.south east);
}
\def\hintcell#1#2#3{
\node at (#1-#2) {\hintbox{#3}};
}
\def\highlightrectangle#1#2#3#4{
\begin{pgfonlayer}{background}
\fill[highlight] (#1-#2.north west) rectangle (#3-#4.south east);
\end{pgfonlayer}
}
% UGLY code. Do not read :-)
\def\hintbox#1{
\resizebox{4.5mm}{4.5mm}{%
\tikz[scale=0.3]{%
\def\auxc{0}
\foreach \m in {1,...,9} {
\pgfmathparse{mod(\auxc,3)}
\xdef\x{\pgfmathresult}
\pgfmathparse{-floor(\auxc/3)}
\xdef\y{\pgfmathresult}
\xdef\hintprinted{0}
\foreach \n in {#1} {
\ifnum\n=\m
\node[hint] at (\x,\y) {\n};
\xdef\hintprinted{1}
\fi
}
\ifnum\hintprinted=0
\node[hint, opacity=0.1] at (\x,\y) {\m};
\fi
\pgfmathparse{\auxc+1}
\xdef\auxc{\pgfmathresult}
}
}%
}
}
\begin{document}
\begin{tikzpicture}[scale=.5]
\begin{scope}
\draw (0, 0) grid (9, 9);
\draw[very thick, scale=3] (0, 0) grid (3, 3);
\setcounter{row}{1}
% Single entries
\setrow {7}{4}{ } { }{8}{ } { }{ }{5}
\setrow { }{ }{ } {4}{ }{6} { }{ }{ }
\setrow { }{ }{1} { }{2}{ } {4}{ }{ }
\setrow { }{6}{ } { }{ }{ } { }{2}{ }
\setrow {5}{ }{8} { }{7}{ } {1}{ }{3}
\setrow { }{3}{ } { }{ }{ } { }{9}{ }
\setrow { }{ }{4} { }{5}{ } {9}{ }{ }
\setrow { }{ }{ } {1}{ }{2} { }{ }{ }
\setrow {3}{ }{ } { }{9}{ } { }{ }{8}
% Hints
% * Row 1
\hintcell{1}{3}{2,3,6,9}
\hintcell{1}{4}{3,9}
\hintcell{1}{6}{1,3,9}
\hintcell{1}{7}{2,3,6}
\hintcell{1}{8}{1,3,6}
% * Row 2
\hintcell{2}{1}{2,8,9}
\hintcell{2}{2}{2,5,8,9}
\hintcell{2}{3}{2,3,5,9}
\hintcell{2}{5}{1,3}
\hintcell{2}{7}{2,3,7,8}
\hintcell{2}{8}{1,3,7,8}
\hintcell{2}{9}{1,2,7,9}
% * Row 3
\hintcell{3}{1}{6,8,9}
\hintcell{3}{2}{5,8,9}
\hintcell{3}{4}{3,5,7,9}
\hintcell{3}{6}{3,5,7,9}
\hintcell{3}{8}{3,6,7,8}
\hintcell{3}{9}{6,7,9}
% * Row 4
\hintcell{4}{1}{1,4,9}
\hintcell{4}{3}{7,9}
\hintcell{4}{4}{3,5,8,9}
\hintcell{4}{5}{1,3,4}
\hintcell{4}{6}{1,3,4,5,8,9}
\hintcell{4}{7}{5,7,8}
\hintcell{4}{9}{4,7}
% * Row 5
\hintcell{5}{2}{2,9}
\hintcell{5}{4}{2,6,9}
\hintcell{5}{6}{4,9}
\hintcell{5}{8}{4,6}
% * Row 6
\hintcell{6}{1}{1,2,4}
\hintcell{6}{3}{2,7}
\hintcell{6}{4}{2,5,6,8}
\hintcell{6}{5}{1,4,6}
\hintcell{6}{6}{1,4,5,8}
\hintcell{6}{7}{5,6,7,8}
\hintcell{6}{9}{4,6,7}
% * Row 7
\hintcell{7}{1}{1,2,6,8}
\hintcell{7}{2}{1,2,7,8}
\hintcell{7}{4}{3,6,7,8}
\hintcell{7}{6}{3,7,8}
\hintcell{7}{8}{1,3,6,7}
\hintcell{7}{9}{1,2,6,7}
% * Row 8
\hintcell{8}{1}{6,8,9}
\hintcell{8}{2}{5,7,8,9}
\hintcell{8}{3}{5,6,7,9}
\hintcell{8}{5}{3,4,6}
\hintcell{8}{7}{3,5,6,7}
\hintcell{8}{8}{3,4,5,6,7}
\hintcell{8}{9}{4,6,7}
% * Row 9
\hintcell{9}{2}{1,2,5,7}
\hintcell{9}{3}{2,5,6,7}
\hintcell{9}{4}{6,7}
\hintcell{9}{6}{4,7}
\hintcell{9}{7}{2,5,6,7}
\hintcell{9}{8}{1,4,5,6,7}
\end{scope}
\end{tikzpicture}
\end{document}
答案1
由于代码中已经有一个非常好的结构,所以这几乎是简单的。
与 existent 类似,我定义了\circlecell
一个新命令,\circlenumber
该命令绘制一个圆圈并放置一个带标签的空节点:
% command to circle numbers:
% #1: optional -> circle color
% #2: mandatory -> cell identifier
% #3: mandatory -> name of the cell
\newcommand\circlenumber[3][red!80!black]{
\draw[circle number=#1, radius=5mm] (#2) circle node[outer sep=1mm] (#3){};
}
稍后,将使用用户提供的标签绘制连接。例如:
% Circle some cell
\circlenumber{4-2}{start}
\circlenumber{3-6}{middle}
\circlenumber{7-4}{end}
% Connect
\foreach \source/\dest in {start/middle,middle/end}
\draw[circle number=red!80!black] (\source)--(\dest);
代码(还有一个例子,其中连接在background
层中绘制):
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{backgrounds}
\usepackage{graphicx}
% Some customizable styles
\tikzset {
highlight/.style = {yellow, opacity=0.3},
digit/.style = {minimum height = 5mm, minimum width=5mm, anchor=center },
circle/.style = {draw=green!80!black, dotted, very thick},
circle number/.style = {draw=#1,very thick},
cross/.style = {red, opacity=.5, shorten >=1mm, shorten <=1mm, very thick, line cap=round},
hint/.style={blue, font=\sf, minimum width=3mm, minimum height=3mm}
}
% Original code-----------------------------------------------------------
% Modified the \node to give a unique name to each one, which is the
% row number, a dash and the column number. E.g: 1-1, 4-5, etc.
\newcounter{row}
\newcounter{col}
\newcommand\setrow[9]{
\setcounter{col}{1}
\foreach \n in {#1, #2, #3, #4, #5, #6, #7, #8, #9} {
\edef\x{\value{col} - 0.5}
\edef\y{9.5 - \value{row}}
\node[digit,name={\arabic{row}-\arabic{col}}] at (\x, \y) {\n};
\stepcounter{col}
}
\stepcounter{row}
}
% New code -------------------------------------------------------------
\def\highlightcell#1#2{
\fill[highlight] (#1-#2.north west) rectangle (#1-#2.south east);
}
\def\circlecell#1#2{
\draw[circle] (#1-#2) circle(4mm);
}
% command to circle numbers:
% #1: optional -> circle color
% #2: mandatory -> cell identifier
% #3: mandatory -> name of the cell
\newcommand\circlenumber[3][red!80!black]{
\draw[circle number=#1, radius=5mm] (#2) circle node[outer sep=1mm] (#3){};
}
\def\crosscell#1#2{
\draw[cross] (#1-#2.north west) -- (#1-#2.south east);
\draw[cross] (#1-#2.north east) -- (#1-#2.south west);
}
\def\highlightrow#1{
\fill[highlight] (#1-1.north west) rectangle (#1-9.south east);
}
\def\highlighcolumn#1{
\fill[highlight] (1-#1.north west) rectangle (9-#1.south east);
}
\def\hintcell#1#2#3{
\node at (#1-#2) {\hintbox{#3}};
}
\def\highlightrectangle#1#2#3#4{
\begin{pgfonlayer}{background}
\fill[highlight] (#1-#2.north west) rectangle (#3-#4.south east);
\end{pgfonlayer}
}
% UGLY code. Do not read :-)
\def\hintbox#1{
\resizebox{4.5mm}{4.5mm}{%
\tikz[scale=0.3]{%
\def\auxc{0}
\foreach \m in {1,...,9} {
\pgfmathparse{mod(\auxc,3)}
\xdef\x{\pgfmathresult}
\pgfmathparse{-floor(\auxc/3)}
\xdef\y{\pgfmathresult}
\xdef\hintprinted{0}
\foreach \n in {#1} {
\ifnum\n=\m
\node[hint] at (\x,\y) {\n};
\xdef\hintprinted{1}
\fi
}
\ifnum\hintprinted=0
\node[hint, opacity=0.1] at (\x,\y) {\m};
\fi
\pgfmathparse{\auxc+1}
\xdef\auxc{\pgfmathresult}
}
}%
}
}
\begin{document}
\begin{tikzpicture}[scale=.5]
\begin{scope}
\draw (0, 0) grid (9, 9);
\draw[very thick, scale=3] (0, 0) grid (3, 3);
\setcounter{row}{1}
% Single entries
\setrow {7}{4}{ } { }{8}{ } { }{ }{5}
\setrow { }{ }{ } {4}{ }{6} { }{ }{ }
\setrow { }{ }{1} { }{2}{ } {4}{ }{ }
\setrow { }{6}{ } { }{ }{ } { }{2}{ }
\setrow {5}{ }{8} { }{7}{ } {1}{ }{3}
\setrow { }{3}{ } { }{ }{ } { }{9}{ }
\setrow { }{ }{4} { }{5}{ } {9}{ }{ }
\setrow { }{ }{ } {1}{ }{2} { }{ }{ }
\setrow {3}{ }{ } { }{9}{ } { }{ }{8}
% Hints
% * Row 1
\hintcell{1}{3}{2,3,6,9}
\hintcell{1}{4}{3,9}
\hintcell{1}{6}{1,3,9}
\hintcell{1}{7}{2,3,6}
\hintcell{1}{8}{1,3,6}
% * Row 2
\hintcell{2}{1}{2,8,9}
\hintcell{2}{2}{2,5,8,9}
\hintcell{2}{3}{2,3,5,9}
\hintcell{2}{5}{1,3}
\hintcell{2}{7}{2,3,7,8}
\hintcell{2}{8}{1,3,7,8}
\hintcell{2}{9}{1,2,7,9}
% * Row 3
\hintcell{3}{1}{6,8,9}
\hintcell{3}{2}{5,8,9}
\hintcell{3}{4}{3,5,7,9}
\hintcell{3}{6}{3,5,7,9}
\hintcell{3}{8}{3,6,7,8}
\hintcell{3}{9}{6,7,9}
% * Row 4
\hintcell{4}{1}{1,4,9}
\hintcell{4}{3}{7,9}
\hintcell{4}{4}{3,5,8,9}
\hintcell{4}{5}{1,3,4}
\hintcell{4}{6}{1,3,4,5,8,9}
\hintcell{4}{7}{5,7,8}
\hintcell{4}{9}{4,7}
% * Row 5
\hintcell{5}{2}{2,9}
\hintcell{5}{4}{2,6,9}
\hintcell{5}{6}{4,9}
\hintcell{5}{8}{4,6}
% * Row 6
\hintcell{6}{1}{1,2,4}
\hintcell{6}{3}{2,7}
\hintcell{6}{4}{2,5,6,8}
\hintcell{6}{5}{1,4,6}
\hintcell{6}{6}{1,4,5,8}
\hintcell{6}{7}{5,6,7,8}
\hintcell{6}{9}{4,6,7}
% * Row 7
\hintcell{7}{1}{1,2,6,8}
\hintcell{7}{2}{1,2,7,8}
\hintcell{7}{4}{3,6,7,8}
\hintcell{7}{6}{3,7,8}
\hintcell{7}{8}{1,3,6,7}
\hintcell{7}{9}{1,2,6,7}
% * Row 8
\hintcell{8}{1}{6,8,9}
\hintcell{8}{2}{5,7,8,9}
\hintcell{8}{3}{5,6,7,9}
\hintcell{8}{5}{3,4,6}
\hintcell{8}{7}{3,5,6,7}
\hintcell{8}{8}{3,4,5,6,7}
\hintcell{8}{9}{4,6,7}
% * Row 9
\hintcell{9}{2}{1,2,5,7}
\hintcell{9}{3}{2,5,6,7}
\hintcell{9}{4}{6,7}
\hintcell{9}{6}{4,7}
\hintcell{9}{7}{2,5,6,7}
\hintcell{9}{8}{1,4,5,6,7}
\end{scope}
% Circle some cell
\circlenumber{4-2}{start}
\circlenumber{3-6}{middle}
\circlenumber{7-4}{end}
% Connect
\foreach \source/\dest in {start/middle,middle/end}
\draw[circle number=red!80!black] (\source)--(\dest);
% In background
\circlenumber{5-9}{end 2}
\begin{pgfonlayer}{background}
\draw[circle number=red!80!black] (middle)--(end 2);
\end{pgfonlayer}
\end{tikzpicture}
\end{document}
结果: