我想通过多边形移动线条规范。我当前的代码如下所示(一点也不 DRY):
\documentclass{article}
\usepackage{tikz}
\begin{document}
\usetikzlibrary{shapes,arrows}
\usetikzlibrary{calc}
\usetikzlibrary{shapes,arrows}
\newcommand{\door} {
\begin{scope}[yshift=-0.1cm,xshift=2cm]
\draw[red] (0,0) arc (180:270:1cm);
\draw[black] (1,-1) -- (1,-0) node[right, near start]{};
\draw[black,dotted] (0,-0) -- (1,-0)node(doorstepcenter)[pos=0.5]{} ;
\end{scope}
}
\newcommand{\room} {
\coordinate (a) at (0,0) ;
\coordinate (b) at (5,0);
\coordinate (c) at (5,5);
\coordinate (d) at (0,4);
\coordinate (e) at (1,3) ;
}
\tikzstyle{seed}=[-latex,red];
\begin{tikzpicture}[node distance =4.5cm,thick]
\tikzstyle{door} = [red,thick];
\room;
\draw (a) -- (b);
\draw[seed] (b)--(c);
\draw (c)--(d);
\draw (d)--(e) node[draw,anchor=north west]{} ;
\draw (d) --(a);
\door;
\begin{scope}[xshift=6cm]
\room;
\draw (a) -- (b);
\draw[dashed] (b)--(c);
\draw[seed] (c)--(d);
\draw (d)--(e) node[draw,anchor=north west]{} ;
\draw (d) --(a);
\door;
\end{scope}
\begin{scope}[xshift=12cm]
\room;
\draw (a) -- (b);
\draw[dashed] (b)--(c);
\draw[dashed] (c)--(d);
\draw[seed] (d)--(e) node[draw=black,anchor=north west]{} ;
\draw (d) --(a);
\door;
\end{scope}
\end{tikzpicture}
\end{document}
还有更多多边形需要处理,所以这会变得非常丑陋。我怎样才能将这个例子压缩成更整洁的东西?
编辑:
因此,在过去几天学习了很多 tikz 之后,我瞄准了该版本(感谢这里许多不同的答案)
\begin{document}
\usetikzlibrary{shapes,arrows}
\usetikzlibrary{calc}
\newcommand{\door}[1] {
\begin{scope}[shift={#1}]
\draw[red] (-0.5,0) arc (180:270:1cm);
\draw[black] (0.5,-1) -- (0.5,-0) node[right, near start]{};
\draw[black,dotted] (-0.5,0) -- (0.5,-0)node(doorstepcenter)[pos=0.5]{} ;
\end{scope}
};
\tikzstyle{seed}=[-latex,red, thick];
\newcommand{\room} { %[2]
\coordinate (a1) at (4.5,0.5);
\coordinate (a2) at (4.5,4.5);
\coordinate (a3) at (0,4);
\coordinate (a4) at (1,3);
\coordinate (a5) at (1.4,3) ;
\coordinate (a6) at (1.4,2.6) ;
\coordinate (a7) at (1,2.6) ;
\coordinate (a8) at (1,3);
\coordinate (a9) at (0,4);
\coordinate (a10) at (0,0.5) ;
\coordinate (a11) at (4.5,0.5);
}
\newcommand{\makerow}[3]{
\pgfmathsetmacro{\rows}{#1}
\pgfmathsetmacro{\rowe}{#2}
\pgfmathsetmacro{\ys}{#3}
\pgfmathsetmacro{\n}{10}
\foreach \i in {\rows,...,\rowe}{
\pgfmathsetmacro{\li}{\i+1}
\pgfmathsetmacro{\si}{6*(\i-\rows)}
\begin{scope}[xshift=\si cm, ,yshift=\ys cm]
\room;
\door{ ($ (a10)!0.5! (a1) -(0,0.1) $) };
\foreach \k in {1,...,\n}{
\pgfmathsetmacro{\hk}{\k+1}
\draw[solid] plot coordinates{(a\k) (a\hk)};
}
\foreach \k in {1,...,\i}{
\pgfmathsetmacro{\hk}{\k+1}
\draw[dashed,white,thick] plot coordinates{(a\k) (a\hk)};
}
\draw[seed] plot coordinates{(a\i) (a\li)};
\end{scope}
}
}
\begin{tikzpicture}%[node distance =4.5cm,thick]
\makerow{1}{5}{0};
\makerow{6}{10}{-6};
\end{tikzpicture}
\end{document}
虽然这非常接近我想要实现的图形,但仍然存在一些缺陷。我必须在黑色上绘制白色才能获得虚线,因为我尝试的任何使用嵌套 foreach 的方法(具有变量开始和结束)都失败了。我想我必须多读一些关于 foreach 的内容,但至少这个解决方案的代码比以前少了很多。如果您有进一步的建议,我将非常乐意了解更多信息。
答案1
一种方法是使用\foreach
循环,但不确定它是否能提供您所需的完全灵活性
\foreach \xShift/\BCStyle/\CDStyle/\DEStyle in {%
0cm/seed/none/none,
6cm/dashed/seed/none,
12cm/dashed/dashed/seed}{%
\begin{scope}[xshift=\xShift]
\room;
\draw (a) -- (b);
\draw [\BCStyle] (b)--(c);
\draw [\CDStyle] (c)--(d);
\draw [\DEStyle] (d)--(e)
node[draw=black,anchor=north west]{} ;
\draw (d) --(a);
\door;
\end{scope}
}%
\end{scope}
根据评论中的要求,我在循环中添加了另一个参数,\foreach
以便在每张图片中放置文本:
\foreach \xShift/\BCStyle/\CDStyle/\DEStyle/\Text in {%
0cm/seed/none/none/{Part One},
6cm/dashed/seed/none/{Part Two},
12cm/dashed/dashed/seed/{Part Three}}{%
我不确定您想要将文本放在哪里,因此我定义了另一个文本coordinate
并将其放置在以下值:
\coordinate (TextLocation) at (2,2);
\node at (TextLocation) {\Text};
当然,您可以将其放置在相对于现有节点的位置。
下面的前三幅图像是您的代码生成的图像,后三幅图像是由循环生成的图像foreach
:
笔记:
已
\tikzstyle
被替换\tikzset
为应该使用 \tikzset 还是 \tikzstyle 来定义 TikZ 样式?:\tikzset{seed/.style={-latex,red}} \tikzset{none/.style={}}
进一步增强:
鉴于您更新的版本,我建议您按照线条变为红色的顺序为每行赋予一个数字。然后循环并增加计数器,
iterationCount
并使用以下几行算法来确定要应用于每行的样式:if
\lineNumber
<iterationCount
使用solid
一行else if
\lineNumber
=iterationCount
使用red, solid
一行否则使用一条
dashed
线
代码:
\documentclass{article}
\usepackage[paperwidth=10.0in]{geometry}
\usepackage{tikz}
\usetikzlibrary{calc}
\begin{document}
\newcommand{\door} {
\begin{scope}[yshift=-0.1cm,xshift=2cm]
\draw[red] (0,0) arc (180:270:1cm);
\draw[black] (1,-1) -- (1,-0) node[right, near start]{};
\draw[black,dotted] (0,-0) -- (1,-0)node(doorstepcenter)[pos=0.5]{} ;
\end{scope}
}
\newcommand{\room} {
\coordinate (a) at (0,0);
\coordinate (b) at (5,0);
\coordinate (c) at (5,5);
\coordinate (d) at (0,4);
\coordinate (e) at (1,3);
\coordinate (TextLocation) at (2,2);
}
\tikzset{seed/.style={-latex,red}}
\tikzset{none/.style={}}
\noindent
\begin{tikzpicture}[node distance =4.5cm,thick]
\tikzstyle{door} = [red,thick];
\begin{scope}[xshift=0cm]
\room;
\draw (a) -- (b);
\draw[seed] (b)--(c);
\draw (c)--(d);
\draw (d)--(e) node[draw,anchor=north west]{} ;
\draw (d) --(a);
\door;
\end{scope}
\begin{scope}[xshift=6cm]
\room;
\draw (a) -- (b);
\draw[dashed] (b)--(c);
\draw[seed] (c)--(d);
\draw (d)--(e) node[draw,anchor=north west]{} ;
\draw (d) --(a);
\door;
\end{scope}
\begin{scope}[xshift=12cm]
\room;
\draw (a) -- (b);
\draw[dashed] (b)--(c);
\draw[dashed] (c)--(d);
\draw[seed] (d)--(e) node[draw=black,anchor=north west]{} ;
\draw (d) --(a);
\door;
\end{scope}
% --------------------------------------------------
% Draws all three of the above shifted below by 6cm:
%
\begin{scope}[yshift=-6cm]
\foreach \xShift/\BCStyle/\CDStyle/\DEStyle/\Text in {%
0cm/seed/none/none/{Part One},
6cm/dashed/seed/none/{Part Two},
12cm/dashed/dashed/seed/{Part Three}}{%
\begin{scope}[xshift=\xShift]
\room;
\draw (a) -- (b);
\draw [\BCStyle] (b)--(c);
\draw [\CDStyle] (c)--(d);
\draw [\DEStyle] (d)--(e)
node[draw=black,,anchor=north west]{} ;
\node at (TextLocation) {\Text};
\draw (d) --(a);
\door;
\end{scope}
}%
\end{scope}
\end{tikzpicture}
\end{document}
答案2
我认为使用样式更灵活,但时间更长。它更灵活,因为你可以轻松添加其他样式
\documentclass[landscape]{article}
\usepackage{tikz}
\begin{document}
\usetikzlibrary{shapes,arrows}
\usetikzlibrary{calc}
\usetikzlibrary{shapes,arrows}
\newcommand{\door} {
\begin{scope}[yshift=-0.1cm,xshift=2cm]
\draw[red] (0,0) arc (180:270:1cm);
\draw[black] (1,-1) -- (1,-0) node[right, near start]{};
\draw[black,dotted] (0,-0) -- (1,-0)node(doorstepcenter)[pos=0.5]{} ;
\end{scope}
}
\newcommand{\room} {
\coordinate (a) at (0,0) ;
\coordinate (b) at (5,0);
\coordinate (c) at (5,5);
\coordinate (d) at (0,4);
\coordinate (e) at (1,3) ;
}
\newcommand\myfig{
\room;
\draw (a) -- (b);
\draw[st1] (b)--(c);
\draw[st2] (c)--(d);
\draw[st3] (d)--(e) node[st4]{} ;
\draw (d) --(a);
\door;
}
\tikzset{seed/.style={-latex,red}}
\tikzset{door/.style={red,thick}}
\tikzset{st1/.style={seed}}
\tikzset{st2/.style={}}
\tikzset{st3/.style={}}
\tikzset{st4/.style={draw,anchor=north west}}
\begin{tikzpicture}[node distance =4.5cm,thick]
\myfig
\begin{scope}[xshift=6cm,st1/.style ={dashed},
st2/.style={seed}]
\myfig
\end{scope}
\begin{scope}[xshift=12cm,st1/.style ={dashed},
st2/.style ={dashed},
st3/.style ={seed},
st4/.append style ={draw=black}]
\myfig
\end{scope}
\end{tikzpicture}
\end{document}